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>
58 #include <QTextCursor>
69 using namespace lyx::support;
74 char const * const tex_graphics[] =
76 "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
77 "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
78 "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
79 "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
84 char const * const tex_graphics_gui[] =
86 N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
87 "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
88 "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
89 "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
90 "XeTeX", N_("None"), ""
94 char const * const tex_fonts_roman[] =
96 "default", "cmr", "lmodern", "ae", "times", "palatino",
97 "charter", "newcent", "bookman", "utopia", "beraserif",
98 "ccfonts", "chancery", ""
102 char const * tex_fonts_roman_gui[] =
104 N_("Default"), N_("Computer Modern Roman"), N_("Latin Modern Roman"),
105 N_("AE (Almost European)"), N_("Times Roman"), N_("Palatino"),
106 N_("Bitstream Charter"), N_("New Century Schoolbook"), N_("Bookman"),
107 N_("Utopia"), N_("Bera Serif"), N_("Concrete Roman"), N_("Zapf Chancery"),
112 char const * const tex_fonts_sans[] =
114 "default", "cmss", "lmss", "helvet", "avant", "berasans", "cmbr", ""
118 char const * tex_fonts_sans_gui[] =
120 N_("Default"), N_("Computer Modern Sans"), N_("Latin Modern Sans"),
121 N_("Helvetica"), N_("Avant Garde"), N_("Bera Sans"), N_("CM Bright"), ""
125 char const * const tex_fonts_monospaced[] =
127 "default", "cmtt", "lmtt", "courier", "beramono", "luximono", "cmtl", ""
131 char const * tex_fonts_monospaced_gui[] =
133 N_("Default"), N_("Computer Modern Typewriter"),
134 N_("Latin Modern Typewriter"), N_("Courier"), N_("Bera Mono"),
135 N_("LuxiMono"), N_("CM Typewriter Light"), ""
139 char const * backref_opts[] =
141 "false", "section", "slide", "page", ""
145 char const * backref_opts_gui[] =
147 N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
151 vector<pair<string, QString> > pagestyles;
154 } // anonymous namespace
159 // used when sorting the textclass list.
160 class less_textclass_avail_desc
161 : public binary_function<string, string, int>
164 bool operator()(string const & lhs, string const & rhs) const
166 // Ordering criteria:
167 // 1. Availability of text class
168 // 2. Description (lexicographic)
169 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
170 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
171 int const rel = compare_no_case(
172 translateIfPossible(from_utf8(tc1.description())),
173 translateIfPossible(from_utf8(tc2.description())));
174 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
175 (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() && rel < 0);
184 vector<string> getRequiredList(string const & modName)
186 LyXModule const * const mod = moduleList[modName];
188 return vector<string>(); //empty such thing
189 return mod->getRequiredModules();
193 vector<string> getExcludedList(string const & modName)
195 LyXModule const * const mod = moduleList[modName];
197 return vector<string>(); //empty such thing
198 return mod->getExcludedModules();
202 docstring getModuleDescription(string const & modName)
204 LyXModule const * const mod = moduleList[modName];
206 return _("Module not found!");
208 return translateIfPossible(from_utf8(mod->getDescription()));
212 vector<string> getPackageList(string const & modName)
214 LyXModule const * const mod = moduleList[modName];
216 return vector<string>(); //empty such thing
217 return mod->getPackageList();
221 bool isModuleAvailable(string const & modName)
223 LyXModule * mod = moduleList[modName];
226 return mod->isAvailable();
229 } // anonymous namespace
232 /////////////////////////////////////////////////////////////////////
234 // ModuleSelectionManager
236 /////////////////////////////////////////////////////////////////////
238 /// SelectionManager for use with modules
239 class ModuleSelectionManager : public GuiSelectionManager
243 ModuleSelectionManager(
244 QListView * availableLV,
245 QListView * selectedLV,
249 QPushButton * downPB,
250 GuiIdListModel * availableModel,
251 GuiIdListModel * selectedModel,
252 GuiDocument const * container)
253 : GuiSelectionManager(availableLV, selectedLV, addPB, delPB,
254 upPB, downPB, availableModel, selectedModel), container_(container)
257 void updateProvidedModules(LayoutModuleList const & pm)
258 { provided_modules_ = pm.list(); }
260 void updateExcludedModules(LayoutModuleList const & em)
261 { excluded_modules_ = em.list(); }
264 virtual void updateAddPB();
266 virtual void updateUpPB();
268 virtual void updateDownPB();
270 virtual void updateDelPB();
271 /// returns availableModel as a GuiIdListModel
272 GuiIdListModel * getAvailableModel()
274 return dynamic_cast<GuiIdListModel *>(availableModel);
276 /// returns selectedModel as a GuiIdListModel
277 GuiIdListModel * getSelectedModel()
279 return dynamic_cast<GuiIdListModel *>(selectedModel);
281 /// keeps a list of the modules the text class provides
282 std::list<std::string> provided_modules_;
284 std::list<std::string> excluded_modules_;
286 GuiDocument const * container_;
289 void ModuleSelectionManager::updateAddPB()
291 int const arows = availableModel->rowCount();
292 QModelIndexList const avail_sels =
293 availableLV->selectionModel()->selectedIndexes();
295 // disable if there aren't any modules (?), if none of them is chosen
296 // in the dialog, or if the chosen one is already selected for use.
297 if (arows == 0 || avail_sels.isEmpty() || isSelected(avail_sels.first())) {
298 addPB->setEnabled(false);
302 QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
303 string const modname = getAvailableModel()->getIDString(idx.row());
306 container_->params().moduleCanBeAdded(modname);
307 addPB->setEnabled(enable);
311 void ModuleSelectionManager::updateDownPB()
313 int const srows = selectedModel->rowCount();
315 downPB->setEnabled(false);
318 QModelIndex const & curidx = selectedLV->selectionModel()->currentIndex();
319 int const curRow = curidx.row();
320 if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
321 downPB->setEnabled(false);
325 // determine whether immediately succeding element requires this one
326 string const curmodname = getSelectedModel()->getIDString(curRow);
327 string const nextmodname = getSelectedModel()->getIDString(curRow + 1);
329 vector<string> reqs = getRequiredList(nextmodname);
331 // if it doesn't require anything....
333 downPB->setEnabled(true);
337 // Enable it if this module isn't required.
338 // FIXME This should perhaps be more flexible and check whether, even
339 // if the next one is required, there is also an earlier one that will do.
341 find(reqs.begin(), reqs.end(), curmodname) == reqs.end());
344 void ModuleSelectionManager::updateUpPB()
346 int const srows = selectedModel->rowCount();
348 upPB->setEnabled(false);
352 QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
353 int curRow = curIdx.row();
354 if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
355 upPB->setEnabled(false);
358 string const curmodname = getSelectedModel()->getIDString(curRow);
360 // determine whether immediately preceding element is required by this one
361 vector<string> reqs = getRequiredList(curmodname);
363 // if this one doesn't require anything....
365 upPB->setEnabled(true);
370 // Enable it if the preceding module isn't required.
371 // NOTE This is less flexible than it might be. We could check whether, even
372 // if the previous one is required, there is an earlier one that would do.
373 string const premod = getSelectedModel()->getIDString(curRow - 1);
374 upPB->setEnabled(find(reqs.begin(), reqs.end(), premod) == reqs.end());
377 void ModuleSelectionManager::updateDelPB()
379 int const srows = selectedModel->rowCount();
381 deletePB->setEnabled(false);
385 QModelIndex const & curidx =
386 selectedLV->selectionModel()->currentIndex();
387 int const curRow = curidx.row();
388 if (curRow < 0 || curRow >= srows) { // invalid index?
389 deletePB->setEnabled(false);
393 string const curmodname = getSelectedModel()->getIDString(curRow);
395 // We're looking here for a reason NOT to enable the button. If we
396 // find one, we disable it and return. If we don't, we'll end up at
397 // the end of the function, and then we enable it.
398 for (int i = curRow + 1; i < srows; ++i) {
399 string const thisMod = getSelectedModel()->getIDString(i);
400 vector<string> reqs = getRequiredList(thisMod);
401 //does this one require us?
402 if (find(reqs.begin(), reqs.end(), curmodname) == reqs.end())
406 // OK, so this module requires us
407 // is there an EARLIER module that also satisfies the require?
408 // NOTE We demand that it be earlier to keep the list of modules
409 // consistent with the rule that a module must be proceeded by a
410 // required module. There would be more flexible ways to proceed,
411 // but that would be a lot more complicated, and the logic here is
412 // already complicated. (That's why I've left the debugging code.)
413 // lyxerr << "Testing " << thisMod << std::endl;
414 bool foundone = false;
415 for (int j = 0; j < curRow; ++j) {
416 string const mod = getSelectedModel()->getIDString(j);
417 // lyxerr << "In loop: Testing " << mod << std::endl;
418 // do we satisfy the require?
419 if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
420 // lyxerr << mod << " does the trick." << std::endl;
425 // did we find a module to satisfy the require?
427 // lyxerr << "No matching module found." << std::endl;
428 deletePB->setEnabled(false);
432 // lyxerr << "All's well that ends well." << std::endl;
433 deletePB->setEnabled(true);
437 /////////////////////////////////////////////////////////////////////
441 /////////////////////////////////////////////////////////////////////
443 PreambleModule::PreambleModule() : current_id_(0)
445 // This is not a memory leak. The object will be destroyed
447 (void) new LaTeXHighlighter(preambleTE->document());
448 setFocusProxy(preambleTE);
449 connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
453 void PreambleModule::update(BufferParams const & params, BufferId id)
455 QString preamble = toqstr(params.preamble);
456 // Nothing to do if the params and preamble are unchanged.
457 if (id == current_id_
458 && preamble == preambleTE->document()->toPlainText())
461 QTextCursor cur = preambleTE->textCursor();
462 // Save the coords before switching to the new one.
463 preamble_coords_[current_id_] =
464 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
466 // Save the params address for further use.
468 preambleTE->document()->setPlainText(preamble);
469 Coords::const_iterator it = preamble_coords_.find(current_id_);
470 if (it == preamble_coords_.end())
471 // First time we open this one.
472 preamble_coords_[current_id_] = make_pair(0, 0);
474 // Restore saved coords.
475 QTextCursor cur = preambleTE->textCursor();
476 cur.setPosition(it->second.first);
477 preambleTE->setTextCursor(cur);
478 preambleTE->verticalScrollBar()->setValue(it->second.second);
483 void PreambleModule::apply(BufferParams & params)
485 params.preamble = fromqstr(preambleTE->document()->toPlainText());
489 void PreambleModule::closeEvent(QCloseEvent * e)
491 // Save the coords before closing.
492 QTextCursor cur = preambleTE->textCursor();
493 preamble_coords_[current_id_] =
494 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
499 /////////////////////////////////////////////////////////////////////
503 /////////////////////////////////////////////////////////////////////
506 GuiDocument::GuiDocument(GuiView & lv)
507 : GuiDialog(lv, "document", qt_("Document Settings"))
511 connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
512 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
513 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
514 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
516 connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
517 connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
519 // Manage the restore, ok, apply, restore and cancel/close buttons
520 bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
522 bc().setApply(applyPB);
523 bc().setCancel(closePB);
524 bc().setRestore(restorePB);
526 textLayoutModule = new UiWidget<Ui::TextLayoutUi>;
528 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
529 this, SLOT(change_adaptor()));
530 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
531 this, SLOT(setLSpacing(int)));
532 connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
533 this, SLOT(change_adaptor()));
534 connect(textLayoutModule->skipRB, SIGNAL(clicked()),
535 this, SLOT(change_adaptor()));
536 connect(textLayoutModule->indentRB, SIGNAL(clicked()),
537 this, SLOT(change_adaptor()));
538 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
539 this, SLOT(change_adaptor()));
540 connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
541 this, SLOT(change_adaptor()));
542 connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
543 this, SLOT(change_adaptor()));
544 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
545 this, SLOT(setSkip(int)));
546 connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
547 this, SLOT(enableSkip(bool)));
548 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
549 this, SLOT(change_adaptor()));
550 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
551 this, SLOT(setColSep()));
552 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
553 this, SLOT(change_adaptor()));
554 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
555 this, SLOT(change_adaptor()));
556 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
557 this, SLOT(setListingsMessage()));
558 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
559 this, SLOT(setListingsMessage()));
560 textLayoutModule->listingsTB->setPlainText(
561 qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
562 textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
563 textLayoutModule->lspacingLE));
564 textLayoutModule->skipLE->setValidator(unsignedLengthValidator(
565 textLayoutModule->skipLE));
567 textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
568 textLayoutModule->skipCO->addItem(qt_("MedSkip"));
569 textLayoutModule->skipCO->addItem(qt_("BigSkip"));
570 textLayoutModule->skipCO->addItem(qt_("Length"));
571 // remove the %-items from the unit choice
572 textLayoutModule->skipLengthCO->noPercents();
573 textLayoutModule->lspacingCO->insertItem(
574 Spacing::Single, qt_("Single"));
575 textLayoutModule->lspacingCO->insertItem(
576 Spacing::Onehalf, qt_("OneHalf"));
577 textLayoutModule->lspacingCO->insertItem(
578 Spacing::Double, qt_("Double"));
579 textLayoutModule->lspacingCO->insertItem(
580 Spacing::Other, qt_("Custom"));
582 // initialize the length validator
583 bc().addCheckedLineEdit(textLayoutModule->skipLE);
585 fontModule = new UiWidget<Ui::FontUi>;
587 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
588 this, SLOT(change_adaptor()));
589 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
590 this, SLOT(romanChanged(int)));
591 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
592 this, SLOT(change_adaptor()));
593 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
594 this, SLOT(sansChanged(int)));
595 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
596 this, SLOT(change_adaptor()));
597 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
598 this, SLOT(ttChanged(int)));
599 connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
600 this, SLOT(change_adaptor()));
601 connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
602 this, SLOT(change_adaptor()));
603 connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
604 this, SLOT(change_adaptor()));
605 connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
606 this, SLOT(change_adaptor()));
607 connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
608 this, SLOT(change_adaptor()));
609 connect(fontModule->fontScCB, SIGNAL(clicked()),
610 this, SLOT(change_adaptor()));
611 connect(fontModule->fontOsfCB, SIGNAL(clicked()),
612 this, SLOT(change_adaptor()));
614 for (int n = 0; tex_fonts_roman[n][0]; ++n) {
615 QString font = qt_(tex_fonts_roman_gui[n]);
616 if (!isFontAvailable(tex_fonts_roman[n]))
617 font += qt_(" (not installed)");
618 fontModule->fontsRomanCO->addItem(font);
620 for (int n = 0; tex_fonts_sans[n][0]; ++n) {
621 QString font = qt_(tex_fonts_sans_gui[n]);
622 if (!isFontAvailable(tex_fonts_sans[n]))
623 font += qt_(" (not installed)");
624 fontModule->fontsSansCO->addItem(font);
626 for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
627 QString font = qt_(tex_fonts_monospaced_gui[n]);
628 if (!isFontAvailable(tex_fonts_monospaced[n]))
629 font += qt_(" (not installed)");
630 fontModule->fontsTypewriterCO->addItem(font);
633 fontModule->fontsizeCO->addItem(qt_("Default"));
634 fontModule->fontsizeCO->addItem(qt_("10"));
635 fontModule->fontsizeCO->addItem(qt_("11"));
636 fontModule->fontsizeCO->addItem(qt_("12"));
638 for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
639 fontModule->fontsDefaultCO->addItem(
640 qt_(GuiDocument::fontfamilies_gui[n]));
643 pageLayoutModule = new UiWidget<Ui::PageLayoutUi>;
645 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
646 this, SLOT(setCustomPapersize(int)));
647 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
648 this, SLOT(setCustomPapersize(int)));
649 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
650 this, SLOT(portraitChanged()));
651 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
652 this, SLOT(change_adaptor()));
653 connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
654 this, SLOT(change_adaptor()));
655 connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
656 this, SLOT(change_adaptor()));
657 connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
658 this, SLOT(change_adaptor()));
659 connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
660 this, SLOT(change_adaptor()));
661 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
662 this, SLOT(change_adaptor()));
663 connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
664 this, SLOT(change_adaptor()));
665 connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
666 this, SLOT(change_adaptor()));
667 connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
668 this, SLOT(change_adaptor()));
670 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
671 pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
672 pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
673 pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
674 pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
675 bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
676 pageLayoutModule->paperheightL);
677 bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
678 pageLayoutModule->paperwidthL);
681 QComboBox * cb = pageLayoutModule->papersizeCO;
682 cb->addItem(qt_("Default"));
683 cb->addItem(qt_("Custom"));
684 cb->addItem(qt_("US letter"));
685 cb->addItem(qt_("US legal"));
686 cb->addItem(qt_("US executive"));
687 cb->addItem(qt_("A3"));
688 cb->addItem(qt_("A4"));
689 cb->addItem(qt_("A5"));
690 cb->addItem(qt_("B3"));
691 cb->addItem(qt_("B4"));
692 cb->addItem(qt_("B5"));
693 // remove the %-items from the unit choice
694 pageLayoutModule->paperwidthUnitCO->noPercents();
695 pageLayoutModule->paperheightUnitCO->noPercents();
696 pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
697 pageLayoutModule->paperheightLE));
698 pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
699 pageLayoutModule->paperwidthLE));
702 marginsModule = new UiWidget<Ui::MarginsUi>;
704 connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
705 this, SLOT(setCustomMargins(bool)));
706 connect(marginsModule->marginCB, SIGNAL(clicked()),
707 this, SLOT(change_adaptor()));
708 connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
709 this, SLOT(change_adaptor()));
710 connect(marginsModule->topUnit, SIGNAL(activated(int)),
711 this, SLOT(change_adaptor()));
712 connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
713 this, SLOT(change_adaptor()));
714 connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
715 this, SLOT(change_adaptor()));
716 connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
717 this, SLOT(change_adaptor()));
718 connect(marginsModule->innerUnit, SIGNAL(activated(int)),
719 this, SLOT(change_adaptor()));
720 connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
721 this, SLOT(change_adaptor()));
722 connect(marginsModule->outerUnit, SIGNAL(activated(int)),
723 this, SLOT(change_adaptor()));
724 connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
725 this, SLOT(change_adaptor()));
726 connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
727 this, SLOT(change_adaptor()));
728 connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
729 this, SLOT(change_adaptor()));
730 connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
731 this, SLOT(change_adaptor()));
732 connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
733 this, SLOT(change_adaptor()));
734 connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
735 this, SLOT(change_adaptor()));
736 connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
737 this, SLOT(change_adaptor()));
738 connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
739 this, SLOT(change_adaptor()));
740 marginsModule->topLE->setValidator(unsignedLengthValidator(
741 marginsModule->topLE));
742 marginsModule->bottomLE->setValidator(unsignedLengthValidator(
743 marginsModule->bottomLE));
744 marginsModule->innerLE->setValidator(unsignedLengthValidator(
745 marginsModule->innerLE));
746 marginsModule->outerLE->setValidator(unsignedLengthValidator(
747 marginsModule->outerLE));
748 marginsModule->headsepLE->setValidator(unsignedLengthValidator(
749 marginsModule->headsepLE));
750 marginsModule->headheightLE->setValidator(unsignedLengthValidator(
751 marginsModule->headheightLE));
752 marginsModule->footskipLE->setValidator(unsignedLengthValidator(
753 marginsModule->footskipLE));
754 marginsModule->columnsepLE->setValidator(unsignedLengthValidator(
755 marginsModule->columnsepLE));
757 bc().addCheckedLineEdit(marginsModule->topLE,
758 marginsModule->topL);
759 bc().addCheckedLineEdit(marginsModule->bottomLE,
760 marginsModule->bottomL);
761 bc().addCheckedLineEdit(marginsModule->innerLE,
762 marginsModule->innerL);
763 bc().addCheckedLineEdit(marginsModule->outerLE,
764 marginsModule->outerL);
765 bc().addCheckedLineEdit(marginsModule->headsepLE,
766 marginsModule->headsepL);
767 bc().addCheckedLineEdit(marginsModule->headheightLE,
768 marginsModule->headheightL);
769 bc().addCheckedLineEdit(marginsModule->footskipLE,
770 marginsModule->footskipL);
771 bc().addCheckedLineEdit(marginsModule->columnsepLE,
772 marginsModule->columnsepL);
775 langModule = new UiWidget<Ui::LanguageUi>;
777 connect(langModule->languageCO, SIGNAL(activated(int)),
778 this, SLOT(change_adaptor()));
779 connect(langModule->defaultencodingRB, SIGNAL(clicked()),
780 this, SLOT(change_adaptor()));
781 connect(langModule->otherencodingRB, SIGNAL(clicked()),
782 this, SLOT(change_adaptor()));
783 connect(langModule->encodingCO, SIGNAL(activated(int)),
784 this, SLOT(change_adaptor()));
785 connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
786 this, SLOT(change_adaptor()));
788 QAbstractItemModel * language_model = guiApp->languageModel();
789 // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
790 language_model->sort(0);
791 langModule->languageCO->setModel(language_model);
793 // Always put the default encoding in the first position.
794 langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
795 QStringList encodinglist;
796 Encodings::const_iterator it = encodings.begin();
797 Encodings::const_iterator const end = encodings.end();
798 for (; it != end; ++it)
799 encodinglist.append(qt_(it->guiName()));
801 langModule->encodingCO->addItems(encodinglist);
803 langModule->quoteStyleCO->addItem(qt_("``text''"));
804 langModule->quoteStyleCO->addItem(qt_("''text''"));
805 langModule->quoteStyleCO->addItem(qt_(",,text``"));
806 langModule->quoteStyleCO->addItem(qt_(",,text''"));
807 langModule->quoteStyleCO->addItem(qt_("<<text>>"));
808 langModule->quoteStyleCO->addItem(qt_(">>text<<"));
811 numberingModule = new UiWidget<Ui::NumberingUi>;
813 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
814 this, SLOT(change_adaptor()));
815 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
816 this, SLOT(change_adaptor()));
817 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
818 this, SLOT(updateNumbering()));
819 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
820 this, SLOT(updateNumbering()));
821 numberingModule->tocTW->setColumnCount(3);
822 numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
823 numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
824 numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
827 biblioModule = new UiWidget<Ui::BiblioUi>;
828 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
829 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
830 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
831 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
833 connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
834 this, SLOT(change_adaptor()));
835 connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
836 this, SLOT(change_adaptor()));
837 connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
838 this, SLOT(change_adaptor()));
839 connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
840 this, SLOT(change_adaptor()));
841 connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
842 this, SLOT(change_adaptor()));
844 biblioModule->citeStyleCO->addItem(qt_("Author-year"));
845 biblioModule->citeStyleCO->addItem(qt_("Numerical"));
846 biblioModule->citeStyleCO->setCurrentIndex(0);
849 mathsModule = new UiWidget<Ui::MathsUi>;
850 connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
851 mathsModule->amsCB, SLOT(setDisabled(bool)));
852 connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
853 mathsModule->esintCB, SLOT(setDisabled(bool)));
855 connect(mathsModule->amsCB, SIGNAL(clicked()),
856 this, SLOT(change_adaptor()));
857 connect(mathsModule->amsautoCB, SIGNAL(clicked()),
858 this, SLOT(change_adaptor()));
859 connect(mathsModule->esintCB, SIGNAL(clicked()),
860 this, SLOT(change_adaptor()));
861 connect(mathsModule->esintautoCB, SIGNAL(clicked()),
862 this, SLOT(change_adaptor()));
864 latexModule = new UiWidget<Ui::LaTeXUi>;
866 connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
867 this, SLOT(change_adaptor()));
868 connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
869 this, SLOT(change_adaptor()));
870 connect(latexModule->psdriverCO, SIGNAL(activated(int)),
871 this, SLOT(change_adaptor()));
872 connect(latexModule->classCO, SIGNAL(activated(int)),
873 this, SLOT(classChanged()));
874 connect(latexModule->classCO, SIGNAL(activated(int)),
875 this, SLOT(change_adaptor()));
876 connect(latexModule->layoutPB, SIGNAL(clicked()),
877 this, SLOT(browseLayout()));
878 connect(latexModule->layoutPB, SIGNAL(clicked()),
879 this, SLOT(change_adaptor()));
880 connect(latexModule->childDocGB, SIGNAL(clicked()),
881 this, SLOT(change_adaptor()));
882 connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
883 this, SLOT(change_adaptor()));
884 connect(latexModule->childDocPB, SIGNAL(clicked()),
885 this, SLOT(browseMaster()));
887 // postscript drivers
888 for (int n = 0; tex_graphics[n][0]; ++n) {
889 QString enc = qt_(tex_graphics_gui[n]);
890 latexModule->psdriverCO->addItem(enc);
893 latexModule->classCO->setModel(&classes_model_);
894 LayoutFileList const & bcl = LayoutFileList::get();
895 vector<LayoutFileIndex> classList = bcl.classList();
896 sort(classList.begin(), classList.end(), less_textclass_avail_desc());
898 vector<LayoutFileIndex>::const_iterator cit = classList.begin();
899 vector<LayoutFileIndex>::const_iterator cen = classList.end();
900 for (int i = 0; cit != cen; ++cit, ++i) {
901 LayoutFile const & tc = bcl[*cit];
902 docstring item = (tc.isTeXClassAvailable()) ?
903 from_utf8(tc.description()) :
904 bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
905 classes_model_.insertRow(i, toqstr(item), *cit);
909 branchesModule = new GuiBranches;
910 connect(branchesModule, SIGNAL(changed()),
911 this, SLOT(change_adaptor()));
914 preambleModule = new PreambleModule;
915 connect(preambleModule, SIGNAL(changed()),
916 this, SLOT(change_adaptor()));
919 bulletsModule = new BulletsModule;
920 connect(bulletsModule, SIGNAL(changed()),
921 this, SLOT(change_adaptor()));
924 modulesModule = new UiWidget<Ui::ModulesUi>;
927 new ModuleSelectionManager(modulesModule->availableLV,
928 modulesModule->selectedLV,
929 modulesModule->addPB, modulesModule->deletePB,
930 modulesModule->upPB, modulesModule->downPB,
931 availableModel(), selectedModel(), this);
932 connect(selectionManager, SIGNAL(updateHook()),
933 this, SLOT(updateModuleInfo()));
934 connect(selectionManager, SIGNAL(updateHook()),
935 this, SLOT(change_adaptor()));
936 connect(selectionManager, SIGNAL(selectionChanged()),
937 this, SLOT(modulesChanged()));
940 pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
942 connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
943 this, SLOT(change_adaptor()));
944 connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
945 this, SLOT(change_adaptor()));
946 connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
947 this, SLOT(change_adaptor()));
948 connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
949 this, SLOT(change_adaptor()));
950 connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
951 this, SLOT(change_adaptor()));
952 connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
953 this, SLOT(change_adaptor()));
954 connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
955 this, SLOT(change_adaptor()));
956 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
957 this, SLOT(change_adaptor()));
958 connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
959 this, SLOT(change_adaptor()));
960 connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
961 this, SLOT(change_adaptor()));
962 connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
963 this, SLOT(change_adaptor()));
964 connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
965 this, SLOT(change_adaptor()));
966 connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
967 this, SLOT(change_adaptor()));
968 connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
969 this, SLOT(change_adaptor()));
970 connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
971 this, SLOT(change_adaptor()));
972 connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
973 this, SLOT(change_adaptor()));
975 for (int i = 0; backref_opts[i][0]; ++i)
976 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
979 floatModule = new FloatPlacement;
980 connect(floatModule, SIGNAL(changed()),
981 this, SLOT(change_adaptor()));
983 docPS->addPanel(latexModule, qt_("Document Class"));
984 docPS->addPanel(modulesModule, qt_("Modules"));
985 docPS->addPanel(fontModule, qt_("Fonts"));
986 docPS->addPanel(textLayoutModule, qt_("Text Layout"));
987 docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
988 docPS->addPanel(marginsModule, qt_("Page Margins"));
989 docPS->addPanel(langModule, qt_("Language"));
990 docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
991 docPS->addPanel(biblioModule, qt_("Bibliography"));
992 docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
993 docPS->addPanel(mathsModule, qt_("Math Options"));
994 docPS->addPanel(floatModule, qt_("Float Placement"));
995 docPS->addPanel(bulletsModule, qt_("Bullets"));
996 docPS->addPanel(branchesModule, qt_("Branches"));
997 docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
998 docPS->setCurrentPanel(qt_("Document Class"));
999 // FIXME: hack to work around resizing bug in Qt >= 4.2
1000 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1001 #if QT_VERSION >= 0x040200
1002 docPS->updateGeometry();
1007 void GuiDocument::showPreamble()
1009 docPS->setCurrentPanel(qt_("LaTeX Preamble"));
1013 void GuiDocument::saveDefaultClicked()
1019 void GuiDocument::useDefaultsClicked()
1025 void GuiDocument::change_adaptor()
1031 QString GuiDocument::validateListingsParameters()
1033 // use a cache here to avoid repeated validation
1034 // of the same parameters
1035 static string param_cache;
1036 static QString msg_cache;
1038 if (textLayoutModule->bypassCB->isChecked())
1041 string params = fromqstr(textLayoutModule->listingsED->toPlainText());
1042 if (params != param_cache) {
1043 param_cache = params;
1044 msg_cache = toqstr(InsetListingsParams(params).validate());
1050 void GuiDocument::setListingsMessage()
1052 static bool isOK = true;
1053 QString msg = validateListingsParameters();
1054 if (msg.isEmpty()) {
1058 // listingsTB->setTextColor("black");
1059 textLayoutModule->listingsTB->setPlainText(
1060 qt_("Input listings parameters on the right. "
1061 "Enter ? for a list of parameters."));
1064 // listingsTB->setTextColor("red");
1065 textLayoutModule->listingsTB->setPlainText(msg);
1070 void GuiDocument::setLSpacing(int item)
1072 textLayoutModule->lspacingLE->setEnabled(item == 3);
1076 void GuiDocument::setSkip(int item)
1078 bool const enable = (item == 3);
1079 textLayoutModule->skipLE->setEnabled(enable);
1080 textLayoutModule->skipLengthCO->setEnabled(enable);
1084 void GuiDocument::enableSkip(bool skip)
1086 textLayoutModule->skipCO->setEnabled(skip);
1087 textLayoutModule->skipLE->setEnabled(skip);
1088 textLayoutModule->skipLengthCO->setEnabled(skip);
1090 setSkip(textLayoutModule->skipCO->currentIndex());
1093 void GuiDocument::portraitChanged()
1095 setMargins(pageLayoutModule->papersizeCO->currentIndex());
1098 void GuiDocument::setMargins(bool custom)
1100 marginsModule->marginCB->setChecked(custom);
1101 setCustomMargins(custom);
1105 void GuiDocument::setCustomPapersize(int papersize)
1107 bool const custom = (papersize == 1);
1109 pageLayoutModule->paperwidthL->setEnabled(custom);
1110 pageLayoutModule->paperwidthLE->setEnabled(custom);
1111 pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1112 pageLayoutModule->paperheightL->setEnabled(custom);
1113 pageLayoutModule->paperheightLE->setEnabled(custom);
1114 pageLayoutModule->paperheightLE->setFocus();
1115 pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1119 void GuiDocument::setColSep()
1121 setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1125 void GuiDocument::setCustomMargins(bool custom)
1127 marginsModule->topL->setEnabled(!custom);
1128 marginsModule->topLE->setEnabled(!custom);
1129 marginsModule->topUnit->setEnabled(!custom);
1131 marginsModule->bottomL->setEnabled(!custom);
1132 marginsModule->bottomLE->setEnabled(!custom);
1133 marginsModule->bottomUnit->setEnabled(!custom);
1135 marginsModule->innerL->setEnabled(!custom);
1136 marginsModule->innerLE->setEnabled(!custom);
1137 marginsModule->innerUnit->setEnabled(!custom);
1139 marginsModule->outerL->setEnabled(!custom);
1140 marginsModule->outerLE->setEnabled(!custom);
1141 marginsModule->outerUnit->setEnabled(!custom);
1143 marginsModule->headheightL->setEnabled(!custom);
1144 marginsModule->headheightLE->setEnabled(!custom);
1145 marginsModule->headheightUnit->setEnabled(!custom);
1147 marginsModule->headsepL->setEnabled(!custom);
1148 marginsModule->headsepLE->setEnabled(!custom);
1149 marginsModule->headsepUnit->setEnabled(!custom);
1151 marginsModule->footskipL->setEnabled(!custom);
1152 marginsModule->footskipLE->setEnabled(!custom);
1153 marginsModule->footskipUnit->setEnabled(!custom);
1155 bool const enableColSep = !custom &&
1156 textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1157 marginsModule->columnsepL->setEnabled(enableColSep);
1158 marginsModule->columnsepLE->setEnabled(enableColSep);
1159 marginsModule->columnsepUnit->setEnabled(enableColSep);
1163 void GuiDocument::updateFontsize(string const & items, string const & sel)
1165 fontModule->fontsizeCO->clear();
1166 fontModule->fontsizeCO->addItem(qt_("Default"));
1168 for (int n = 0; !token(items,'|',n).empty(); ++n)
1169 fontModule->fontsizeCO->
1170 addItem(toqstr(token(items,'|',n)));
1172 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1173 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1174 fontModule->fontsizeCO->setCurrentIndex(n);
1181 void GuiDocument::romanChanged(int item)
1183 string const font = tex_fonts_roman[item];
1184 fontModule->fontScCB->setEnabled(providesSC(font));
1185 fontModule->fontOsfCB->setEnabled(providesOSF(font));
1189 void GuiDocument::sansChanged(int item)
1191 string const font = tex_fonts_sans[item];
1192 bool scaleable = providesScale(font);
1193 fontModule->scaleSansSB->setEnabled(scaleable);
1194 fontModule->scaleSansLA->setEnabled(scaleable);
1198 void GuiDocument::ttChanged(int item)
1200 string const font = tex_fonts_monospaced[item];
1201 bool scaleable = providesScale(font);
1202 fontModule->scaleTypewriterSB->setEnabled(scaleable);
1203 fontModule->scaleTypewriterLA->setEnabled(scaleable);
1207 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1210 pageLayoutModule->pagestyleCO->clear();
1211 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1213 for (int n = 0; !token(items, '|', n).empty(); ++n) {
1214 string style = token(items, '|', n);
1215 QString style_gui = qt_(style);
1216 pagestyles.push_back(pair<string, QString>(style, style_gui));
1217 pageLayoutModule->pagestyleCO->addItem(style_gui);
1220 if (sel == "default") {
1221 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1227 for (size_t i = 0; i < pagestyles.size(); ++i)
1228 if (pagestyles[i].first == sel)
1229 nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1232 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1236 void GuiDocument::browseLayout()
1238 QString const label1 = qt_("Layouts|#o#O");
1239 QString const dir1 = toqstr(lyxrc.document_path);
1240 QStringList const filter(qt_("LyX Layout (*.layout)"));
1241 QString file = browseRelFile(QString(), bufferFilepath(),
1242 qt_("Local layout file"), filter, false,
1245 if (!file.endsWith(".layout"))
1248 FileName layoutFile = support::makeAbsPath(fromqstr(file),
1249 fromqstr(bufferFilepath()));
1251 int const ret = Alert::prompt(_("Local layout file"),
1252 _("The layout file you have selected is a local layout\n"
1253 "file, not one in the system or user directory. Your\n"
1254 "document may not work with this layout if you do not\n"
1255 "keep the layout file in the document directory."),
1256 1, 1, _("&Set Layout"), _("&Cancel"));
1260 // load the layout file
1261 LayoutFileList & bcl = LayoutFileList::get();
1262 string classname = layoutFile.onlyFileName();
1263 // this will update an existing layout if that layout has been loaded before.
1264 LayoutFileIndex name = bcl.addLocalLayout(
1265 classname.substr(0, classname.size() - 7),
1266 layoutFile.onlyPath().absFilename());
1269 Alert::error(_("Error"),
1270 _("Unable to read local layout file."));
1274 // do not trigger classChanged if there is no change.
1275 if (latexModule->classCO->currentText() == toqstr(name))
1279 int idx = latexModule->classCO->findText(toqstr(name));
1281 classes_model_.insertRow(0, toqstr(name), name);
1282 latexModule->classCO->setCurrentIndex(0);
1284 latexModule->classCO->setCurrentIndex(idx);
1290 void GuiDocument::browseMaster()
1292 QString const title = qt_("Select master document");
1293 QString const dir1 = toqstr(lyxrc.document_path);
1294 QString const old = latexModule->childDocLE->text();
1295 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1296 QStringList const filter(qt_("LyX Files (*.lyx)"));
1297 QString file = browseRelFile(old, docpath, title, filter, false,
1298 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1300 latexModule->childDocLE->setText(file);
1304 void GuiDocument::classChanged()
1306 int idx = latexModule->classCO->currentIndex();
1309 string const classname = classes_model_.getIDString(idx);
1311 // check whether the selected modules have changed.
1312 bool modules_changed = false;
1313 unsigned int const srows = selectedModel()->rowCount();
1314 if (srows != bp_.getModules().size())
1315 modules_changed = true;
1317 list<string>::const_iterator mit = bp_.getModules().begin();
1318 list<string>::const_iterator men = bp_.getModules().end();
1319 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1320 if (selectedModel()->getIDString(i) != *mit) {
1321 modules_changed = true;
1326 if (modules_changed || lyxrc.auto_reset_options) {
1327 if (applyPB->isEnabled()) {
1328 int const ret = Alert::prompt(_("Unapplied changes"),
1329 _("Some changes in the dialog were not yet applied.\n"
1330 "If you do not apply now, they will be lost after this action."),
1331 1, 1, _("&Apply"), _("&Dismiss"));
1337 // We load the TextClass as soon as it is selected. This is
1338 // necessary so that other options in the dialog can be updated
1339 // according to the new class. Note, however, that, if you use
1340 // the scroll wheel when sitting on the combo box, we'll load a
1341 // lot of TextClass objects very quickly....
1342 if (!bp_.setBaseClass(classname)) {
1343 Alert::error(_("Error"), _("Unable to set document class."));
1346 if (lyxrc.auto_reset_options)
1347 bp_.useClassDefaults();
1349 // With the introduction of modules came a distinction between the base
1350 // class and the document class. The former corresponds to the main layout
1351 // file; the latter is that plus the modules (or the document-specific layout,
1352 // or whatever else there could be). Our parameters come from the document
1353 // class. So when we set the base class, we also need to recreate the document
1354 // class. Otherwise, we still have the old one.
1355 bp_.makeDocumentClass();
1361 // This is an insanely complicated attempt to make this sort of thing
1362 // work with RTL languages.
1363 docstring formatStrVec(vector<string> const & v, docstring const & s)
1365 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1369 return from_utf8(v[0]);
1370 if (v.size() == 2) {
1371 docstring retval = _("%1$s and %2$s");
1372 retval = subst(retval, _("and"), s);
1373 return bformat(retval, from_utf8(v[0]), from_utf8(v[1]));
1375 // The idea here is to format all but the last two items...
1376 int const vSize = v.size();
1377 docstring t2 = _("%1$s, %2$s");
1378 docstring retval = from_utf8(v[0]);
1379 for (int i = 1; i < vSize - 2; ++i)
1380 retval = bformat(t2, retval, from_utf8(v[i]));
1381 //...and then to plug them, and the last two, into this schema
1382 docstring t = _("%1$s, %2$s, and %3$s");
1383 t = subst(t, _("and"), s);
1384 return bformat(t, retval, from_utf8(v[vSize - 2]), from_utf8(v[vSize - 1]));
1387 vector<string> idsToNames(vector<string> const & idList)
1389 vector<string> retval;
1390 vector<string>::const_iterator it = idList.begin();
1391 vector<string>::const_iterator end = idList.end();
1392 for (; it != end; ++it) {
1393 LyXModule const * const mod = moduleList[*it];
1395 retval.push_back(*it + " (Unavailable)");
1397 retval.push_back(mod->getName());
1404 void GuiDocument::modulesToParams(BufferParams & bp)
1406 // update list of loaded modules
1407 bp.clearLayoutModules();
1408 int const srows = modules_sel_model_.rowCount();
1409 for (int i = 0; i < srows; ++i)
1410 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1412 // update the list of removed modules
1413 bp.clearRemovedModules();
1414 LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
1415 list<string>::const_iterator rit = reqmods.begin();
1416 list<string>::const_iterator ren = reqmods.end();
1418 // check each of the default modules
1419 for (; rit != ren; rit++) {
1420 list<string>::const_iterator mit = bp.getModules().begin();
1421 list<string>::const_iterator men = bp.getModules().end();
1423 for (; mit != men; mit++) {
1430 // the module isn't present so must have been removed by the user
1431 bp.addRemovedModule(*rit);
1436 void GuiDocument::modulesChanged()
1438 modulesToParams(bp_);
1439 bp_.makeDocumentClass();
1444 void GuiDocument::updateModuleInfo()
1446 selectionManager->update();
1448 //Module description
1449 bool const focus_on_selected = selectionManager->selectedFocused();
1450 QListView const * const lv =
1451 focus_on_selected ? modulesModule->selectedLV : modulesModule->availableLV;
1452 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1453 modulesModule->infoML->document()->clear();
1456 QModelIndex const & idx = lv->selectionModel()->currentIndex();
1457 GuiIdListModel const & id_model =
1458 focus_on_selected ? modules_sel_model_ : modules_av_model_;
1459 string const modName = id_model.getIDString(idx.row());
1460 docstring desc = getModuleDescription(modName);
1462 LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
1463 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
1466 desc += _("Module provided by document class.");
1469 vector<string> pkglist = getPackageList(modName);
1470 docstring pkgdesc = formatStrVec(pkglist, _("and"));
1471 if (!pkgdesc.empty()) {
1474 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1477 pkglist = getRequiredList(modName);
1478 if (!pkglist.empty()) {
1479 vector<string> const reqdescs = idsToNames(pkglist);
1480 pkgdesc = formatStrVec(reqdescs, _("or"));
1483 desc += bformat(_("Module required: %1$s."), pkgdesc);
1486 pkglist = getExcludedList(modName);
1487 if (!pkglist.empty()) {
1488 vector<string> const reqdescs = idsToNames(pkglist);
1489 pkgdesc = formatStrVec(reqdescs, _( "and"));
1492 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1495 if (!isModuleAvailable(modName)) {
1498 desc += _("WARNING: Some required packages are unavailable!");
1501 modulesModule->infoML->document()->setPlainText(toqstr(desc));
1505 void GuiDocument::updateNumbering()
1507 DocumentClass const & tclass = documentClass();
1509 numberingModule->tocTW->setUpdatesEnabled(false);
1510 numberingModule->tocTW->clear();
1512 int const depth = numberingModule->depthSL->value();
1513 int const toc = numberingModule->tocSL->value();
1514 QString const no = qt_("No");
1515 QString const yes = qt_("Yes");
1516 QTreeWidgetItem * item = 0;
1518 DocumentClass::const_iterator lit = tclass.begin();
1519 DocumentClass::const_iterator len = tclass.end();
1520 for (; lit != len; ++lit) {
1521 int const toclevel = lit->toclevel;
1522 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1523 item = new QTreeWidgetItem(numberingModule->tocTW);
1524 item->setText(0, toqstr(translateIfPossible(lit->name())));
1525 item->setText(1, (toclevel <= depth) ? yes : no);
1526 item->setText(2, (toclevel <= toc) ? yes : no);
1530 numberingModule->tocTW->setUpdatesEnabled(true);
1531 numberingModule->tocTW->update();
1535 void GuiDocument::applyView()
1538 preambleModule->apply(bp_);
1541 bp_.setCiteEngine(ENGINE_BASIC);
1543 if (biblioModule->citeNatbibRB->isChecked()) {
1544 bool const use_numerical_citations =
1545 biblioModule->citeStyleCO->currentIndex();
1546 if (use_numerical_citations)
1547 bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1549 bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1551 } else if (biblioModule->citeJurabibRB->isChecked())
1552 bp_.setCiteEngine(ENGINE_JURABIB);
1555 biblioModule->bibtopicCB->isChecked();
1557 // language & quotes
1558 if (langModule->defaultencodingRB->isChecked()) {
1559 bp_.inputenc = "auto";
1561 int i = langModule->encodingCO->currentIndex();
1563 bp_.inputenc = "default";
1565 QString const enc_gui =
1566 langModule->encodingCO->currentText();
1567 Encodings::const_iterator it = encodings.begin();
1568 Encodings::const_iterator const end = encodings.end();
1570 for (; it != end; ++it) {
1571 if (qt_(it->guiName()) == enc_gui) {
1572 bp_.inputenc = it->latexName();
1578 // should not happen
1579 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1580 bp_.inputenc = "default";
1585 InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1586 switch (langModule->quoteStyleCO->currentIndex()) {
1588 lga = InsetQuotes::EnglishQuotes;
1591 lga = InsetQuotes::SwedishQuotes;
1594 lga = InsetQuotes::GermanQuotes;
1597 lga = InsetQuotes::PolishQuotes;
1600 lga = InsetQuotes::FrenchQuotes;
1603 lga = InsetQuotes::DanishQuotes;
1606 bp_.quotes_language = lga;
1608 QString const lang = langModule->languageCO->itemData(
1609 langModule->languageCO->currentIndex()).toString();
1610 bp_.language = lyx::languages.getLanguage(fromqstr(lang));
1613 if (bp_.documentClass().hasTocLevels()) {
1614 bp_.tocdepth = numberingModule->tocSL->value();
1615 bp_.secnumdepth = numberingModule->depthSL->value();
1619 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
1620 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
1621 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
1622 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
1625 bp_.graphicsDriver =
1626 tex_graphics[latexModule->psdriverCO->currentIndex()];
1629 int idx = latexModule->classCO->currentIndex();
1631 string const classname = classes_model_.getIDString(idx);
1632 bp_.setBaseClass(classname);
1636 modulesToParams(bp_);
1638 if (mathsModule->amsautoCB->isChecked()) {
1639 bp_.use_amsmath = BufferParams::package_auto;
1641 if (mathsModule->amsCB->isChecked())
1642 bp_.use_amsmath = BufferParams::package_on;
1644 bp_.use_amsmath = BufferParams::package_off;
1647 if (mathsModule->esintautoCB->isChecked())
1648 bp_.use_esint = BufferParams::package_auto;
1650 if (mathsModule->esintCB->isChecked())
1651 bp_.use_esint = BufferParams::package_on;
1653 bp_.use_esint = BufferParams::package_off;
1656 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1657 bp_.pagestyle = "default";
1659 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1660 for (size_t i = 0; i != pagestyles.size(); ++i)
1661 if (pagestyles[i].second == style_gui)
1662 bp_.pagestyle = pagestyles[i].first;
1665 switch (textLayoutModule->lspacingCO->currentIndex()) {
1667 bp_.spacing().set(Spacing::Single);
1670 bp_.spacing().set(Spacing::Onehalf);
1673 bp_.spacing().set(Spacing::Double);
1676 bp_.spacing().set(Spacing::Other,
1677 fromqstr(textLayoutModule->lspacingLE->text()));
1681 if (textLayoutModule->twoColumnCB->isChecked())
1686 // text should have passed validation
1687 bp_.listings_params =
1688 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1690 if (textLayoutModule->indentRB->isChecked())
1691 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1693 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1695 switch (textLayoutModule->skipCO->currentIndex()) {
1697 bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
1700 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1703 bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
1708 widgetsToLength(textLayoutModule->skipLE,
1709 textLayoutModule->skipLengthCO)
1715 // DocumentDefskipCB assures that this never happens
1716 // so Assert then !!! - jbl
1717 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1722 fromqstr(latexModule->optionsLE->text());
1724 bp_.use_default_options =
1725 latexModule->defaultOptionsCB->isChecked();
1727 if (latexModule->childDocGB->isChecked())
1729 fromqstr(latexModule->childDocLE->text());
1731 bp_.master = string();
1733 bp_.float_placement = floatModule->get();
1737 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1740 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1742 bp_.fontsTypewriter =
1743 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1746 fromqstr(fontModule->cjkFontLE->text());
1748 bp_.fontsSansScale = fontModule->scaleSansSB->value();
1750 bp_.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1752 bp_.fontsSC = fontModule->fontScCB->isChecked();
1754 bp_.fontsOSF = fontModule->fontOsfCB->isChecked();
1756 bp_.fontsDefaultFamily = GuiDocument::fontfamilies[
1757 fontModule->fontsDefaultCO->currentIndex()];
1759 if (fontModule->fontsizeCO->currentIndex() == 0)
1760 bp_.fontsize = "default";
1763 fromqstr(fontModule->fontsizeCO->currentText());
1766 bp_.papersize = PAPER_SIZE(
1767 pageLayoutModule->papersizeCO->currentIndex());
1769 // custom, A3, B3 and B4 paper sizes need geometry
1770 int psize = pageLayoutModule->papersizeCO->currentIndex();
1771 bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1773 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1774 pageLayoutModule->paperwidthUnitCO);
1776 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1777 pageLayoutModule->paperheightUnitCO);
1779 if (pageLayoutModule->facingPagesCB->isChecked())
1780 bp_.sides = TwoSides;
1782 bp_.sides = OneSide;
1784 if (pageLayoutModule->landscapeRB->isChecked())
1785 bp_.orientation = ORIENTATION_LANDSCAPE;
1787 bp_.orientation = ORIENTATION_PORTRAIT;
1790 bp_.use_geometry = !marginsModule->marginCB->isChecked()
1793 Ui::MarginsUi const * m = marginsModule;
1795 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1796 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
1797 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1798 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1799 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1800 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1801 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1802 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
1804 branchesModule->apply(bp_);
1807 PDFOptions & pdf = bp_.pdfoptions();
1808 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
1809 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
1810 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
1811 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
1812 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
1814 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
1815 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
1816 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
1817 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
1819 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
1820 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
1821 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
1822 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
1824 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
1825 if (pdfSupportModule->fullscreenCB->isChecked())
1826 pdf.pagemode = pdf.pagemode_fullscreen;
1828 pdf.pagemode.clear();
1829 pdf.quoted_options = pdf.quoted_options_check(
1830 fromqstr(pdfSupportModule->optionsLE->text()));
1834 void GuiDocument::paramsToDialog()
1836 // set the default unit
1837 Length::UNIT const defaultUnit = Length::defaultUnit();
1840 preambleModule->update(bp_, id());
1843 biblioModule->citeDefaultRB->setChecked(
1844 bp_.citeEngine() == ENGINE_BASIC);
1846 biblioModule->citeNatbibRB->setChecked(
1847 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
1848 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
1850 biblioModule->citeStyleCO->setCurrentIndex(
1851 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
1853 biblioModule->citeJurabibRB->setChecked(
1854 bp_.citeEngine() == ENGINE_JURABIB);
1856 biblioModule->bibtopicCB->setChecked(
1859 // language & quotes
1860 int const pos = langModule->languageCO->findData(toqstr(
1861 bp_.language->lang()));
1862 langModule->languageCO->setCurrentIndex(pos);
1864 langModule->quoteStyleCO->setCurrentIndex(
1865 bp_.quotes_language);
1867 bool default_enc = true;
1868 if (bp_.inputenc != "auto") {
1869 default_enc = false;
1870 if (bp_.inputenc == "default") {
1871 langModule->encodingCO->setCurrentIndex(0);
1874 Encodings::const_iterator it = encodings.begin();
1875 Encodings::const_iterator const end = encodings.end();
1876 for (; it != end; ++it) {
1877 if (it->latexName() == bp_.inputenc) {
1878 enc_gui = it->guiName();
1882 int const i = langModule->encodingCO->findText(
1885 langModule->encodingCO->setCurrentIndex(i);
1887 // unknown encoding. Set to default.
1891 langModule->defaultencodingRB->setChecked(default_enc);
1892 langModule->otherencodingRB->setChecked(!default_enc);
1895 int const min_toclevel = documentClass().min_toclevel();
1896 int const max_toclevel = documentClass().max_toclevel();
1897 if (documentClass().hasTocLevels()) {
1898 numberingModule->setEnabled(true);
1899 numberingModule->depthSL->setMinimum(min_toclevel - 1);
1900 numberingModule->depthSL->setMaximum(max_toclevel);
1901 numberingModule->depthSL->setValue(bp_.secnumdepth);
1902 numberingModule->tocSL->setMaximum(min_toclevel - 1);
1903 numberingModule->tocSL->setMaximum(max_toclevel);
1904 numberingModule->tocSL->setValue(bp_.tocdepth);
1907 numberingModule->setEnabled(false);
1908 numberingModule->tocTW->clear();
1912 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
1913 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
1914 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
1915 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
1916 bulletsModule->init();
1919 int nitem = findToken(tex_graphics, bp_.graphicsDriver);
1921 latexModule->psdriverCO->setCurrentIndex(nitem);
1924 mathsModule->amsCB->setChecked(
1925 bp_.use_amsmath == BufferParams::package_on);
1926 mathsModule->amsautoCB->setChecked(
1927 bp_.use_amsmath == BufferParams::package_auto);
1929 mathsModule->esintCB->setChecked(
1930 bp_.use_esint == BufferParams::package_on);
1931 mathsModule->esintautoCB->setChecked(
1932 bp_.use_esint == BufferParams::package_auto);
1934 switch (bp_.spacing().getSpace()) {
1935 case Spacing::Other: nitem = 3; break;
1936 case Spacing::Double: nitem = 2; break;
1937 case Spacing::Onehalf: nitem = 1; break;
1938 case Spacing::Default: case Spacing::Single: nitem = 0; break;
1942 string const & layoutID = bp_.baseClassID();
1943 setLayoutComboByIDString(layoutID);
1945 updatePagestyle(documentClass().opt_pagestyle(),
1948 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
1949 if (bp_.spacing().getSpace() == Spacing::Other) {
1950 textLayoutModule->lspacingLE->setText(
1951 toqstr(bp_.spacing().getValueAsString()));
1955 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation)
1956 textLayoutModule->indentRB->setChecked(true);
1958 textLayoutModule->skipRB->setChecked(true);
1961 switch (bp_.getDefSkip().kind()) {
1962 case VSpace::SMALLSKIP:
1965 case VSpace::MEDSKIP:
1968 case VSpace::BIGSKIP:
1971 case VSpace::LENGTH:
1974 string const length = bp_.getDefSkip().asLyXCommand();
1975 lengthToWidgets(textLayoutModule->skipLE,
1976 textLayoutModule->skipLengthCO,
1977 length, defaultUnit);
1984 textLayoutModule->skipCO->setCurrentIndex(skip);
1987 textLayoutModule->twoColumnCB->setChecked(
1990 // break listings_params to multiple lines
1992 InsetListingsParams(bp_.listings_params).separatedParams();
1993 textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
1995 if (!bp_.options.empty()) {
1996 latexModule->optionsLE->setText(
1997 toqstr(bp_.options));
1999 latexModule->optionsLE->setText(QString());
2003 latexModule->defaultOptionsCB->setChecked(
2004 bp_.use_default_options);
2005 updateSelectedModules();
2006 selectionManager->updateProvidedModules(
2007 bp_.baseClass()->providedModules());
2008 selectionManager->updateExcludedModules(
2009 bp_.baseClass()->excludedModules());
2011 if (!documentClass().options().empty()) {
2012 latexModule->defaultOptionsLE->setText(
2013 toqstr(documentClass().options()));
2015 latexModule->defaultOptionsLE->setText(
2016 toqstr(_("[No options predefined]")));
2019 latexModule->defaultOptionsLE->setEnabled(
2020 bp_.use_default_options
2021 && !documentClass().options().empty());
2023 latexModule->defaultOptionsCB->setEnabled(
2024 !documentClass().options().empty());
2026 if (!bp_.master.empty()) {
2027 latexModule->childDocGB->setChecked(true);
2028 latexModule->childDocLE->setText(
2029 toqstr(bp_.master));
2031 latexModule->childDocLE->setText(QString());
2032 latexModule->childDocGB->setChecked(false);
2035 floatModule->set(bp_.float_placement);
2038 updateFontsize(documentClass().opt_fontsize(),
2041 int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2043 fontModule->fontsRomanCO->setCurrentIndex(n);
2047 n = findToken(tex_fonts_sans, bp_.fontsSans);
2049 fontModule->fontsSansCO->setCurrentIndex(n);
2053 n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2055 fontModule->fontsTypewriterCO->setCurrentIndex(n);
2059 if (!bp_.fontsCJK.empty())
2060 fontModule->cjkFontLE->setText(
2061 toqstr(bp_.fontsCJK));
2063 fontModule->cjkFontLE->setText(QString());
2065 fontModule->fontScCB->setChecked(bp_.fontsSC);
2066 fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2067 fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2068 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2069 n = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2071 fontModule->fontsDefaultCO->setCurrentIndex(n);
2074 int const psize = bp_.papersize;
2075 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2076 setCustomPapersize(psize);
2078 bool const landscape =
2079 bp_.orientation == ORIENTATION_LANDSCAPE;
2080 pageLayoutModule->landscapeRB->setChecked(landscape);
2081 pageLayoutModule->portraitRB->setChecked(!landscape);
2083 pageLayoutModule->facingPagesCB->setChecked(
2084 bp_.sides == TwoSides);
2087 lengthToWidgets(pageLayoutModule->paperwidthLE,
2088 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2090 lengthToWidgets(pageLayoutModule->paperheightLE,
2091 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2094 Ui::MarginsUi * m = marginsModule;
2096 setMargins(!bp_.use_geometry);
2098 lengthToWidgets(m->topLE, m->topUnit,
2099 bp_.topmargin, defaultUnit);
2101 lengthToWidgets(m->bottomLE, m->bottomUnit,
2102 bp_.bottommargin, defaultUnit);
2104 lengthToWidgets(m->innerLE, m->innerUnit,
2105 bp_.leftmargin, defaultUnit);
2107 lengthToWidgets(m->outerLE, m->outerUnit,
2108 bp_.rightmargin, defaultUnit);
2110 lengthToWidgets(m->headheightLE, m->headheightUnit,
2111 bp_.headheight, defaultUnit);
2113 lengthToWidgets(m->headsepLE, m->headsepUnit,
2114 bp_.headsep, defaultUnit);
2116 lengthToWidgets(m->footskipLE, m->footskipUnit,
2117 bp_.footskip, defaultUnit);
2119 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2120 bp_.columnsep, defaultUnit);
2122 branchesModule->update(bp_);
2125 PDFOptions const & pdf = bp_.pdfoptions();
2126 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2127 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2128 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2129 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2130 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2132 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2133 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2134 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2136 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2138 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2139 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2140 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2141 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2143 n = findToken(backref_opts, pdf.backref);
2145 pdfSupportModule->backrefCO->setCurrentIndex(n);
2147 pdfSupportModule->fullscreenCB->setChecked
2148 (pdf.pagemode == pdf.pagemode_fullscreen);
2150 pdfSupportModule->optionsLE->setText(
2151 toqstr(pdf.quoted_options));
2153 // Make sure that the bc is in the INITIAL state
2154 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
2159 void GuiDocument::saveDocDefault()
2161 // we have to apply the params first
2167 void GuiDocument::updateAvailableModules()
2169 modules_av_model_.clear();
2170 list<modInfoStruct> const & modInfoList = getModuleInfo();
2171 list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2172 list<modInfoStruct>::const_iterator men = modInfoList.end();
2173 for (int i = 0; mit != men; ++mit, ++i)
2174 modules_av_model_.insertRow(i, mit->name, mit->id,
2179 void GuiDocument::updateSelectedModules()
2181 modules_sel_model_.clear();
2182 list<modInfoStruct> const selModList = getSelectedModules();
2183 list<modInfoStruct>::const_iterator mit = selModList.begin();
2184 list<modInfoStruct>::const_iterator men = selModList.end();
2185 for (int i = 0; mit != men; ++mit, ++i)
2186 modules_sel_model_.insertRow(i, mit->name, mit->id,
2191 void GuiDocument::updateContents()
2193 // Nothing to do here as the document settings is not cursor dependant.
2198 void GuiDocument::useClassDefaults()
2200 if (applyPB->isEnabled()) {
2201 int const ret = Alert::prompt(_("Unapplied changes"),
2202 _("Some changes in the dialog were not yet applied.\n"
2203 "If you do not apply now, they will be lost after this action."),
2204 1, 1, _("&Apply"), _("&Dismiss"));
2209 int idx = latexModule->classCO->currentIndex();
2210 string const classname = classes_model_.getIDString(idx);
2211 if (!bp_.setBaseClass(classname)) {
2212 Alert::error(_("Error"), _("Unable to set document class."));
2215 bp_.useClassDefaults();
2220 void GuiDocument::setLayoutComboByIDString(string const & idString)
2222 int idx = classes_model_.findIDString(idString);
2224 Alert::warning(_("Can't set layout!"),
2225 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2227 latexModule->classCO->setCurrentIndex(idx);
2231 bool GuiDocument::isValid()
2233 return validateListingsParameters().isEmpty()
2234 && (textLayoutModule->skipCO->currentIndex() != 3
2235 || !textLayoutModule->skipLE->text().isEmpty());
2239 char const * const GuiDocument::fontfamilies[5] = {
2240 "default", "rmdefault", "sfdefault", "ttdefault", ""
2244 char const * GuiDocument::fontfamilies_gui[5] = {
2245 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2249 bool GuiDocument::initialiseParams(string const &)
2251 BufferView const * view = bufferview();
2253 bp_ = BufferParams();
2257 bp_ = view->buffer().params();
2259 updateAvailableModules();
2260 //FIXME It'd be nice to make sure here that the selected
2261 //modules are consistent: That required modules are actually
2262 //selected, and that we don't have conflicts. If so, we could
2263 //at least pop up a warning.
2269 void GuiDocument::clearParams()
2271 bp_ = BufferParams();
2275 BufferId GuiDocument::id() const
2277 BufferView const * const view = bufferview();
2278 return view? &view->buffer() : 0;
2282 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2284 return moduleNames_;
2288 list<GuiDocument::modInfoStruct> const
2289 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
2291 LayoutModuleList::const_iterator it = mods.begin();
2292 LayoutModuleList::const_iterator end = mods.end();
2293 list<modInfoStruct> mInfo;
2294 for (; it != end; ++it) {
2297 LyXModule * mod = moduleList[*it];
2300 m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
2302 m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2309 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2311 return makeModuleInfo(params().getModules());
2315 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
2317 return makeModuleInfo(params().baseClass()->providedModules());
2321 DocumentClass const & GuiDocument::documentClass() const
2323 return bp_.documentClass();
2327 static void dispatch_bufferparams(Dialog const & dialog,
2328 BufferParams const & bp, FuncCode lfun)
2331 ss << "\\begin_header\n";
2333 ss << "\\end_header\n";
2334 dialog.dispatch(FuncRequest(lfun, ss.str()));
2338 void GuiDocument::dispatchParams()
2340 // This must come first so that a language change is correctly noticed
2343 // Apply the BufferParams. Note that this will set the base class
2344 // and then update the buffer's layout.
2345 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2347 if (!params().master.empty()) {
2348 FileName const master_file = support::makeAbsPath(params().master,
2349 support::onlyPath(buffer().absFileName()));
2350 if (isLyXFilename(master_file.absFilename())) {
2351 Buffer * master = checkAndLoadLyXFile(master_file);
2353 if (master->isChild(const_cast<Buffer *>(&buffer())))
2354 const_cast<Buffer &>(buffer()).setParent(master);
2356 Alert::warning(_("Assigned master does not include this file"),
2357 bformat(_("You must include this file in the document\n"
2358 "'%1$s' in order to use the master document\n"
2359 "feature."), from_utf8(params().master)));
2361 Alert::warning(_("Could not load master"),
2362 bformat(_("The master document '%1$s'\n"
2363 "could not be loaded."),
2364 from_utf8(params().master)));
2368 // Generate the colours requested by each new branch.
2369 BranchList & branchlist = params().branchlist();
2370 if (!branchlist.empty()) {
2371 BranchList::const_iterator it = branchlist.begin();
2372 BranchList::const_iterator const end = branchlist.end();
2373 for (; it != end; ++it) {
2374 docstring const & current_branch = it->branch();
2375 Branch const * branch = branchlist.find(current_branch);
2376 string const x11hexname = X11hexname(branch->color());
2377 // display the new color
2378 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2379 dispatch(FuncRequest(LFUN_SET_COLOR, str));
2382 // Open insets of selected branches, close deselected ones
2383 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2386 // FIXME: If we used an LFUN, we would not need those two lines:
2387 BufferView * bv = const_cast<BufferView *>(bufferview());
2388 bv->processUpdateFlags(Update::Force | Update::FitCursor);
2392 void GuiDocument::setLanguage() const
2394 Language const * const newL = bp_.language;
2395 if (buffer().params().language == newL)
2398 string const & lang_name = newL->lang();
2399 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2403 void GuiDocument::saveAsDefault() const
2405 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2409 bool GuiDocument::isFontAvailable(string const & font) const
2411 if (font == "default" || font == "cmr"
2412 || font == "cmss" || font == "cmtt")
2413 // these are standard
2415 if (font == "lmodern" || font == "lmss" || font == "lmtt")
2416 return LaTeXFeatures::isAvailable("lmodern");
2417 if (font == "times" || font == "palatino"
2418 || font == "helvet" || font == "courier")
2419 return LaTeXFeatures::isAvailable("psnfss");
2420 if (font == "cmbr" || font == "cmtl")
2421 return LaTeXFeatures::isAvailable("cmbright");
2422 if (font == "utopia")
2423 return LaTeXFeatures::isAvailable("utopia")
2424 || LaTeXFeatures::isAvailable("fourier");
2425 if (font == "beraserif" || font == "berasans"
2426 || font == "beramono")
2427 return LaTeXFeatures::isAvailable("bera");
2428 return LaTeXFeatures::isAvailable(font);
2432 bool GuiDocument::providesOSF(string const & font) const
2435 return isFontAvailable("eco");
2436 if (font == "palatino")
2437 return isFontAvailable("mathpazo");
2442 bool GuiDocument::providesSC(string const & font) const
2444 if (font == "palatino")
2445 return isFontAvailable("mathpazo");
2446 if (font == "utopia")
2447 return isFontAvailable("fourier");
2452 bool GuiDocument::providesScale(string const & font) const
2454 return font == "helvet" || font == "luximono"
2455 || font == "berasans" || font == "beramono";
2459 void GuiDocument::loadModuleInfo()
2461 moduleNames_.clear();
2462 LyXModuleList::const_iterator it = moduleList.begin();
2463 LyXModuleList::const_iterator end = moduleList.end();
2464 for (; it != end; ++it) {
2468 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
2469 // this is supposed to give us the first sentence of the description
2472 toqstr(translateIfPossible(from_utf8(it->getDescription())));
2473 int const pos = desc.indexOf(".");
2475 desc.truncate(pos + 1);
2476 m.description = desc;
2477 moduleNames_.push_back(m);
2482 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2485 } // namespace frontend
2488 #include "moc_GuiDocument.cpp"