#include "BufferView.h"
#include "Color.h"
#include "ColorCache.h"
+#include "Cursor.h"
#include "Encoding.h"
#include "FloatPlacement.h"
#include "Format.h"
#include "qt_helpers.h"
#include "Spacing.h"
#include "TextClass.h"
+#include "Undo.h"
+#include "VSpace.h"
#include "insets/InsetListingsParams.h"
bool is_fontcolor;
RGBColor set_notefontcolor;
RGBColor set_boxbgcolor;
+bool forced_fontspec_activation;
namespace {
// used when sorting the textclass list.
void LocalLayout::update(BufferParams const & params, BufferId id)
{
- QString layout = toqstr(params.local_layout);
+ QString layout = toqstr(params.getLocalLayout(false));
// Nothing to do if the params and preamble are unchanged.
if (id == current_id_
&& layout == locallayoutTE->document()->toPlainText())
void LocalLayout::apply(BufferParams & params)
{
string const layout = fromqstr(locallayoutTE->document()->toPlainText());
- params.local_layout = layout;
+ params.setLocalLayout(layout, false);
}
GuiDocument::GuiDocument(GuiView & lv)
- : GuiDialog(lv, "document", qt_("Document Settings"))
+ : GuiDialog(lv, "document", qt_("Document Settings")),
+ nonModuleChanged_(false)
{
setupUi(this);
headers << qt_("Package") << qt_("Load automatically")
<< qt_("Load always") << qt_("Do not load");
mathsModule->packagesTW->setHorizontalHeaderLabels(headers);
- setSectionResizeMode(mathsModule->packagesTW->horizontalHeader(), QHeaderView::Stretch);
+ setSectionResizeMode(mathsModule->packagesTW->horizontalHeader(), QHeaderView::Stretch);
map<string, string> const & packages = BufferParams::auto_packages();
mathsModule->packagesTW->setRowCount(packages.size());
int i = 0;
this, SLOT(allPackagesAlways()));
connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
this, SLOT(allPackagesNot()));
+ connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
+ this, SLOT(change_adaptor()));
+ connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
+ this, SLOT(change_adaptor()));
+ connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
+ this, SLOT(change_adaptor()));
// latex class
connect(latexModule->psdriverCO, SIGNAL(activated(int)),
this, SLOT(change_adaptor()));
connect(latexModule->classCO, SIGNAL(activated(int)),
- this, SLOT(classChanged()));
+ this, SLOT(classChanged_adaptor()));
connect(latexModule->classCO, SIGNAL(activated(int)),
this, SLOT(change_adaptor()));
connect(latexModule->layoutPB, SIGNAL(clicked()),
availableModel(), selectedModel(), this);
connect(selectionManager, SIGNAL(updateHook()),
this, SLOT(updateModuleInfo()));
- connect(selectionManager, SIGNAL(updateHook()),
- this, SLOT(change_adaptor()));
connect(selectionManager, SIGNAL(selectionChanged()),
this, SLOT(modulesChanged()));
void GuiDocument::change_adaptor()
{
+ nonModuleChanged_ = true;
changed();
}
includeonlys_.push_back(child);
updateIncludeonlys();
- changed();
+ change_adaptor();
}
{
// use a cache here to avoid repeated validation
// of the same parameters
+ // FIXME THREAD
static string param_cache;
static QString msg_cache;
void GuiDocument::setListingsMessage()
{
+ // FIXME THREAD
static bool isOK = true;
QString msg = validateListingsParameters();
if (msg.isEmpty()) {
// listingsTB->setTextColor("black");
listingsModule->listingsTB->setPlainText(
qt_("Input listings parameters below. "
- "Enter ? for a list of parameters."));
+ "Enter ? for a list of parameters."));
} else {
isOK = false;
// listingsTB->setTextColor("red");
// save color
set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
is_backgroundcolor = true;
- changed();
+ change_adaptor();
}
// save default color (white)
set_backgroundcolor = rgbFromHexName("#ffffff");
is_backgroundcolor = false;
- changed();
+ change_adaptor();
}
// save color
set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
is_fontcolor = true;
- changed();
+ change_adaptor();
}
// save default color (black)
set_fontcolor = rgbFromHexName("#000000");
is_fontcolor = false;
- changed();
+ change_adaptor();
}
colorButtonStyleSheet(newColor));
// save color
set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
- changed();
+ change_adaptor();
}
theApp()->getRgbColor(Color_greyedouttext, set_notefontcolor);
colorModule->noteFontColorPB->setStyleSheet(
colorButtonStyleSheet(rgb2qcolor(set_notefontcolor)));
- changed();
+ change_adaptor();
}
colorButtonStyleSheet(newColor));
// save color
set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
- changed();
+ change_adaptor();
}
theApp()->getRgbColor(Color_shadedbg, set_boxbgcolor);
colorModule->boxBackgroundPB->setStyleSheet(
colorButtonStyleSheet(rgb2qcolor(set_boxbgcolor)));
- changed();
+ change_adaptor();
}
Language const * lang = lyx::languages.getLanguage(
fromqstr(langModule->languageCO->itemData(i).toString()));
if (lang->babel().empty() && !lang->polyglossia().empty()) {
+ // If we force to switch fontspec on, store
+ // current state (#8717)
+ if (fontModule->osFontsCB->isEnabled())
+ forced_fontspec_activation =
+ !fontModule->osFontsCB->isChecked();
fontModule->osFontsCB->setChecked(true);
fontModule->osFontsCB->setEnabled(false);
}
- else
+ else {
fontModule->osFontsCB->setEnabled(true);
+ // If we have forced to switch fontspec on,
+ // restore previous state (#8717)
+ if (forced_fontspec_activation)
+ fontModule->osFontsCB->setChecked(false);
+ forced_fontspec_activation = false;
+ }
// set appropriate quotation mark style
if (!lang->quoteStyle().empty()) {
if (!tex_fonts)
fontModule->fontencLE->setEnabled(false);
else
- fontencChanged(fontModule->fontencCO->currentIndex());
+ fontencChanged(fontModule->fontencCO->currentIndex());
}
fontModule->fontsTypewriterCO->clear();
fontModule->fontsMathCO->clear();
- // With XeTeX, we have access to all system fonts, but not the LaTeX fonts
+ // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
if (fontModule->osFontsCB->isChecked()) {
fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
fontModule->fontsRomanCO->addItem(rmi.key(), rmi.value());
++rmi;
}
-
+
fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
QMap<QString, QString>::const_iterator sfi = sffonts_.constBegin();
while (sfi != sffonts_.constEnd()) {
fontModule->fontsSansCO->addItem(sfi.key(), sfi.value());
++sfi;
}
-
+
fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
QMap<QString, QString>::const_iterator tti = ttfonts_.constBegin();
while (tti != ttfonts_.constEnd()) {
int const ret = Alert::prompt(_("Local layout file"),
_("The layout file you have selected is a local layout\n"
- "file, not one in the system or user directory. Your\n"
- "document may not work with this layout if you do not\n"
- "keep the layout file in the document directory."),
+ "file, not one in the system or user directory.\n"
+ "Your document will not work with this layout if you\n"
+ "move the layout file to a different directory."),
1, 1, _("&Set Layout"), _("&Cancel"));
if (ret == 1)
return;
LayoutFileList & bcl = LayoutFileList::get();
string classname = layoutFile.onlyFileName();
// this will update an existing layout if that layout has been loaded before.
- LayoutFileIndex name = bcl.addLocalLayout(
+ LayoutFileIndex name = support::onlyFileName(bcl.addLocalLayout(
classname.substr(0, classname.size() - 7),
- layoutFile.onlyPath().absFileName());
+ layoutFile.onlyPath().absFileName()));
if (name.empty()) {
Alert::error(_("Error"),
return;
}
+ const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
+
// do not trigger classChanged if there is no change.
if (latexModule->classCO->currentText() == toqstr(name))
return;
}
+void GuiDocument::classChanged_adaptor()
+{
+ const_cast<Buffer &>(buffer()).setLayoutPos(string());
+ classChanged();
+}
+
+
void GuiDocument::classChanged()
{
int idx = latexModule->classCO->currentIndex();
return;
string const classname = fromqstr(latexModule->classCO->getData(idx));
- // check whether the selected modules have changed.
- bool modules_changed = false;
- unsigned int const srows = selectedModel()->rowCount();
- if (srows != bp_.getModules().size())
- modules_changed = true;
- else {
- list<string>::const_iterator mit = bp_.getModules().begin();
- list<string>::const_iterator men = bp_.getModules().end();
- for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
- if (selectedModel()->getIDString(i) != *mit) {
- modules_changed = true;
- break;
- }
- }
-
- if (modules_changed || lyxrc.auto_reset_options) {
- if (applyPB->isEnabled()) {
- int const ret = Alert::prompt(_("Unapplied changes"),
- _("Some changes in the dialog were not yet applied.\n"
- "If you do not apply now, they will be lost after this action."),
- 1, 1, _("&Apply"), _("&Dismiss"));
- if (ret == 0)
- applyView();
- }
+ if (applyPB->isEnabled()) {
+ int const ret = Alert::prompt(_("Unapplied changes"),
+ _("Some changes in the dialog were not yet applied.\n"
+ "If you do not apply now, they will be lost after this action."),
+ 1, 1, _("&Apply"), _("&Dismiss"));
+ if (ret == 0)
+ applyView();
}
// We load the TextClass as soon as it is selected. This is
void GuiDocument::biblioChanged()
{
biblioChanged_ = true;
- changed();
+ change_adaptor();
}
biblioModule->citeStyleCO->setCurrentIndex(0);
break;
case ENGINE_TYPE_NUMERICAL:
+ case ENGINE_TYPE_DEFAULT:
biblioModule->citeStyleCO->setCurrentIndex(1);
break;
}
void GuiDocument::modulesChanged()
{
modulesToParams(bp_);
+
+ if (applyPB->isEnabled() && nonModuleChanged_) {
+ int const ret = Alert::prompt(_("Unapplied changes"),
+ _("Some changes in the dialog were not yet applied.\n"
+ "If you do not apply now, they will be lost after this action."),
+ 1, 1, _("&Apply"), _("&Dismiss"));
+ if (ret == 0)
+ applyView();
+ }
+
bp_.makeDocumentClass();
paramsToDialog();
+ changed();
}
if (idx >= 0) {
string const classname = fromqstr(latexModule->classCO->getData(idx));
param_copy.setBaseClass(classname);
- param_copy.makeDocumentClass();
+ param_copy.makeDocumentClass(true);
}
outputModule->defaultFormatCO->blockSignals(true);
outputModule->defaultFormatCO->clear();
bp_.setCiteEngine("natbib");
else if (biblioModule->citeJurabibRB->isChecked())
bp_.setCiteEngine("jurabib");
- else
+ if (biblioModule->citeDefaultRB->isChecked()) {
bp_.setCiteEngine("basic");
-
+ bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
+ }
+ else
if (biblioModule->citeStyleCO->currentIndex())
bp_.setCiteEngineType(ENGINE_TYPE_NUMERICAL);
else
bp_.quotes_language = (InsetQuotes::QuoteLanguage) langModule->quoteStyleCO->itemData(
langModule->quoteStyleCO->currentIndex()).toInt();
- QString const lang = langModule->languageCO->itemData(
+ QString const langname = langModule->languageCO->itemData(
langModule->languageCO->currentIndex()).toString();
- bp_.language = lyx::languages.getLanguage(fromqstr(lang));
+ Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
+ Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
+ // If current cursor language was the document language, then update it too.
+ if (cur.current_font.language() == bp_.language) {
+ cur.current_font.setLanguage(newlang);
+ cur.real_current_font.setLanguage(newlang);
+ }
+ bp_.language = newlang;
QString const pack = langModule->languagePackageCO->itemData(
langModule->languagePackageCO->currentIndex()).toString();
bp_.useNonTeXFonts = nontexfonts;
bp_.output_sync = outputModule->outputsyncCB->isChecked();
-
+
bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
int mathfmt = outputModule->mathoutCB->currentIndex();
bp_.html_be_strict = outputModule->strictCB->isChecked();
bp_.html_css_as_file = outputModule->cssCB->isChecked();
bp_.html_math_img_scale = outputModule->mathimgSB->value();
+ bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
// fonts
bp_.fonts_roman =
pdf.pagemode.clear();
pdf.quoted_options = pdf.quoted_options_check(
fromqstr(pdfSupportModule->optionsLE->text()));
+
+ // reset tracker
+ nonModuleChanged_ = false;
}
cite_engine == "natbib");
biblioModule->citeStyleCO->setCurrentIndex(
- bp_.citeEngineType() == ENGINE_TYPE_NUMERICAL);
+ bp_.citeEngineType() & ENGINE_TYPE_NUMERICAL);
updateEngineType(documentClass().opt_enginetype(),
bp_.citeEngineType());
biblioChanged_ = false;
// indices
- indicesModule->update(bp_);
+ indicesModule->update(bp_, buffer().isReadonly());
// language & quotes
int const pos = langModule->languageCO->findData(toqstr(
listingsModule->listingsED->setPlainText(toqstr(lstparams));
// Fonts
+ // some languages only work with polyglossia/XeTeX
+ Language const * lang = lyx::languages.getLanguage(
+ fromqstr(langModule->languageCO->itemData(
+ langModule->languageCO->currentIndex()).toString()));
+ bool const need_fontspec =
+ lang->babel().empty() && !lang->polyglossia().empty();
bool const os_fonts_available =
bp_.baseClass()->outputType() == lyx::LATEX
&& LaTeXFeatures::isAvailable("fontspec");
- fontModule->osFontsCB->setEnabled(os_fonts_available);
+ fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
fontModule->osFontsCB->setChecked(
- os_fonts_available && bp_.useNonTeXFonts);
+ (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
updateFontsize(documentClass().opt_fontsize(),
bp_.fontsize);
// clear changed branches cache
changedBranches_.clear();
+
+ // reset tracker
+ nonModuleChanged_ = false;
}
static void dispatch_bufferparams(Dialog const & dialog,
- BufferParams const & bp, FuncCode lfun)
+ BufferParams const & bp, FuncCode lfun, Buffer const * buf)
{
ostringstream ss;
ss << "\\begin_header\n";
- bp.writeFile(ss);
+ bp.writeFile(ss, buf);
ss << "\\end_header\n";
dialog.dispatch(FuncRequest(lfun, ss.str()));
}
void GuiDocument::dispatchParams()
{
+ // We need a non-const buffer object.
+ Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
+ // There may be several undo records; group them (bug #8998)
+ buf.undo().beginUndoGroup();
+
// This must come first so that a language change is correctly noticed
setLanguage();
// Apply the BufferParams. Note that this will set the base class
// and then update the buffer's layout.
- dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
+ dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
if (!params().master.empty()) {
FileName const master_file = support::makeAbsPath(params().master,
// If we used an LFUN, we would not need these two lines:
BufferView * bv = const_cast<BufferView *>(bufferview());
bv->processUpdateFlags(Update::Force | Update::FitCursor);
+
+ // Don't forget to close the group. Note that it is important
+ // to check that there is no early return in the method.
+ buf.undo().endUndoGroup();
}
void GuiDocument::saveAsDefault() const
{
- dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
+ dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
}