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 "LayoutModuleList.h"
39 #include "ModuleList.h"
40 #include "OutputParams.h"
41 #include "PDFOptions.h"
42 #include "qt_helpers.h"
45 #include "insets/InsetListingsParams.h"
47 #include "support/debug.h"
48 #include "support/FileName.h"
49 #include "support/filetools.h"
50 #include "support/gettext.h"
51 #include "support/lstrings.h"
53 #include "frontends/alert.h"
55 #include <QAbstractItemModel>
56 #include <QCloseEvent>
57 #include <QFontDatabase>
59 #include <QTextCursor>
70 using namespace lyx::support;
75 char const * const tex_graphics[] =
77 "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
78 "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
79 "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
80 "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
85 char const * const tex_graphics_gui[] =
87 N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
88 "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
89 "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
90 "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
91 "XeTeX", N_("None"), ""
95 char const * const tex_fonts_roman[] =
97 "default", "cmr", "lmodern", "ae", "times", "palatino",
98 "charter", "newcent", "bookman", "utopia", "beraserif",
99 "ccfonts", "chancery", ""
103 char const * tex_fonts_roman_gui[] =
105 N_("Default"), N_("Computer Modern Roman"), N_("Latin Modern Roman"),
106 N_("AE (Almost European)"), N_("Times Roman"), N_("Palatino"),
107 N_("Bitstream Charter"), N_("New Century Schoolbook"), N_("Bookman"),
108 N_("Utopia"), N_("Bera Serif"), N_("Concrete Roman"), N_("Zapf Chancery"),
113 char const * const tex_fonts_sans[] =
115 "default", "cmss", "lmss", "helvet", "avant", "berasans", "cmbr", ""
119 char const * tex_fonts_sans_gui[] =
121 N_("Default"), N_("Computer Modern Sans"), N_("Latin Modern Sans"),
122 N_("Helvetica"), N_("Avant Garde"), N_("Bera Sans"), N_("CM Bright"), ""
126 char const * const tex_fonts_monospaced[] =
128 "default", "cmtt", "lmtt", "courier", "beramono", "luximono", "cmtl", ""
132 char const * tex_fonts_monospaced_gui[] =
134 N_("Default"), N_("Computer Modern Typewriter"),
135 N_("Latin Modern Typewriter"), N_("Courier"), N_("Bera Mono"),
136 N_("LuxiMono"), N_("CM Typewriter Light"), ""
140 char const * backref_opts[] =
142 "false", "section", "slide", "page", ""
146 char const * backref_opts_gui[] =
148 N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
152 vector<pair<string, QString> > pagestyles;
155 } // anonymous namespace
160 // used when sorting the textclass list.
161 class less_textclass_avail_desc
162 : public binary_function<string, string, int>
165 bool operator()(string const & lhs, string const & rhs) const
167 // Ordering criteria:
168 // 1. Availability of text class
169 // 2. Description (lexicographic)
170 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
171 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
172 int const rel = compare_no_case(
173 translateIfPossible(from_utf8(tc1.description())),
174 translateIfPossible(from_utf8(tc2.description())));
175 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
176 (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() && rel < 0);
185 vector<string> getRequiredList(string const & modName)
187 LyXModule const * const mod = moduleList[modName];
189 return vector<string>(); //empty such thing
190 return mod->getRequiredModules();
194 vector<string> getExcludedList(string const & modName)
196 LyXModule const * const mod = moduleList[modName];
198 return vector<string>(); //empty such thing
199 return mod->getExcludedModules();
203 docstring getModuleDescription(string const & modName)
205 LyXModule const * const mod = moduleList[modName];
207 return _("Module not found!");
209 return translateIfPossible(from_utf8(mod->getDescription()));
213 vector<string> getPackageList(string const & modName)
215 LyXModule const * const mod = moduleList[modName];
217 return vector<string>(); //empty such thing
218 return mod->getPackageList();
222 bool isModuleAvailable(string const & modName)
224 LyXModule * mod = moduleList[modName];
227 return mod->isAvailable();
230 } // anonymous namespace
233 /////////////////////////////////////////////////////////////////////
235 // ModuleSelectionManager
237 /////////////////////////////////////////////////////////////////////
239 /// SelectionManager for use with modules
240 class ModuleSelectionManager : public GuiSelectionManager
244 ModuleSelectionManager(
245 QListView * availableLV,
246 QListView * selectedLV,
250 QPushButton * downPB,
251 GuiIdListModel * availableModel,
252 GuiIdListModel * selectedModel,
253 GuiDocument const * container)
254 : GuiSelectionManager(availableLV, selectedLV, addPB, delPB,
255 upPB, downPB, availableModel, selectedModel), container_(container)
258 void updateProvidedModules(LayoutModuleList const & pm)
259 { provided_modules_ = pm.list(); }
261 void updateExcludedModules(LayoutModuleList const & em)
262 { excluded_modules_ = em.list(); }
265 virtual void updateAddPB();
267 virtual void updateUpPB();
269 virtual void updateDownPB();
271 virtual void updateDelPB();
272 /// returns availableModel as a GuiIdListModel
273 GuiIdListModel * getAvailableModel()
275 return dynamic_cast<GuiIdListModel *>(availableModel);
277 /// returns selectedModel as a GuiIdListModel
278 GuiIdListModel * getSelectedModel()
280 return dynamic_cast<GuiIdListModel *>(selectedModel);
282 /// keeps a list of the modules the text class provides
283 std::list<std::string> provided_modules_;
285 std::list<std::string> excluded_modules_;
287 GuiDocument const * container_;
290 void ModuleSelectionManager::updateAddPB()
292 int const arows = availableModel->rowCount();
293 QModelIndexList const avail_sels =
294 availableLV->selectionModel()->selectedIndexes();
296 // disable if there aren't any modules (?), if none of them is chosen
297 // in the dialog, or if the chosen one is already selected for use.
298 if (arows == 0 || avail_sels.isEmpty() || isSelected(avail_sels.first())) {
299 addPB->setEnabled(false);
303 QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
304 string const modname = getAvailableModel()->getIDString(idx.row());
307 container_->params().moduleCanBeAdded(modname);
308 addPB->setEnabled(enable);
312 void ModuleSelectionManager::updateDownPB()
314 int const srows = selectedModel->rowCount();
316 downPB->setEnabled(false);
319 QModelIndex const & curidx = selectedLV->selectionModel()->currentIndex();
320 int const curRow = curidx.row();
321 if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
322 downPB->setEnabled(false);
326 // determine whether immediately succeding element requires this one
327 string const curmodname = getSelectedModel()->getIDString(curRow);
328 string const nextmodname = getSelectedModel()->getIDString(curRow + 1);
330 vector<string> reqs = getRequiredList(nextmodname);
332 // if it doesn't require anything....
334 downPB->setEnabled(true);
338 // Enable it if this module isn't required.
339 // FIXME This should perhaps be more flexible and check whether, even
340 // if the next one is required, there is also an earlier one that will do.
342 find(reqs.begin(), reqs.end(), curmodname) == reqs.end());
345 void ModuleSelectionManager::updateUpPB()
347 int const srows = selectedModel->rowCount();
349 upPB->setEnabled(false);
353 QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
354 int curRow = curIdx.row();
355 if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
356 upPB->setEnabled(false);
359 string const curmodname = getSelectedModel()->getIDString(curRow);
361 // determine whether immediately preceding element is required by this one
362 vector<string> reqs = getRequiredList(curmodname);
364 // if this one doesn't require anything....
366 upPB->setEnabled(true);
371 // Enable it if the preceding module isn't required.
372 // NOTE This is less flexible than it might be. We could check whether, even
373 // if the previous one is required, there is an earlier one that would do.
374 string const premod = getSelectedModel()->getIDString(curRow - 1);
375 upPB->setEnabled(find(reqs.begin(), reqs.end(), premod) == reqs.end());
378 void ModuleSelectionManager::updateDelPB()
380 int const srows = selectedModel->rowCount();
382 deletePB->setEnabled(false);
386 QModelIndex const & curidx =
387 selectedLV->selectionModel()->currentIndex();
388 int const curRow = curidx.row();
389 if (curRow < 0 || curRow >= srows) { // invalid index?
390 deletePB->setEnabled(false);
394 string const curmodname = getSelectedModel()->getIDString(curRow);
396 // We're looking here for a reason NOT to enable the button. If we
397 // find one, we disable it and return. If we don't, we'll end up at
398 // the end of the function, and then we enable it.
399 for (int i = curRow + 1; i < srows; ++i) {
400 string const thisMod = getSelectedModel()->getIDString(i);
401 vector<string> reqs = getRequiredList(thisMod);
402 //does this one require us?
403 if (find(reqs.begin(), reqs.end(), curmodname) == reqs.end())
407 // OK, so this module requires us
408 // is there an EARLIER module that also satisfies the require?
409 // NOTE We demand that it be earlier to keep the list of modules
410 // consistent with the rule that a module must be proceeded by a
411 // required module. There would be more flexible ways to proceed,
412 // but that would be a lot more complicated, and the logic here is
413 // already complicated. (That's why I've left the debugging code.)
414 // lyxerr << "Testing " << thisMod << std::endl;
415 bool foundone = false;
416 for (int j = 0; j < curRow; ++j) {
417 string const mod = getSelectedModel()->getIDString(j);
418 // lyxerr << "In loop: Testing " << mod << std::endl;
419 // do we satisfy the require?
420 if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
421 // lyxerr << mod << " does the trick." << std::endl;
426 // did we find a module to satisfy the require?
428 // lyxerr << "No matching module found." << std::endl;
429 deletePB->setEnabled(false);
433 // lyxerr << "All's well that ends well." << std::endl;
434 deletePB->setEnabled(true);
438 /////////////////////////////////////////////////////////////////////
442 /////////////////////////////////////////////////////////////////////
444 PreambleModule::PreambleModule() : current_id_(0)
446 // This is not a memory leak. The object will be destroyed
448 (void) new LaTeXHighlighter(preambleTE->document());
449 setFocusProxy(preambleTE);
450 connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
454 void PreambleModule::update(BufferParams const & params, BufferId id)
456 QString preamble = toqstr(params.preamble);
457 // Nothing to do if the params and preamble are unchanged.
458 if (id == current_id_
459 && preamble == preambleTE->document()->toPlainText())
462 QTextCursor cur = preambleTE->textCursor();
463 // Save the coords before switching to the new one.
464 preamble_coords_[current_id_] =
465 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
467 // Save the params address for further use.
469 preambleTE->document()->setPlainText(preamble);
470 Coords::const_iterator it = preamble_coords_.find(current_id_);
471 if (it == preamble_coords_.end())
472 // First time we open this one.
473 preamble_coords_[current_id_] = make_pair(0, 0);
475 // Restore saved coords.
476 QTextCursor cur = preambleTE->textCursor();
477 cur.setPosition(it->second.first);
478 preambleTE->setTextCursor(cur);
479 preambleTE->verticalScrollBar()->setValue(it->second.second);
484 void PreambleModule::apply(BufferParams & params)
486 params.preamble = fromqstr(preambleTE->document()->toPlainText());
490 void PreambleModule::closeEvent(QCloseEvent * e)
492 // Save the coords before closing.
493 QTextCursor cur = preambleTE->textCursor();
494 preamble_coords_[current_id_] =
495 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
500 /////////////////////////////////////////////////////////////////////
504 /////////////////////////////////////////////////////////////////////
507 GuiDocument::GuiDocument(GuiView & lv)
508 : GuiDialog(lv, "document", qt_("Document Settings"))
512 connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
513 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
514 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
515 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
517 connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
518 connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
520 // Manage the restore, ok, apply, restore and cancel/close buttons
521 bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
523 bc().setApply(applyPB);
524 bc().setCancel(closePB);
525 bc().setRestore(restorePB);
527 textLayoutModule = new UiWidget<Ui::TextLayoutUi>;
529 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
530 this, SLOT(change_adaptor()));
531 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
532 this, SLOT(setLSpacing(int)));
533 connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
534 this, SLOT(change_adaptor()));
535 connect(textLayoutModule->skipRB, SIGNAL(clicked()),
536 this, SLOT(change_adaptor()));
537 connect(textLayoutModule->indentRB, SIGNAL(clicked()),
538 this, SLOT(change_adaptor()));
539 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
540 this, SLOT(change_adaptor()));
541 connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
542 this, SLOT(change_adaptor()));
543 connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
544 this, SLOT(change_adaptor()));
545 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
546 this, SLOT(setSkip(int)));
547 connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
548 this, SLOT(enableSkip(bool)));
549 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
550 this, SLOT(change_adaptor()));
551 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
552 this, SLOT(setColSep()));
553 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
554 this, SLOT(change_adaptor()));
555 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
556 this, SLOT(change_adaptor()));
557 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
558 this, SLOT(setListingsMessage()));
559 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
560 this, SLOT(setListingsMessage()));
561 textLayoutModule->listingsTB->setPlainText(
562 qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
563 textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
564 textLayoutModule->lspacingLE));
565 textLayoutModule->skipLE->setValidator(unsignedLengthValidator(
566 textLayoutModule->skipLE));
568 textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
569 textLayoutModule->skipCO->addItem(qt_("MedSkip"));
570 textLayoutModule->skipCO->addItem(qt_("BigSkip"));
571 textLayoutModule->skipCO->addItem(qt_("Length"));
572 // remove the %-items from the unit choice
573 textLayoutModule->skipLengthCO->noPercents();
574 textLayoutModule->lspacingCO->insertItem(
575 Spacing::Single, qt_("Single"));
576 textLayoutModule->lspacingCO->insertItem(
577 Spacing::Onehalf, qt_("OneHalf"));
578 textLayoutModule->lspacingCO->insertItem(
579 Spacing::Double, qt_("Double"));
580 textLayoutModule->lspacingCO->insertItem(
581 Spacing::Other, qt_("Custom"));
583 // initialize the length validator
584 bc().addCheckedLineEdit(textLayoutModule->skipLE);
586 fontModule = new UiWidget<Ui::FontUi>;
588 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
589 this, SLOT(change_adaptor()));
590 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
591 this, SLOT(romanChanged(int)));
592 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
593 this, SLOT(change_adaptor()));
594 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
595 this, SLOT(sansChanged(int)));
596 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
597 this, SLOT(change_adaptor()));
598 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
599 this, SLOT(ttChanged(int)));
600 connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
601 this, SLOT(change_adaptor()));
602 connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
603 this, SLOT(change_adaptor()));
604 connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
605 this, SLOT(change_adaptor()));
606 connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
607 this, SLOT(change_adaptor()));
608 connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
609 this, SLOT(change_adaptor()));
610 connect(fontModule->fontScCB, SIGNAL(clicked()),
611 this, SLOT(change_adaptor()));
612 connect(fontModule->fontOsfCB, SIGNAL(clicked()),
613 this, SLOT(change_adaptor()));
614 connect(fontModule->xetexCB, SIGNAL(clicked()),
615 this, SLOT(change_adaptor()));
616 connect(fontModule->xetexCB, SIGNAL(toggled(bool)),
617 this, SLOT(xetexChanged(bool)));
621 fontModule->fontsizeCO->addItem(qt_("Default"));
622 fontModule->fontsizeCO->addItem(qt_("10"));
623 fontModule->fontsizeCO->addItem(qt_("11"));
624 fontModule->fontsizeCO->addItem(qt_("12"));
626 for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
627 fontModule->fontsDefaultCO->addItem(
628 qt_(GuiDocument::fontfamilies_gui[n]));
631 pageLayoutModule = new UiWidget<Ui::PageLayoutUi>;
633 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
634 this, SLOT(setCustomPapersize(int)));
635 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
636 this, SLOT(setCustomPapersize(int)));
637 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
638 this, SLOT(portraitChanged()));
639 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
640 this, SLOT(change_adaptor()));
641 connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
642 this, SLOT(change_adaptor()));
643 connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
644 this, SLOT(change_adaptor()));
645 connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
646 this, SLOT(change_adaptor()));
647 connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
648 this, SLOT(change_adaptor()));
649 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
650 this, SLOT(change_adaptor()));
651 connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
652 this, SLOT(change_adaptor()));
653 connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
654 this, SLOT(change_adaptor()));
655 connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
656 this, SLOT(change_adaptor()));
658 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
659 pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
660 pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
661 pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
662 pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
663 bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
664 pageLayoutModule->paperheightL);
665 bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
666 pageLayoutModule->paperwidthL);
669 QComboBox * cb = pageLayoutModule->papersizeCO;
670 cb->addItem(qt_("Default"));
671 cb->addItem(qt_("Custom"));
672 cb->addItem(qt_("US letter"));
673 cb->addItem(qt_("US legal"));
674 cb->addItem(qt_("US executive"));
675 cb->addItem(qt_("A3"));
676 cb->addItem(qt_("A4"));
677 cb->addItem(qt_("A5"));
678 cb->addItem(qt_("B3"));
679 cb->addItem(qt_("B4"));
680 cb->addItem(qt_("B5"));
681 // remove the %-items from the unit choice
682 pageLayoutModule->paperwidthUnitCO->noPercents();
683 pageLayoutModule->paperheightUnitCO->noPercents();
684 pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
685 pageLayoutModule->paperheightLE));
686 pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
687 pageLayoutModule->paperwidthLE));
690 marginsModule = new UiWidget<Ui::MarginsUi>;
692 connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
693 this, SLOT(setCustomMargins(bool)));
694 connect(marginsModule->marginCB, SIGNAL(clicked()),
695 this, SLOT(change_adaptor()));
696 connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
697 this, SLOT(change_adaptor()));
698 connect(marginsModule->topUnit, SIGNAL(activated(int)),
699 this, SLOT(change_adaptor()));
700 connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
701 this, SLOT(change_adaptor()));
702 connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
703 this, SLOT(change_adaptor()));
704 connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
705 this, SLOT(change_adaptor()));
706 connect(marginsModule->innerUnit, SIGNAL(activated(int)),
707 this, SLOT(change_adaptor()));
708 connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
709 this, SLOT(change_adaptor()));
710 connect(marginsModule->outerUnit, SIGNAL(activated(int)),
711 this, SLOT(change_adaptor()));
712 connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
713 this, SLOT(change_adaptor()));
714 connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
715 this, SLOT(change_adaptor()));
716 connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
717 this, SLOT(change_adaptor()));
718 connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
719 this, SLOT(change_adaptor()));
720 connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
721 this, SLOT(change_adaptor()));
722 connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
723 this, SLOT(change_adaptor()));
724 connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
725 this, SLOT(change_adaptor()));
726 connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
727 this, SLOT(change_adaptor()));
728 marginsModule->topLE->setValidator(unsignedLengthValidator(
729 marginsModule->topLE));
730 marginsModule->bottomLE->setValidator(unsignedLengthValidator(
731 marginsModule->bottomLE));
732 marginsModule->innerLE->setValidator(unsignedLengthValidator(
733 marginsModule->innerLE));
734 marginsModule->outerLE->setValidator(unsignedLengthValidator(
735 marginsModule->outerLE));
736 marginsModule->headsepLE->setValidator(unsignedLengthValidator(
737 marginsModule->headsepLE));
738 marginsModule->headheightLE->setValidator(unsignedLengthValidator(
739 marginsModule->headheightLE));
740 marginsModule->footskipLE->setValidator(unsignedLengthValidator(
741 marginsModule->footskipLE));
742 marginsModule->columnsepLE->setValidator(unsignedLengthValidator(
743 marginsModule->columnsepLE));
745 bc().addCheckedLineEdit(marginsModule->topLE,
746 marginsModule->topL);
747 bc().addCheckedLineEdit(marginsModule->bottomLE,
748 marginsModule->bottomL);
749 bc().addCheckedLineEdit(marginsModule->innerLE,
750 marginsModule->innerL);
751 bc().addCheckedLineEdit(marginsModule->outerLE,
752 marginsModule->outerL);
753 bc().addCheckedLineEdit(marginsModule->headsepLE,
754 marginsModule->headsepL);
755 bc().addCheckedLineEdit(marginsModule->headheightLE,
756 marginsModule->headheightL);
757 bc().addCheckedLineEdit(marginsModule->footskipLE,
758 marginsModule->footskipL);
759 bc().addCheckedLineEdit(marginsModule->columnsepLE,
760 marginsModule->columnsepL);
763 langModule = new UiWidget<Ui::LanguageUi>;
765 connect(langModule->languageCO, SIGNAL(activated(int)),
766 this, SLOT(change_adaptor()));
767 connect(langModule->defaultencodingRB, SIGNAL(clicked()),
768 this, SLOT(change_adaptor()));
769 connect(langModule->otherencodingRB, SIGNAL(clicked()),
770 this, SLOT(change_adaptor()));
771 connect(langModule->encodingCO, SIGNAL(activated(int)),
772 this, SLOT(change_adaptor()));
773 connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
774 this, SLOT(change_adaptor()));
776 QAbstractItemModel * language_model = guiApp->languageModel();
777 // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
778 language_model->sort(0);
779 langModule->languageCO->setModel(language_model);
781 // Always put the default encoding in the first position.
782 langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
783 QStringList encodinglist;
784 Encodings::const_iterator it = encodings.begin();
785 Encodings::const_iterator const end = encodings.end();
786 for (; it != end; ++it)
787 encodinglist.append(qt_(it->guiName()));
789 langModule->encodingCO->addItems(encodinglist);
791 langModule->quoteStyleCO->addItem(qt_("``text''"));
792 langModule->quoteStyleCO->addItem(qt_("''text''"));
793 langModule->quoteStyleCO->addItem(qt_(",,text``"));
794 langModule->quoteStyleCO->addItem(qt_(",,text''"));
795 langModule->quoteStyleCO->addItem(qt_("<<text>>"));
796 langModule->quoteStyleCO->addItem(qt_(">>text<<"));
799 numberingModule = new UiWidget<Ui::NumberingUi>;
801 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
802 this, SLOT(change_adaptor()));
803 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
804 this, SLOT(change_adaptor()));
805 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
806 this, SLOT(updateNumbering()));
807 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
808 this, SLOT(updateNumbering()));
809 numberingModule->tocTW->setColumnCount(3);
810 numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
811 numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
812 numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
815 biblioModule = new UiWidget<Ui::BiblioUi>;
816 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
817 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
818 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
819 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
821 connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
822 this, SLOT(change_adaptor()));
823 connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
824 this, SLOT(change_adaptor()));
825 connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
826 this, SLOT(change_adaptor()));
827 connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
828 this, SLOT(change_adaptor()));
829 connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
830 this, SLOT(change_adaptor()));
832 biblioModule->citeStyleCO->addItem(qt_("Author-year"));
833 biblioModule->citeStyleCO->addItem(qt_("Numerical"));
834 biblioModule->citeStyleCO->setCurrentIndex(0);
837 mathsModule = new UiWidget<Ui::MathsUi>;
838 connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
839 mathsModule->amsCB, SLOT(setDisabled(bool)));
840 connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
841 mathsModule->esintCB, SLOT(setDisabled(bool)));
843 connect(mathsModule->amsCB, SIGNAL(clicked()),
844 this, SLOT(change_adaptor()));
845 connect(mathsModule->amsautoCB, SIGNAL(clicked()),
846 this, SLOT(change_adaptor()));
847 connect(mathsModule->esintCB, SIGNAL(clicked()),
848 this, SLOT(change_adaptor()));
849 connect(mathsModule->esintautoCB, SIGNAL(clicked()),
850 this, SLOT(change_adaptor()));
852 latexModule = new UiWidget<Ui::LaTeXUi>;
854 connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
855 this, SLOT(change_adaptor()));
856 connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
857 this, SLOT(change_adaptor()));
858 connect(latexModule->psdriverCO, SIGNAL(activated(int)),
859 this, SLOT(change_adaptor()));
860 connect(latexModule->classCO, SIGNAL(activated(int)),
861 this, SLOT(classChanged()));
862 connect(latexModule->classCO, SIGNAL(activated(int)),
863 this, SLOT(change_adaptor()));
864 connect(latexModule->layoutPB, SIGNAL(clicked()),
865 this, SLOT(browseLayout()));
866 connect(latexModule->layoutPB, SIGNAL(clicked()),
867 this, SLOT(change_adaptor()));
868 connect(latexModule->childDocGB, SIGNAL(clicked()),
869 this, SLOT(change_adaptor()));
870 connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
871 this, SLOT(change_adaptor()));
872 connect(latexModule->childDocPB, SIGNAL(clicked()),
873 this, SLOT(browseMaster()));
875 // postscript drivers
876 for (int n = 0; tex_graphics[n][0]; ++n) {
877 QString enc = qt_(tex_graphics_gui[n]);
878 latexModule->psdriverCO->addItem(enc);
881 latexModule->classCO->setModel(&classes_model_);
882 LayoutFileList const & bcl = LayoutFileList::get();
883 vector<LayoutFileIndex> classList = bcl.classList();
884 sort(classList.begin(), classList.end(), less_textclass_avail_desc());
886 vector<LayoutFileIndex>::const_iterator cit = classList.begin();
887 vector<LayoutFileIndex>::const_iterator cen = classList.end();
888 for (int i = 0; cit != cen; ++cit, ++i) {
889 LayoutFile const & tc = bcl[*cit];
890 docstring item = (tc.isTeXClassAvailable()) ?
891 from_utf8(tc.description()) :
892 bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
893 classes_model_.insertRow(i, toqstr(item), *cit);
897 branchesModule = new GuiBranches;
898 connect(branchesModule, SIGNAL(changed()),
899 this, SLOT(change_adaptor()));
902 preambleModule = new PreambleModule;
903 connect(preambleModule, SIGNAL(changed()),
904 this, SLOT(change_adaptor()));
907 bulletsModule = new BulletsModule;
908 connect(bulletsModule, SIGNAL(changed()),
909 this, SLOT(change_adaptor()));
912 modulesModule = new UiWidget<Ui::ModulesUi>;
915 new ModuleSelectionManager(modulesModule->availableLV,
916 modulesModule->selectedLV,
917 modulesModule->addPB, modulesModule->deletePB,
918 modulesModule->upPB, modulesModule->downPB,
919 availableModel(), selectedModel(), this);
920 connect(selectionManager, SIGNAL(updateHook()),
921 this, SLOT(updateModuleInfo()));
922 connect(selectionManager, SIGNAL(updateHook()),
923 this, SLOT(change_adaptor()));
924 connect(selectionManager, SIGNAL(selectionChanged()),
925 this, SLOT(modulesChanged()));
928 pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
930 connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
931 this, SLOT(change_adaptor()));
932 connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
933 this, SLOT(change_adaptor()));
934 connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
935 this, SLOT(change_adaptor()));
936 connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
937 this, SLOT(change_adaptor()));
938 connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
939 this, SLOT(change_adaptor()));
940 connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
941 this, SLOT(change_adaptor()));
942 connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
943 this, SLOT(change_adaptor()));
944 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
945 this, SLOT(change_adaptor()));
946 connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
947 this, SLOT(change_adaptor()));
948 connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
949 this, SLOT(change_adaptor()));
950 connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
951 this, SLOT(change_adaptor()));
952 connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
953 this, SLOT(change_adaptor()));
954 connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
955 this, SLOT(change_adaptor()));
956 connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
957 this, SLOT(change_adaptor()));
958 connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
959 this, SLOT(change_adaptor()));
960 connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
961 this, SLOT(change_adaptor()));
963 for (int i = 0; backref_opts[i][0]; ++i)
964 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
967 floatModule = new FloatPlacement;
968 connect(floatModule, SIGNAL(changed()),
969 this, SLOT(change_adaptor()));
971 docPS->addPanel(latexModule, qt_("Document Class"));
972 docPS->addPanel(modulesModule, qt_("Modules"));
973 docPS->addPanel(fontModule, qt_("Fonts"));
974 docPS->addPanel(textLayoutModule, qt_("Text Layout"));
975 docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
976 docPS->addPanel(marginsModule, qt_("Page Margins"));
977 docPS->addPanel(langModule, qt_("Language"));
978 docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
979 docPS->addPanel(biblioModule, qt_("Bibliography"));
980 docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
981 docPS->addPanel(mathsModule, qt_("Math Options"));
982 docPS->addPanel(floatModule, qt_("Float Placement"));
983 docPS->addPanel(bulletsModule, qt_("Bullets"));
984 docPS->addPanel(branchesModule, qt_("Branches"));
985 docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
986 docPS->setCurrentPanel(qt_("Document Class"));
987 // FIXME: hack to work around resizing bug in Qt >= 4.2
988 // bug verified with Qt 4.2.{0-3} (JSpitzm)
989 #if QT_VERSION >= 0x040200
990 docPS->updateGeometry();
995 void GuiDocument::showPreamble()
997 docPS->setCurrentPanel(qt_("LaTeX Preamble"));
1001 void GuiDocument::saveDefaultClicked()
1007 void GuiDocument::useDefaultsClicked()
1013 void GuiDocument::change_adaptor()
1019 QString GuiDocument::validateListingsParameters()
1021 // use a cache here to avoid repeated validation
1022 // of the same parameters
1023 static string param_cache;
1024 static QString msg_cache;
1026 if (textLayoutModule->bypassCB->isChecked())
1029 string params = fromqstr(textLayoutModule->listingsED->toPlainText());
1030 if (params != param_cache) {
1031 param_cache = params;
1032 msg_cache = toqstr(InsetListingsParams(params).validate());
1038 void GuiDocument::setListingsMessage()
1040 static bool isOK = true;
1041 QString msg = validateListingsParameters();
1042 if (msg.isEmpty()) {
1046 // listingsTB->setTextColor("black");
1047 textLayoutModule->listingsTB->setPlainText(
1048 qt_("Input listings parameters on the right. "
1049 "Enter ? for a list of parameters."));
1052 // listingsTB->setTextColor("red");
1053 textLayoutModule->listingsTB->setPlainText(msg);
1058 void GuiDocument::setLSpacing(int item)
1060 textLayoutModule->lspacingLE->setEnabled(item == 3);
1064 void GuiDocument::setSkip(int item)
1066 bool const enable = (item == 3);
1067 textLayoutModule->skipLE->setEnabled(enable);
1068 textLayoutModule->skipLengthCO->setEnabled(enable);
1072 void GuiDocument::enableSkip(bool skip)
1074 textLayoutModule->skipCO->setEnabled(skip);
1075 textLayoutModule->skipLE->setEnabled(skip);
1076 textLayoutModule->skipLengthCO->setEnabled(skip);
1078 setSkip(textLayoutModule->skipCO->currentIndex());
1082 void GuiDocument::portraitChanged()
1084 setMargins(pageLayoutModule->papersizeCO->currentIndex());
1088 void GuiDocument::setMargins(bool custom)
1090 bool const extern_geometry =
1091 documentClass().provides("geometry");
1092 marginsModule->marginCB->setEnabled(!extern_geometry);
1093 if (extern_geometry) {
1094 marginsModule->marginCB->setChecked(false);
1095 setCustomMargins(true);
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::xetexChanged(bool xetex)
1164 langModule->encodingCO->setEnabled(!xetex &&
1165 !langModule->defaultencodingRB->isChecked());
1166 langModule->defaultencodingRB->setEnabled(!xetex);
1167 langModule->otherencodingRB->setEnabled(!xetex);
1171 void GuiDocument::updateFontsize(string const & items, string const & sel)
1173 fontModule->fontsizeCO->clear();
1174 fontModule->fontsizeCO->addItem(qt_("Default"));
1176 for (int n = 0; !token(items,'|',n).empty(); ++n)
1177 fontModule->fontsizeCO->
1178 addItem(toqstr(token(items,'|',n)));
1180 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1181 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1182 fontModule->fontsizeCO->setCurrentIndex(n);
1189 void GuiDocument::updateFontlist()
1191 fontModule->fontsRomanCO->clear();
1192 fontModule->fontsSansCO->clear();
1193 fontModule->fontsTypewriterCO->clear();
1195 // With XeTeX, we have access to all system fonts, but not the LaTeX fonts
1196 if (fontModule->xetexCB->isChecked()) {
1197 fontModule->fontsRomanCO->addItem(qt_("Default"));
1198 fontModule->fontsSansCO->addItem(qt_("Default"));
1199 fontModule->fontsTypewriterCO->addItem(qt_("Default"));
1201 QFontDatabase fontdb;
1202 QStringList families(fontdb.families());
1203 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
1204 fontModule->fontsRomanCO->addItem(*it);
1205 fontModule->fontsSansCO->addItem(*it);
1206 fontModule->fontsTypewriterCO->addItem(*it);
1211 for (int n = 0; tex_fonts_roman[n][0]; ++n) {
1212 QString font = qt_(tex_fonts_roman_gui[n]);
1213 if (!isFontAvailable(tex_fonts_roman[n]))
1214 font += qt_(" (not installed)");
1215 fontModule->fontsRomanCO->addItem(font);
1217 for (int n = 0; tex_fonts_sans[n][0]; ++n) {
1218 QString font = qt_(tex_fonts_sans_gui[n]);
1219 if (!isFontAvailable(tex_fonts_sans[n]))
1220 font += qt_(" (not installed)");
1221 fontModule->fontsSansCO->addItem(font);
1223 for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
1224 QString font = qt_(tex_fonts_monospaced_gui[n]);
1225 if (!isFontAvailable(tex_fonts_monospaced[n]))
1226 font += qt_(" (not installed)");
1227 fontModule->fontsTypewriterCO->addItem(font);
1232 void GuiDocument::romanChanged(int item)
1234 if (fontModule->xetexCB->isChecked()) {
1235 fontModule->fontScCB->setEnabled(false);
1238 string const font = tex_fonts_roman[item];
1239 fontModule->fontScCB->setEnabled(providesSC(font));
1240 fontModule->fontOsfCB->setEnabled(providesOSF(font));
1244 void GuiDocument::sansChanged(int item)
1246 if (fontModule->xetexCB->isChecked()) {
1247 fontModule->fontScCB->setEnabled(false);
1250 string const font = tex_fonts_sans[item];
1251 bool scaleable = providesScale(font);
1252 fontModule->scaleSansSB->setEnabled(scaleable);
1253 fontModule->scaleSansLA->setEnabled(scaleable);
1257 void GuiDocument::ttChanged(int item)
1259 if (fontModule->xetexCB->isChecked()) {
1260 fontModule->fontScCB->setEnabled(false);
1263 string const font = tex_fonts_monospaced[item];
1264 bool scaleable = providesScale(font);
1265 fontModule->scaleTypewriterSB->setEnabled(scaleable);
1266 fontModule->scaleTypewriterLA->setEnabled(scaleable);
1270 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1273 pageLayoutModule->pagestyleCO->clear();
1274 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1276 for (int n = 0; !token(items, '|', n).empty(); ++n) {
1277 string style = token(items, '|', n);
1278 QString style_gui = qt_(style);
1279 pagestyles.push_back(pair<string, QString>(style, style_gui));
1280 pageLayoutModule->pagestyleCO->addItem(style_gui);
1283 if (sel == "default") {
1284 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1290 for (size_t i = 0; i < pagestyles.size(); ++i)
1291 if (pagestyles[i].first == sel)
1292 nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1295 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1299 void GuiDocument::browseLayout()
1301 QString const label1 = qt_("Layouts|#o#O");
1302 QString const dir1 = toqstr(lyxrc.document_path);
1303 QStringList const filter(qt_("LyX Layout (*.layout)"));
1304 QString file = browseRelFile(QString(), bufferFilepath(),
1305 qt_("Local layout file"), filter, false,
1308 if (!file.endsWith(".layout"))
1311 FileName layoutFile = support::makeAbsPath(fromqstr(file),
1312 fromqstr(bufferFilepath()));
1314 int const ret = Alert::prompt(_("Local layout file"),
1315 _("The layout file you have selected is a local layout\n"
1316 "file, not one in the system or user directory. Your\n"
1317 "document may not work with this layout if you do not\n"
1318 "keep the layout file in the document directory."),
1319 1, 1, _("&Set Layout"), _("&Cancel"));
1323 // load the layout file
1324 LayoutFileList & bcl = LayoutFileList::get();
1325 string classname = layoutFile.onlyFileName();
1326 // this will update an existing layout if that layout has been loaded before.
1327 LayoutFileIndex name = bcl.addLocalLayout(
1328 classname.substr(0, classname.size() - 7),
1329 layoutFile.onlyPath().absFilename());
1332 Alert::error(_("Error"),
1333 _("Unable to read local layout file."));
1337 // do not trigger classChanged if there is no change.
1338 if (latexModule->classCO->currentText() == toqstr(name))
1342 int idx = latexModule->classCO->findText(toqstr(name));
1344 classes_model_.insertRow(0, toqstr(name), name);
1345 latexModule->classCO->setCurrentIndex(0);
1347 latexModule->classCO->setCurrentIndex(idx);
1353 void GuiDocument::browseMaster()
1355 QString const title = qt_("Select master document");
1356 QString const dir1 = toqstr(lyxrc.document_path);
1357 QString const old = latexModule->childDocLE->text();
1358 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1359 QStringList const filter(qt_("LyX Files (*.lyx)"));
1360 QString file = browseRelFile(old, docpath, title, filter, false,
1361 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1363 latexModule->childDocLE->setText(file);
1367 void GuiDocument::classChanged()
1369 int idx = latexModule->classCO->currentIndex();
1372 string const classname = classes_model_.getIDString(idx);
1374 // check whether the selected modules have changed.
1375 bool modules_changed = false;
1376 unsigned int const srows = selectedModel()->rowCount();
1377 if (srows != bp_.getModules().size())
1378 modules_changed = true;
1380 list<string>::const_iterator mit = bp_.getModules().begin();
1381 list<string>::const_iterator men = bp_.getModules().end();
1382 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1383 if (selectedModel()->getIDString(i) != *mit) {
1384 modules_changed = true;
1389 if (modules_changed || lyxrc.auto_reset_options) {
1390 if (applyPB->isEnabled()) {
1391 int const ret = Alert::prompt(_("Unapplied changes"),
1392 _("Some changes in the dialog were not yet applied.\n"
1393 "If you do not apply now, they will be lost after this action."),
1394 1, 1, _("&Apply"), _("&Dismiss"));
1400 // We load the TextClass as soon as it is selected. This is
1401 // necessary so that other options in the dialog can be updated
1402 // according to the new class. Note, however, that, if you use
1403 // the scroll wheel when sitting on the combo box, we'll load a
1404 // lot of TextClass objects very quickly....
1405 if (!bp_.setBaseClass(classname)) {
1406 Alert::error(_("Error"), _("Unable to set document class."));
1409 if (lyxrc.auto_reset_options)
1410 bp_.useClassDefaults();
1412 // With the introduction of modules came a distinction between the base
1413 // class and the document class. The former corresponds to the main layout
1414 // file; the latter is that plus the modules (or the document-specific layout,
1415 // or whatever else there could be). Our parameters come from the document
1416 // class. So when we set the base class, we also need to recreate the document
1417 // class. Otherwise, we still have the old one.
1418 bp_.makeDocumentClass();
1424 // This is an insanely complicated attempt to make this sort of thing
1425 // work with RTL languages.
1426 docstring formatStrVec(vector<string> const & v, docstring const & s)
1428 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1432 return from_utf8(v[0]);
1433 if (v.size() == 2) {
1434 docstring retval = _("%1$s and %2$s");
1435 retval = subst(retval, _("and"), s);
1436 return bformat(retval, from_utf8(v[0]), from_utf8(v[1]));
1438 // The idea here is to format all but the last two items...
1439 int const vSize = v.size();
1440 docstring t2 = _("%1$s, %2$s");
1441 docstring retval = from_utf8(v[0]);
1442 for (int i = 1; i < vSize - 2; ++i)
1443 retval = bformat(t2, retval, from_utf8(v[i]));
1444 //...and then to plug them, and the last two, into this schema
1445 docstring t = _("%1$s, %2$s, and %3$s");
1446 t = subst(t, _("and"), s);
1447 return bformat(t, retval, from_utf8(v[vSize - 2]), from_utf8(v[vSize - 1]));
1450 vector<string> idsToNames(vector<string> const & idList)
1452 vector<string> retval;
1453 vector<string>::const_iterator it = idList.begin();
1454 vector<string>::const_iterator end = idList.end();
1455 for (; it != end; ++it) {
1456 LyXModule const * const mod = moduleList[*it];
1458 retval.push_back(*it + " (Unavailable)");
1460 retval.push_back(mod->getName());
1467 void GuiDocument::modulesToParams(BufferParams & bp)
1469 // update list of loaded modules
1470 bp.clearLayoutModules();
1471 int const srows = modules_sel_model_.rowCount();
1472 for (int i = 0; i < srows; ++i)
1473 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1475 // update the list of removed modules
1476 bp.clearRemovedModules();
1477 LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
1478 list<string>::const_iterator rit = reqmods.begin();
1479 list<string>::const_iterator ren = reqmods.end();
1481 // check each of the default modules
1482 for (; rit != ren; rit++) {
1483 list<string>::const_iterator mit = bp.getModules().begin();
1484 list<string>::const_iterator men = bp.getModules().end();
1486 for (; mit != men; mit++) {
1493 // the module isn't present so must have been removed by the user
1494 bp.addRemovedModule(*rit);
1499 void GuiDocument::modulesChanged()
1501 modulesToParams(bp_);
1502 bp_.makeDocumentClass();
1507 void GuiDocument::updateModuleInfo()
1509 selectionManager->update();
1511 //Module description
1512 bool const focus_on_selected = selectionManager->selectedFocused();
1513 QListView const * const lv =
1514 focus_on_selected ? modulesModule->selectedLV : modulesModule->availableLV;
1515 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1516 modulesModule->infoML->document()->clear();
1519 QModelIndex const & idx = lv->selectionModel()->currentIndex();
1520 GuiIdListModel const & id_model =
1521 focus_on_selected ? modules_sel_model_ : modules_av_model_;
1522 string const modName = id_model.getIDString(idx.row());
1523 docstring desc = getModuleDescription(modName);
1525 LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
1526 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
1529 desc += _("Module provided by document class.");
1532 vector<string> pkglist = getPackageList(modName);
1533 docstring pkgdesc = formatStrVec(pkglist, _("and"));
1534 if (!pkgdesc.empty()) {
1537 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1540 pkglist = getRequiredList(modName);
1541 if (!pkglist.empty()) {
1542 vector<string> const reqdescs = idsToNames(pkglist);
1543 pkgdesc = formatStrVec(reqdescs, _("or"));
1546 desc += bformat(_("Module required: %1$s."), pkgdesc);
1549 pkglist = getExcludedList(modName);
1550 if (!pkglist.empty()) {
1551 vector<string> const reqdescs = idsToNames(pkglist);
1552 pkgdesc = formatStrVec(reqdescs, _( "and"));
1555 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1558 if (!isModuleAvailable(modName)) {
1561 desc += _("WARNING: Some required packages are unavailable!");
1564 modulesModule->infoML->document()->setPlainText(toqstr(desc));
1568 void GuiDocument::updateNumbering()
1570 DocumentClass const & tclass = documentClass();
1572 numberingModule->tocTW->setUpdatesEnabled(false);
1573 numberingModule->tocTW->clear();
1575 int const depth = numberingModule->depthSL->value();
1576 int const toc = numberingModule->tocSL->value();
1577 QString const no = qt_("No");
1578 QString const yes = qt_("Yes");
1579 QTreeWidgetItem * item = 0;
1581 DocumentClass::const_iterator lit = tclass.begin();
1582 DocumentClass::const_iterator len = tclass.end();
1583 for (; lit != len; ++lit) {
1584 int const toclevel = lit->toclevel;
1585 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1586 item = new QTreeWidgetItem(numberingModule->tocTW);
1587 item->setText(0, toqstr(translateIfPossible(lit->name())));
1588 item->setText(1, (toclevel <= depth) ? yes : no);
1589 item->setText(2, (toclevel <= toc) ? yes : no);
1593 numberingModule->tocTW->setUpdatesEnabled(true);
1594 numberingModule->tocTW->update();
1598 void GuiDocument::applyView()
1601 preambleModule->apply(bp_);
1604 bp_.setCiteEngine(ENGINE_BASIC);
1606 if (biblioModule->citeNatbibRB->isChecked()) {
1607 bool const use_numerical_citations =
1608 biblioModule->citeStyleCO->currentIndex();
1609 if (use_numerical_citations)
1610 bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1612 bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1614 } else if (biblioModule->citeJurabibRB->isChecked())
1615 bp_.setCiteEngine(ENGINE_JURABIB);
1618 biblioModule->bibtopicCB->isChecked();
1620 // language & quotes
1621 if (langModule->defaultencodingRB->isChecked()) {
1622 bp_.inputenc = "auto";
1624 int i = langModule->encodingCO->currentIndex();
1626 bp_.inputenc = "default";
1628 QString const enc_gui =
1629 langModule->encodingCO->currentText();
1630 Encodings::const_iterator it = encodings.begin();
1631 Encodings::const_iterator const end = encodings.end();
1633 for (; it != end; ++it) {
1634 if (qt_(it->guiName()) == enc_gui) {
1635 bp_.inputenc = it->latexName();
1641 // should not happen
1642 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1643 bp_.inputenc = "default";
1648 InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1649 switch (langModule->quoteStyleCO->currentIndex()) {
1651 lga = InsetQuotes::EnglishQuotes;
1654 lga = InsetQuotes::SwedishQuotes;
1657 lga = InsetQuotes::GermanQuotes;
1660 lga = InsetQuotes::PolishQuotes;
1663 lga = InsetQuotes::FrenchQuotes;
1666 lga = InsetQuotes::DanishQuotes;
1669 bp_.quotes_language = lga;
1671 QString const lang = langModule->languageCO->itemData(
1672 langModule->languageCO->currentIndex()).toString();
1673 bp_.language = lyx::languages.getLanguage(fromqstr(lang));
1676 if (bp_.documentClass().hasTocLevels()) {
1677 bp_.tocdepth = numberingModule->tocSL->value();
1678 bp_.secnumdepth = numberingModule->depthSL->value();
1682 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
1683 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
1684 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
1685 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
1688 bp_.graphicsDriver =
1689 tex_graphics[latexModule->psdriverCO->currentIndex()];
1692 int idx = latexModule->classCO->currentIndex();
1694 string const classname = classes_model_.getIDString(idx);
1695 bp_.setBaseClass(classname);
1699 modulesToParams(bp_);
1701 if (mathsModule->amsautoCB->isChecked()) {
1702 bp_.use_amsmath = BufferParams::package_auto;
1704 if (mathsModule->amsCB->isChecked())
1705 bp_.use_amsmath = BufferParams::package_on;
1707 bp_.use_amsmath = BufferParams::package_off;
1710 if (mathsModule->esintautoCB->isChecked())
1711 bp_.use_esint = BufferParams::package_auto;
1713 if (mathsModule->esintCB->isChecked())
1714 bp_.use_esint = BufferParams::package_on;
1716 bp_.use_esint = BufferParams::package_off;
1719 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1720 bp_.pagestyle = "default";
1722 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1723 for (size_t i = 0; i != pagestyles.size(); ++i)
1724 if (pagestyles[i].second == style_gui)
1725 bp_.pagestyle = pagestyles[i].first;
1728 switch (textLayoutModule->lspacingCO->currentIndex()) {
1730 bp_.spacing().set(Spacing::Single);
1733 bp_.spacing().set(Spacing::Onehalf);
1736 bp_.spacing().set(Spacing::Double);
1739 bp_.spacing().set(Spacing::Other,
1740 fromqstr(textLayoutModule->lspacingLE->text()));
1744 if (textLayoutModule->twoColumnCB->isChecked())
1749 // text should have passed validation
1750 bp_.listings_params =
1751 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1753 if (textLayoutModule->indentRB->isChecked())
1754 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1756 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1758 switch (textLayoutModule->skipCO->currentIndex()) {
1760 bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
1763 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1766 bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
1771 widgetsToLength(textLayoutModule->skipLE,
1772 textLayoutModule->skipLengthCO)
1778 // DocumentDefskipCB assures that this never happens
1779 // so Assert then !!! - jbl
1780 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1785 fromqstr(latexModule->optionsLE->text());
1787 bp_.use_default_options =
1788 latexModule->defaultOptionsCB->isChecked();
1790 if (latexModule->childDocGB->isChecked())
1792 fromqstr(latexModule->childDocLE->text());
1794 bp_.master = string();
1796 bp_.float_placement = floatModule->get();
1799 bool const xetex = fontModule->xetexCB->isChecked();
1800 bp_.useXetex = xetex;
1803 if (fontModule->fontsRomanCO->currentIndex() == 0)
1804 bp_.fontsRoman = "default";
1807 fromqstr(fontModule->fontsRomanCO->currentText());
1809 if (fontModule->fontsSansCO->currentIndex() == 0)
1810 bp_.fontsSans = "default";
1813 fromqstr(fontModule->fontsSansCO->currentText());
1815 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
1816 bp_.fontsTypewriter = "default";
1818 bp_.fontsTypewriter =
1819 fromqstr(fontModule->fontsTypewriterCO->currentText());
1822 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1825 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1827 bp_.fontsTypewriter =
1828 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1832 fromqstr(fontModule->cjkFontLE->text());
1834 bp_.fontsSansScale = fontModule->scaleSansSB->value();
1836 bp_.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1838 bp_.fontsSC = fontModule->fontScCB->isChecked();
1840 bp_.fontsOSF = fontModule->fontOsfCB->isChecked();
1842 bp_.fontsDefaultFamily = GuiDocument::fontfamilies[
1843 fontModule->fontsDefaultCO->currentIndex()];
1845 if (fontModule->fontsizeCO->currentIndex() == 0)
1846 bp_.fontsize = "default";
1849 fromqstr(fontModule->fontsizeCO->currentText());
1852 bp_.papersize = PAPER_SIZE(
1853 pageLayoutModule->papersizeCO->currentIndex());
1855 // custom, A3, B3 and B4 paper sizes need geometry
1856 int psize = pageLayoutModule->papersizeCO->currentIndex();
1857 bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1859 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1860 pageLayoutModule->paperwidthUnitCO);
1862 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1863 pageLayoutModule->paperheightUnitCO);
1865 if (pageLayoutModule->facingPagesCB->isChecked())
1866 bp_.sides = TwoSides;
1868 bp_.sides = OneSide;
1870 if (pageLayoutModule->landscapeRB->isChecked())
1871 bp_.orientation = ORIENTATION_LANDSCAPE;
1873 bp_.orientation = ORIENTATION_PORTRAIT;
1876 bp_.use_geometry = !marginsModule->marginCB->isChecked()
1879 Ui::MarginsUi const * m = marginsModule;
1881 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1882 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
1883 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1884 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1885 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1886 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1887 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1888 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
1890 branchesModule->apply(bp_);
1893 PDFOptions & pdf = bp_.pdfoptions();
1894 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
1895 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
1896 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
1897 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
1898 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
1900 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
1901 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
1902 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
1903 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
1905 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
1906 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
1907 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
1908 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
1910 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
1911 if (pdfSupportModule->fullscreenCB->isChecked())
1912 pdf.pagemode = pdf.pagemode_fullscreen;
1914 pdf.pagemode.clear();
1915 pdf.quoted_options = pdf.quoted_options_check(
1916 fromqstr(pdfSupportModule->optionsLE->text()));
1920 void GuiDocument::paramsToDialog()
1922 // set the default unit
1923 Length::UNIT const defaultUnit = Length::defaultUnit();
1926 preambleModule->update(bp_, id());
1929 biblioModule->citeDefaultRB->setChecked(
1930 bp_.citeEngine() == ENGINE_BASIC);
1932 biblioModule->citeNatbibRB->setChecked(
1933 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
1934 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
1936 biblioModule->citeStyleCO->setCurrentIndex(
1937 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
1939 biblioModule->citeJurabibRB->setChecked(
1940 bp_.citeEngine() == ENGINE_JURABIB);
1942 biblioModule->bibtopicCB->setChecked(
1945 // language & quotes
1946 int const pos = langModule->languageCO->findData(toqstr(
1947 bp_.language->lang()));
1948 langModule->languageCO->setCurrentIndex(pos);
1950 langModule->quoteStyleCO->setCurrentIndex(
1951 bp_.quotes_language);
1953 bool default_enc = true;
1954 if (bp_.inputenc != "auto") {
1955 default_enc = false;
1956 if (bp_.inputenc == "default") {
1957 langModule->encodingCO->setCurrentIndex(0);
1960 Encodings::const_iterator it = encodings.begin();
1961 Encodings::const_iterator const end = encodings.end();
1962 for (; it != end; ++it) {
1963 if (it->latexName() == bp_.inputenc) {
1964 enc_gui = it->guiName();
1968 int const i = langModule->encodingCO->findText(
1971 langModule->encodingCO->setCurrentIndex(i);
1973 // unknown encoding. Set to default.
1977 langModule->defaultencodingRB->setChecked(default_enc);
1978 langModule->otherencodingRB->setChecked(!default_enc);
1981 int const min_toclevel = documentClass().min_toclevel();
1982 int const max_toclevel = documentClass().max_toclevel();
1983 if (documentClass().hasTocLevels()) {
1984 numberingModule->setEnabled(true);
1985 numberingModule->depthSL->setMinimum(min_toclevel - 1);
1986 numberingModule->depthSL->setMaximum(max_toclevel);
1987 numberingModule->depthSL->setValue(bp_.secnumdepth);
1988 numberingModule->tocSL->setMaximum(min_toclevel - 1);
1989 numberingModule->tocSL->setMaximum(max_toclevel);
1990 numberingModule->tocSL->setValue(bp_.tocdepth);
1993 numberingModule->setEnabled(false);
1994 numberingModule->tocTW->clear();
1998 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
1999 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2000 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2001 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2002 bulletsModule->init();
2005 int nitem = findToken(tex_graphics, bp_.graphicsDriver);
2007 latexModule->psdriverCO->setCurrentIndex(nitem);
2010 mathsModule->amsCB->setChecked(
2011 bp_.use_amsmath == BufferParams::package_on);
2012 mathsModule->amsautoCB->setChecked(
2013 bp_.use_amsmath == BufferParams::package_auto);
2015 mathsModule->esintCB->setChecked(
2016 bp_.use_esint == BufferParams::package_on);
2017 mathsModule->esintautoCB->setChecked(
2018 bp_.use_esint == BufferParams::package_auto);
2020 switch (bp_.spacing().getSpace()) {
2021 case Spacing::Other: nitem = 3; break;
2022 case Spacing::Double: nitem = 2; break;
2023 case Spacing::Onehalf: nitem = 1; break;
2024 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2028 string const & layoutID = bp_.baseClassID();
2029 setLayoutComboByIDString(layoutID);
2031 updatePagestyle(documentClass().opt_pagestyle(),
2034 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2035 if (bp_.spacing().getSpace() == Spacing::Other) {
2036 textLayoutModule->lspacingLE->setText(
2037 toqstr(bp_.spacing().getValueAsString()));
2041 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation)
2042 textLayoutModule->indentRB->setChecked(true);
2044 textLayoutModule->skipRB->setChecked(true);
2047 switch (bp_.getDefSkip().kind()) {
2048 case VSpace::SMALLSKIP:
2051 case VSpace::MEDSKIP:
2054 case VSpace::BIGSKIP:
2057 case VSpace::LENGTH:
2060 string const length = bp_.getDefSkip().asLyXCommand();
2061 lengthToWidgets(textLayoutModule->skipLE,
2062 textLayoutModule->skipLengthCO,
2063 length, defaultUnit);
2070 textLayoutModule->skipCO->setCurrentIndex(skip);
2073 textLayoutModule->twoColumnCB->setChecked(
2076 // break listings_params to multiple lines
2078 InsetListingsParams(bp_.listings_params).separatedParams();
2079 textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
2081 if (!bp_.options.empty()) {
2082 latexModule->optionsLE->setText(
2083 toqstr(bp_.options));
2085 latexModule->optionsLE->setText(QString());
2089 latexModule->defaultOptionsCB->setChecked(
2090 bp_.use_default_options);
2091 updateSelectedModules();
2092 selectionManager->updateProvidedModules(
2093 bp_.baseClass()->providedModules());
2094 selectionManager->updateExcludedModules(
2095 bp_.baseClass()->excludedModules());
2097 if (!documentClass().options().empty()) {
2098 latexModule->defaultOptionsLE->setText(
2099 toqstr(documentClass().options()));
2101 latexModule->defaultOptionsLE->setText(
2102 toqstr(_("[No options predefined]")));
2105 latexModule->defaultOptionsLE->setEnabled(
2106 bp_.use_default_options
2107 && !documentClass().options().empty());
2109 latexModule->defaultOptionsCB->setEnabled(
2110 !documentClass().options().empty());
2112 if (!bp_.master.empty()) {
2113 latexModule->childDocGB->setChecked(true);
2114 latexModule->childDocLE->setText(
2115 toqstr(bp_.master));
2117 latexModule->childDocLE->setText(QString());
2118 latexModule->childDocGB->setChecked(false);
2121 floatModule->set(bp_.float_placement);
2124 updateFontsize(documentClass().opt_fontsize(),
2127 fontModule->xetexCB->setChecked(bp_.useXetex);
2130 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2131 if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fontsRoman)) {
2132 fontModule->fontsRomanCO->setCurrentIndex(i);
2137 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2138 if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fontsSans)) {
2139 fontModule->fontsSansCO->setCurrentIndex(i);
2143 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2144 if (fontModule->fontsTypewriterCO->itemText(i) ==
2145 toqstr(bp_.fontsTypewriter)) {
2146 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2151 int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2153 fontModule->fontsRomanCO->setCurrentIndex(n);
2157 n = findToken(tex_fonts_sans, bp_.fontsSans);
2159 fontModule->fontsSansCO->setCurrentIndex(n);
2163 n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2165 fontModule->fontsTypewriterCO->setCurrentIndex(n);
2170 if (!bp_.fontsCJK.empty())
2171 fontModule->cjkFontLE->setText(
2172 toqstr(bp_.fontsCJK));
2174 fontModule->cjkFontLE->setText(QString());
2176 fontModule->fontScCB->setChecked(bp_.fontsSC);
2177 fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2178 fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2179 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2181 int nn = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2183 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2186 bool const extern_geometry =
2187 documentClass().provides("geometry");
2188 int const psize = bp_.papersize;
2189 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2190 setCustomPapersize(!extern_geometry && psize);
2191 pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2193 bool const landscape =
2194 bp_.orientation == ORIENTATION_LANDSCAPE;
2195 pageLayoutModule->landscapeRB->setChecked(landscape);
2196 pageLayoutModule->portraitRB->setChecked(!landscape);
2197 pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2198 pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2200 pageLayoutModule->facingPagesCB->setChecked(
2201 bp_.sides == TwoSides);
2204 lengthToWidgets(pageLayoutModule->paperwidthLE,
2205 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2207 lengthToWidgets(pageLayoutModule->paperheightLE,
2208 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2211 Ui::MarginsUi * m = marginsModule;
2213 setMargins(!bp_.use_geometry);
2215 lengthToWidgets(m->topLE, m->topUnit,
2216 bp_.topmargin, defaultUnit);
2218 lengthToWidgets(m->bottomLE, m->bottomUnit,
2219 bp_.bottommargin, defaultUnit);
2221 lengthToWidgets(m->innerLE, m->innerUnit,
2222 bp_.leftmargin, defaultUnit);
2224 lengthToWidgets(m->outerLE, m->outerUnit,
2225 bp_.rightmargin, defaultUnit);
2227 lengthToWidgets(m->headheightLE, m->headheightUnit,
2228 bp_.headheight, defaultUnit);
2230 lengthToWidgets(m->headsepLE, m->headsepUnit,
2231 bp_.headsep, defaultUnit);
2233 lengthToWidgets(m->footskipLE, m->footskipUnit,
2234 bp_.footskip, defaultUnit);
2236 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2237 bp_.columnsep, defaultUnit);
2239 branchesModule->update(bp_);
2242 PDFOptions const & pdf = bp_.pdfoptions();
2243 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2244 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2245 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2246 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2247 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2249 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2250 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2251 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2253 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2255 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2256 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2257 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2258 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2260 nn = findToken(backref_opts, pdf.backref);
2262 pdfSupportModule->backrefCO->setCurrentIndex(nn);
2264 pdfSupportModule->fullscreenCB->setChecked
2265 (pdf.pagemode == pdf.pagemode_fullscreen);
2267 pdfSupportModule->optionsLE->setText(
2268 toqstr(pdf.quoted_options));
2270 // Make sure that the bc is in the INITIAL state
2271 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
2276 void GuiDocument::saveDocDefault()
2278 // we have to apply the params first
2284 void GuiDocument::updateAvailableModules()
2286 modules_av_model_.clear();
2287 list<modInfoStruct> const & modInfoList = getModuleInfo();
2288 list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2289 list<modInfoStruct>::const_iterator men = modInfoList.end();
2290 for (int i = 0; mit != men; ++mit, ++i)
2291 modules_av_model_.insertRow(i, mit->name, mit->id,
2296 void GuiDocument::updateSelectedModules()
2298 modules_sel_model_.clear();
2299 list<modInfoStruct> const selModList = getSelectedModules();
2300 list<modInfoStruct>::const_iterator mit = selModList.begin();
2301 list<modInfoStruct>::const_iterator men = selModList.end();
2302 for (int i = 0; mit != men; ++mit, ++i)
2303 modules_sel_model_.insertRow(i, mit->name, mit->id,
2308 void GuiDocument::updateContents()
2310 // Nothing to do here as the document settings is not cursor dependant.
2315 void GuiDocument::useClassDefaults()
2317 if (applyPB->isEnabled()) {
2318 int const ret = Alert::prompt(_("Unapplied changes"),
2319 _("Some changes in the dialog were not yet applied.\n"
2320 "If you do not apply now, they will be lost after this action."),
2321 1, 1, _("&Apply"), _("&Dismiss"));
2326 int idx = latexModule->classCO->currentIndex();
2327 string const classname = classes_model_.getIDString(idx);
2328 if (!bp_.setBaseClass(classname)) {
2329 Alert::error(_("Error"), _("Unable to set document class."));
2332 bp_.useClassDefaults();
2337 void GuiDocument::setLayoutComboByIDString(string const & idString)
2339 int idx = classes_model_.findIDString(idString);
2341 Alert::warning(_("Can't set layout!"),
2342 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2344 latexModule->classCO->setCurrentIndex(idx);
2348 bool GuiDocument::isValid()
2350 return validateListingsParameters().isEmpty()
2351 && (textLayoutModule->skipCO->currentIndex() != 3
2352 || !textLayoutModule->skipLE->text().isEmpty());
2356 char const * const GuiDocument::fontfamilies[5] = {
2357 "default", "rmdefault", "sfdefault", "ttdefault", ""
2361 char const * GuiDocument::fontfamilies_gui[5] = {
2362 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2366 bool GuiDocument::initialiseParams(string const &)
2368 BufferView const * view = bufferview();
2370 bp_ = BufferParams();
2374 bp_ = view->buffer().params();
2376 updateAvailableModules();
2377 //FIXME It'd be nice to make sure here that the selected
2378 //modules are consistent: That required modules are actually
2379 //selected, and that we don't have conflicts. If so, we could
2380 //at least pop up a warning.
2386 void GuiDocument::clearParams()
2388 bp_ = BufferParams();
2392 BufferId GuiDocument::id() const
2394 BufferView const * const view = bufferview();
2395 return view? &view->buffer() : 0;
2399 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2401 return moduleNames_;
2405 list<GuiDocument::modInfoStruct> const
2406 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
2408 LayoutModuleList::const_iterator it = mods.begin();
2409 LayoutModuleList::const_iterator end = mods.end();
2410 list<modInfoStruct> mInfo;
2411 for (; it != end; ++it) {
2414 LyXModule * mod = moduleList[*it];
2417 m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
2419 m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2426 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2428 return makeModuleInfo(params().getModules());
2432 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
2434 return makeModuleInfo(params().baseClass()->providedModules());
2438 DocumentClass const & GuiDocument::documentClass() const
2440 return bp_.documentClass();
2444 static void dispatch_bufferparams(Dialog const & dialog,
2445 BufferParams const & bp, FuncCode lfun)
2448 ss << "\\begin_header\n";
2450 ss << "\\end_header\n";
2451 dialog.dispatch(FuncRequest(lfun, ss.str()));
2455 void GuiDocument::dispatchParams()
2457 // This must come first so that a language change is correctly noticed
2460 // Apply the BufferParams. Note that this will set the base class
2461 // and then update the buffer's layout.
2462 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2464 if (!params().master.empty()) {
2465 FileName const master_file = support::makeAbsPath(params().master,
2466 support::onlyPath(buffer().absFileName()));
2467 if (isLyXFilename(master_file.absFilename())) {
2468 Buffer * master = checkAndLoadLyXFile(master_file);
2470 if (master->isChild(const_cast<Buffer *>(&buffer())))
2471 const_cast<Buffer &>(buffer()).setParent(master);
2473 Alert::warning(_("Assigned master does not include this file"),
2474 bformat(_("You must include this file in the document\n"
2475 "'%1$s' in order to use the master document\n"
2476 "feature."), from_utf8(params().master)));
2478 Alert::warning(_("Could not load master"),
2479 bformat(_("The master document '%1$s'\n"
2480 "could not be loaded."),
2481 from_utf8(params().master)));
2485 // Generate the colours requested by each new branch.
2486 BranchList & branchlist = params().branchlist();
2487 if (!branchlist.empty()) {
2488 BranchList::const_iterator it = branchlist.begin();
2489 BranchList::const_iterator const end = branchlist.end();
2490 for (; it != end; ++it) {
2491 docstring const & current_branch = it->branch();
2492 Branch const * branch = branchlist.find(current_branch);
2493 string const x11hexname = X11hexname(branch->color());
2494 // display the new color
2495 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2496 dispatch(FuncRequest(LFUN_SET_COLOR, str));
2499 // Open insets of selected branches, close deselected ones
2500 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2503 // FIXME: If we used an LFUN, we would not need those two lines:
2504 BufferView * bv = const_cast<BufferView *>(bufferview());
2505 bv->processUpdateFlags(Update::Force | Update::FitCursor);
2509 void GuiDocument::setLanguage() const
2511 Language const * const newL = bp_.language;
2512 if (buffer().params().language == newL)
2515 string const & lang_name = newL->lang();
2516 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2520 void GuiDocument::saveAsDefault() const
2522 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2526 bool GuiDocument::isFontAvailable(string const & font) const
2528 if (font == "default" || font == "cmr"
2529 || font == "cmss" || font == "cmtt")
2530 // these are standard
2532 if (font == "lmodern" || font == "lmss" || font == "lmtt")
2533 return LaTeXFeatures::isAvailable("lmodern");
2534 if (font == "times" || font == "palatino"
2535 || font == "helvet" || font == "courier")
2536 return LaTeXFeatures::isAvailable("psnfss");
2537 if (font == "cmbr" || font == "cmtl")
2538 return LaTeXFeatures::isAvailable("cmbright");
2539 if (font == "utopia")
2540 return LaTeXFeatures::isAvailable("utopia")
2541 || LaTeXFeatures::isAvailable("fourier");
2542 if (font == "beraserif" || font == "berasans"
2543 || font == "beramono")
2544 return LaTeXFeatures::isAvailable("bera");
2545 return LaTeXFeatures::isAvailable(font);
2549 bool GuiDocument::providesOSF(string const & font) const
2552 return isFontAvailable("eco");
2553 if (font == "palatino")
2554 return isFontAvailable("mathpazo");
2559 bool GuiDocument::providesSC(string const & font) const
2561 if (font == "palatino")
2562 return isFontAvailable("mathpazo");
2563 if (font == "utopia")
2564 return isFontAvailable("fourier");
2569 bool GuiDocument::providesScale(string const & font) const
2571 return font == "helvet" || font == "luximono"
2572 || font == "berasans" || font == "beramono";
2576 void GuiDocument::loadModuleInfo()
2578 moduleNames_.clear();
2579 LyXModuleList::const_iterator it = moduleList.begin();
2580 LyXModuleList::const_iterator end = moduleList.end();
2581 for (; it != end; ++it) {
2585 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
2586 // this is supposed to give us the first sentence of the description
2589 toqstr(translateIfPossible(from_utf8(it->getDescription())));
2590 int const pos = desc.indexOf(".");
2592 desc.truncate(pos + 1);
2593 m.description = desc;
2594 moduleNames_.push_back(m);
2599 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2602 } // namespace frontend
2605 #include "moc_GuiDocument.cpp"