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);
1169 fontModule->fontsDefaultCO->setEnabled(!xetex);
1171 fontModule->fontScCB->setEnabled(false);
1175 void GuiDocument::updateFontsize(string const & items, string const & sel)
1177 fontModule->fontsizeCO->clear();
1178 fontModule->fontsizeCO->addItem(qt_("Default"));
1180 for (int n = 0; !token(items,'|',n).empty(); ++n)
1181 fontModule->fontsizeCO->
1182 addItem(toqstr(token(items,'|',n)));
1184 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1185 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1186 fontModule->fontsizeCO->setCurrentIndex(n);
1193 void GuiDocument::updateFontlist()
1195 fontModule->fontsRomanCO->clear();
1196 fontModule->fontsSansCO->clear();
1197 fontModule->fontsTypewriterCO->clear();
1199 // With XeTeX, we have access to all system fonts, but not the LaTeX fonts
1200 if (fontModule->xetexCB->isChecked()) {
1201 fontModule->fontsRomanCO->addItem(qt_("Default"));
1202 fontModule->fontsSansCO->addItem(qt_("Default"));
1203 fontModule->fontsTypewriterCO->addItem(qt_("Default"));
1205 QFontDatabase fontdb;
1206 QStringList families(fontdb.families());
1207 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
1208 fontModule->fontsRomanCO->addItem(*it);
1209 fontModule->fontsSansCO->addItem(*it);
1210 fontModule->fontsTypewriterCO->addItem(*it);
1215 for (int n = 0; tex_fonts_roman[n][0]; ++n) {
1216 QString font = qt_(tex_fonts_roman_gui[n]);
1217 if (!isFontAvailable(tex_fonts_roman[n]))
1218 font += qt_(" (not installed)");
1219 fontModule->fontsRomanCO->addItem(font);
1221 for (int n = 0; tex_fonts_sans[n][0]; ++n) {
1222 QString font = qt_(tex_fonts_sans_gui[n]);
1223 if (!isFontAvailable(tex_fonts_sans[n]))
1224 font += qt_(" (not installed)");
1225 fontModule->fontsSansCO->addItem(font);
1227 for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
1228 QString font = qt_(tex_fonts_monospaced_gui[n]);
1229 if (!isFontAvailable(tex_fonts_monospaced[n]))
1230 font += qt_(" (not installed)");
1231 fontModule->fontsTypewriterCO->addItem(font);
1236 void GuiDocument::romanChanged(int item)
1238 if (fontModule->xetexCB->isChecked()) {
1239 fontModule->fontScCB->setEnabled(false);
1242 string const font = tex_fonts_roman[item];
1243 fontModule->fontScCB->setEnabled(providesSC(font));
1244 fontModule->fontOsfCB->setEnabled(providesOSF(font));
1248 void GuiDocument::sansChanged(int item)
1250 if (fontModule->xetexCB->isChecked()) {
1251 fontModule->fontScCB->setEnabled(false);
1254 string const font = tex_fonts_sans[item];
1255 bool scaleable = providesScale(font);
1256 fontModule->scaleSansSB->setEnabled(scaleable);
1257 fontModule->scaleSansLA->setEnabled(scaleable);
1261 void GuiDocument::ttChanged(int item)
1263 if (fontModule->xetexCB->isChecked()) {
1264 fontModule->fontScCB->setEnabled(false);
1267 string const font = tex_fonts_monospaced[item];
1268 bool scaleable = providesScale(font);
1269 fontModule->scaleTypewriterSB->setEnabled(scaleable);
1270 fontModule->scaleTypewriterLA->setEnabled(scaleable);
1274 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1277 pageLayoutModule->pagestyleCO->clear();
1278 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1280 for (int n = 0; !token(items, '|', n).empty(); ++n) {
1281 string style = token(items, '|', n);
1282 QString style_gui = qt_(style);
1283 pagestyles.push_back(pair<string, QString>(style, style_gui));
1284 pageLayoutModule->pagestyleCO->addItem(style_gui);
1287 if (sel == "default") {
1288 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1294 for (size_t i = 0; i < pagestyles.size(); ++i)
1295 if (pagestyles[i].first == sel)
1296 nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1299 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1303 void GuiDocument::browseLayout()
1305 QString const label1 = qt_("Layouts|#o#O");
1306 QString const dir1 = toqstr(lyxrc.document_path);
1307 QStringList const filter(qt_("LyX Layout (*.layout)"));
1308 QString file = browseRelFile(QString(), bufferFilepath(),
1309 qt_("Local layout file"), filter, false,
1312 if (!file.endsWith(".layout"))
1315 FileName layoutFile = support::makeAbsPath(fromqstr(file),
1316 fromqstr(bufferFilepath()));
1318 int const ret = Alert::prompt(_("Local layout file"),
1319 _("The layout file you have selected is a local layout\n"
1320 "file, not one in the system or user directory. Your\n"
1321 "document may not work with this layout if you do not\n"
1322 "keep the layout file in the document directory."),
1323 1, 1, _("&Set Layout"), _("&Cancel"));
1327 // load the layout file
1328 LayoutFileList & bcl = LayoutFileList::get();
1329 string classname = layoutFile.onlyFileName();
1330 // this will update an existing layout if that layout has been loaded before.
1331 LayoutFileIndex name = bcl.addLocalLayout(
1332 classname.substr(0, classname.size() - 7),
1333 layoutFile.onlyPath().absFilename());
1336 Alert::error(_("Error"),
1337 _("Unable to read local layout file."));
1341 // do not trigger classChanged if there is no change.
1342 if (latexModule->classCO->currentText() == toqstr(name))
1346 int idx = latexModule->classCO->findText(toqstr(name));
1348 classes_model_.insertRow(0, toqstr(name), name);
1349 latexModule->classCO->setCurrentIndex(0);
1351 latexModule->classCO->setCurrentIndex(idx);
1357 void GuiDocument::browseMaster()
1359 QString const title = qt_("Select master document");
1360 QString const dir1 = toqstr(lyxrc.document_path);
1361 QString const old = latexModule->childDocLE->text();
1362 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1363 QStringList const filter(qt_("LyX Files (*.lyx)"));
1364 QString file = browseRelFile(old, docpath, title, filter, false,
1365 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1367 latexModule->childDocLE->setText(file);
1371 void GuiDocument::classChanged()
1373 int idx = latexModule->classCO->currentIndex();
1376 string const classname = classes_model_.getIDString(idx);
1378 // check whether the selected modules have changed.
1379 bool modules_changed = false;
1380 unsigned int const srows = selectedModel()->rowCount();
1381 if (srows != bp_.getModules().size())
1382 modules_changed = true;
1384 list<string>::const_iterator mit = bp_.getModules().begin();
1385 list<string>::const_iterator men = bp_.getModules().end();
1386 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1387 if (selectedModel()->getIDString(i) != *mit) {
1388 modules_changed = true;
1393 if (modules_changed || lyxrc.auto_reset_options) {
1394 if (applyPB->isEnabled()) {
1395 int const ret = Alert::prompt(_("Unapplied changes"),
1396 _("Some changes in the dialog were not yet applied.\n"
1397 "If you do not apply now, they will be lost after this action."),
1398 1, 1, _("&Apply"), _("&Dismiss"));
1404 // We load the TextClass as soon as it is selected. This is
1405 // necessary so that other options in the dialog can be updated
1406 // according to the new class. Note, however, that, if you use
1407 // the scroll wheel when sitting on the combo box, we'll load a
1408 // lot of TextClass objects very quickly....
1409 if (!bp_.setBaseClass(classname)) {
1410 Alert::error(_("Error"), _("Unable to set document class."));
1413 if (lyxrc.auto_reset_options)
1414 bp_.useClassDefaults();
1416 // With the introduction of modules came a distinction between the base
1417 // class and the document class. The former corresponds to the main layout
1418 // file; the latter is that plus the modules (or the document-specific layout,
1419 // or whatever else there could be). Our parameters come from the document
1420 // class. So when we set the base class, we also need to recreate the document
1421 // class. Otherwise, we still have the old one.
1422 bp_.makeDocumentClass();
1428 // This is an insanely complicated attempt to make this sort of thing
1429 // work with RTL languages.
1430 docstring formatStrVec(vector<string> const & v, docstring const & s)
1432 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1436 return from_utf8(v[0]);
1437 if (v.size() == 2) {
1438 docstring retval = _("%1$s and %2$s");
1439 retval = subst(retval, _("and"), s);
1440 return bformat(retval, from_utf8(v[0]), from_utf8(v[1]));
1442 // The idea here is to format all but the last two items...
1443 int const vSize = v.size();
1444 docstring t2 = _("%1$s, %2$s");
1445 docstring retval = from_utf8(v[0]);
1446 for (int i = 1; i < vSize - 2; ++i)
1447 retval = bformat(t2, retval, from_utf8(v[i]));
1448 //...and then to plug them, and the last two, into this schema
1449 docstring t = _("%1$s, %2$s, and %3$s");
1450 t = subst(t, _("and"), s);
1451 return bformat(t, retval, from_utf8(v[vSize - 2]), from_utf8(v[vSize - 1]));
1454 vector<string> idsToNames(vector<string> const & idList)
1456 vector<string> retval;
1457 vector<string>::const_iterator it = idList.begin();
1458 vector<string>::const_iterator end = idList.end();
1459 for (; it != end; ++it) {
1460 LyXModule const * const mod = moduleList[*it];
1462 retval.push_back(*it + " (Unavailable)");
1464 retval.push_back(mod->getName());
1471 void GuiDocument::modulesToParams(BufferParams & bp)
1473 // update list of loaded modules
1474 bp.clearLayoutModules();
1475 int const srows = modules_sel_model_.rowCount();
1476 for (int i = 0; i < srows; ++i)
1477 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1479 // update the list of removed modules
1480 bp.clearRemovedModules();
1481 LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
1482 list<string>::const_iterator rit = reqmods.begin();
1483 list<string>::const_iterator ren = reqmods.end();
1485 // check each of the default modules
1486 for (; rit != ren; rit++) {
1487 list<string>::const_iterator mit = bp.getModules().begin();
1488 list<string>::const_iterator men = bp.getModules().end();
1490 for (; mit != men; mit++) {
1497 // the module isn't present so must have been removed by the user
1498 bp.addRemovedModule(*rit);
1503 void GuiDocument::modulesChanged()
1505 modulesToParams(bp_);
1506 bp_.makeDocumentClass();
1511 void GuiDocument::updateModuleInfo()
1513 selectionManager->update();
1515 //Module description
1516 bool const focus_on_selected = selectionManager->selectedFocused();
1517 QListView const * const lv =
1518 focus_on_selected ? modulesModule->selectedLV : modulesModule->availableLV;
1519 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1520 modulesModule->infoML->document()->clear();
1523 QModelIndex const & idx = lv->selectionModel()->currentIndex();
1524 GuiIdListModel const & id_model =
1525 focus_on_selected ? modules_sel_model_ : modules_av_model_;
1526 string const modName = id_model.getIDString(idx.row());
1527 docstring desc = getModuleDescription(modName);
1529 LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
1530 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
1533 desc += _("Module provided by document class.");
1536 vector<string> pkglist = getPackageList(modName);
1537 docstring pkgdesc = formatStrVec(pkglist, _("and"));
1538 if (!pkgdesc.empty()) {
1541 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1544 pkglist = getRequiredList(modName);
1545 if (!pkglist.empty()) {
1546 vector<string> const reqdescs = idsToNames(pkglist);
1547 pkgdesc = formatStrVec(reqdescs, _("or"));
1550 desc += bformat(_("Module required: %1$s."), pkgdesc);
1553 pkglist = getExcludedList(modName);
1554 if (!pkglist.empty()) {
1555 vector<string> const reqdescs = idsToNames(pkglist);
1556 pkgdesc = formatStrVec(reqdescs, _( "and"));
1559 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1562 if (!isModuleAvailable(modName)) {
1565 desc += _("WARNING: Some required packages are unavailable!");
1568 modulesModule->infoML->document()->setPlainText(toqstr(desc));
1572 void GuiDocument::updateNumbering()
1574 DocumentClass const & tclass = documentClass();
1576 numberingModule->tocTW->setUpdatesEnabled(false);
1577 numberingModule->tocTW->clear();
1579 int const depth = numberingModule->depthSL->value();
1580 int const toc = numberingModule->tocSL->value();
1581 QString const no = qt_("No");
1582 QString const yes = qt_("Yes");
1583 QTreeWidgetItem * item = 0;
1585 DocumentClass::const_iterator lit = tclass.begin();
1586 DocumentClass::const_iterator len = tclass.end();
1587 for (; lit != len; ++lit) {
1588 int const toclevel = lit->toclevel;
1589 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1590 item = new QTreeWidgetItem(numberingModule->tocTW);
1591 item->setText(0, toqstr(translateIfPossible(lit->name())));
1592 item->setText(1, (toclevel <= depth) ? yes : no);
1593 item->setText(2, (toclevel <= toc) ? yes : no);
1597 numberingModule->tocTW->setUpdatesEnabled(true);
1598 numberingModule->tocTW->update();
1602 void GuiDocument::applyView()
1605 preambleModule->apply(bp_);
1608 bp_.setCiteEngine(ENGINE_BASIC);
1610 if (biblioModule->citeNatbibRB->isChecked()) {
1611 bool const use_numerical_citations =
1612 biblioModule->citeStyleCO->currentIndex();
1613 if (use_numerical_citations)
1614 bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1616 bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1618 } else if (biblioModule->citeJurabibRB->isChecked())
1619 bp_.setCiteEngine(ENGINE_JURABIB);
1622 biblioModule->bibtopicCB->isChecked();
1624 // language & quotes
1625 if (langModule->defaultencodingRB->isChecked()) {
1626 bp_.inputenc = "auto";
1628 int i = langModule->encodingCO->currentIndex();
1630 bp_.inputenc = "default";
1632 QString const enc_gui =
1633 langModule->encodingCO->currentText();
1634 Encodings::const_iterator it = encodings.begin();
1635 Encodings::const_iterator const end = encodings.end();
1637 for (; it != end; ++it) {
1638 if (qt_(it->guiName()) == enc_gui) {
1639 bp_.inputenc = it->latexName();
1645 // should not happen
1646 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1647 bp_.inputenc = "default";
1652 InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1653 switch (langModule->quoteStyleCO->currentIndex()) {
1655 lga = InsetQuotes::EnglishQuotes;
1658 lga = InsetQuotes::SwedishQuotes;
1661 lga = InsetQuotes::GermanQuotes;
1664 lga = InsetQuotes::PolishQuotes;
1667 lga = InsetQuotes::FrenchQuotes;
1670 lga = InsetQuotes::DanishQuotes;
1673 bp_.quotes_language = lga;
1675 QString const lang = langModule->languageCO->itemData(
1676 langModule->languageCO->currentIndex()).toString();
1677 bp_.language = lyx::languages.getLanguage(fromqstr(lang));
1680 if (bp_.documentClass().hasTocLevels()) {
1681 bp_.tocdepth = numberingModule->tocSL->value();
1682 bp_.secnumdepth = numberingModule->depthSL->value();
1686 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
1687 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
1688 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
1689 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
1692 bp_.graphicsDriver =
1693 tex_graphics[latexModule->psdriverCO->currentIndex()];
1696 int idx = latexModule->classCO->currentIndex();
1698 string const classname = classes_model_.getIDString(idx);
1699 bp_.setBaseClass(classname);
1703 modulesToParams(bp_);
1705 if (mathsModule->amsautoCB->isChecked()) {
1706 bp_.use_amsmath = BufferParams::package_auto;
1708 if (mathsModule->amsCB->isChecked())
1709 bp_.use_amsmath = BufferParams::package_on;
1711 bp_.use_amsmath = BufferParams::package_off;
1714 if (mathsModule->esintautoCB->isChecked())
1715 bp_.use_esint = BufferParams::package_auto;
1717 if (mathsModule->esintCB->isChecked())
1718 bp_.use_esint = BufferParams::package_on;
1720 bp_.use_esint = BufferParams::package_off;
1723 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1724 bp_.pagestyle = "default";
1726 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1727 for (size_t i = 0; i != pagestyles.size(); ++i)
1728 if (pagestyles[i].second == style_gui)
1729 bp_.pagestyle = pagestyles[i].first;
1732 switch (textLayoutModule->lspacingCO->currentIndex()) {
1734 bp_.spacing().set(Spacing::Single);
1737 bp_.spacing().set(Spacing::Onehalf);
1740 bp_.spacing().set(Spacing::Double);
1743 bp_.spacing().set(Spacing::Other,
1744 fromqstr(textLayoutModule->lspacingLE->text()));
1748 if (textLayoutModule->twoColumnCB->isChecked())
1753 // text should have passed validation
1754 bp_.listings_params =
1755 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1757 if (textLayoutModule->indentRB->isChecked())
1758 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1760 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1762 switch (textLayoutModule->skipCO->currentIndex()) {
1764 bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
1767 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1770 bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
1775 widgetsToLength(textLayoutModule->skipLE,
1776 textLayoutModule->skipLengthCO)
1782 // DocumentDefskipCB assures that this never happens
1783 // so Assert then !!! - jbl
1784 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1789 fromqstr(latexModule->optionsLE->text());
1791 bp_.use_default_options =
1792 latexModule->defaultOptionsCB->isChecked();
1794 if (latexModule->childDocGB->isChecked())
1796 fromqstr(latexModule->childDocLE->text());
1798 bp_.master = string();
1800 bp_.float_placement = floatModule->get();
1803 bool const xetex = fontModule->xetexCB->isChecked();
1804 bp_.useXetex = xetex;
1807 if (fontModule->fontsRomanCO->currentIndex() == 0)
1808 bp_.fontsRoman = "default";
1811 fromqstr(fontModule->fontsRomanCO->currentText());
1813 if (fontModule->fontsSansCO->currentIndex() == 0)
1814 bp_.fontsSans = "default";
1817 fromqstr(fontModule->fontsSansCO->currentText());
1819 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
1820 bp_.fontsTypewriter = "default";
1822 bp_.fontsTypewriter =
1823 fromqstr(fontModule->fontsTypewriterCO->currentText());
1826 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1829 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1831 bp_.fontsTypewriter =
1832 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1836 fromqstr(fontModule->cjkFontLE->text());
1838 bp_.fontsSansScale = fontModule->scaleSansSB->value();
1840 bp_.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1842 bp_.fontsSC = fontModule->fontScCB->isChecked();
1844 bp_.fontsOSF = fontModule->fontOsfCB->isChecked();
1847 bp_.fontsDefaultFamily = "default";
1849 bp_.fontsDefaultFamily = GuiDocument::fontfamilies[
1850 fontModule->fontsDefaultCO->currentIndex()];
1852 if (fontModule->fontsizeCO->currentIndex() == 0)
1853 bp_.fontsize = "default";
1856 fromqstr(fontModule->fontsizeCO->currentText());
1859 bp_.papersize = PAPER_SIZE(
1860 pageLayoutModule->papersizeCO->currentIndex());
1862 // custom, A3, B3 and B4 paper sizes need geometry
1863 int psize = pageLayoutModule->papersizeCO->currentIndex();
1864 bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1866 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1867 pageLayoutModule->paperwidthUnitCO);
1869 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1870 pageLayoutModule->paperheightUnitCO);
1872 if (pageLayoutModule->facingPagesCB->isChecked())
1873 bp_.sides = TwoSides;
1875 bp_.sides = OneSide;
1877 if (pageLayoutModule->landscapeRB->isChecked())
1878 bp_.orientation = ORIENTATION_LANDSCAPE;
1880 bp_.orientation = ORIENTATION_PORTRAIT;
1883 bp_.use_geometry = !marginsModule->marginCB->isChecked()
1886 Ui::MarginsUi const * m = marginsModule;
1888 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1889 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
1890 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1891 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1892 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1893 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1894 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1895 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
1897 branchesModule->apply(bp_);
1900 PDFOptions & pdf = bp_.pdfoptions();
1901 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
1902 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
1903 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
1904 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
1905 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
1907 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
1908 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
1909 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
1910 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
1912 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
1913 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
1914 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
1915 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
1917 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
1918 if (pdfSupportModule->fullscreenCB->isChecked())
1919 pdf.pagemode = pdf.pagemode_fullscreen;
1921 pdf.pagemode.clear();
1922 pdf.quoted_options = pdf.quoted_options_check(
1923 fromqstr(pdfSupportModule->optionsLE->text()));
1927 void GuiDocument::paramsToDialog()
1929 // set the default unit
1930 Length::UNIT const defaultUnit = Length::defaultUnit();
1933 preambleModule->update(bp_, id());
1936 biblioModule->citeDefaultRB->setChecked(
1937 bp_.citeEngine() == ENGINE_BASIC);
1939 biblioModule->citeNatbibRB->setChecked(
1940 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
1941 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
1943 biblioModule->citeStyleCO->setCurrentIndex(
1944 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
1946 biblioModule->citeJurabibRB->setChecked(
1947 bp_.citeEngine() == ENGINE_JURABIB);
1949 biblioModule->bibtopicCB->setChecked(
1952 // language & quotes
1953 int const pos = langModule->languageCO->findData(toqstr(
1954 bp_.language->lang()));
1955 langModule->languageCO->setCurrentIndex(pos);
1957 langModule->quoteStyleCO->setCurrentIndex(
1958 bp_.quotes_language);
1960 bool default_enc = true;
1961 if (bp_.inputenc != "auto") {
1962 default_enc = false;
1963 if (bp_.inputenc == "default") {
1964 langModule->encodingCO->setCurrentIndex(0);
1967 Encodings::const_iterator it = encodings.begin();
1968 Encodings::const_iterator const end = encodings.end();
1969 for (; it != end; ++it) {
1970 if (it->latexName() == bp_.inputenc) {
1971 enc_gui = it->guiName();
1975 int const i = langModule->encodingCO->findText(
1978 langModule->encodingCO->setCurrentIndex(i);
1980 // unknown encoding. Set to default.
1984 langModule->defaultencodingRB->setChecked(default_enc);
1985 langModule->otherencodingRB->setChecked(!default_enc);
1988 int const min_toclevel = documentClass().min_toclevel();
1989 int const max_toclevel = documentClass().max_toclevel();
1990 if (documentClass().hasTocLevels()) {
1991 numberingModule->setEnabled(true);
1992 numberingModule->depthSL->setMinimum(min_toclevel - 1);
1993 numberingModule->depthSL->setMaximum(max_toclevel);
1994 numberingModule->depthSL->setValue(bp_.secnumdepth);
1995 numberingModule->tocSL->setMaximum(min_toclevel - 1);
1996 numberingModule->tocSL->setMaximum(max_toclevel);
1997 numberingModule->tocSL->setValue(bp_.tocdepth);
2000 numberingModule->setEnabled(false);
2001 numberingModule->tocTW->clear();
2005 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2006 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2007 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2008 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2009 bulletsModule->init();
2012 int nitem = findToken(tex_graphics, bp_.graphicsDriver);
2014 latexModule->psdriverCO->setCurrentIndex(nitem);
2017 mathsModule->amsCB->setChecked(
2018 bp_.use_amsmath == BufferParams::package_on);
2019 mathsModule->amsautoCB->setChecked(
2020 bp_.use_amsmath == BufferParams::package_auto);
2022 mathsModule->esintCB->setChecked(
2023 bp_.use_esint == BufferParams::package_on);
2024 mathsModule->esintautoCB->setChecked(
2025 bp_.use_esint == BufferParams::package_auto);
2027 switch (bp_.spacing().getSpace()) {
2028 case Spacing::Other: nitem = 3; break;
2029 case Spacing::Double: nitem = 2; break;
2030 case Spacing::Onehalf: nitem = 1; break;
2031 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2035 string const & layoutID = bp_.baseClassID();
2036 setLayoutComboByIDString(layoutID);
2038 updatePagestyle(documentClass().opt_pagestyle(),
2041 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2042 if (bp_.spacing().getSpace() == Spacing::Other) {
2043 textLayoutModule->lspacingLE->setText(
2044 toqstr(bp_.spacing().getValueAsString()));
2048 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation)
2049 textLayoutModule->indentRB->setChecked(true);
2051 textLayoutModule->skipRB->setChecked(true);
2054 switch (bp_.getDefSkip().kind()) {
2055 case VSpace::SMALLSKIP:
2058 case VSpace::MEDSKIP:
2061 case VSpace::BIGSKIP:
2064 case VSpace::LENGTH:
2067 string const length = bp_.getDefSkip().asLyXCommand();
2068 lengthToWidgets(textLayoutModule->skipLE,
2069 textLayoutModule->skipLengthCO,
2070 length, defaultUnit);
2077 textLayoutModule->skipCO->setCurrentIndex(skip);
2080 textLayoutModule->twoColumnCB->setChecked(
2083 // break listings_params to multiple lines
2085 InsetListingsParams(bp_.listings_params).separatedParams();
2086 textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
2088 if (!bp_.options.empty()) {
2089 latexModule->optionsLE->setText(
2090 toqstr(bp_.options));
2092 latexModule->optionsLE->setText(QString());
2096 latexModule->defaultOptionsCB->setChecked(
2097 bp_.use_default_options);
2098 updateSelectedModules();
2099 selectionManager->updateProvidedModules(
2100 bp_.baseClass()->providedModules());
2101 selectionManager->updateExcludedModules(
2102 bp_.baseClass()->excludedModules());
2104 if (!documentClass().options().empty()) {
2105 latexModule->defaultOptionsLE->setText(
2106 toqstr(documentClass().options()));
2108 latexModule->defaultOptionsLE->setText(
2109 toqstr(_("[No options predefined]")));
2112 latexModule->defaultOptionsLE->setEnabled(
2113 bp_.use_default_options
2114 && !documentClass().options().empty());
2116 latexModule->defaultOptionsCB->setEnabled(
2117 !documentClass().options().empty());
2119 if (!bp_.master.empty()) {
2120 latexModule->childDocGB->setChecked(true);
2121 latexModule->childDocLE->setText(
2122 toqstr(bp_.master));
2124 latexModule->childDocLE->setText(QString());
2125 latexModule->childDocGB->setChecked(false);
2128 floatModule->set(bp_.float_placement);
2131 updateFontsize(documentClass().opt_fontsize(),
2134 fontModule->xetexCB->setChecked(bp_.useXetex);
2137 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2138 if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fontsRoman)) {
2139 fontModule->fontsRomanCO->setCurrentIndex(i);
2144 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2145 if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fontsSans)) {
2146 fontModule->fontsSansCO->setCurrentIndex(i);
2150 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2151 if (fontModule->fontsTypewriterCO->itemText(i) ==
2152 toqstr(bp_.fontsTypewriter)) {
2153 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2158 int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2160 fontModule->fontsRomanCO->setCurrentIndex(n);
2164 n = findToken(tex_fonts_sans, bp_.fontsSans);
2166 fontModule->fontsSansCO->setCurrentIndex(n);
2170 n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2172 fontModule->fontsTypewriterCO->setCurrentIndex(n);
2177 if (!bp_.fontsCJK.empty())
2178 fontModule->cjkFontLE->setText(
2179 toqstr(bp_.fontsCJK));
2181 fontModule->cjkFontLE->setText(QString());
2183 fontModule->fontScCB->setChecked(bp_.fontsSC);
2184 fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2185 fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2186 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2188 int nn = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2190 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2193 bool const extern_geometry =
2194 documentClass().provides("geometry");
2195 int const psize = bp_.papersize;
2196 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2197 setCustomPapersize(!extern_geometry && psize);
2198 pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2200 bool const landscape =
2201 bp_.orientation == ORIENTATION_LANDSCAPE;
2202 pageLayoutModule->landscapeRB->setChecked(landscape);
2203 pageLayoutModule->portraitRB->setChecked(!landscape);
2204 pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2205 pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2207 pageLayoutModule->facingPagesCB->setChecked(
2208 bp_.sides == TwoSides);
2211 lengthToWidgets(pageLayoutModule->paperwidthLE,
2212 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2214 lengthToWidgets(pageLayoutModule->paperheightLE,
2215 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2218 Ui::MarginsUi * m = marginsModule;
2220 setMargins(!bp_.use_geometry);
2222 lengthToWidgets(m->topLE, m->topUnit,
2223 bp_.topmargin, defaultUnit);
2225 lengthToWidgets(m->bottomLE, m->bottomUnit,
2226 bp_.bottommargin, defaultUnit);
2228 lengthToWidgets(m->innerLE, m->innerUnit,
2229 bp_.leftmargin, defaultUnit);
2231 lengthToWidgets(m->outerLE, m->outerUnit,
2232 bp_.rightmargin, defaultUnit);
2234 lengthToWidgets(m->headheightLE, m->headheightUnit,
2235 bp_.headheight, defaultUnit);
2237 lengthToWidgets(m->headsepLE, m->headsepUnit,
2238 bp_.headsep, defaultUnit);
2240 lengthToWidgets(m->footskipLE, m->footskipUnit,
2241 bp_.footskip, defaultUnit);
2243 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2244 bp_.columnsep, defaultUnit);
2246 branchesModule->update(bp_);
2249 PDFOptions const & pdf = bp_.pdfoptions();
2250 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2251 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2252 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2253 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2254 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2256 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2257 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2258 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2260 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2262 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2263 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2264 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2265 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2267 nn = findToken(backref_opts, pdf.backref);
2269 pdfSupportModule->backrefCO->setCurrentIndex(nn);
2271 pdfSupportModule->fullscreenCB->setChecked
2272 (pdf.pagemode == pdf.pagemode_fullscreen);
2274 pdfSupportModule->optionsLE->setText(
2275 toqstr(pdf.quoted_options));
2277 // Make sure that the bc is in the INITIAL state
2278 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
2283 void GuiDocument::saveDocDefault()
2285 // we have to apply the params first
2291 void GuiDocument::updateAvailableModules()
2293 modules_av_model_.clear();
2294 list<modInfoStruct> const & modInfoList = getModuleInfo();
2295 list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2296 list<modInfoStruct>::const_iterator men = modInfoList.end();
2297 for (int i = 0; mit != men; ++mit, ++i)
2298 modules_av_model_.insertRow(i, mit->name, mit->id,
2303 void GuiDocument::updateSelectedModules()
2305 modules_sel_model_.clear();
2306 list<modInfoStruct> const selModList = getSelectedModules();
2307 list<modInfoStruct>::const_iterator mit = selModList.begin();
2308 list<modInfoStruct>::const_iterator men = selModList.end();
2309 for (int i = 0; mit != men; ++mit, ++i)
2310 modules_sel_model_.insertRow(i, mit->name, mit->id,
2315 void GuiDocument::updateContents()
2317 // Nothing to do here as the document settings is not cursor dependant.
2322 void GuiDocument::useClassDefaults()
2324 if (applyPB->isEnabled()) {
2325 int const ret = Alert::prompt(_("Unapplied changes"),
2326 _("Some changes in the dialog were not yet applied.\n"
2327 "If you do not apply now, they will be lost after this action."),
2328 1, 1, _("&Apply"), _("&Dismiss"));
2333 int idx = latexModule->classCO->currentIndex();
2334 string const classname = classes_model_.getIDString(idx);
2335 if (!bp_.setBaseClass(classname)) {
2336 Alert::error(_("Error"), _("Unable to set document class."));
2339 bp_.useClassDefaults();
2344 void GuiDocument::setLayoutComboByIDString(string const & idString)
2346 int idx = classes_model_.findIDString(idString);
2348 Alert::warning(_("Can't set layout!"),
2349 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2351 latexModule->classCO->setCurrentIndex(idx);
2355 bool GuiDocument::isValid()
2357 return validateListingsParameters().isEmpty()
2358 && (textLayoutModule->skipCO->currentIndex() != 3
2359 || !textLayoutModule->skipLE->text().isEmpty());
2363 char const * const GuiDocument::fontfamilies[5] = {
2364 "default", "rmdefault", "sfdefault", "ttdefault", ""
2368 char const * GuiDocument::fontfamilies_gui[5] = {
2369 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2373 bool GuiDocument::initialiseParams(string const &)
2375 BufferView const * view = bufferview();
2377 bp_ = BufferParams();
2381 bp_ = view->buffer().params();
2383 updateAvailableModules();
2384 //FIXME It'd be nice to make sure here that the selected
2385 //modules are consistent: That required modules are actually
2386 //selected, and that we don't have conflicts. If so, we could
2387 //at least pop up a warning.
2393 void GuiDocument::clearParams()
2395 bp_ = BufferParams();
2399 BufferId GuiDocument::id() const
2401 BufferView const * const view = bufferview();
2402 return view? &view->buffer() : 0;
2406 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2408 return moduleNames_;
2412 list<GuiDocument::modInfoStruct> const
2413 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
2415 LayoutModuleList::const_iterator it = mods.begin();
2416 LayoutModuleList::const_iterator end = mods.end();
2417 list<modInfoStruct> mInfo;
2418 for (; it != end; ++it) {
2421 LyXModule * mod = moduleList[*it];
2424 m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
2426 m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2433 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2435 return makeModuleInfo(params().getModules());
2439 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
2441 return makeModuleInfo(params().baseClass()->providedModules());
2445 DocumentClass const & GuiDocument::documentClass() const
2447 return bp_.documentClass();
2451 static void dispatch_bufferparams(Dialog const & dialog,
2452 BufferParams const & bp, FuncCode lfun)
2455 ss << "\\begin_header\n";
2457 ss << "\\end_header\n";
2458 dialog.dispatch(FuncRequest(lfun, ss.str()));
2462 void GuiDocument::dispatchParams()
2464 // This must come first so that a language change is correctly noticed
2467 // Apply the BufferParams. Note that this will set the base class
2468 // and then update the buffer's layout.
2469 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2471 if (!params().master.empty()) {
2472 FileName const master_file = support::makeAbsPath(params().master,
2473 support::onlyPath(buffer().absFileName()));
2474 if (isLyXFilename(master_file.absFilename())) {
2475 Buffer * master = checkAndLoadLyXFile(master_file);
2477 if (master->isChild(const_cast<Buffer *>(&buffer())))
2478 const_cast<Buffer &>(buffer()).setParent(master);
2480 Alert::warning(_("Assigned master does not include this file"),
2481 bformat(_("You must include this file in the document\n"
2482 "'%1$s' in order to use the master document\n"
2483 "feature."), from_utf8(params().master)));
2485 Alert::warning(_("Could not load master"),
2486 bformat(_("The master document '%1$s'\n"
2487 "could not be loaded."),
2488 from_utf8(params().master)));
2492 // Generate the colours requested by each new branch.
2493 BranchList & branchlist = params().branchlist();
2494 if (!branchlist.empty()) {
2495 BranchList::const_iterator it = branchlist.begin();
2496 BranchList::const_iterator const end = branchlist.end();
2497 for (; it != end; ++it) {
2498 docstring const & current_branch = it->branch();
2499 Branch const * branch = branchlist.find(current_branch);
2500 string const x11hexname = X11hexname(branch->color());
2501 // display the new color
2502 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2503 dispatch(FuncRequest(LFUN_SET_COLOR, str));
2506 // Open insets of selected branches, close deselected ones
2507 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2510 // FIXME: If we used an LFUN, we would not need those two lines:
2511 BufferView * bv = const_cast<BufferView *>(bufferview());
2512 bv->processUpdateFlags(Update::Force | Update::FitCursor);
2516 void GuiDocument::setLanguage() const
2518 Language const * const newL = bp_.language;
2519 if (buffer().params().language == newL)
2522 string const & lang_name = newL->lang();
2523 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2527 void GuiDocument::saveAsDefault() const
2529 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2533 bool GuiDocument::isFontAvailable(string const & font) const
2535 if (font == "default" || font == "cmr"
2536 || font == "cmss" || font == "cmtt")
2537 // these are standard
2539 if (font == "lmodern" || font == "lmss" || font == "lmtt")
2540 return LaTeXFeatures::isAvailable("lmodern");
2541 if (font == "times" || font == "palatino"
2542 || font == "helvet" || font == "courier")
2543 return LaTeXFeatures::isAvailable("psnfss");
2544 if (font == "cmbr" || font == "cmtl")
2545 return LaTeXFeatures::isAvailable("cmbright");
2546 if (font == "utopia")
2547 return LaTeXFeatures::isAvailable("utopia")
2548 || LaTeXFeatures::isAvailable("fourier");
2549 if (font == "beraserif" || font == "berasans"
2550 || font == "beramono")
2551 return LaTeXFeatures::isAvailable("bera");
2552 return LaTeXFeatures::isAvailable(font);
2556 bool GuiDocument::providesOSF(string const & font) const
2559 return isFontAvailable("eco");
2560 if (font == "palatino")
2561 return isFontAvailable("mathpazo");
2566 bool GuiDocument::providesSC(string const & font) const
2568 if (font == "palatino")
2569 return isFontAvailable("mathpazo");
2570 if (font == "utopia")
2571 return isFontAvailable("fourier");
2576 bool GuiDocument::providesScale(string const & font) const
2578 return font == "helvet" || font == "luximono"
2579 || font == "berasans" || font == "beramono";
2583 void GuiDocument::loadModuleInfo()
2585 moduleNames_.clear();
2586 LyXModuleList::const_iterator it = moduleList.begin();
2587 LyXModuleList::const_iterator end = moduleList.end();
2588 for (; it != end; ++it) {
2592 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
2593 // this is supposed to give us the first sentence of the description
2596 toqstr(translateIfPossible(from_utf8(it->getDescription())));
2597 int const pos = desc.indexOf(".");
2599 desc.truncate(pos + 1);
2600 m.description = desc;
2601 moduleNames_.push_back(m);
2606 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2609 } // namespace frontend
2612 #include "moc_GuiDocument.cpp"