From: Bo Peng Date: Sat, 28 Apr 2007 20:44:46 +0000 (+0000) Subject: Last (?) batch of renames: X-Git-Tag: 1.6.10~10005 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=e36fba33abc2e80599b164d91e90e1558225576d;p=features.git Last (?) batch of renames: src/frontends/Alert.h src/frontends/alert.h src/frontends/Alert.cpp src/frontends/alert.cpp src/frontends/Alert_pimpl.cpp src/frontends/alert_pimpl.cpp src/frontends/qt4/Alert_pimpl.cpp src/frontends/qt4/alert_pimpl.cpp src/frontends/controllers/ButtonPolicies.cpp src/frontends/controllers/ButtonPolicy.cpp src/frontends/controllers/ButtonPolicies.h src/frontends/controllers/ButtonPolicy.h src/insets/InsetEnv.cpp src/insets/InsetEnvironment.cpp src/insets/InsetEnv.h src/insets/InsetEnvironment.h src/mathed/MathMacroTable.h src/mathed/MacroTable.h src/mathed/MathMacroTable.cpp src/mathed/MacroTable.cpp src/lyx_cb.h src/callback.h src/lyx_cb.cpp src/callback.cpp src/UpdateFlags.h src/update_flags.h git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18076 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/development/scons/scons_manifest.py b/development/scons/scons_manifest.py index c8d1c9948f..ee7c7514b3 100644 --- a/development/scons/scons_manifest.py +++ b/development/scons/scons_manifest.py @@ -234,7 +234,7 @@ src_mathed_header_files = Split(''' MathFactory.h MathGridInfo.h MathMacroArgument.h - MathMacroTable.h + MacroTable.h MathMacroTemplate.h MathParser.h ReplaceData.h @@ -314,7 +314,7 @@ src_mathed_files = Split(''' MathExtern.cpp MathFactory.cpp MathMacroArgument.cpp - MathMacroTable.cpp + MacroTable.cpp MathMacroTemplate.cpp MathParser.cpp MathStream.cpp @@ -339,7 +339,7 @@ src_insets_header_files = Split(''' InsetCollapsable.h InsetCommand.h InsetCommandParams.h - InsetEnv.h + InsetEnvironment.h InsetERT.h InsetExternal.h InsetFloat.h @@ -397,7 +397,7 @@ src_insets_files = Split(''' InsetCollapsable.cpp InsetCommand.cpp InsetCommandParams.cpp - InsetEnv.cpp + InsetEnvironment.cpp InsetERT.cpp InsetExternal.cpp InsetFloat.cpp @@ -435,7 +435,7 @@ src_insets_files = Split(''' src_frontends_header_files = Split(''' - Alert.h + alert.h Alert_pimpl.h Application.h Clipboard.h @@ -460,7 +460,7 @@ src_frontends_header_files = Split(''' src_frontends_files = Split(''' - Alert.cpp + alert.cpp Application.cpp Dialogs.cpp LyXView.cpp @@ -504,7 +504,7 @@ src_graphics_files = Split(''' src_frontends_controllers_header_files = Split(''' BCView.h ButtonController.h - ButtonPolicies.h + ButtonPolicy.h ControlAboutlyx.h ControlBibtex.h ControlBox.h @@ -549,7 +549,7 @@ src_frontends_controllers_header_files = Split(''' src_frontends_controllers_files = Split(''' BCView.cpp ButtonController.cpp - ButtonPolicies.cpp + ButtonPolicy.cpp ControlAboutlyx.cpp ControlBibtex.cpp ControlBox.cpp @@ -825,7 +825,7 @@ src_frontends_qt4_header_files = Split(''' src_frontends_qt4_files = Split(''' Action.cpp - Alert_pimpl.cpp + alert_pimpl.cpp BulletsModule.cpp ColorCache.cpp Dialogs.cpp @@ -996,7 +996,7 @@ src_header_files = Split(''' Thesaurus.h TocBackend.h ToolbarBackend.h - UpdateFlags.h + update_flags.h Variables.h WordLangTuple.h ASpell_local.h @@ -1035,7 +1035,7 @@ src_header_files = Split(''' layout.h lengthcommon.h lfuns.h - lyx_cb.h + callback.h LyX.h lyx_sty.h lyxfind.h @@ -1138,7 +1138,7 @@ src_pre_files = Split(''' KeySequence.cpp Language.cpp lengthcommon.cpp - lyx_cb.cpp + callback.cpp LyX.cpp lyx_sty.cpp lyxfind.cpp diff --git a/po/POTFILES.in b/po/POTFILES.in index a50bff47cc..335c38ccca 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -41,7 +41,7 @@ src/frontends/controllers/ControlPrint.cpp src/frontends/controllers/ControlSpellchecker.cpp src/frontends/controllers/ControlToc.cpp src/frontends/controllers/frontend_helpers.cpp -src/frontends/qt4/Alert_pimpl.cpp +src/frontends/qt4/alert_pimpl.cpp src/frontends/qt4/BulletsModule.cpp src/frontends/qt4/Dialogs.cpp src/frontends/qt4/FileDialog.cpp @@ -93,7 +93,7 @@ src/insets/InsetCharStyle.cpp src/insets/InsetCommand.cpp src/insets/InsetCommandParams.cpp src/insets/InsetERT.cpp -src/insets/InsetEnv.cpp +src/insets/InsetEnvironment.cpp src/insets/InsetExternal.cpp src/insets/InsetFloat.cpp src/insets/InsetFloatList.cpp @@ -118,7 +118,7 @@ src/insets/InsetWrap.cpp src/insets/RenderGraphic.cpp src/insets/RenderPreview.cpp src/lengthcommon.cpp -src/lyx_cb.cpp +src/callback.cpp src/lyxfind.cpp src/mathed/InsetFormulaMacro.cpp src/mathed/InsetMathAMSArray.cpp diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 2216084ed1..1ab2f17814 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -56,10 +56,10 @@ #include "insets/InsetText.h" #include "mathed/MathMacroTemplate.h" -#include "mathed/MathMacroTable.h" +#include "mathed/MacroTable.h" #include "mathed/MathSupport.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "graphics/Previews.h" diff --git a/src/BufferList.cpp b/src/BufferList.cpp index 0a776240e6..bdcfc55b67 100644 --- a/src/BufferList.cpp +++ b/src/BufferList.cpp @@ -18,13 +18,13 @@ #include "debug.h" #include "gettext.h" #include "Session.h" -#include "lyx_cb.h" +#include "callback.h" #include "LyX.h" #include "output_latex.h" #include "Paragraph.h" #include "ParagraphList.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "support/filetools.h" #include "support/Package.h" diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index fd8d964a18..dad14ae1d7 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -36,7 +36,7 @@ #include "TexRow.h" #include "VSpace.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "support/lyxalgo.h" // for lyx::count #include "support/convert.h" diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 6a1d0da6a4..62b91fae76 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -35,7 +35,7 @@ #include "InsetIterator.h" #include "Language.h" #include "LaTeXFeatures.h" -#include "lyx_cb.h" // added for Dispatch functions +#include "callback.h" // added for Dispatch functions #include "LyX.h" #include "lyxfind.h" #include "LyXFunc.h" @@ -60,7 +60,7 @@ #include "insets/InsetRef.h" #include "insets/InsetText.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "frontends/FileDialog.h" #include "frontends/FontMetrics.h" diff --git a/src/BufferView.h b/src/BufferView.h index 5ef1af2db1..3929c68892 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -19,7 +19,7 @@ #include "Cursor.h" #include "MetricsInfo.h" #include "TextMetrics.h" -#include "UpdateFlags.h" +#include "update_flags.h" #include "support/types.h" diff --git a/src/Converter.cpp b/src/Converter.cpp index 523be646f5..cd6ec60146 100644 --- a/src/Converter.cpp +++ b/src/Converter.cpp @@ -23,7 +23,7 @@ #include "LaTeX.h" #include "Mover.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "support/filetools.h" #include "support/lyxlib.h" diff --git a/src/Cursor.cpp b/src/Cursor.cpp index 7c6e64c903..134017e865 100644 --- a/src/Cursor.cpp +++ b/src/Cursor.cpp @@ -39,7 +39,7 @@ #include "mathed/MathData.h" #include "mathed/InsetMath.h" #include "mathed/InsetMathScript.h" -#include "mathed/MathMacroTable.h" +#include "mathed/MacroTable.h" #include "support/limited_stack.h" diff --git a/src/DispatchResult.h b/src/DispatchResult.h index 560fc0d1bc..3ce0c54065 100644 --- a/src/DispatchResult.h +++ b/src/DispatchResult.h @@ -13,7 +13,7 @@ #ifndef DISPATCH_RESULT_H #define DISPATCH_RESULT_H -#include "UpdateFlags.h" +#include "update_flags.h" namespace lyx { diff --git a/src/Exporter.cpp b/src/Exporter.cpp index f8bd191af8..0cf67d4785 100644 --- a/src/Exporter.cpp +++ b/src/Exporter.cpp @@ -28,7 +28,7 @@ #include "Mover.h" #include "output_plaintext.h" #include "OutputParams.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "support/filetools.h" #include "support/lyxlib.h" diff --git a/src/Format.cpp b/src/Format.cpp index bddaf0948e..989e190023 100644 --- a/src/Format.cpp +++ b/src/Format.cpp @@ -19,7 +19,7 @@ #include "LyXServerSocket.h" #include "frontends/Application.h" -#include "frontends/Alert.h" //to be removed? +#include "frontends/alert.h" //to be removed? #include "support/filetools.h" #include "support/lstrings.h" diff --git a/src/Importer.cpp b/src/Importer.cpp index 63c92a4a28..8bd7bccb64 100644 --- a/src/Importer.cpp +++ b/src/Importer.cpp @@ -17,11 +17,11 @@ #include "Format.h" #include "frontends/LyXView.h" #include "FuncRequest.h" -#include "lyx_cb.h" +#include "callback.h" #include "support/filetools.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "gettext.h" #include "BufferView.h" diff --git a/src/LyX.cpp b/src/LyX.cpp index 1a65c497b9..77d5b179e1 100644 --- a/src/LyX.cpp +++ b/src/LyX.cpp @@ -31,7 +31,7 @@ #include "Language.h" #include "Session.h" #include "Color.h" -#include "lyx_cb.h" +#include "callback.h" #include "LyXAction.h" #include "LyXFunc.h" #include "Lexer.h" @@ -44,7 +44,7 @@ #include "Mover.h" #include "ToolbarBackend.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "frontends/Application.h" #include "frontends/Gui.h" #include "frontends/LyXView.h" diff --git a/src/LyXFunc.cpp b/src/LyXFunc.cpp index 1ea7b4acfc..f13a2970dc 100644 --- a/src/LyXFunc.cpp +++ b/src/LyXFunc.cpp @@ -47,7 +47,7 @@ #include "Color.h" #include "Session.h" #include "LyX.h" -#include "lyx_cb.h" +#include "callback.h" #include "LyXAction.h" #include "lyxfind.h" #include "Lexer.h" @@ -75,7 +75,7 @@ #include "insets/InsetWrap.h" #include "frontends/Application.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "frontends/Dialogs.h" #include "frontends/FileDialog.h" #include "frontends/FontLoader.h" diff --git a/src/LyXVC.cpp b/src/LyXVC.cpp index 8d72962ed4..cb82337f72 100644 --- a/src/LyXVC.cpp +++ b/src/LyXVC.cpp @@ -21,7 +21,7 @@ #include "Buffer.h" #include "gettext.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "support/filetools.h" #include "support/lyxlib.h" diff --git a/src/Makefile.am b/src/Makefile.am index 8301b89135..deee6c157d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -167,8 +167,8 @@ lyx_SOURCES = \ lfuns.h \ LyXAction.cpp \ LyXAction.h \ - lyx_cb.cpp \ - lyx_cb.h \ + callback.cpp \ + callback.h \ LyX.cpp \ lyxfind.cpp \ lyxfind.h \ @@ -265,7 +265,7 @@ lyx_SOURCES = \ TransState.h \ Undo.cpp \ Undo.h \ - UpdateFlags.h \ + update_flags.h \ VCBackend.cpp \ VCBackend.h \ version.C \ diff --git a/src/UpdateFlags.h b/src/UpdateFlags.h deleted file mode 100644 index d092e74b3e..0000000000 --- a/src/UpdateFlags.h +++ /dev/null @@ -1,40 +0,0 @@ -// -*- C++ -*- -/** - * \file UpdateFlags.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author The Denmark Cowboys - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef UPDATE_FLAGS_H -#define UPDATE_FLAGS_H - -namespace lyx { - -namespace Update { - enum flags { - None = 0, - FitCursor = 1, - Force = 2, - SinglePar = 4, - MultiParSel = 8, - Decoration = 16 - }; - -inline flags operator|(flags const f, flags const g) -{ - return static_cast(int(f) | int(g)); -} - -inline flags operator&(flags const f, flags const g) -{ - return static_cast(int(f) & int(g)); -} - -} // namespace - -} // namespace lyx -#endif diff --git a/src/buffer_funcs.cpp b/src/buffer_funcs.cpp index aa15b8963f..7578bc997e 100644 --- a/src/buffer_funcs.cpp +++ b/src/buffer_funcs.cpp @@ -35,7 +35,7 @@ #include "TocBackend.h" #include "VCBackend.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "insets/InsetBibitem.h" #include "insets/InsetCaption.h" diff --git a/src/bufferview_funcs.cpp b/src/bufferview_funcs.cpp index 86a1f17b97..b8358ab8ad 100644 --- a/src/bufferview_funcs.cpp +++ b/src/bufferview_funcs.cpp @@ -31,7 +31,7 @@ #include "ParagraphParameters.h" #include "ParIterator.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "insets/InsetCommand.h" #include "insets/InsetText.h" diff --git a/src/callback.cpp b/src/callback.cpp new file mode 100644 index 0000000000..2a51d3ae00 --- /dev/null +++ b/src/callback.cpp @@ -0,0 +1,432 @@ +/** + * \file callback.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Lars Gullik Bjønnes + * \author Angus Leeming + * \author John Levon + * \author André Pönitz + * \author Jürgen Vigna + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "callback.h" + +#include "Buffer.h" +#include "BufferList.h" +#include "BufferView.h" +#include "buffer_funcs.h" +#include "Cursor.h" +#include "CutAndPaste.h" +#include "debug.h" +#include "gettext.h" +#include "Session.h" +#include "LaTeXFeatures.h" +#include "LyX.h" +#include "LyXLayout.h" +#include "LyXRC.h" +#include "LyXText.h" +#include "Paragraph.h" +#include "Undo.h" + +#include "frontends/alert.h" +#include "frontends/Application.h" +#include "frontends/FileDialog.h" +#include "frontends/LyXView.h" + +#include "support/FileFilterList.h" +#include "support/filetools.h" +#include "support/Forkedcall.h" +#include "support/fs_extras.h" +#include "support/lyxlib.h" +#include "support/Package.h" +#include "support/Path.h" +#include "support/Systemcall.h" + +#if !defined (HAVE_FORK) +# define fork() -1 +#endif + +#include +#include + +#include +#include + + +namespace lyx { + +using support::bformat; +using support::FileFilterList; +using support::FileName; +using support::ForkedProcess; +using support::isLyXFilename; +using support::libFileSearch; +using support::makeAbsPath; +using support::makeDisplayPath; +using support::onlyFilename; +using support::onlyPath; +using support::package; +using support::removeAutosaveFile; +using support::rename; +using support::split; +using support::Systemcall; +using support::tempName; +using support::unlink; + +using boost::shared_ptr; + +namespace Alert = frontend::Alert; +namespace fs = boost::filesystem; + +using std::back_inserter; +using std::copy; +using std::endl; +using std::make_pair; +using std::string; +using std::ifstream; +using std::ios; +using std::istream_iterator; + + +// this should be static, but I need it in Buffer.cpp +bool quitting; // flag, that we are quitting the program + +// +// Menu callbacks +// + +bool menuWrite(Buffer * buffer) +{ + if (buffer->save()) { + LyX::ref().session().lastFiles().add(FileName(buffer->fileName())); + return true; + } + + // FIXME: we don't tell the user *WHY* the save failed !! + + docstring const file = makeDisplayPath(buffer->fileName(), 30); + + docstring text = bformat(_("The document %1$s could not be saved.\n\n" + "Do you want to rename the document and try again?"), file); + int const ret = Alert::prompt(_("Rename and save?"), + text, 0, 1, _("&Rename"), _("&Cancel")); + + if (ret == 0) + return writeAs(buffer); + return false; +} + + + +bool writeAs(Buffer * buffer, string const & newname) +{ + string fname = buffer->fileName(); + string const oldname = fname; + + if (newname.empty()) { + + // FIXME UNICODE + FileDialog fileDlg(_("Choose a filename to save document as"), + LFUN_BUFFER_WRITE_AS, + make_pair(_("Documents|#o#O"), from_utf8(lyxrc.document_path)), + make_pair(_("Templates|#T#t"), from_utf8(lyxrc.template_path))); + + if (!isLyXFilename(fname)) + fname += ".lyx"; + + FileFilterList const filter (_("LyX Documents (*.lyx)")); + + FileDialog::Result result = + fileDlg.save(from_utf8(onlyPath(fname)), + filter, + from_utf8(onlyFilename(fname))); + + if (result.first == FileDialog::Later) + return false; + + fname = to_utf8(result.second); + + if (fname.empty()) + return false; + + // Make sure the absolute filename ends with appropriate suffix + fname = makeAbsPath(fname).absFilename(); + if (!isLyXFilename(fname)) + fname += ".lyx"; + } else + fname = newname; + + FileName const filename(fname); + if (fs::exists(filename.toFilesystemEncoding())) { + docstring const file = makeDisplayPath(fname, 30); + docstring text = bformat(_("The document %1$s already exists.\n\n" + "Do you want to over-write that document?"), file); + int const ret = Alert::prompt(_("Over-write document?"), + text, 0, 1, _("&Over-write"), _("&Cancel")); + + if (ret == 1) + return false; + } + + // Ok, change the name of the buffer + buffer->setFileName(fname); + buffer->markDirty(); + bool unnamed = buffer->isUnnamed(); + buffer->setUnnamed(false); + + if (!menuWrite(buffer)) { + buffer->setFileName(oldname); + buffer->setUnnamed(unnamed); + return false; + } + + removeAutosaveFile(oldname); + return true; +} + + +namespace { + +class AutoSaveBuffer : public ForkedProcess { +public: + /// + AutoSaveBuffer(BufferView & bv, FileName const & fname) + : bv_(bv), fname_(fname) {} + /// + virtual shared_ptr clone() const + { + return shared_ptr(new AutoSaveBuffer(*this)); + } + /// + int start(); +private: + /// + virtual int generateChild(); + /// + BufferView & bv_; + FileName fname_; +}; + + +int AutoSaveBuffer::start() +{ + command_ = to_utf8(bformat(_("Auto-saving %1$s"), from_utf8(fname_.absFilename()))); + return run(DontWait); +} + + +int AutoSaveBuffer::generateChild() +{ + // tmp_ret will be located (usually) in /tmp + // will that be a problem? + pid_t const pid = fork(); // If you want to debug the autosave + // you should set pid to -1, and comment out the + // fork. + if (pid == 0 || pid == -1) { + // pid = -1 signifies that lyx was unable + // to fork. But we will do the save + // anyway. + bool failed = false; + + FileName const tmp_ret(tempName(FileName(), "lyxauto")); + if (!tmp_ret.empty()) { + bv_.buffer()->writeFile(tmp_ret); + // assume successful write of tmp_ret + if (!rename(tmp_ret, fname_)) { + failed = true; + // most likely couldn't move between filesystems + // unless write of tmp_ret failed + // so remove tmp file (if it exists) + unlink(tmp_ret); + } + } else { + failed = true; + } + + if (failed) { + // failed to write/rename tmp_ret so try writing direct + if (!bv_.buffer()->writeFile(fname_)) { + // It is dangerous to do this in the child, + // but safe in the parent, so... + if (pid == -1) + // emit message signal. + bv_.buffer()->message(_("Autosave failed!")); + } + } + if (pid == 0) { // we are the child so... + _exit(0); + } + } + return pid; +} + +} // namespace anon + + +void autoSave(BufferView * bv) + // should probably be moved into BufferList (Lgb) + // Perfect target for a thread... +{ + if (!bv->buffer()) + return; + + if (bv->buffer()->isBakClean() || bv->buffer()->isReadonly()) { + // We don't save now, but we'll try again later + bv->buffer()->resetAutosaveTimers(); + return; + } + + // emit message signal. + bv->buffer()->message(_("Autosaving current document...")); + + // create autosave filename + string fname = bv->buffer()->filePath(); + fname += '#'; + fname += onlyFilename(bv->buffer()->fileName()); + fname += '#'; + + AutoSaveBuffer autosave(*bv, FileName(fname)); + autosave.start(); + + bv->buffer()->markBakClean(); + bv->buffer()->resetAutosaveTimers(); +} + + +// +// Copyright CHT Software Service GmbH +// Uwe C. Schroeder +// +// create new file with template +// SERVERCMD ! +// +void newFile(BufferView * bv, string const & filename) +{ + // Split argument by : + string name; + string tmpname = split(filename, name, ':'); + LYXERR(Debug::INFO) << "Arg is " << filename + << "\nName is " << name + << "\nTemplate is " << tmpname << endl; + + Buffer * const b = newFile(name, tmpname); + if (b) + bv->setBuffer(b); +} + + +// Insert plain text file (if filename is empty, prompt for one) +void insertPlaintextFile(BufferView * bv, string const & f, bool asParagraph) +{ + if (!bv->buffer()) + return; + + docstring const tmpstr = getContentsOfPlaintextFile(bv, f, asParagraph); + if (tmpstr.empty()) + return; + + Cursor & cur = bv->cursor(); + cap::replaceSelection(cur); + recordUndo(cur); + if (asParagraph) + cur.innerText()->insertStringAsParagraphs(cur, tmpstr); + else + cur.innerText()->insertStringAsLines(cur, tmpstr); +} + + +docstring const getContentsOfPlaintextFile(BufferView * bv, string const & f, + bool asParagraph) +{ + FileName fname(f); + + if (fname.empty()) { + FileDialog fileDlg(_("Select file to insert"), + (asParagraph) ? LFUN_FILE_INSERT_PLAINTEXT_PARA : LFUN_FILE_INSERT_PLAINTEXT); + + FileDialog::Result result = + fileDlg.open(from_utf8(bv->buffer()->filePath()), + FileFilterList(), docstring()); + + if (result.first == FileDialog::Later) + return docstring(); + + fname = makeAbsPath(to_utf8(result.second)); + + if (fname.empty()) + return docstring(); + } + + if (!fs::is_readable(fname.toFilesystemEncoding())) { + docstring const error = from_ascii(strerror(errno)); + docstring const file = makeDisplayPath(fname.absFilename(), 50); + docstring const text = bformat(_("Could not read the specified document\n" + "%1$s\ndue to the error: %2$s"), file, error); + Alert::error(_("Could not read file"), text); + return docstring(); + } + + ifstream ifs(fname.toFilesystemEncoding().c_str()); + if (!ifs) { + docstring const error = from_ascii(strerror(errno)); + docstring const file = makeDisplayPath(fname.absFilename(), 50); + docstring const text = bformat(_("Could not open the specified document\n" + "%1$s\ndue to the error: %2$s"), file, error); + Alert::error(_("Could not open file"), text); + return docstring(); + } + + ifs.unsetf(ios::skipws); + istream_iterator ii(ifs); + istream_iterator end; +#if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD) + // We use this until the compilers get better... + std::vector tmp; + copy(ii, end, back_inserter(tmp)); + string const tmpstr(tmp.begin(), tmp.end()); +#else + // This is what we want to use and what we will use once the + // compilers get good enough. + //string tmpstr(ii, end); // yet a reason for using std::string + // alternate approach to get the file into a string: + string tmpstr; + copy(ii, end, back_inserter(tmpstr)); +#endif + + // FIXME UNICODE: We don't know the encoding of the file + return normalize_kc(from_utf8(tmpstr)); +} + + +// This function runs "configure" and then rereads lyx.defaults to +// reconfigure the automatic settings. +void reconfigure(LyXView & lv) +{ + // emit message signal. + lv.message(_("Running configure...")); + + // Run configure in user lyx directory + support::Path p(package().user_support()); + string const configure_command = package().configure_command(); + Systemcall one; + one.startscript(Systemcall::Wait, configure_command); + p.pop(); + // emit message signal. + lv.message(_("Reloading configuration...")); + lyxrc.read(libFileSearch(string(), "lyxrc.defaults")); + // Re-read packages.lst + LaTeXFeatures::getAvailable(); + + Alert::information(_("System reconfigured"), + _("The system has been reconfigured.\n" + "You need to restart LyX to make use of any\n" + "updated document class specifications.")); +} + + +} // namespace lyx diff --git a/src/callback.h b/src/callback.h new file mode 100644 index 0000000000..6ce3858b72 --- /dev/null +++ b/src/callback.h @@ -0,0 +1,44 @@ +// -*- C++ -*- +/** + * \file callback.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Lars Gullik Bjønnes + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef CALLBACK_H +#define CALLBACK_H + +#include "support/docstring.h" + +namespace lyx { + +class Buffer; +class BufferView; +class LyXView; + +/// +extern bool quitting; + +/// +bool menuWrite(Buffer * buffer); +/// write the given file, or ask if no name given +bool writeAs(Buffer * buffer, std::string const & filename = std::string()); +/// +void autoSave(BufferView * bv); +/// +void newFile(BufferView * bv, std::string const & filename); +/// +void insertPlaintextFile(BufferView * bv, std::string const & f, bool asParagraph); +/// read plain text file (if \p f is empty, prompt for a filename) +docstring const getContentsOfPlaintextFile(BufferView * bv, + std::string const & f, bool asParagraph); +/// +void reconfigure(LyXView & lv); + +} // namespace lyx + +#endif diff --git a/src/factory.cpp b/src/factory.cpp index 3337399431..1343dfb50b 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -28,7 +28,7 @@ #include "insets/InsetCaption.h" #include "insets/InsetCitation.h" #include "insets/InsetCharStyle.h" -#include "insets/InsetEnv.h" +#include "insets/InsetEnvironment.h" #include "insets/InsetERT.h" #include "insets/InsetExternal.h" #include "insets/InsetFloat.h" @@ -58,7 +58,7 @@ #include "mathed/MathMacroTemplate.h" #include "mathed/InsetMathHull.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "support/lstrings.h" #include "support/ExceptionMessage.h" diff --git a/src/frontends/Alert.cpp b/src/frontends/Alert.cpp deleted file mode 100644 index 4822bd76dc..0000000000 --- a/src/frontends/Alert.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/** - * \file Alert.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author John Levon - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "Alert.h" -#include "Alert_pimpl.h" - -#include "debug.h" -#include "LyX.h" // for lyx::use_gui - -using std::endl; -using std::make_pair; -using std::pair; -using std::string; - - -namespace lyx { - -namespace frontend { - -int Alert::prompt(docstring const & title, docstring const & question, - int default_button, int escape_button, - docstring const & b1, docstring const & b2, docstring const & b3) -{ - if (!use_gui || lyxerr.debugging()) { - lyxerr << to_utf8(title) << '\n' - << "----------------------------------------\n" - << to_utf8(question) << endl; - - lyxerr << "Assuming answer is "; - switch (default_button) { - case 0: lyxerr << to_utf8(b1) << endl; - case 1: lyxerr << to_utf8(b2) << endl; - case 2: lyxerr << to_utf8(b3) << endl; - } - if (!use_gui) - return default_button; - } - - return prompt_pimpl(title, question, - default_button, escape_button, b1, b2, b3); - -} - - -void Alert::warning(docstring const & title, docstring const & message) -{ - lyxerr << "Warning: " << to_utf8(title) << '\n' - << "----------------------------------------\n" - << to_utf8(message) << endl; - - if (use_gui) - warning_pimpl(title, message); -} - - -void Alert::error(docstring const & title, docstring const & message) -{ - lyxerr << "Error: " << to_utf8(title) << '\n' - << "----------------------------------------\n" - << to_utf8(message) << endl; - - if (use_gui) - error_pimpl(title, message); -} - - -void Alert::information(docstring const & title, docstring const & message) -{ - if (!use_gui || lyxerr.debugging()) - lyxerr << to_utf8(title) << '\n' - << "----------------------------------------\n" - << to_utf8(message) << endl; - - if (use_gui) - information_pimpl(title, message); -} - - -pair const Alert::askForText(docstring const & msg, - docstring const & dflt) -{ - if (!use_gui || lyxerr.debugging()) { - lyxerr << "----------------------------------------\n" - << to_utf8(msg) << '\n' - << "Assuming answer is " << to_utf8(dflt) << '\n' - << "----------------------------------------" << endl; - if (!use_gui) - return make_pair(true, dflt); - } - - return askForText_pimpl(msg, dflt); -} - -} // namespace frontend -} // namespace lyx diff --git a/src/frontends/Alert.h b/src/frontends/Alert.h deleted file mode 100644 index 7bd81ebe4c..0000000000 --- a/src/frontends/Alert.h +++ /dev/null @@ -1,65 +0,0 @@ -// -*- C++ -*- -/** - * \file Alert.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author John Levon - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef LYX_ALERT_H -#define LYX_ALERT_H - -#include "support/lstrings.h" - - -namespace lyx { -namespace frontend { -namespace Alert { - -/** - * Prompt for a question. Returns 0-2 for the chosen button. - * Set default_button and cancel_button to reasonable values. b1-b3 - * should have accelerators marked with an '&'. title should be - * a short summary. Strings should be gettextised. - * Please think about the poor user. - * - * Remember to use boost::format. If you make any of these buttons - * "Yes" or "No", I will personally come around to your house and - * slap you with fish, and not in an enjoyable way either. - */ -int prompt(docstring const & title, docstring const & question, - int default_button, int cancel_button, - docstring const & b1, docstring const & b2, docstring const & b3 = docstring()); - -/** - * Display a warning to the user. Title should be a short (general) summary. - * Only use this if the user cannot perform some remedial action. - */ -void warning(docstring const & title, docstring const & message); - -/** - * Display a warning to the user. Title should be a short (general) summary. - * Only use this if the user cannot perform some remedial action. - */ -void error(docstring const & title, docstring const & message); - -/** - * Informational message. Use very very sparingly. That is, you must - * apply to me, in triplicate, under the sea, breathing in petrol - * and reciting the Nicene Creed, whilst running uphill and also - * eating. - */ -void information(docstring const & title, docstring const & message); - -/// Asks for a text. DO NOT USE !! -std::pair const -askForText(docstring const & msg, docstring const & dflt = docstring()); - -} // namespace Alert -} // namespace frontend -} // namespace lyx - -#endif // LYX_ALERT_H diff --git a/src/frontends/Dialogs.cpp b/src/frontends/Dialogs.cpp index 05d0128dec..13132814e5 100644 --- a/src/frontends/Dialogs.cpp +++ b/src/frontends/Dialogs.cpp @@ -14,7 +14,7 @@ #include "Dialogs.h" -#include "lyx_cb.h" +#include "callback.h" #include "controllers/Dialog.h" diff --git a/src/frontends/LyXView.cpp b/src/frontends/LyXView.cpp index 378425dc53..64712c23b0 100644 --- a/src/frontends/LyXView.cpp +++ b/src/frontends/LyXView.cpp @@ -29,7 +29,7 @@ #include "FuncRequest.h" #include "gettext.h" #include "Intl.h" -#include "lyx_cb.h" +#include "callback.h" #include "LyXFunc.h" #include "LyXRC.h" #include "LyXText.h" diff --git a/src/frontends/Makefile.am b/src/frontends/Makefile.am index a8b4a6024a..257b303e66 100644 --- a/src/frontends/Makefile.am +++ b/src/frontends/Makefile.am @@ -13,8 +13,8 @@ noinst_LTLIBRARIES = libfrontends.la AM_CPPFLAGS += $(PCH_FLAGS) -I$(srcdir)/.. $(BOOST_INCLUDES) libfrontends_la_SOURCES = \ - Alert.cpp \ - Alert.h \ + alert.cpp \ + alert.h \ Alert_pimpl.h \ Application.cpp \ Application.h \ diff --git a/src/frontends/alert.cpp b/src/frontends/alert.cpp new file mode 100644 index 0000000000..69ac6c849c --- /dev/null +++ b/src/frontends/alert.cpp @@ -0,0 +1,104 @@ +/** + * \file alert.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author John Levon + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "alert.h" +#include "Alert_pimpl.h" + +#include "debug.h" +#include "LyX.h" // for lyx::use_gui + +using std::endl; +using std::make_pair; +using std::pair; +using std::string; + + +namespace lyx { + +namespace frontend { + +int Alert::prompt(docstring const & title, docstring const & question, + int default_button, int escape_button, + docstring const & b1, docstring const & b2, docstring const & b3) +{ + if (!use_gui || lyxerr.debugging()) { + lyxerr << to_utf8(title) << '\n' + << "----------------------------------------\n" + << to_utf8(question) << endl; + + lyxerr << "Assuming answer is "; + switch (default_button) { + case 0: lyxerr << to_utf8(b1) << endl; + case 1: lyxerr << to_utf8(b2) << endl; + case 2: lyxerr << to_utf8(b3) << endl; + } + if (!use_gui) + return default_button; + } + + return prompt_pimpl(title, question, + default_button, escape_button, b1, b2, b3); + +} + + +void Alert::warning(docstring const & title, docstring const & message) +{ + lyxerr << "Warning: " << to_utf8(title) << '\n' + << "----------------------------------------\n" + << to_utf8(message) << endl; + + if (use_gui) + warning_pimpl(title, message); +} + + +void Alert::error(docstring const & title, docstring const & message) +{ + lyxerr << "Error: " << to_utf8(title) << '\n' + << "----------------------------------------\n" + << to_utf8(message) << endl; + + if (use_gui) + error_pimpl(title, message); +} + + +void Alert::information(docstring const & title, docstring const & message) +{ + if (!use_gui || lyxerr.debugging()) + lyxerr << to_utf8(title) << '\n' + << "----------------------------------------\n" + << to_utf8(message) << endl; + + if (use_gui) + information_pimpl(title, message); +} + + +pair const Alert::askForText(docstring const & msg, + docstring const & dflt) +{ + if (!use_gui || lyxerr.debugging()) { + lyxerr << "----------------------------------------\n" + << to_utf8(msg) << '\n' + << "Assuming answer is " << to_utf8(dflt) << '\n' + << "----------------------------------------" << endl; + if (!use_gui) + return make_pair(true, dflt); + } + + return askForText_pimpl(msg, dflt); +} + +} // namespace frontend +} // namespace lyx diff --git a/src/frontends/alert.h b/src/frontends/alert.h new file mode 100644 index 0000000000..a163caf69a --- /dev/null +++ b/src/frontends/alert.h @@ -0,0 +1,65 @@ +// -*- C++ -*- +/** + * \file alert.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author John Levon + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef LYX_ALERT_H +#define LYX_ALERT_H + +#include "support/lstrings.h" + + +namespace lyx { +namespace frontend { +namespace Alert { + +/** + * Prompt for a question. Returns 0-2 for the chosen button. + * Set default_button and cancel_button to reasonable values. b1-b3 + * should have accelerators marked with an '&'. title should be + * a short summary. Strings should be gettextised. + * Please think about the poor user. + * + * Remember to use boost::format. If you make any of these buttons + * "Yes" or "No", I will personally come around to your house and + * slap you with fish, and not in an enjoyable way either. + */ +int prompt(docstring const & title, docstring const & question, + int default_button, int cancel_button, + docstring const & b1, docstring const & b2, docstring const & b3 = docstring()); + +/** + * Display a warning to the user. Title should be a short (general) summary. + * Only use this if the user cannot perform some remedial action. + */ +void warning(docstring const & title, docstring const & message); + +/** + * Display a warning to the user. Title should be a short (general) summary. + * Only use this if the user cannot perform some remedial action. + */ +void error(docstring const & title, docstring const & message); + +/** + * Informational message. Use very very sparingly. That is, you must + * apply to me, in triplicate, under the sea, breathing in petrol + * and reciting the Nicene Creed, whilst running uphill and also + * eating. + */ +void information(docstring const & title, docstring const & message); + +/// Asks for a text. DO NOT USE !! +std::pair const +askForText(docstring const & msg, docstring const & dflt = docstring()); + +} // namespace Alert +} // namespace frontend +} // namespace lyx + +#endif // LYX_ALERT_H diff --git a/src/frontends/controllers/BCView.tmpl b/src/frontends/controllers/BCView.tmpl index c8567f01d4..0e1aa800c7 100644 --- a/src/frontends/controllers/BCView.tmpl +++ b/src/frontends/controllers/BCView.tmpl @@ -15,7 +15,7 @@ */ #include "BCView.h" -#include "ButtonPolicies.h" +#include "ButtonPolicy.h" #include "debug.h" namespace lyx { diff --git a/src/frontends/controllers/ButtonController.h b/src/frontends/controllers/ButtonController.h index 2e48a81547..8c454537de 100644 --- a/src/frontends/controllers/ButtonController.h +++ b/src/frontends/controllers/ButtonController.h @@ -12,7 +12,7 @@ #ifndef BUTTONCONTROLLER_H #define BUTTONCONTROLLER_H -#include "ButtonPolicies.h" +#include "ButtonPolicy.h" #include namespace lyx { diff --git a/src/frontends/controllers/ButtonPolicies.cpp b/src/frontends/controllers/ButtonPolicies.cpp deleted file mode 100644 index c14b0729b2..0000000000 --- a/src/frontends/controllers/ButtonPolicies.cpp +++ /dev/null @@ -1,633 +0,0 @@ -/** - * \file ButtonPolicies.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Allan Rae - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "ButtonPolicies.h" -#include "debug.h" -#include - -using std::endl; -using std::string; - -namespace lyx { -namespace frontend { - -namespace { - -string const printState(ButtonPolicy::State const & state) -{ - string output; - - switch(state) { - case ButtonPolicy::INITIAL: - output = "INITIAL"; - break; - case ButtonPolicy::VALID: - output = "VALID"; - break; - case ButtonPolicy::INVALID: - output = "INVALID"; - break; - case ButtonPolicy::APPLIED: - output = "APPLIED"; - break; - case ButtonPolicy::RO_INITIAL: - output = "RO_INITIAL"; - break; - case ButtonPolicy::RO_VALID: - output = "RO_VALID"; - break; - case ButtonPolicy::RO_INVALID: - output = "RO_INVALID"; - break; - case ButtonPolicy::RO_APPLIED: - output = "RO_APPLIED"; - break; - case ButtonPolicy::BOGUS: - output = "BOGUS"; - break; - } - - return output; -} - - -string const printInput(ButtonPolicy::SMInput const & input) -{ - string output; - - switch (input) { - case ButtonPolicy::SMI_VALID: - output = "SMI_VALID"; - break; - case ButtonPolicy::SMI_INVALID: - output = "SMI_INVALID"; - break; - case ButtonPolicy::SMI_OKAY: - output = "SMI_OKAY"; - break; - case ButtonPolicy::SMI_APPLY: - output = "SMI_APPLY"; - break; - case ButtonPolicy::SMI_CANCEL: - output = "SMI_CANCEL"; - break; - case ButtonPolicy::SMI_RESTORE: - output = "SMI_RESTORE"; - break; - case ButtonPolicy::SMI_HIDE: - output = "SMI_HIDE"; - break; - case ButtonPolicy::SMI_READ_ONLY: - output = "SMI_READ_ONLY"; - break; - case ButtonPolicy::SMI_READ_WRITE: - output = "SMI_READ_WRITE"; - break; - case ButtonPolicy::SMI_NOOP: - output = "SMI_NOOP"; - break; - case ButtonPolicy::SMI_TOTAL: - output = "SMI_TOTAL"; - break; - } - - return output; -} - - -/// Helper function -void nextState(ButtonPolicy::State & state, - ButtonPolicy::SMInput in, - ButtonPolicy::StateMachine const & s_m, - char const * function_name = "nextState") -{ - if (ButtonPolicy::SMI_NOOP == in) return; - - ButtonPolicy::State tmp = s_m[state][in]; - - LYXERR(Debug::GUI) << "Transition from state " - << printState(state) << " to state " - << printState(tmp) << " after input " - << printInput(in) << std::endl; - - if (ButtonPolicy::BOGUS != tmp) { - state = tmp; - } else { - lyxerr << function_name - << ": No transition for input " - << printInput(in) - << " from state " - << printState(state) - << endl; - } -} - -} // namespace anon - - -/*-----------------------------PreferencesPolicy-----------------------------*/ - - -PreferencesPolicy::PreferencesPolicy() - : state_(INITIAL), - outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS), - state_machine_(APPLIED + 1, - StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) -{ - // Build the state output map - outputs_[INITIAL] = CLOSE; - outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; - outputs_[INVALID] = RESTORE | CANCEL; - outputs_[APPLIED] = OKAY | CLOSE; - - // Build the state machine one state at a time - // NOTE: Since CANCEL and HIDE always go to INITIAL they are - // left out of the state machine and handled explicitly - // in input(). This won't necessarily be true for all - // policies though so I'll leave those two as distinct - // inputs rather than merge them. For example, a dialog - // that doesn't update it's input fields when reshown - // after being hidden needs a policy where CANCEL and - // HIDE are treated differently. - // - // State::INITIAL - state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL; - state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; - state_machine_[INITIAL][SMI_VALID] = VALID; - state_machine_[INITIAL][SMI_INVALID] = INVALID; - // State::VALID - state_machine_[VALID][SMI_VALID] = VALID; - state_machine_[VALID][SMI_READ_ONLY] = VALID; - state_machine_[VALID][SMI_READ_WRITE] = VALID; - state_machine_[VALID][SMI_INVALID] = INVALID; - state_machine_[VALID][SMI_APPLY] = APPLIED; - state_machine_[VALID][SMI_OKAY] = INITIAL; - state_machine_[VALID][SMI_RESTORE] = INITIAL; - // State::INVALID - state_machine_[INVALID][SMI_VALID] = VALID; - state_machine_[INVALID][SMI_INVALID] = INVALID; - state_machine_[INVALID][SMI_READ_ONLY] = INVALID; - state_machine_[INVALID][SMI_READ_WRITE] = INVALID; - state_machine_[INVALID][SMI_RESTORE] = INITIAL; - // State::APPLIED - state_machine_[APPLIED][SMI_VALID] = VALID; - state_machine_[APPLIED][SMI_INVALID] = INVALID; - state_machine_[APPLIED][SMI_OKAY] = INITIAL; - state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED; - state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED; -} - - -void PreferencesPolicy::input(SMInput input) -{ - // The APPLIED state is persistent. Next time the dialog is opened, - // the user will be able to press 'Save'. - if (SMI_CANCEL == input - || SMI_HIDE == input) { - if (state_ != APPLIED) - state_ = INITIAL; - } else { - nextState(state_, - input, - state_machine_, - "PreferencesPolicy"); - } -} - - -/*-------------------------------OkCancelPolicy------------------------------*/ - - -OkCancelPolicy::OkCancelPolicy() - : state_(INITIAL), - outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS), - state_machine_(INVALID + 1, - StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) -{ - // Build the state output map - outputs_[INITIAL] = CLOSE; - outputs_[VALID] = RESTORE | OKAY | CANCEL; - outputs_[INVALID] = RESTORE | CANCEL; - - // Build the state machine one state at a time - // NOTE: Since CANCEL and HIDE always go to INITIAL they are - // left out of the state machine and handled explicitly - // in input() - // - // State::INITIAL - state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL; - state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; - state_machine_[INITIAL][SMI_VALID] = VALID; - state_machine_[INITIAL][SMI_INVALID] = INVALID; - // State::VALID - state_machine_[VALID][SMI_VALID] = VALID; - state_machine_[VALID][SMI_READ_ONLY] = VALID; - state_machine_[VALID][SMI_READ_WRITE] = VALID; - state_machine_[VALID][SMI_INVALID] = INVALID; - state_machine_[VALID][SMI_OKAY] = INITIAL; - state_machine_[VALID][SMI_RESTORE] = INITIAL; - // State::INVALID - state_machine_[INVALID][SMI_VALID] = VALID; - state_machine_[INVALID][SMI_INVALID] = INVALID; - state_machine_[INVALID][SMI_READ_ONLY] = INVALID; - state_machine_[INVALID][SMI_READ_WRITE] = INVALID; - state_machine_[INVALID][SMI_RESTORE] = INITIAL; -} - - - -void OkCancelPolicy::input(SMInput input) -{ - //lyxerr << "OkCancelPolicy::input" << endl; - - // CANCEL and HIDE always take us to INITIAL for all cases - if (SMI_CANCEL == input - || SMI_HIDE == input) { - state_ = INITIAL; - } else { - nextState(state_, input, state_machine_, "OkCancelPolicy"); - } -} - - -/*---------------------------OkCancelReadOnlyPolicy-------------------------*/ - - -OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy() - : state_(INITIAL), - outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS), - state_machine_(RO_INVALID + 1, - StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) -{ - // Build the state output map - outputs_[INITIAL] = CLOSE; - outputs_[VALID] = RESTORE | OKAY | CANCEL; - outputs_[INVALID] = RESTORE | CANCEL; - outputs_[RO_INITIAL] = CLOSE; - outputs_[RO_VALID] = RESTORE | CANCEL; - outputs_[RO_INVALID] = RESTORE | CANCEL; - - // Build the state machine one state at a time - // NOTE: Since CANCEL and HIDE always go to INITIAL they are - // left out of the state machine and handled explicitly - // in input() - // - // State::INITIAL - state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; - state_machine_[INITIAL][SMI_VALID] = VALID; - state_machine_[INITIAL][SMI_INVALID] = INVALID; - state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL; - // State::VALID - state_machine_[VALID][SMI_VALID] = VALID; - state_machine_[VALID][SMI_READ_WRITE] = VALID; - state_machine_[VALID][SMI_INVALID] = INVALID; - state_machine_[VALID][SMI_OKAY] = INITIAL; - state_machine_[VALID][SMI_RESTORE] = INITIAL; - state_machine_[VALID][SMI_READ_ONLY] = RO_VALID; - // State::INVALID - state_machine_[INVALID][SMI_INVALID] = INVALID; - state_machine_[INVALID][SMI_READ_WRITE] = INVALID; - state_machine_[INVALID][SMI_VALID] = VALID; - state_machine_[INVALID][SMI_RESTORE] = INITIAL; - state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID; - // State::RO_INITIAL - state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL; - state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID; - state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID; - state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL; - // State::RO_VALID - state_machine_[RO_VALID][SMI_VALID] = RO_VALID; - state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID; - state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID; - state_machine_[RO_VALID][SMI_READ_WRITE] = VALID; - state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL; - // State::RO_INVALID - state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID; - state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID; - state_machine_[RO_INVALID][SMI_VALID] = RO_VALID; - state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID; - state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL; -} - - -void OkCancelReadOnlyPolicy::input(SMInput input) -{ - //lyxerr << "OkCancelReadOnlyPolicy::input" << endl; - - // CANCEL and HIDE always take us to INITIAL for all cases - if (SMI_CANCEL == input - || SMI_HIDE == input) { - state_ = INITIAL; - } else { - nextState(state_, - input, - state_machine_, - "OkCancelReadOnlyPolicy"); - } -} - - -/*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/ - - -NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy() - : state_(INITIAL), - outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS), - state_machine_(RO_INVALID + 1, - StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) -{ - // Build the state output map - outputs_[INITIAL] = CLOSE; - outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; - outputs_[INVALID] = RESTORE | CANCEL; - outputs_[RO_INITIAL] = CLOSE; - outputs_[RO_VALID] = RESTORE | CANCEL; - outputs_[RO_INVALID] = RESTORE | CANCEL; - - // Build the state machine one state at a time - // NOTE: Since CANCEL and HIDE always go to INITIAL they are - // left out of the state machine and handled explicitly - // in input() - // - // State::INITIAL - state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; - state_machine_[INITIAL][SMI_VALID] = VALID; - state_machine_[INITIAL][SMI_INVALID] = INVALID; - state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL; - // State::VALID - state_machine_[VALID][SMI_VALID] = VALID; - state_machine_[VALID][SMI_READ_WRITE] = VALID; - state_machine_[VALID][SMI_INVALID] = INVALID; - state_machine_[VALID][SMI_OKAY] = INITIAL; - state_machine_[VALID][SMI_APPLY] = INITIAL; - state_machine_[VALID][SMI_RESTORE] = INITIAL; - state_machine_[VALID][SMI_READ_ONLY] = RO_VALID; - // State::INVALID - state_machine_[INVALID][SMI_INVALID] = INVALID; - state_machine_[INVALID][SMI_READ_WRITE] = INVALID; - state_machine_[INVALID][SMI_VALID] = VALID; - state_machine_[INVALID][SMI_RESTORE] = INITIAL; - state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID; - // State::RO_INITIAL - state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL; - state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID; - state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID; - state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL; - // State::RO_VALID - state_machine_[RO_VALID][SMI_VALID] = RO_VALID; - state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID; - state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID; - state_machine_[RO_VALID][SMI_READ_WRITE] = VALID; - state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL; - // State::RO_INVALID - state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID; - state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID; - state_machine_[RO_INVALID][SMI_VALID] = RO_VALID; - state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID; - state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL; -} - - -void NoRepeatedApplyReadOnlyPolicy::input(SMInput input) -{ - //lyxerr << "NoReapeatedApplyReadOnlyPolicy::input" << endl; - - // CANCEL and HIDE always take us to INITIAL for all cases - if (SMI_CANCEL == input - || SMI_HIDE == input) { - state_ = INITIAL; - } else { - nextState(state_, - input, - state_machine_, - "NoRepeatedApplyReadOnlyPolicy"); - } -} - - -/*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/ - - -OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy() - : state_(INITIAL), - outputs_(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS), - state_machine_(RO_APPLIED + 1, - StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) -{ - // Build the state output map - outputs_[INITIAL] = CLOSE; - outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; - outputs_[INVALID] = RESTORE | CANCEL; - outputs_[APPLIED] = OKAY | APPLY | CLOSE; - outputs_[RO_INITIAL] = CLOSE; - outputs_[RO_VALID] = RESTORE | CANCEL; - outputs_[RO_INVALID] = RESTORE | CANCEL; - outputs_[RO_APPLIED] = CLOSE; - - // Build the state machine one state at a time - // NOTE: Since CANCEL and HIDE always go to INITIAL they are - // left out of the state machine and handled explicitly - // in input() - // - // State::INITIAL - state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; - state_machine_[INITIAL][SMI_VALID] = VALID; - state_machine_[INITIAL][SMI_INVALID] = INVALID; - state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL; - // State::VALID - state_machine_[VALID][SMI_VALID] = VALID; - state_machine_[VALID][SMI_READ_WRITE] = VALID; - state_machine_[VALID][SMI_INVALID] = INVALID; - state_machine_[VALID][SMI_OKAY] = INITIAL; - state_machine_[VALID][SMI_RESTORE] = INITIAL; - state_machine_[VALID][SMI_APPLY] = APPLIED; - state_machine_[VALID][SMI_READ_ONLY] = RO_VALID; - // State::INVALID - state_machine_[INVALID][SMI_INVALID] = INVALID; - state_machine_[INVALID][SMI_READ_WRITE] = INVALID; - state_machine_[INVALID][SMI_VALID] = VALID; - state_machine_[INVALID][SMI_RESTORE] = INITIAL; - state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID; - // State::APPLIED - state_machine_[APPLIED][SMI_APPLY] = APPLIED; - state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED; - state_machine_[APPLIED][SMI_VALID] = VALID; - state_machine_[APPLIED][SMI_INVALID] = INVALID; - state_machine_[APPLIED][SMI_OKAY] = INITIAL; - state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED; - // State::RO_INITIAL - state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL; - state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID; - state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID; - state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL; - // State::RO_VALID - state_machine_[RO_VALID][SMI_VALID] = RO_VALID; - state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID; - state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID; - state_machine_[RO_VALID][SMI_READ_WRITE] = VALID; - state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL; - // State::RO_INVALID - state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID; - state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID; - state_machine_[RO_INVALID][SMI_VALID] = RO_VALID; - state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID; - state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL; - // State::RO_APPLIED - state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED; - state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID; - state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID; - state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED; -} - - -void OkApplyCancelReadOnlyPolicy::input(SMInput input) -{ - //lyxerr << "OkApplyCancelReadOnlyPolicy::input" << endl; - - // CANCEL and HIDE always take us to INITIAL for all cases - if (SMI_CANCEL == input - || SMI_HIDE == input) { - state_ = INITIAL; - } else { - nextState(state_, - input, - state_machine_, - "OkApplyCancelReadOnlyPolicy"); - } -} - - -/*--------------------------OkApplyCancelPolicy----------------------*/ - - -OkApplyCancelPolicy::OkApplyCancelPolicy() - : state_(INITIAL), - outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS), - state_machine_(APPLIED + 1, - StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) -{ - // Build the state output map - outputs_[INITIAL] = CLOSE; - outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; - outputs_[INVALID] = RESTORE | CANCEL; - outputs_[APPLIED] = OKAY | APPLY | CLOSE; - - // Build the state machine one state at a time - // NOTE: Since CANCEL and HIDE always go to INITIAL they are - // left out of the state machine and handled explicitly - // in input() - // - // State::INITIAL - state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL; - state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; - state_machine_[INITIAL][SMI_VALID] = VALID; - state_machine_[INITIAL][SMI_INVALID] = INVALID; - // State::VALID - state_machine_[VALID][SMI_VALID] = VALID; - state_machine_[VALID][SMI_READ_ONLY] = VALID; - state_machine_[VALID][SMI_READ_WRITE] = VALID; - state_machine_[VALID][SMI_INVALID] = INVALID; - state_machine_[VALID][SMI_OKAY] = INITIAL; - state_machine_[VALID][SMI_RESTORE] = INITIAL; - state_machine_[VALID][SMI_APPLY] = APPLIED; - // State::INVALID - state_machine_[INVALID][SMI_INVALID] = INVALID; - state_machine_[INVALID][SMI_READ_ONLY] = INVALID; - state_machine_[INVALID][SMI_READ_WRITE] = INVALID; - state_machine_[INVALID][SMI_VALID] = VALID; - state_machine_[INVALID][SMI_RESTORE] = INITIAL; - // State::APPLIED - state_machine_[APPLIED][SMI_APPLY] = APPLIED; - state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED; - state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED; - state_machine_[APPLIED][SMI_VALID] = VALID; - state_machine_[APPLIED][SMI_INVALID] = INVALID; - state_machine_[APPLIED][SMI_OKAY] = INITIAL; -} - - -void OkApplyCancelPolicy::input(SMInput input) -{ - //lyxerr << "OkApplyCancelPolicy::input" << endl; - - // CANCEL and HIDE always take us to INITIAL for all cases - if (SMI_CANCEL == input - || SMI_HIDE == input) { - state_ = INITIAL; - } else { - nextState(state_, - input, - state_machine_, - "OkApplyCancelPolicy"); - } -} - - -/*--------------------------NoRepeatedApplyPolicy----------------------*/ - - -NoRepeatedApplyPolicy::NoRepeatedApplyPolicy() - : state_(INITIAL), - outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS), - state_machine_(INVALID + 1, - StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) -{ - // Build the state output map - outputs_[INITIAL] = CLOSE; - outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; - outputs_[INVALID] = RESTORE | CANCEL; - - // Build the state machine one state at a time - // NOTE: Since CANCEL and HIDE always go to INITIAL they are - // left out of the state machine and handled explicitly - // in input() - // - // State::INITIAL - state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL; - state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; - state_machine_[INITIAL][SMI_VALID] = VALID; - state_machine_[INITIAL][SMI_INVALID] = INVALID; - // State::VALID - state_machine_[VALID][SMI_VALID] = VALID; - state_machine_[VALID][SMI_READ_ONLY] = VALID; - state_machine_[VALID][SMI_READ_WRITE] = VALID; - state_machine_[VALID][SMI_INVALID] = INVALID; - state_machine_[VALID][SMI_OKAY] = INITIAL; - state_machine_[VALID][SMI_APPLY] = INITIAL; - state_machine_[VALID][SMI_RESTORE] = INITIAL; - // State::INVALID - state_machine_[INVALID][SMI_INVALID] = INVALID; - state_machine_[INVALID][SMI_READ_ONLY] = INVALID; - state_machine_[INVALID][SMI_READ_WRITE] = INVALID; - state_machine_[INVALID][SMI_VALID] = VALID; - state_machine_[INVALID][SMI_RESTORE] = INITIAL; -} - - -void NoRepeatedApplyPolicy::input(SMInput input) -{ - //lyxerr << "NoRepeatedApplyPolicy::input" << endl; - - // CANCEL and HIDE always take us to INITIAL for all cases - if (SMI_CANCEL == input - || SMI_HIDE == input) { - state_ = INITIAL; - } else { - nextState(state_, - input, - state_machine_, - "NoRepeatedApplyPolicy"); - } -} - -} // namespace frontend -} // namespace lyx diff --git a/src/frontends/controllers/ButtonPolicies.h b/src/frontends/controllers/ButtonPolicies.h deleted file mode 100644 index 3300c9a208..0000000000 --- a/src/frontends/controllers/ButtonPolicies.h +++ /dev/null @@ -1,474 +0,0 @@ -// -*- C++ -*- -/** - * \file ButtonPolicies.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Allan Rae - * - * Full author contact details are available in file CREDITS. - * - * Provides a state machine implementation of the various button policies - * used by the dialogs. - */ - -#ifndef BUTTONPOLICIES_H -#define BUTTONPOLICIES_H - - -#include -#include - -#include "support/std_ostream.h" - -namespace lyx { -namespace frontend { - -/** An abstract base class for button policies. - A state machine implementation of the various button policies used by the - dialogs. Only the policy is implemented here. Separate ButtonController - classes are needed for each GUI implementation. - - Policy | ReadOnly | Apply Button | Repeated Apply - ======================================================================== - OkCancel | N | N | - - OkCancelReadOnly | Y | N | - - OkApplyCancel | N | Y | Y - OkApplyCancelReadOnly | Y | Y | Y - NoRepeatedApply | N | Y | N - NoRepeatedApplyReadOnly | Y | Y | N - Preferences | N | Y | No (Ok-Close) - Ignorant | N/A | N/A | N/A - ======================================================================== - - Policy - The name of the policy - ReadOnly - Does the policy treat read-only docs differently to read-write docs? - This usually means that when an SMI_READ_ONLY input arrives then - all the buttons are disabled except Cancel/Close. The state - machine tracks the inputs (valid/invalid) and has states for all - combinations. When an SMI_READ_WRITE input arrives the appropriate - machine state is entered (just as if the document had always been - read-write). - NOTE: If a dialog doesn't care about the read-only status of a document - (and uses an appropriate policy) it can never get into a read-only state - so isReadOnly() can only ever return false even though the document may - be read-only. - Repeated Apply - Simply means that it is alright to use the Apply button multiple times - without requiring a change of the dialog contents. If no repeating is - allowed the Ok+Apply buttons are deactivated. The Preferences dialog - has its own special version of repeated apply handling because its Ok - button is actually a Save button -- its always reasonable to Save the - preferences if the dialog has changed since the last save. - - The IgnorantPolicy is a special case that allows anything. - */ -class ButtonPolicy : boost::noncopyable { -public: - /// - virtual ~ButtonPolicy() {} - - /** The various possible state names. - Not all state-machines have this many states. However, we need - to define them all here so we can share the code. - */ - enum State { - /// - INITIAL = 0, - /// - VALID, - /// - INVALID, - /// - APPLIED, - /// - RO_INITIAL, - /// - RO_VALID, - /// - RO_INVALID, - /// - RO_APPLIED, - /// - BOGUS = 55 - }; - - /// The various button types. - enum Button { - /// - CLOSE = 0, // Not a real button, but effectively !CANCEL - /// - OKAY = 1, - /// - APPLY = 2, - /// - CANCEL = 4, - /// - RESTORE = 8 - }; - /// - static const Button ALL_BUTTONS = - Button(OKAY | APPLY | CANCEL | RESTORE); - - /** State machine inputs. - All the policies so far have both CANCEL and HIDE always going to - INITIAL. This won't necessarily be true for all [future] policies - though so I'll leave those two as distinct inputs rather than merge - them. For example, a dialog that doesn't update it's input fields - when reshown after being hidden needs a policy where CANCEL and - HIDE are treated differently. - */ - enum SMInput { - /// the dialog contents are now valid - SMI_VALID = 0, - /// the dialog contents are now invalid - SMI_INVALID, - /// an apply-and-hide action has happened - SMI_OKAY, - /// an apply action has happened - SMI_APPLY, - /// a cancel action has happened - SMI_CANCEL, - /// a restore action has happened - SMI_RESTORE, - /// the dialog has been hidden - SMI_HIDE, - /// the dialog contents are read-only - SMI_READ_ONLY, - /// the dialog contents can be modified - SMI_READ_WRITE, - /// the state of the dialog contents has not changed - SMI_NOOP, - /// for internal use - SMI_TOTAL - }; - - /// Trigger a transition with this input. - virtual void input(SMInput) = 0; - /// Activation status of a button - virtual bool buttonStatus(Button) const = 0; - /// Are we in a read-only state? - virtual bool isReadOnly() const = 0; - - /// Transition map of the state machine. - typedef std::vector StateArray; - /// - typedef std::vector StateMachine; - /// The state outputs are the status of the buttons. - typedef std::vector StateOutputs; -}; - - -inline -std::ostream & operator<<(std::ostream & os, ButtonPolicy::State st) -{ - os << int(st); - return os; -} - - -inline -std::ostream & operator<<(std::ostream & os, ButtonPolicy::SMInput smi) -{ - os << int(smi); - return os; -} - - -//--------------------- Actual Policy Classes ----------------------------- - -/** Ok and Cancel buttons for dialogs with read-only operation. - Note: This scheme supports the relabelling of Cancel to Close and - vice versa. - This is based on the value of the bool state of the Button::CANCEL. - true == Cancel, false == Close - */ -class OkCancelPolicy : public ButtonPolicy { -public: - /// - OkCancelPolicy(); - /// - //virtual ~OkCancelPolicy() {} - - /// Trigger a transition with this input. - virtual void input(SMInput); - /** Activation status of a button. - We assume that we haven't gotten into an undefined state. - This is reasonable since we can only reach states defined - in the state machine and they should all have been defined in - the outputs_ variable. Perhaps we can do something at compile - time to check that all the states have corresponding outputs. - */ - virtual bool buttonStatus(Button button) const { - return button & outputs_[state_]; - } - /// Are we in a read-only state? - virtual bool isReadOnly() const { - return false; - } -private: - /// Current state. - State state_; - /// Which buttons are active for a given state. - StateOutputs outputs_; - /// - StateMachine state_machine_; -}; - -/** Ok and Cancel buttons for dialogs where read-only operation is blocked. - The state machine design for this policy allows changes to occur within - the dialog while a file is read-only -- the okay button is disabled until - a read-write input is given. When the file is made read-write the dialog - will then be in the correct state (as if the file had always been - read-write). - Note: This scheme supports the relabelling of Cancel to Close - and vice versa. - This is based on the value of the bool state of the Button::CANCEL. - true == Cancel, false == Close - */ -class OkCancelReadOnlyPolicy : public ButtonPolicy { -public: - /// - OkCancelReadOnlyPolicy(); - /// - //virtual ~OkCancelReadOnlyPolicy() {} - - /// Trigger a transition with this input. - virtual void input(SMInput); - /// Activation status of a button. - virtual bool buttonStatus(Button button) const { - return button & outputs_[state_]; - } - /// Are we in a read-only state? - virtual bool isReadOnly() const { - return RO_INITIAL == state_ - || RO_VALID == state_ - || RO_INVALID == state_ - || RO_APPLIED == state_; - } -private: - /// Current state. - State state_; - /// Which buttons are active for a given state. - StateOutputs outputs_; - /// - StateMachine state_machine_; -}; - - -/** Ok, Apply and Cancel buttons for dialogs where read-only operation - is blocked. - Repeated Apply are not allowed. Likewise, Ok cannot follow Apply without - some valid input. That is, the dialog contents must change between - each Apply or Apply and Ok. - The state machine design for this policy allows changes to occur within - the dialog while a file is read-only -- the Ok+Apply buttons are disabled - until a read-write input is given. When the file is made read-write the - dialog will then be in the correct state (as if the file had always been - read-write). - Note: This scheme supports the relabelling of Cancel to Close - and vice versa. - This is based on the value of the bool state of the Button::CANCEL. - true == Cancel, false == Close - */ -class NoRepeatedApplyReadOnlyPolicy : public ButtonPolicy { -public: - /// - NoRepeatedApplyReadOnlyPolicy(); - /// - //virtual ~NoRepeatedApplyReadOnlyPolicy() {} - - /// Trigger a transition with this input. - virtual void input(SMInput); - /// Activation status of a button. - virtual bool buttonStatus(Button button) const { - return button & outputs_[state_]; - } - /// Are we in a read-only state? - virtual bool isReadOnly() const { - return RO_INITIAL == state_ - || RO_VALID == state_ - || RO_INVALID == state_ - || RO_APPLIED == state_; - } -private: - /// Current state. - State state_; - /// Which buttons are active for a given state. - StateOutputs outputs_; - /// - StateMachine state_machine_; -}; - - -/** Ok, Apply and Cancel buttons for dialogs where read-only - operation is blocked. - Repeated Apply is allowed. Likewise, Ok can follow Apply. - The state machine design for this policy allows changes to occur within - the dialog while a file is read-only -- the Ok+Apply buttons are disabled - until a read-write input is given. When the file is made read-write the - dialog will then be in the correct state (as if the file had always been - read-write). - Note: This scheme supports the relabelling of Cancel to Close - and vice versa. - This is based on the value of the bool state of the Button::CANCEL. - true == Cancel, false == Close - */ -class OkApplyCancelReadOnlyPolicy : public ButtonPolicy { -public: - /// - OkApplyCancelReadOnlyPolicy(); - /// - //virtual ~OkApplyCancelReadOnlyPolicy() {} - - /// Trigger a transition with this input. - virtual void input(SMInput); - /// Activation status of a button. - virtual bool buttonStatus(Button button) const { - return button & outputs_[state_]; - } - /// Are we in a read-only state? - virtual bool isReadOnly() const { - return RO_INITIAL == state_ - || RO_VALID == state_ - || RO_INVALID == state_ - || RO_APPLIED == state_; - } -private: - /// Current state. - State state_; - /// Which buttons are active for a given state. - StateOutputs outputs_; - /// - StateMachine state_machine_; -}; - - -/** Ok, Apply and Cancel buttons for dialogs where repeated Apply is allowed. - Note: This scheme supports the relabelling of Cancel to Close - and vice versa. - This is based on the value of the bool state of the Button::CANCEL. - true == Cancel, false == Close - */ -class OkApplyCancelPolicy : public ButtonPolicy { -public: - /// - OkApplyCancelPolicy(); - /// - //virtual ~OkApplyCancelPolicy() {} - - /// Trigger a transition with this input. - virtual void input(SMInput); - /// Activation status of a button. - virtual bool buttonStatus(Button button) const { - return button & outputs_[state_]; - } - /// Are we in a read-only state? - virtual bool isReadOnly() const { - return false; - } -private: - /// Current state. - State state_; - /// Which buttons are active for a given state. - StateOutputs outputs_; - /// - StateMachine state_machine_; -}; - - -/** Ok, Apply and Cancel buttons for dialogs with no repeated Apply. - Note: This scheme supports the relabelling of Cancel to Close - and vice versa. - This is based on the value of the bool state of the Button::CANCEL. - true == Cancel, false == Close - */ -class NoRepeatedApplyPolicy : public ButtonPolicy { -public: - /// - NoRepeatedApplyPolicy(); - /// - //virtual ~NoRepeatedApplyPolicy() {} - - /// Trigger a transition with this input. - virtual void input(SMInput); - /// Activation status of a button. - virtual bool buttonStatus(Button button) const { - return button & outputs_[state_]; - } - /// Are we in a read-only state? - virtual bool isReadOnly() const { - return false; - } -private: - /// Current state. - State state_; - /// Which buttons are active for a given state. - StateOutputs outputs_; - /// - StateMachine state_machine_; -}; - - -/** Defines the policy used by the Preferences dialog. - Four buttons: Ok (Save), Apply, Cancel/Close, Restore. - Note: This scheme supports the relabelling of Cancel to Close - and vice versa. - This is based on the value of the bool state of the Button::CANCEL. - true == Cancel, false == Close - */ -class PreferencesPolicy : public ButtonPolicy { -public: - /// - PreferencesPolicy(); - /// - //virtual ~PreferencesPolicy() {} - - /// Trigger a transition with this input. - virtual void input(SMInput); - /// Activation status of a button. - virtual bool buttonStatus(Button button) const { - return button & outputs_[state_]; - } - /// Are we in a read-only state? - virtual bool isReadOnly() const { - return false; - } -private: - /// Current state. - State state_; - /// Which buttons are active for a given state. - StateOutputs outputs_; - /// - StateMachine state_machine_; -}; - - -/** Defines the policy used by dialogs that are forced to support a button - controller when they either don't have a use for one or are not ready to - use one. This may be useful when testing a new button policy but wishing - to minimise problems to users by supplying an anything-goes policy via a - preprocessor directive. - */ -class IgnorantPolicy : public ButtonPolicy { -public: - //virtual ~IgnorantPolicy() {} - - /// Trigger a transition with this input. - virtual void input(SMInput) {} - /// Activation status of a button. - virtual bool buttonStatus(Button) const { - return true; - } - /// Are we in a read-only state? - virtual bool isReadOnly() const { - return false; - } -}; - -} // namespace frontend -} // namespace lyx - -#endif diff --git a/src/frontends/controllers/ButtonPolicy.cpp b/src/frontends/controllers/ButtonPolicy.cpp new file mode 100644 index 0000000000..b76d636081 --- /dev/null +++ b/src/frontends/controllers/ButtonPolicy.cpp @@ -0,0 +1,633 @@ +/** + * \file ButtonPolicy.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Allan Rae + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "ButtonPolicy.h" +#include "debug.h" +#include + +using std::endl; +using std::string; + +namespace lyx { +namespace frontend { + +namespace { + +string const printState(ButtonPolicy::State const & state) +{ + string output; + + switch(state) { + case ButtonPolicy::INITIAL: + output = "INITIAL"; + break; + case ButtonPolicy::VALID: + output = "VALID"; + break; + case ButtonPolicy::INVALID: + output = "INVALID"; + break; + case ButtonPolicy::APPLIED: + output = "APPLIED"; + break; + case ButtonPolicy::RO_INITIAL: + output = "RO_INITIAL"; + break; + case ButtonPolicy::RO_VALID: + output = "RO_VALID"; + break; + case ButtonPolicy::RO_INVALID: + output = "RO_INVALID"; + break; + case ButtonPolicy::RO_APPLIED: + output = "RO_APPLIED"; + break; + case ButtonPolicy::BOGUS: + output = "BOGUS"; + break; + } + + return output; +} + + +string const printInput(ButtonPolicy::SMInput const & input) +{ + string output; + + switch (input) { + case ButtonPolicy::SMI_VALID: + output = "SMI_VALID"; + break; + case ButtonPolicy::SMI_INVALID: + output = "SMI_INVALID"; + break; + case ButtonPolicy::SMI_OKAY: + output = "SMI_OKAY"; + break; + case ButtonPolicy::SMI_APPLY: + output = "SMI_APPLY"; + break; + case ButtonPolicy::SMI_CANCEL: + output = "SMI_CANCEL"; + break; + case ButtonPolicy::SMI_RESTORE: + output = "SMI_RESTORE"; + break; + case ButtonPolicy::SMI_HIDE: + output = "SMI_HIDE"; + break; + case ButtonPolicy::SMI_READ_ONLY: + output = "SMI_READ_ONLY"; + break; + case ButtonPolicy::SMI_READ_WRITE: + output = "SMI_READ_WRITE"; + break; + case ButtonPolicy::SMI_NOOP: + output = "SMI_NOOP"; + break; + case ButtonPolicy::SMI_TOTAL: + output = "SMI_TOTAL"; + break; + } + + return output; +} + + +/// Helper function +void nextState(ButtonPolicy::State & state, + ButtonPolicy::SMInput in, + ButtonPolicy::StateMachine const & s_m, + char const * function_name = "nextState") +{ + if (ButtonPolicy::SMI_NOOP == in) return; + + ButtonPolicy::State tmp = s_m[state][in]; + + LYXERR(Debug::GUI) << "Transition from state " + << printState(state) << " to state " + << printState(tmp) << " after input " + << printInput(in) << std::endl; + + if (ButtonPolicy::BOGUS != tmp) { + state = tmp; + } else { + lyxerr << function_name + << ": No transition for input " + << printInput(in) + << " from state " + << printState(state) + << endl; + } +} + +} // namespace anon + + +/*-----------------------------PreferencesPolicy-----------------------------*/ + + +PreferencesPolicy::PreferencesPolicy() + : state_(INITIAL), + outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS), + state_machine_(APPLIED + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) +{ + // Build the state output map + outputs_[INITIAL] = CLOSE; + outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; + outputs_[INVALID] = RESTORE | CANCEL; + outputs_[APPLIED] = OKAY | CLOSE; + + // Build the state machine one state at a time + // NOTE: Since CANCEL and HIDE always go to INITIAL they are + // left out of the state machine and handled explicitly + // in input(). This won't necessarily be true for all + // policies though so I'll leave those two as distinct + // inputs rather than merge them. For example, a dialog + // that doesn't update it's input fields when reshown + // after being hidden needs a policy where CANCEL and + // HIDE are treated differently. + // + // State::INITIAL + state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL; + state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; + state_machine_[INITIAL][SMI_VALID] = VALID; + state_machine_[INITIAL][SMI_INVALID] = INVALID; + // State::VALID + state_machine_[VALID][SMI_VALID] = VALID; + state_machine_[VALID][SMI_READ_ONLY] = VALID; + state_machine_[VALID][SMI_READ_WRITE] = VALID; + state_machine_[VALID][SMI_INVALID] = INVALID; + state_machine_[VALID][SMI_APPLY] = APPLIED; + state_machine_[VALID][SMI_OKAY] = INITIAL; + state_machine_[VALID][SMI_RESTORE] = INITIAL; + // State::INVALID + state_machine_[INVALID][SMI_VALID] = VALID; + state_machine_[INVALID][SMI_INVALID] = INVALID; + state_machine_[INVALID][SMI_READ_ONLY] = INVALID; + state_machine_[INVALID][SMI_READ_WRITE] = INVALID; + state_machine_[INVALID][SMI_RESTORE] = INITIAL; + // State::APPLIED + state_machine_[APPLIED][SMI_VALID] = VALID; + state_machine_[APPLIED][SMI_INVALID] = INVALID; + state_machine_[APPLIED][SMI_OKAY] = INITIAL; + state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED; + state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED; +} + + +void PreferencesPolicy::input(SMInput input) +{ + // The APPLIED state is persistent. Next time the dialog is opened, + // the user will be able to press 'Save'. + if (SMI_CANCEL == input + || SMI_HIDE == input) { + if (state_ != APPLIED) + state_ = INITIAL; + } else { + nextState(state_, + input, + state_machine_, + "PreferencesPolicy"); + } +} + + +/*-------------------------------OkCancelPolicy------------------------------*/ + + +OkCancelPolicy::OkCancelPolicy() + : state_(INITIAL), + outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS), + state_machine_(INVALID + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) +{ + // Build the state output map + outputs_[INITIAL] = CLOSE; + outputs_[VALID] = RESTORE | OKAY | CANCEL; + outputs_[INVALID] = RESTORE | CANCEL; + + // Build the state machine one state at a time + // NOTE: Since CANCEL and HIDE always go to INITIAL they are + // left out of the state machine and handled explicitly + // in input() + // + // State::INITIAL + state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL; + state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; + state_machine_[INITIAL][SMI_VALID] = VALID; + state_machine_[INITIAL][SMI_INVALID] = INVALID; + // State::VALID + state_machine_[VALID][SMI_VALID] = VALID; + state_machine_[VALID][SMI_READ_ONLY] = VALID; + state_machine_[VALID][SMI_READ_WRITE] = VALID; + state_machine_[VALID][SMI_INVALID] = INVALID; + state_machine_[VALID][SMI_OKAY] = INITIAL; + state_machine_[VALID][SMI_RESTORE] = INITIAL; + // State::INVALID + state_machine_[INVALID][SMI_VALID] = VALID; + state_machine_[INVALID][SMI_INVALID] = INVALID; + state_machine_[INVALID][SMI_READ_ONLY] = INVALID; + state_machine_[INVALID][SMI_READ_WRITE] = INVALID; + state_machine_[INVALID][SMI_RESTORE] = INITIAL; +} + + + +void OkCancelPolicy::input(SMInput input) +{ + //lyxerr << "OkCancelPolicy::input" << endl; + + // CANCEL and HIDE always take us to INITIAL for all cases + if (SMI_CANCEL == input + || SMI_HIDE == input) { + state_ = INITIAL; + } else { + nextState(state_, input, state_machine_, "OkCancelPolicy"); + } +} + + +/*---------------------------OkCancelReadOnlyPolicy-------------------------*/ + + +OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy() + : state_(INITIAL), + outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS), + state_machine_(RO_INVALID + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) +{ + // Build the state output map + outputs_[INITIAL] = CLOSE; + outputs_[VALID] = RESTORE | OKAY | CANCEL; + outputs_[INVALID] = RESTORE | CANCEL; + outputs_[RO_INITIAL] = CLOSE; + outputs_[RO_VALID] = RESTORE | CANCEL; + outputs_[RO_INVALID] = RESTORE | CANCEL; + + // Build the state machine one state at a time + // NOTE: Since CANCEL and HIDE always go to INITIAL they are + // left out of the state machine and handled explicitly + // in input() + // + // State::INITIAL + state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; + state_machine_[INITIAL][SMI_VALID] = VALID; + state_machine_[INITIAL][SMI_INVALID] = INVALID; + state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL; + // State::VALID + state_machine_[VALID][SMI_VALID] = VALID; + state_machine_[VALID][SMI_READ_WRITE] = VALID; + state_machine_[VALID][SMI_INVALID] = INVALID; + state_machine_[VALID][SMI_OKAY] = INITIAL; + state_machine_[VALID][SMI_RESTORE] = INITIAL; + state_machine_[VALID][SMI_READ_ONLY] = RO_VALID; + // State::INVALID + state_machine_[INVALID][SMI_INVALID] = INVALID; + state_machine_[INVALID][SMI_READ_WRITE] = INVALID; + state_machine_[INVALID][SMI_VALID] = VALID; + state_machine_[INVALID][SMI_RESTORE] = INITIAL; + state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID; + // State::RO_INITIAL + state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL; + state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID; + state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID; + state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL; + // State::RO_VALID + state_machine_[RO_VALID][SMI_VALID] = RO_VALID; + state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID; + state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID; + state_machine_[RO_VALID][SMI_READ_WRITE] = VALID; + state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL; + // State::RO_INVALID + state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID; + state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID; + state_machine_[RO_INVALID][SMI_VALID] = RO_VALID; + state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID; + state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL; +} + + +void OkCancelReadOnlyPolicy::input(SMInput input) +{ + //lyxerr << "OkCancelReadOnlyPolicy::input" << endl; + + // CANCEL and HIDE always take us to INITIAL for all cases + if (SMI_CANCEL == input + || SMI_HIDE == input) { + state_ = INITIAL; + } else { + nextState(state_, + input, + state_machine_, + "OkCancelReadOnlyPolicy"); + } +} + + +/*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/ + + +NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy() + : state_(INITIAL), + outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS), + state_machine_(RO_INVALID + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) +{ + // Build the state output map + outputs_[INITIAL] = CLOSE; + outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; + outputs_[INVALID] = RESTORE | CANCEL; + outputs_[RO_INITIAL] = CLOSE; + outputs_[RO_VALID] = RESTORE | CANCEL; + outputs_[RO_INVALID] = RESTORE | CANCEL; + + // Build the state machine one state at a time + // NOTE: Since CANCEL and HIDE always go to INITIAL they are + // left out of the state machine and handled explicitly + // in input() + // + // State::INITIAL + state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; + state_machine_[INITIAL][SMI_VALID] = VALID; + state_machine_[INITIAL][SMI_INVALID] = INVALID; + state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL; + // State::VALID + state_machine_[VALID][SMI_VALID] = VALID; + state_machine_[VALID][SMI_READ_WRITE] = VALID; + state_machine_[VALID][SMI_INVALID] = INVALID; + state_machine_[VALID][SMI_OKAY] = INITIAL; + state_machine_[VALID][SMI_APPLY] = INITIAL; + state_machine_[VALID][SMI_RESTORE] = INITIAL; + state_machine_[VALID][SMI_READ_ONLY] = RO_VALID; + // State::INVALID + state_machine_[INVALID][SMI_INVALID] = INVALID; + state_machine_[INVALID][SMI_READ_WRITE] = INVALID; + state_machine_[INVALID][SMI_VALID] = VALID; + state_machine_[INVALID][SMI_RESTORE] = INITIAL; + state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID; + // State::RO_INITIAL + state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL; + state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID; + state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID; + state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL; + // State::RO_VALID + state_machine_[RO_VALID][SMI_VALID] = RO_VALID; + state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID; + state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID; + state_machine_[RO_VALID][SMI_READ_WRITE] = VALID; + state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL; + // State::RO_INVALID + state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID; + state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID; + state_machine_[RO_INVALID][SMI_VALID] = RO_VALID; + state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID; + state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL; +} + + +void NoRepeatedApplyReadOnlyPolicy::input(SMInput input) +{ + //lyxerr << "NoReapeatedApplyReadOnlyPolicy::input" << endl; + + // CANCEL and HIDE always take us to INITIAL for all cases + if (SMI_CANCEL == input + || SMI_HIDE == input) { + state_ = INITIAL; + } else { + nextState(state_, + input, + state_machine_, + "NoRepeatedApplyReadOnlyPolicy"); + } +} + + +/*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/ + + +OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy() + : state_(INITIAL), + outputs_(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS), + state_machine_(RO_APPLIED + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) +{ + // Build the state output map + outputs_[INITIAL] = CLOSE; + outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; + outputs_[INVALID] = RESTORE | CANCEL; + outputs_[APPLIED] = OKAY | APPLY | CLOSE; + outputs_[RO_INITIAL] = CLOSE; + outputs_[RO_VALID] = RESTORE | CANCEL; + outputs_[RO_INVALID] = RESTORE | CANCEL; + outputs_[RO_APPLIED] = CLOSE; + + // Build the state machine one state at a time + // NOTE: Since CANCEL and HIDE always go to INITIAL they are + // left out of the state machine and handled explicitly + // in input() + // + // State::INITIAL + state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; + state_machine_[INITIAL][SMI_VALID] = VALID; + state_machine_[INITIAL][SMI_INVALID] = INVALID; + state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL; + // State::VALID + state_machine_[VALID][SMI_VALID] = VALID; + state_machine_[VALID][SMI_READ_WRITE] = VALID; + state_machine_[VALID][SMI_INVALID] = INVALID; + state_machine_[VALID][SMI_OKAY] = INITIAL; + state_machine_[VALID][SMI_RESTORE] = INITIAL; + state_machine_[VALID][SMI_APPLY] = APPLIED; + state_machine_[VALID][SMI_READ_ONLY] = RO_VALID; + // State::INVALID + state_machine_[INVALID][SMI_INVALID] = INVALID; + state_machine_[INVALID][SMI_READ_WRITE] = INVALID; + state_machine_[INVALID][SMI_VALID] = VALID; + state_machine_[INVALID][SMI_RESTORE] = INITIAL; + state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID; + // State::APPLIED + state_machine_[APPLIED][SMI_APPLY] = APPLIED; + state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED; + state_machine_[APPLIED][SMI_VALID] = VALID; + state_machine_[APPLIED][SMI_INVALID] = INVALID; + state_machine_[APPLIED][SMI_OKAY] = INITIAL; + state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED; + // State::RO_INITIAL + state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL; + state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID; + state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID; + state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL; + // State::RO_VALID + state_machine_[RO_VALID][SMI_VALID] = RO_VALID; + state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID; + state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID; + state_machine_[RO_VALID][SMI_READ_WRITE] = VALID; + state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL; + // State::RO_INVALID + state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID; + state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID; + state_machine_[RO_INVALID][SMI_VALID] = RO_VALID; + state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID; + state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL; + // State::RO_APPLIED + state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED; + state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID; + state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID; + state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED; +} + + +void OkApplyCancelReadOnlyPolicy::input(SMInput input) +{ + //lyxerr << "OkApplyCancelReadOnlyPolicy::input" << endl; + + // CANCEL and HIDE always take us to INITIAL for all cases + if (SMI_CANCEL == input + || SMI_HIDE == input) { + state_ = INITIAL; + } else { + nextState(state_, + input, + state_machine_, + "OkApplyCancelReadOnlyPolicy"); + } +} + + +/*--------------------------OkApplyCancelPolicy----------------------*/ + + +OkApplyCancelPolicy::OkApplyCancelPolicy() + : state_(INITIAL), + outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS), + state_machine_(APPLIED + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) +{ + // Build the state output map + outputs_[INITIAL] = CLOSE; + outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; + outputs_[INVALID] = RESTORE | CANCEL; + outputs_[APPLIED] = OKAY | APPLY | CLOSE; + + // Build the state machine one state at a time + // NOTE: Since CANCEL and HIDE always go to INITIAL they are + // left out of the state machine and handled explicitly + // in input() + // + // State::INITIAL + state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL; + state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; + state_machine_[INITIAL][SMI_VALID] = VALID; + state_machine_[INITIAL][SMI_INVALID] = INVALID; + // State::VALID + state_machine_[VALID][SMI_VALID] = VALID; + state_machine_[VALID][SMI_READ_ONLY] = VALID; + state_machine_[VALID][SMI_READ_WRITE] = VALID; + state_machine_[VALID][SMI_INVALID] = INVALID; + state_machine_[VALID][SMI_OKAY] = INITIAL; + state_machine_[VALID][SMI_RESTORE] = INITIAL; + state_machine_[VALID][SMI_APPLY] = APPLIED; + // State::INVALID + state_machine_[INVALID][SMI_INVALID] = INVALID; + state_machine_[INVALID][SMI_READ_ONLY] = INVALID; + state_machine_[INVALID][SMI_READ_WRITE] = INVALID; + state_machine_[INVALID][SMI_VALID] = VALID; + state_machine_[INVALID][SMI_RESTORE] = INITIAL; + // State::APPLIED + state_machine_[APPLIED][SMI_APPLY] = APPLIED; + state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED; + state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED; + state_machine_[APPLIED][SMI_VALID] = VALID; + state_machine_[APPLIED][SMI_INVALID] = INVALID; + state_machine_[APPLIED][SMI_OKAY] = INITIAL; +} + + +void OkApplyCancelPolicy::input(SMInput input) +{ + //lyxerr << "OkApplyCancelPolicy::input" << endl; + + // CANCEL and HIDE always take us to INITIAL for all cases + if (SMI_CANCEL == input + || SMI_HIDE == input) { + state_ = INITIAL; + } else { + nextState(state_, + input, + state_machine_, + "OkApplyCancelPolicy"); + } +} + + +/*--------------------------NoRepeatedApplyPolicy----------------------*/ + + +NoRepeatedApplyPolicy::NoRepeatedApplyPolicy() + : state_(INITIAL), + outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS), + state_machine_(INVALID + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) +{ + // Build the state output map + outputs_[INITIAL] = CLOSE; + outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; + outputs_[INVALID] = RESTORE | CANCEL; + + // Build the state machine one state at a time + // NOTE: Since CANCEL and HIDE always go to INITIAL they are + // left out of the state machine and handled explicitly + // in input() + // + // State::INITIAL + state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL; + state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; + state_machine_[INITIAL][SMI_VALID] = VALID; + state_machine_[INITIAL][SMI_INVALID] = INVALID; + // State::VALID + state_machine_[VALID][SMI_VALID] = VALID; + state_machine_[VALID][SMI_READ_ONLY] = VALID; + state_machine_[VALID][SMI_READ_WRITE] = VALID; + state_machine_[VALID][SMI_INVALID] = INVALID; + state_machine_[VALID][SMI_OKAY] = INITIAL; + state_machine_[VALID][SMI_APPLY] = INITIAL; + state_machine_[VALID][SMI_RESTORE] = INITIAL; + // State::INVALID + state_machine_[INVALID][SMI_INVALID] = INVALID; + state_machine_[INVALID][SMI_READ_ONLY] = INVALID; + state_machine_[INVALID][SMI_READ_WRITE] = INVALID; + state_machine_[INVALID][SMI_VALID] = VALID; + state_machine_[INVALID][SMI_RESTORE] = INITIAL; +} + + +void NoRepeatedApplyPolicy::input(SMInput input) +{ + //lyxerr << "NoRepeatedApplyPolicy::input" << endl; + + // CANCEL and HIDE always take us to INITIAL for all cases + if (SMI_CANCEL == input + || SMI_HIDE == input) { + state_ = INITIAL; + } else { + nextState(state_, + input, + state_machine_, + "NoRepeatedApplyPolicy"); + } +} + +} // namespace frontend +} // namespace lyx diff --git a/src/frontends/controllers/ButtonPolicy.h b/src/frontends/controllers/ButtonPolicy.h new file mode 100644 index 0000000000..6591b85fb2 --- /dev/null +++ b/src/frontends/controllers/ButtonPolicy.h @@ -0,0 +1,474 @@ +// -*- C++ -*- +/** + * \file ButtonPolicy.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Allan Rae + * + * Full author contact details are available in file CREDITS. + * + * Provides a state machine implementation of the various button policies + * used by the dialogs. + */ + +#ifndef BUTTONPOLICY_H +#define BUTTONPOLICY_H + + +#include +#include + +#include "support/std_ostream.h" + +namespace lyx { +namespace frontend { + +/** An abstract base class for button policies. + A state machine implementation of the various button policies used by the + dialogs. Only the policy is implemented here. Separate ButtonController + classes are needed for each GUI implementation. + + Policy | ReadOnly | Apply Button | Repeated Apply + ======================================================================== + OkCancel | N | N | - + OkCancelReadOnly | Y | N | - + OkApplyCancel | N | Y | Y + OkApplyCancelReadOnly | Y | Y | Y + NoRepeatedApply | N | Y | N + NoRepeatedApplyReadOnly | Y | Y | N + Preferences | N | Y | No (Ok-Close) + Ignorant | N/A | N/A | N/A + ======================================================================== + + Policy + The name of the policy + ReadOnly + Does the policy treat read-only docs differently to read-write docs? + This usually means that when an SMI_READ_ONLY input arrives then + all the buttons are disabled except Cancel/Close. The state + machine tracks the inputs (valid/invalid) and has states for all + combinations. When an SMI_READ_WRITE input arrives the appropriate + machine state is entered (just as if the document had always been + read-write). + NOTE: If a dialog doesn't care about the read-only status of a document + (and uses an appropriate policy) it can never get into a read-only state + so isReadOnly() can only ever return false even though the document may + be read-only. + Repeated Apply + Simply means that it is alright to use the Apply button multiple times + without requiring a change of the dialog contents. If no repeating is + allowed the Ok+Apply buttons are deactivated. The Preferences dialog + has its own special version of repeated apply handling because its Ok + button is actually a Save button -- its always reasonable to Save the + preferences if the dialog has changed since the last save. + + The IgnorantPolicy is a special case that allows anything. + */ +class ButtonPolicy : boost::noncopyable { +public: + /// + virtual ~ButtonPolicy() {} + + /** The various possible state names. + Not all state-machines have this many states. However, we need + to define them all here so we can share the code. + */ + enum State { + /// + INITIAL = 0, + /// + VALID, + /// + INVALID, + /// + APPLIED, + /// + RO_INITIAL, + /// + RO_VALID, + /// + RO_INVALID, + /// + RO_APPLIED, + /// + BOGUS = 55 + }; + + /// The various button types. + enum Button { + /// + CLOSE = 0, // Not a real button, but effectively !CANCEL + /// + OKAY = 1, + /// + APPLY = 2, + /// + CANCEL = 4, + /// + RESTORE = 8 + }; + /// + static const Button ALL_BUTTONS = + Button(OKAY | APPLY | CANCEL | RESTORE); + + /** State machine inputs. + All the policies so far have both CANCEL and HIDE always going to + INITIAL. This won't necessarily be true for all [future] policies + though so I'll leave those two as distinct inputs rather than merge + them. For example, a dialog that doesn't update it's input fields + when reshown after being hidden needs a policy where CANCEL and + HIDE are treated differently. + */ + enum SMInput { + /// the dialog contents are now valid + SMI_VALID = 0, + /// the dialog contents are now invalid + SMI_INVALID, + /// an apply-and-hide action has happened + SMI_OKAY, + /// an apply action has happened + SMI_APPLY, + /// a cancel action has happened + SMI_CANCEL, + /// a restore action has happened + SMI_RESTORE, + /// the dialog has been hidden + SMI_HIDE, + /// the dialog contents are read-only + SMI_READ_ONLY, + /// the dialog contents can be modified + SMI_READ_WRITE, + /// the state of the dialog contents has not changed + SMI_NOOP, + /// for internal use + SMI_TOTAL + }; + + /// Trigger a transition with this input. + virtual void input(SMInput) = 0; + /// Activation status of a button + virtual bool buttonStatus(Button) const = 0; + /// Are we in a read-only state? + virtual bool isReadOnly() const = 0; + + /// Transition map of the state machine. + typedef std::vector StateArray; + /// + typedef std::vector StateMachine; + /// The state outputs are the status of the buttons. + typedef std::vector StateOutputs; +}; + + +inline +std::ostream & operator<<(std::ostream & os, ButtonPolicy::State st) +{ + os << int(st); + return os; +} + + +inline +std::ostream & operator<<(std::ostream & os, ButtonPolicy::SMInput smi) +{ + os << int(smi); + return os; +} + + +//--------------------- Actual Policy Classes ----------------------------- + +/** Ok and Cancel buttons for dialogs with read-only operation. + Note: This scheme supports the relabelling of Cancel to Close and + vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ +class OkCancelPolicy : public ButtonPolicy { +public: + /// + OkCancelPolicy(); + /// + //virtual ~OkCancelPolicy() {} + + /// Trigger a transition with this input. + virtual void input(SMInput); + /** Activation status of a button. + We assume that we haven't gotten into an undefined state. + This is reasonable since we can only reach states defined + in the state machine and they should all have been defined in + the outputs_ variable. Perhaps we can do something at compile + time to check that all the states have corresponding outputs. + */ + virtual bool buttonStatus(Button button) const { + return button & outputs_[state_]; + } + /// Are we in a read-only state? + virtual bool isReadOnly() const { + return false; + } +private: + /// Current state. + State state_; + /// Which buttons are active for a given state. + StateOutputs outputs_; + /// + StateMachine state_machine_; +}; + +/** Ok and Cancel buttons for dialogs where read-only operation is blocked. + The state machine design for this policy allows changes to occur within + the dialog while a file is read-only -- the okay button is disabled until + a read-write input is given. When the file is made read-write the dialog + will then be in the correct state (as if the file had always been + read-write). + Note: This scheme supports the relabelling of Cancel to Close + and vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ +class OkCancelReadOnlyPolicy : public ButtonPolicy { +public: + /// + OkCancelReadOnlyPolicy(); + /// + //virtual ~OkCancelReadOnlyPolicy() {} + + /// Trigger a transition with this input. + virtual void input(SMInput); + /// Activation status of a button. + virtual bool buttonStatus(Button button) const { + return button & outputs_[state_]; + } + /// Are we in a read-only state? + virtual bool isReadOnly() const { + return RO_INITIAL == state_ + || RO_VALID == state_ + || RO_INVALID == state_ + || RO_APPLIED == state_; + } +private: + /// Current state. + State state_; + /// Which buttons are active for a given state. + StateOutputs outputs_; + /// + StateMachine state_machine_; +}; + + +/** Ok, Apply and Cancel buttons for dialogs where read-only operation + is blocked. + Repeated Apply are not allowed. Likewise, Ok cannot follow Apply without + some valid input. That is, the dialog contents must change between + each Apply or Apply and Ok. + The state machine design for this policy allows changes to occur within + the dialog while a file is read-only -- the Ok+Apply buttons are disabled + until a read-write input is given. When the file is made read-write the + dialog will then be in the correct state (as if the file had always been + read-write). + Note: This scheme supports the relabelling of Cancel to Close + and vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ +class NoRepeatedApplyReadOnlyPolicy : public ButtonPolicy { +public: + /// + NoRepeatedApplyReadOnlyPolicy(); + /// + //virtual ~NoRepeatedApplyReadOnlyPolicy() {} + + /// Trigger a transition with this input. + virtual void input(SMInput); + /// Activation status of a button. + virtual bool buttonStatus(Button button) const { + return button & outputs_[state_]; + } + /// Are we in a read-only state? + virtual bool isReadOnly() const { + return RO_INITIAL == state_ + || RO_VALID == state_ + || RO_INVALID == state_ + || RO_APPLIED == state_; + } +private: + /// Current state. + State state_; + /// Which buttons are active for a given state. + StateOutputs outputs_; + /// + StateMachine state_machine_; +}; + + +/** Ok, Apply and Cancel buttons for dialogs where read-only + operation is blocked. + Repeated Apply is allowed. Likewise, Ok can follow Apply. + The state machine design for this policy allows changes to occur within + the dialog while a file is read-only -- the Ok+Apply buttons are disabled + until a read-write input is given. When the file is made read-write the + dialog will then be in the correct state (as if the file had always been + read-write). + Note: This scheme supports the relabelling of Cancel to Close + and vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ +class OkApplyCancelReadOnlyPolicy : public ButtonPolicy { +public: + /// + OkApplyCancelReadOnlyPolicy(); + /// + //virtual ~OkApplyCancelReadOnlyPolicy() {} + + /// Trigger a transition with this input. + virtual void input(SMInput); + /// Activation status of a button. + virtual bool buttonStatus(Button button) const { + return button & outputs_[state_]; + } + /// Are we in a read-only state? + virtual bool isReadOnly() const { + return RO_INITIAL == state_ + || RO_VALID == state_ + || RO_INVALID == state_ + || RO_APPLIED == state_; + } +private: + /// Current state. + State state_; + /// Which buttons are active for a given state. + StateOutputs outputs_; + /// + StateMachine state_machine_; +}; + + +/** Ok, Apply and Cancel buttons for dialogs where repeated Apply is allowed. + Note: This scheme supports the relabelling of Cancel to Close + and vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ +class OkApplyCancelPolicy : public ButtonPolicy { +public: + /// + OkApplyCancelPolicy(); + /// + //virtual ~OkApplyCancelPolicy() {} + + /// Trigger a transition with this input. + virtual void input(SMInput); + /// Activation status of a button. + virtual bool buttonStatus(Button button) const { + return button & outputs_[state_]; + } + /// Are we in a read-only state? + virtual bool isReadOnly() const { + return false; + } +private: + /// Current state. + State state_; + /// Which buttons are active for a given state. + StateOutputs outputs_; + /// + StateMachine state_machine_; +}; + + +/** Ok, Apply and Cancel buttons for dialogs with no repeated Apply. + Note: This scheme supports the relabelling of Cancel to Close + and vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ +class NoRepeatedApplyPolicy : public ButtonPolicy { +public: + /// + NoRepeatedApplyPolicy(); + /// + //virtual ~NoRepeatedApplyPolicy() {} + + /// Trigger a transition with this input. + virtual void input(SMInput); + /// Activation status of a button. + virtual bool buttonStatus(Button button) const { + return button & outputs_[state_]; + } + /// Are we in a read-only state? + virtual bool isReadOnly() const { + return false; + } +private: + /// Current state. + State state_; + /// Which buttons are active for a given state. + StateOutputs outputs_; + /// + StateMachine state_machine_; +}; + + +/** Defines the policy used by the Preferences dialog. + Four buttons: Ok (Save), Apply, Cancel/Close, Restore. + Note: This scheme supports the relabelling of Cancel to Close + and vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ +class PreferencesPolicy : public ButtonPolicy { +public: + /// + PreferencesPolicy(); + /// + //virtual ~PreferencesPolicy() {} + + /// Trigger a transition with this input. + virtual void input(SMInput); + /// Activation status of a button. + virtual bool buttonStatus(Button button) const { + return button & outputs_[state_]; + } + /// Are we in a read-only state? + virtual bool isReadOnly() const { + return false; + } +private: + /// Current state. + State state_; + /// Which buttons are active for a given state. + StateOutputs outputs_; + /// + StateMachine state_machine_; +}; + + +/** Defines the policy used by dialogs that are forced to support a button + controller when they either don't have a use for one or are not ready to + use one. This may be useful when testing a new button policy but wishing + to minimise problems to users by supplying an anything-goes policy via a + preprocessor directive. + */ +class IgnorantPolicy : public ButtonPolicy { +public: + //virtual ~IgnorantPolicy() {} + + /// Trigger a transition with this input. + virtual void input(SMInput) {} + /// Activation status of a button. + virtual bool buttonStatus(Button) const { + return true; + } + /// Are we in a read-only state? + virtual bool isReadOnly() const { + return false; + } +}; + +} // namespace frontend +} // namespace lyx + +#endif diff --git a/src/frontends/controllers/ControlSpellchecker.cpp b/src/frontends/controllers/ControlSpellchecker.cpp index ac9f063a3f..e62bb01959 100644 --- a/src/frontends/controllers/ControlSpellchecker.cpp +++ b/src/frontends/controllers/ControlSpellchecker.cpp @@ -39,7 +39,7 @@ #include "support/convert.h" #include "support/docstring.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" // FIXME: those two headers are needed because of the // WorkArea::redraw() call below. #include "frontends/LyXView.h" diff --git a/src/frontends/controllers/Makefile.am b/src/frontends/controllers/Makefile.am index 67e4395b11..563e2b298e 100644 --- a/src/frontends/controllers/Makefile.am +++ b/src/frontends/controllers/Makefile.am @@ -19,8 +19,8 @@ libcontrollers_la_SOURCES= \ BCView.cpp \ ButtonController.cpp \ ButtonController.h \ - ButtonPolicies.cpp \ - ButtonPolicies.h \ + ButtonPolicy.cpp \ + ButtonPolicy.h \ ControlAboutlyx.cpp \ ControlAboutlyx.h \ ControlBibtex.cpp \ diff --git a/src/frontends/controllers/frontend_helpers.cpp b/src/frontends/controllers/frontend_helpers.cpp index 4acc4acf29..7708e9d1f5 100644 --- a/src/frontends/controllers/frontend_helpers.cpp +++ b/src/frontends/controllers/frontend_helpers.cpp @@ -28,7 +28,7 @@ #include "Color.h" #include "frontends/FileDialog.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "support/filetools.h" #include "support/lstrings.h" #include "support/Package.h" diff --git a/src/frontends/qt4/Action.cpp b/src/frontends/qt4/Action.cpp index bbca50deb1..2cbe3d8e58 100644 --- a/src/frontends/qt4/Action.cpp +++ b/src/frontends/qt4/Action.cpp @@ -15,7 +15,7 @@ #include "GuiView.h" #include "qt_helpers.h" -#include "lyx_cb.h" +#include "callback.h" #include "LyXFunc.h" #include "FuncStatus.h" #include "debug.h" diff --git a/src/frontends/qt4/Alert_pimpl.cpp b/src/frontends/qt4/Alert_pimpl.cpp deleted file mode 100644 index 6bf50fc152..0000000000 --- a/src/frontends/qt4/Alert_pimpl.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/** - * \file qt4/Alert_pimpl.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author John Levon - * \author Abdelrazak Younes - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "Alert_pimpl.h" -#include "Alert.h" - -#include "ui/AskForTextUi.h" -#include "qt_helpers.h" - -#include "frontends/Application.h" - -#include "gettext.h" - -#include -#include -#include -#include -#include -#include - -#include - -using std::pair; -using std::make_pair; -using lyx::support::bformat; - -namespace lyx { - -namespace { - -class MessageBox: public QMessageBox -{ -public: - MessageBox(QWidget * parent = 0) : QMessageBox(parent) - { - setAttribute(Qt::WA_DeleteOnClose, true); - setAttribute(Qt::WA_QuitOnClose, false); - } -}; - -} // anonymous namespace - - -int prompt_pimpl(docstring const & tit, docstring const & question, - int default_button, int cancel_button, - docstring const & b1, docstring const & b2, docstring const & b3) -{ - docstring const title = bformat(_("LyX: %1$s"), tit); - - MessageBox mb; - - // For some reason, sometimes Qt uses an hourglass or watch cursor when - // displaying the alert. Hence, we ask for the standard cursor shape. - // This call has no effect if the cursor has not been overridden. - qApp->changeOverrideCursor(Qt::ArrowCursor); - - // FIXME replace that with theApp->gui()->currentView() - int res = mb.information(qApp->focusWidget(), - toqstr(title), - toqstr(formatted(question)), - toqstr(b1), - toqstr(b2), - b3.empty() ? QString::null : toqstr(b3), - default_button, cancel_button); - - // Qt bug: can return -1 on cancel or WM close, despite the docs. - if (res == -1) - res = cancel_button; - return res; -} - - -void warning_pimpl(docstring const & tit, docstring const & message) -{ - docstring const title = bformat(_("LyX: %1$s"), tit); - - if (theApp() == 0) { - int argc = 1; - char * argv[1]; - QApplication app(argc, argv); - QMessageBox::warning(0, - toqstr(title), - toqstr(formatted(message))); - return; - } - MessageBox mb; - mb.warning(qApp->focusWidget(), - toqstr(title), - toqstr(formatted(message))); -} - - -void error_pimpl(docstring const & tit, docstring const & message) -{ - docstring const title = bformat(_("LyX: %1$s"), tit); - if (theApp() == 0) { - int argc = 1; - char * argv[1]; - QApplication app(argc, argv); - QMessageBox::critical(0, - toqstr(title), - toqstr(formatted(message))); - return; - } - MessageBox mb; - mb.critical(qApp->focusWidget(), - toqstr(title), - toqstr(formatted(message))); -} - - -void information_pimpl(docstring const & tit, docstring const & message) -{ - docstring const title = bformat(_("LyX: %1$s"), tit); - MessageBox mb; - mb.information(qApp->focusWidget(), - toqstr(title), - toqstr(formatted(message))); -} - - -pair const -askForText_pimpl(docstring const & msg, docstring const & dflt) -{ - docstring const title = bformat(_("LyX: %1$s"), msg); - - bool ok; - QString text = QInputDialog::getText(qApp->focusWidget(), - toqstr(title), - toqstr(char_type('&') + msg), - QLineEdit::Normal, - toqstr(dflt), &ok); - - if (ok && !text.isEmpty()) - return make_pair(true, qstring_to_ucs4(text)); - else - return make_pair(false, docstring()); -} - - -} // namespace lyx diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index d0b6771b34..bb7c89e747 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -35,7 +35,7 @@ #include "BufferList.h" #include "debug.h" #include "FuncRequest.h" -#include "lyx_cb.h" +#include "callback.h" #include "LyXRC.h" #include "LyX.h" #include "Session.h" diff --git a/src/frontends/qt4/Makefile.am b/src/frontends/qt4/Makefile.am index 092d2968fb..8af7fafb56 100644 --- a/src/frontends/qt4/Makefile.am +++ b/src/frontends/qt4/Makefile.am @@ -30,7 +30,7 @@ AM_CPPFLAGS += \ -I$(top_srcdir)/src/frontends/controllers libqt4_la_SOURCES = \ - Alert_pimpl.cpp \ + alert_pimpl.cpp \ ColorCache.h ColorCache.cpp \ DockView.h \ Dialogs.cpp \ diff --git a/src/frontends/qt4/QBibtex.cpp b/src/frontends/qt4/QBibtex.cpp index 8fa5eb9e4f..bb85f9c45a 100644 --- a/src/frontends/qt4/QBibtex.cpp +++ b/src/frontends/qt4/QBibtex.cpp @@ -22,7 +22,7 @@ #include "CheckedLineEdit.h" #include "controllers/ControlBibtex.h" -#include "controllers/ButtonPolicies.h" +#include "controllers/ButtonPolicy.h" #include "controllers/ControlBibtex.h" diff --git a/src/frontends/qt4/QPrefs.cpp b/src/frontends/qt4/QPrefs.cpp index 3ebc19e20b..f08c2dd61c 100644 --- a/src/frontends/qt4/QPrefs.cpp +++ b/src/frontends/qt4/QPrefs.cpp @@ -30,7 +30,7 @@ #include "controllers/ControlPrefs.h" #include "controllers/frontend_helpers.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "frontends/Application.h" #include diff --git a/src/frontends/qt4/Validator.cpp b/src/frontends/qt4/Validator.cpp index b73e06ef2e..e8e393a689 100644 --- a/src/frontends/qt4/Validator.cpp +++ b/src/frontends/qt4/Validator.cpp @@ -18,7 +18,7 @@ #include "gettext.h" #include "LyXRC.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "frontends/controllers/Dialog.h" diff --git a/src/frontends/qt4/alert_pimpl.cpp b/src/frontends/qt4/alert_pimpl.cpp new file mode 100644 index 0000000000..dbc9f77640 --- /dev/null +++ b/src/frontends/qt4/alert_pimpl.cpp @@ -0,0 +1,151 @@ +/** + * \file qt4/alert_pimpl.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author John Levon + * \author Abdelrazak Younes + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "Alert_pimpl.h" +#include "alert.h" + +#include "ui/AskForTextUi.h" +#include "qt_helpers.h" + +#include "frontends/Application.h" + +#include "gettext.h" + +#include +#include +#include +#include +#include +#include + +#include + +using std::pair; +using std::make_pair; +using lyx::support::bformat; + +namespace lyx { + +namespace { + +class MessageBox: public QMessageBox +{ +public: + MessageBox(QWidget * parent = 0) : QMessageBox(parent) + { + setAttribute(Qt::WA_DeleteOnClose, true); + setAttribute(Qt::WA_QuitOnClose, false); + } +}; + +} // anonymous namespace + + +int prompt_pimpl(docstring const & tit, docstring const & question, + int default_button, int cancel_button, + docstring const & b1, docstring const & b2, docstring const & b3) +{ + docstring const title = bformat(_("LyX: %1$s"), tit); + + MessageBox mb; + + // For some reason, sometimes Qt uses an hourglass or watch cursor when + // displaying the alert. Hence, we ask for the standard cursor shape. + // This call has no effect if the cursor has not been overridden. + qApp->changeOverrideCursor(Qt::ArrowCursor); + + // FIXME replace that with theApp->gui()->currentView() + int res = mb.information(qApp->focusWidget(), + toqstr(title), + toqstr(formatted(question)), + toqstr(b1), + toqstr(b2), + b3.empty() ? QString::null : toqstr(b3), + default_button, cancel_button); + + // Qt bug: can return -1 on cancel or WM close, despite the docs. + if (res == -1) + res = cancel_button; + return res; +} + + +void warning_pimpl(docstring const & tit, docstring const & message) +{ + docstring const title = bformat(_("LyX: %1$s"), tit); + + if (theApp() == 0) { + int argc = 1; + char * argv[1]; + QApplication app(argc, argv); + QMessageBox::warning(0, + toqstr(title), + toqstr(formatted(message))); + return; + } + MessageBox mb; + mb.warning(qApp->focusWidget(), + toqstr(title), + toqstr(formatted(message))); +} + + +void error_pimpl(docstring const & tit, docstring const & message) +{ + docstring const title = bformat(_("LyX: %1$s"), tit); + if (theApp() == 0) { + int argc = 1; + char * argv[1]; + QApplication app(argc, argv); + QMessageBox::critical(0, + toqstr(title), + toqstr(formatted(message))); + return; + } + MessageBox mb; + mb.critical(qApp->focusWidget(), + toqstr(title), + toqstr(formatted(message))); +} + + +void information_pimpl(docstring const & tit, docstring const & message) +{ + docstring const title = bformat(_("LyX: %1$s"), tit); + MessageBox mb; + mb.information(qApp->focusWidget(), + toqstr(title), + toqstr(formatted(message))); +} + + +pair const +askForText_pimpl(docstring const & msg, docstring const & dflt) +{ + docstring const title = bformat(_("LyX: %1$s"), msg); + + bool ok; + QString text = QInputDialog::getText(qApp->focusWidget(), + toqstr(title), + toqstr(char_type('&') + msg), + QLineEdit::Normal, + toqstr(dflt), &ok); + + if (ok && !text.isEmpty()) + return make_pair(true, qstring_to_ucs4(text)); + else + return make_pair(false, docstring()); +} + + +} // namespace lyx diff --git a/src/insets/InsetBibtex.cpp b/src/insets/InsetBibtex.cpp index a92e44590a..9bd9f1d79d 100644 --- a/src/insets/InsetBibtex.cpp +++ b/src/insets/InsetBibtex.cpp @@ -23,7 +23,7 @@ #include "MetricsInfo.h" #include "OutputParams.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "support/filetools.h" #include "support/lstrings.h" diff --git a/src/insets/InsetERT.cpp b/src/insets/InsetERT.cpp index f87b1c7b35..8ca6a4511a 100644 --- a/src/insets/InsetERT.cpp +++ b/src/insets/InsetERT.cpp @@ -31,7 +31,7 @@ #include "ParagraphParameters.h" #include "Paragraph.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include diff --git a/src/insets/InsetEnv.cpp b/src/insets/InsetEnv.cpp deleted file mode 100644 index 01f4aed774..0000000000 --- a/src/insets/InsetEnv.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/** - * \file InsetEnv.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author André Pönitz - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "InsetEnv.h" - -#include "BufferParams.h" -#include "gettext.h" -#include "Paragraph.h" -#include "OutputParams.h" -#include "output_latex.h" -#include "TexRow.h" - - -namespace lyx { - -using std::string; -using std::auto_ptr; -using std::ostream; - - -InsetEnvironment::InsetEnvironment - (BufferParams const & bp, string const & name) - : InsetText(bp), layout_(bp.getLyXTextClass()[name]) -{ - setInsetName(from_utf8(name)); - setAutoBreakRows(true); - setDrawFrame(true); -} - - -InsetEnvironment::InsetEnvironment(InsetEnvironment const & in) - : InsetText(in), layout_(in.layout_) -{} - - -auto_ptr InsetEnvironment::doClone() const -{ - return auto_ptr(new InsetEnvironment(*this)); -} - - -void InsetEnvironment::write(Buffer const & buf, ostream & os) const -{ - os << "Environment " << to_utf8(getInsetName()) << "\n"; - InsetText::write(buf, os); -} - - -void InsetEnvironment::read(Buffer const & buf, Lexer & lex) -{ - InsetText::read(buf, lex); -} - - -docstring const InsetEnvironment::editMessage() const -{ - return _("Opened Environment Inset: ") + getInsetName(); -} - - -int InsetEnvironment::latex(Buffer const & buf, odocstream & os, - OutputParams const & runparams) const -{ - // FIXME UNICODE - os << from_utf8(layout_->latexheader); - TexRow texrow; - latexParagraphs(buf, paragraphs(), os, texrow, runparams, - layout_->latexparagraph); - // FIXME UNICODE - os << from_utf8(layout_->latexfooter); - return texrow.rows(); -} - - -int InsetEnvironment::plaintext(Buffer const & buf, odocstream & os, - OutputParams const & runparams) const -{ - os << '[' << to_utf8(getInsetName()) << ":\n"; - InsetText::plaintext(buf, os, runparams); - os << "\n]"; - - return PLAINTEXT_NEWLINE + 1; // one char on a separate line -} - - -LyXLayout_ptr const & InsetEnvironment::layout() const -{ - return layout_; -} - - -} // namespace lyx diff --git a/src/insets/InsetEnv.h b/src/insets/InsetEnv.h deleted file mode 100644 index 8084c90a89..0000000000 --- a/src/insets/InsetEnv.h +++ /dev/null @@ -1,58 +0,0 @@ -// -*- C++ -*- -/** - * \file InsetEnv.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author André Pönitz - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef INSETENVIRONMENT_H -#define INSETENVIRONMENT_H - -#include "InsetText.h" -#include "lyxlayout_ptr_fwd.h" - - -namespace lyx { - -class InsetEnvironment : public InsetText { -public: - /// - InsetEnvironment(BufferParams const &, std::string const & name); - /// - void write(Buffer const & buf, std::ostream & os) const; - /// - void read(Buffer const & buf, Lexer & lex); - /// - InsetBase::Code lyxCode() const { return InsetBase::ENVIRONMENT_CODE; } - /// - int latex(Buffer const &, odocstream &, - OutputParams const &) const; - /// - int plaintext(Buffer const &, odocstream &, - OutputParams const &) const; - /// - virtual docstring const editMessage() const; - /// - InsetBase::EDITABLE editable() const { return HIGHLY_EDITABLE; } - /// - LyXLayout_ptr const & layout() const; - /** returns true if, when outputing LaTeX, font changes should - be closed before generating this inset. This is needed for - insets that may contain several paragraphs */ - bool noFontChange() const { return true; } -protected: - InsetEnvironment(InsetEnvironment const &); -private: - virtual std::auto_ptr doClone() const; - /// the layout - LyXLayout_ptr layout_; -}; - - -} // namespace lyx - -#endif diff --git a/src/insets/InsetEnvironment.cpp b/src/insets/InsetEnvironment.cpp new file mode 100644 index 0000000000..01015f74f1 --- /dev/null +++ b/src/insets/InsetEnvironment.cpp @@ -0,0 +1,101 @@ +/** + * \file InsetEnvironment.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author André Pönitz + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "InsetEnvironment.h" + +#include "BufferParams.h" +#include "gettext.h" +#include "Paragraph.h" +#include "OutputParams.h" +#include "output_latex.h" +#include "TexRow.h" + + +namespace lyx { + +using std::string; +using std::auto_ptr; +using std::ostream; + + +InsetEnvironment::InsetEnvironment + (BufferParams const & bp, string const & name) + : InsetText(bp), layout_(bp.getLyXTextClass()[name]) +{ + setInsetName(from_utf8(name)); + setAutoBreakRows(true); + setDrawFrame(true); +} + + +InsetEnvironment::InsetEnvironment(InsetEnvironment const & in) + : InsetText(in), layout_(in.layout_) +{} + + +auto_ptr InsetEnvironment::doClone() const +{ + return auto_ptr(new InsetEnvironment(*this)); +} + + +void InsetEnvironment::write(Buffer const & buf, ostream & os) const +{ + os << "Environment " << to_utf8(getInsetName()) << "\n"; + InsetText::write(buf, os); +} + + +void InsetEnvironment::read(Buffer const & buf, Lexer & lex) +{ + InsetText::read(buf, lex); +} + + +docstring const InsetEnvironment::editMessage() const +{ + return _("Opened Environment Inset: ") + getInsetName(); +} + + +int InsetEnvironment::latex(Buffer const & buf, odocstream & os, + OutputParams const & runparams) const +{ + // FIXME UNICODE + os << from_utf8(layout_->latexheader); + TexRow texrow; + latexParagraphs(buf, paragraphs(), os, texrow, runparams, + layout_->latexparagraph); + // FIXME UNICODE + os << from_utf8(layout_->latexfooter); + return texrow.rows(); +} + + +int InsetEnvironment::plaintext(Buffer const & buf, odocstream & os, + OutputParams const & runparams) const +{ + os << '[' << to_utf8(getInsetName()) << ":\n"; + InsetText::plaintext(buf, os, runparams); + os << "\n]"; + + return PLAINTEXT_NEWLINE + 1; // one char on a separate line +} + + +LyXLayout_ptr const & InsetEnvironment::layout() const +{ + return layout_; +} + + +} // namespace lyx diff --git a/src/insets/InsetEnvironment.h b/src/insets/InsetEnvironment.h new file mode 100644 index 0000000000..5564f3ab6d --- /dev/null +++ b/src/insets/InsetEnvironment.h @@ -0,0 +1,58 @@ +// -*- C++ -*- +/** + * \file InsetEnvironment.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author André Pönitz + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef INSETENVIRONMENT_H +#define INSETENVIRONMENT_H + +#include "InsetText.h" +#include "lyxlayout_ptr_fwd.h" + + +namespace lyx { + +class InsetEnvironment : public InsetText { +public: + /// + InsetEnvironment(BufferParams const &, std::string const & name); + /// + void write(Buffer const & buf, std::ostream & os) const; + /// + void read(Buffer const & buf, Lexer & lex); + /// + InsetBase::Code lyxCode() const { return InsetBase::ENVIRONMENT_CODE; } + /// + int latex(Buffer const &, odocstream &, + OutputParams const &) const; + /// + int plaintext(Buffer const &, odocstream &, + OutputParams const &) const; + /// + virtual docstring const editMessage() const; + /// + InsetBase::EDITABLE editable() const { return HIGHLY_EDITABLE; } + /// + LyXLayout_ptr const & layout() const; + /** returns true if, when outputing LaTeX, font changes should + be closed before generating this inset. This is needed for + insets that may contain several paragraphs */ + bool noFontChange() const { return true; } +protected: + InsetEnvironment(InsetEnvironment const &); +private: + virtual std::auto_ptr doClone() const; + /// the layout + LyXLayout_ptr layout_; +}; + + +} // namespace lyx + +#endif diff --git a/src/insets/InsetGraphics.cpp b/src/insets/InsetGraphics.cpp index d921b12a76..d44fa89c2f 100644 --- a/src/insets/InsetGraphics.cpp +++ b/src/insets/InsetGraphics.cpp @@ -71,7 +71,7 @@ TODO #include "OutputParams.h" #include "sgml.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "support/convert.h" #include "support/filetools.h" diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp index 51f9143cd8..f0d497adbb 100644 --- a/src/insets/InsetInclude.cpp +++ b/src/insets/InsetInclude.cpp @@ -32,7 +32,7 @@ #include "OutputParams.h" #include "TocBackend.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "frontends/Painter.h" #include "graphics/PreviewImage.h" diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index adb374719b..40f74627e7 100644 --- a/src/insets/InsetTabular.cpp +++ b/src/insets/InsetTabular.cpp @@ -34,7 +34,7 @@ #include "Language.h" #include "LaTeXFeatures.h" #include "Color.h" -#include "lyx_cb.h" +#include "callback.h" #include "Lexer.h" #include "MetricsInfo.h" #include "OutputParams.h" @@ -46,7 +46,7 @@ #include "support/convert.h" #include "support/lstrings.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "frontends/Clipboard.h" #include "frontends/Painter.h" #include "frontends/Selection.h" diff --git a/src/insets/InsetText.cpp b/src/insets/InsetText.cpp index f9b90bc682..977d5289ff 100644 --- a/src/insets/InsetText.cpp +++ b/src/insets/InsetText.cpp @@ -44,7 +44,7 @@ #include "TexRow.h" #include "Undo.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "frontends/Painter.h" #include "support/lyxalgo.h" // count diff --git a/src/insets/Makefile.am b/src/insets/Makefile.am index aab94712b1..ea03ac15a4 100644 --- a/src/insets/Makefile.am +++ b/src/insets/Makefile.am @@ -51,8 +51,8 @@ libinsets_la_SOURCES = \ InsetCommand.h \ InsetCommandParams.cpp \ InsetCommandParams.h \ - InsetEnv.cpp \ - InsetEnv.h \ + InsetEnvironment.cpp \ + InsetEnvironment.h \ InsetERT.cpp \ InsetERT.h \ InsetExternal.cpp \ diff --git a/src/lyx_cb.cpp b/src/lyx_cb.cpp deleted file mode 100644 index 447498316b..0000000000 --- a/src/lyx_cb.cpp +++ /dev/null @@ -1,432 +0,0 @@ -/** - * \file lyx_cb.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Lars Gullik Bjønnes - * \author Angus Leeming - * \author John Levon - * \author André Pönitz - * \author Jürgen Vigna - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "lyx_cb.h" - -#include "Buffer.h" -#include "BufferList.h" -#include "BufferView.h" -#include "buffer_funcs.h" -#include "Cursor.h" -#include "CutAndPaste.h" -#include "debug.h" -#include "gettext.h" -#include "Session.h" -#include "LaTeXFeatures.h" -#include "LyX.h" -#include "LyXLayout.h" -#include "LyXRC.h" -#include "LyXText.h" -#include "Paragraph.h" -#include "Undo.h" - -#include "frontends/Alert.h" -#include "frontends/Application.h" -#include "frontends/FileDialog.h" -#include "frontends/LyXView.h" - -#include "support/FileFilterList.h" -#include "support/filetools.h" -#include "support/Forkedcall.h" -#include "support/fs_extras.h" -#include "support/lyxlib.h" -#include "support/Package.h" -#include "support/Path.h" -#include "support/Systemcall.h" - -#if !defined (HAVE_FORK) -# define fork() -1 -#endif - -#include -#include - -#include -#include - - -namespace lyx { - -using support::bformat; -using support::FileFilterList; -using support::FileName; -using support::ForkedProcess; -using support::isLyXFilename; -using support::libFileSearch; -using support::makeAbsPath; -using support::makeDisplayPath; -using support::onlyFilename; -using support::onlyPath; -using support::package; -using support::removeAutosaveFile; -using support::rename; -using support::split; -using support::Systemcall; -using support::tempName; -using support::unlink; - -using boost::shared_ptr; - -namespace Alert = frontend::Alert; -namespace fs = boost::filesystem; - -using std::back_inserter; -using std::copy; -using std::endl; -using std::make_pair; -using std::string; -using std::ifstream; -using std::ios; -using std::istream_iterator; - - -// this should be static, but I need it in Buffer.cpp -bool quitting; // flag, that we are quitting the program - -// -// Menu callbacks -// - -bool menuWrite(Buffer * buffer) -{ - if (buffer->save()) { - LyX::ref().session().lastFiles().add(FileName(buffer->fileName())); - return true; - } - - // FIXME: we don't tell the user *WHY* the save failed !! - - docstring const file = makeDisplayPath(buffer->fileName(), 30); - - docstring text = bformat(_("The document %1$s could not be saved.\n\n" - "Do you want to rename the document and try again?"), file); - int const ret = Alert::prompt(_("Rename and save?"), - text, 0, 1, _("&Rename"), _("&Cancel")); - - if (ret == 0) - return writeAs(buffer); - return false; -} - - - -bool writeAs(Buffer * buffer, string const & newname) -{ - string fname = buffer->fileName(); - string const oldname = fname; - - if (newname.empty()) { - - // FIXME UNICODE - FileDialog fileDlg(_("Choose a filename to save document as"), - LFUN_BUFFER_WRITE_AS, - make_pair(_("Documents|#o#O"), from_utf8(lyxrc.document_path)), - make_pair(_("Templates|#T#t"), from_utf8(lyxrc.template_path))); - - if (!isLyXFilename(fname)) - fname += ".lyx"; - - FileFilterList const filter (_("LyX Documents (*.lyx)")); - - FileDialog::Result result = - fileDlg.save(from_utf8(onlyPath(fname)), - filter, - from_utf8(onlyFilename(fname))); - - if (result.first == FileDialog::Later) - return false; - - fname = to_utf8(result.second); - - if (fname.empty()) - return false; - - // Make sure the absolute filename ends with appropriate suffix - fname = makeAbsPath(fname).absFilename(); - if (!isLyXFilename(fname)) - fname += ".lyx"; - } else - fname = newname; - - FileName const filename(fname); - if (fs::exists(filename.toFilesystemEncoding())) { - docstring const file = makeDisplayPath(fname, 30); - docstring text = bformat(_("The document %1$s already exists.\n\n" - "Do you want to over-write that document?"), file); - int const ret = Alert::prompt(_("Over-write document?"), - text, 0, 1, _("&Over-write"), _("&Cancel")); - - if (ret == 1) - return false; - } - - // Ok, change the name of the buffer - buffer->setFileName(fname); - buffer->markDirty(); - bool unnamed = buffer->isUnnamed(); - buffer->setUnnamed(false); - - if (!menuWrite(buffer)) { - buffer->setFileName(oldname); - buffer->setUnnamed(unnamed); - return false; - } - - removeAutosaveFile(oldname); - return true; -} - - -namespace { - -class AutoSaveBuffer : public ForkedProcess { -public: - /// - AutoSaveBuffer(BufferView & bv, FileName const & fname) - : bv_(bv), fname_(fname) {} - /// - virtual shared_ptr clone() const - { - return shared_ptr(new AutoSaveBuffer(*this)); - } - /// - int start(); -private: - /// - virtual int generateChild(); - /// - BufferView & bv_; - FileName fname_; -}; - - -int AutoSaveBuffer::start() -{ - command_ = to_utf8(bformat(_("Auto-saving %1$s"), from_utf8(fname_.absFilename()))); - return run(DontWait); -} - - -int AutoSaveBuffer::generateChild() -{ - // tmp_ret will be located (usually) in /tmp - // will that be a problem? - pid_t const pid = fork(); // If you want to debug the autosave - // you should set pid to -1, and comment out the - // fork. - if (pid == 0 || pid == -1) { - // pid = -1 signifies that lyx was unable - // to fork. But we will do the save - // anyway. - bool failed = false; - - FileName const tmp_ret(tempName(FileName(), "lyxauto")); - if (!tmp_ret.empty()) { - bv_.buffer()->writeFile(tmp_ret); - // assume successful write of tmp_ret - if (!rename(tmp_ret, fname_)) { - failed = true; - // most likely couldn't move between filesystems - // unless write of tmp_ret failed - // so remove tmp file (if it exists) - unlink(tmp_ret); - } - } else { - failed = true; - } - - if (failed) { - // failed to write/rename tmp_ret so try writing direct - if (!bv_.buffer()->writeFile(fname_)) { - // It is dangerous to do this in the child, - // but safe in the parent, so... - if (pid == -1) - // emit message signal. - bv_.buffer()->message(_("Autosave failed!")); - } - } - if (pid == 0) { // we are the child so... - _exit(0); - } - } - return pid; -} - -} // namespace anon - - -void autoSave(BufferView * bv) - // should probably be moved into BufferList (Lgb) - // Perfect target for a thread... -{ - if (!bv->buffer()) - return; - - if (bv->buffer()->isBakClean() || bv->buffer()->isReadonly()) { - // We don't save now, but we'll try again later - bv->buffer()->resetAutosaveTimers(); - return; - } - - // emit message signal. - bv->buffer()->message(_("Autosaving current document...")); - - // create autosave filename - string fname = bv->buffer()->filePath(); - fname += '#'; - fname += onlyFilename(bv->buffer()->fileName()); - fname += '#'; - - AutoSaveBuffer autosave(*bv, FileName(fname)); - autosave.start(); - - bv->buffer()->markBakClean(); - bv->buffer()->resetAutosaveTimers(); -} - - -// -// Copyright CHT Software Service GmbH -// Uwe C. Schroeder -// -// create new file with template -// SERVERCMD ! -// -void newFile(BufferView * bv, string const & filename) -{ - // Split argument by : - string name; - string tmpname = split(filename, name, ':'); - LYXERR(Debug::INFO) << "Arg is " << filename - << "\nName is " << name - << "\nTemplate is " << tmpname << endl; - - Buffer * const b = newFile(name, tmpname); - if (b) - bv->setBuffer(b); -} - - -// Insert plain text file (if filename is empty, prompt for one) -void insertPlaintextFile(BufferView * bv, string const & f, bool asParagraph) -{ - if (!bv->buffer()) - return; - - docstring const tmpstr = getContentsOfPlaintextFile(bv, f, asParagraph); - if (tmpstr.empty()) - return; - - Cursor & cur = bv->cursor(); - cap::replaceSelection(cur); - recordUndo(cur); - if (asParagraph) - cur.innerText()->insertStringAsParagraphs(cur, tmpstr); - else - cur.innerText()->insertStringAsLines(cur, tmpstr); -} - - -docstring const getContentsOfPlaintextFile(BufferView * bv, string const & f, - bool asParagraph) -{ - FileName fname(f); - - if (fname.empty()) { - FileDialog fileDlg(_("Select file to insert"), - (asParagraph) ? LFUN_FILE_INSERT_PLAINTEXT_PARA : LFUN_FILE_INSERT_PLAINTEXT); - - FileDialog::Result result = - fileDlg.open(from_utf8(bv->buffer()->filePath()), - FileFilterList(), docstring()); - - if (result.first == FileDialog::Later) - return docstring(); - - fname = makeAbsPath(to_utf8(result.second)); - - if (fname.empty()) - return docstring(); - } - - if (!fs::is_readable(fname.toFilesystemEncoding())) { - docstring const error = from_ascii(strerror(errno)); - docstring const file = makeDisplayPath(fname.absFilename(), 50); - docstring const text = bformat(_("Could not read the specified document\n" - "%1$s\ndue to the error: %2$s"), file, error); - Alert::error(_("Could not read file"), text); - return docstring(); - } - - ifstream ifs(fname.toFilesystemEncoding().c_str()); - if (!ifs) { - docstring const error = from_ascii(strerror(errno)); - docstring const file = makeDisplayPath(fname.absFilename(), 50); - docstring const text = bformat(_("Could not open the specified document\n" - "%1$s\ndue to the error: %2$s"), file, error); - Alert::error(_("Could not open file"), text); - return docstring(); - } - - ifs.unsetf(ios::skipws); - istream_iterator ii(ifs); - istream_iterator end; -#if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD) - // We use this until the compilers get better... - std::vector tmp; - copy(ii, end, back_inserter(tmp)); - string const tmpstr(tmp.begin(), tmp.end()); -#else - // This is what we want to use and what we will use once the - // compilers get good enough. - //string tmpstr(ii, end); // yet a reason for using std::string - // alternate approach to get the file into a string: - string tmpstr; - copy(ii, end, back_inserter(tmpstr)); -#endif - - // FIXME UNICODE: We don't know the encoding of the file - return normalize_kc(from_utf8(tmpstr)); -} - - -// This function runs "configure" and then rereads lyx.defaults to -// reconfigure the automatic settings. -void reconfigure(LyXView & lv) -{ - // emit message signal. - lv.message(_("Running configure...")); - - // Run configure in user lyx directory - support::Path p(package().user_support()); - string const configure_command = package().configure_command(); - Systemcall one; - one.startscript(Systemcall::Wait, configure_command); - p.pop(); - // emit message signal. - lv.message(_("Reloading configuration...")); - lyxrc.read(libFileSearch(string(), "lyxrc.defaults")); - // Re-read packages.lst - LaTeXFeatures::getAvailable(); - - Alert::information(_("System reconfigured"), - _("The system has been reconfigured.\n" - "You need to restart LyX to make use of any\n" - "updated document class specifications.")); -} - - -} // namespace lyx diff --git a/src/lyx_cb.h b/src/lyx_cb.h deleted file mode 100644 index f320a1ffe0..0000000000 --- a/src/lyx_cb.h +++ /dev/null @@ -1,44 +0,0 @@ -// -*- C++ -*- -/** - * \file lyx_cb.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Lars Gullik Bjønnes - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef LYX_CB_H -#define LYX_CB_H - -#include "support/docstring.h" - -namespace lyx { - -class Buffer; -class BufferView; -class LyXView; - -/// -extern bool quitting; - -/// -bool menuWrite(Buffer * buffer); -/// write the given file, or ask if no name given -bool writeAs(Buffer * buffer, std::string const & filename = std::string()); -/// -void autoSave(BufferView * bv); -/// -void newFile(BufferView * bv, std::string const & filename); -/// -void insertPlaintextFile(BufferView * bv, std::string const & f, bool asParagraph); -/// read plain text file (if \p f is empty, prompt for a filename) -docstring const getContentsOfPlaintextFile(BufferView * bv, - std::string const & f, bool asParagraph); -/// -void reconfigure(LyXView & lv); - -} // namespace lyx - -#endif diff --git a/src/lyxfind.cpp b/src/lyxfind.cpp index f0d9e96c44..8aa3175ab6 100644 --- a/src/lyxfind.cpp +++ b/src/lyxfind.cpp @@ -28,7 +28,7 @@ #include "ParIterator.h" #include "Undo.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "support/convert.h" #include "support/docstream.h" diff --git a/src/mathed/InsetFormulaMacro.cpp b/src/mathed/InsetFormulaMacro.cpp index 91195646f1..cbf2058aaa 100644 --- a/src/mathed/InsetFormulaMacro.cpp +++ b/src/mathed/InsetFormulaMacro.cpp @@ -12,7 +12,7 @@ #include #include "InsetFormulaMacro.h" -#include "MathMacroTable.h" +#include "MacroTable.h" #include "MathMacroTemplate.h" #include "BufferView.h" diff --git a/src/mathed/MacroTable.cpp b/src/mathed/MacroTable.cpp new file mode 100644 index 0000000000..871dc6edb6 --- /dev/null +++ b/src/mathed/MacroTable.cpp @@ -0,0 +1,124 @@ +/** + * \file MacroTable.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author André Pönitz + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "MacroTable.h" +#include "MathMacroTemplate.h" +#include "MathMacroArgument.h" +#include "MathSupport.h" +#include "InsetMathSqrt.h" + +#include "debug.h" +#include "DocIterator.h" + +#include + +#include + + +namespace lyx { + +using std::endl; +using std::istringstream; +using std::map; +using std::pair; +using std::string; +using std::vector; +using std::size_t; + + +MacroData::MacroData() + : numargs_(0), lockCount_(0) +{} + + +MacroData::MacroData(docstring const & def, int numargs, docstring const & disp, string const & requires) + : def_(def), numargs_(numargs), disp_(disp), requires_(requires), lockCount_(0) +{} + + +void MacroData::expand(vector const & args, MathData & to) const +{ + InsetMathSqrt inset; // Hack. Any inset with a cell would do. + // FIXME UNICODE + asArray(disp_.empty() ? def_ : disp_, inset.cell(0)); + //lyxerr << "MathData::expand: args: " << args << endl; + //lyxerr << "MathData::expand: ar: " << inset.cell(0) << endl; + for (DocIterator it = doc_iterator_begin(inset); it; it.forwardChar()) { + if (!it.nextInset()) + continue; + if (it.nextInset()->lyxCode() != InsetBase::MATHMACROARG_CODE) + continue; + //it.cell().erase(it.pos()); + //it.cell().insert(it.pos(), it.nextInset()->asInsetMath() + size_t n = static_cast(it.nextInset())->number(); + if (n <= args.size()) { + it.cell().erase(it.pos()); + it.cell().insert(it.pos(), args[n - 1]); + } + } + //lyxerr << "MathData::expand: res: " << inset.cell(0) << endl; + to = inset.cell(0); +} + + +// The global table. +MacroTable & MacroTable::globalMacros() +{ + static MacroTable theGlobalMacros; + return theGlobalMacros; +} + + +bool MacroTable::has(docstring const & name) const +{ + return find(name) != end(); +} + + +MacroData const & MacroTable::get(docstring const & name) const +{ + const_iterator it = find(name); + BOOST_ASSERT(it != end()); + return it->second; +} + + +void MacroTable::insert(docstring const & name, MacroData const & data) +{ + //lyxerr << "MacroTable::insert: " << to_utf8(name) << endl; + operator[](name) = data; +} + + +void MacroTable::insert(docstring const & def, string const & requires) +{ + //lyxerr << "MacroTable::insert, def: " << to_utf8(def) << endl; + MathMacroTemplate mac(def); + MacroData data = mac.asMacroData(); + data.requires() = requires; + insert(mac.name(), data); +} + + +void MacroTable::dump() +{ + lyxerr << "\n------------------------------------------" << endl; + for (const_iterator it = begin(); it != end(); ++it) + lyxerr << to_utf8(it->first) + << " [" << to_utf8(it->second.def()) << "] : " + << " [" << to_utf8(it->second.disp()) << "] : " + << endl; + lyxerr << "------------------------------------------" << endl; +} + + +} // namespace lyx diff --git a/src/mathed/MacroTable.h b/src/mathed/MacroTable.h new file mode 100644 index 0000000000..7bc220a7e2 --- /dev/null +++ b/src/mathed/MacroTable.h @@ -0,0 +1,93 @@ +// -*- C++ -*- +/** + * \file MacroTable.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author André Pönitz + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef MATH_MACROTABLE_H +#define MATH_MACROTABLE_H + +#include "support/docstring.h" + +#include + +#include +#include + +namespace lyx { + +class MathData; + +/// +class MacroData { +public: + /// + MacroData(); + /// + MacroData(docstring const & def, int nargs, docstring const & disp, std::string const &); + /// + docstring def() const { return def_; } + /// + docstring disp() const { return disp_; } + /// + int numargs() const { return numargs_; } + /// replace #1,#2,... by given MathAtom 0,1,.. + void expand(std::vector const & from, MathData & to) const; + /// + std::string requires() const { return requires_; } + /// + std::string & requires() { return requires_; } + /// lock while being drawn + int lock() const { return ++lockCount_; } + /// is it being drawn? + bool locked() const { return lockCount_ != 0; } + /// + void unlock() const { --lockCount_; BOOST_ASSERT(lockCount_ >= 0); } + +private: + /// + docstring def_; + /// + int numargs_; + /// + docstring disp_; + /// + std::string requires_; + /// + mutable int lockCount_; +}; + + +// This contains a table of "global" macros that are always accessible, +// either because they implement a feature of standard LaTeX or some +// hack to display certain contents nicely. + +class MacroTable : public std::map +{ +public: + /// Parse full "\\def..." or "\\newcommand..." or ... + void insert(docstring const & definition, std::string const &); + /// Insert pre-digested macro definition + void insert(docstring const & name, MacroData const & data); + /// Do we have a macro by that name? + bool has(docstring const & name) const; + /// + MacroData const & get(docstring const & name) const; + /// + void dump(); + + /// the global list + static MacroTable & globalMacros(); + /// the local list hack + //static MacroTable & localMacros(); +}; + + +} // namespace lyx + +#endif diff --git a/src/mathed/Makefile.am b/src/mathed/Makefile.am index d856a8cb53..356fa40cec 100644 --- a/src/mathed/Makefile.am +++ b/src/mathed/Makefile.am @@ -140,8 +140,8 @@ libmathed_la_SOURCES = \ MathGridInfo.h \ MathMacroArgument.cpp \ MathMacroArgument.h \ - MathMacroTable.cpp \ - MathMacroTable.h \ + MacroTable.cpp \ + MacroTable.h \ MathMacroTemplate.cpp \ MathMacroTemplate.h \ MathParser.cpp \ diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp index 806e61e89d..a911cc839a 100644 --- a/src/mathed/MathData.cpp +++ b/src/mathed/MathData.cpp @@ -14,7 +14,7 @@ #include "InsetMathFont.h" #include "InsetMathScript.h" #include "MathMacro.h" -#include "MathMacroTable.h" +#include "MacroTable.h" #include "MathStream.h" #include "MathSupport.h" #include "ReplaceData.h" diff --git a/src/mathed/MathFactory.cpp b/src/mathed/MathFactory.cpp index 1ae36429c7..70244a7006 100644 --- a/src/mathed/MathFactory.cpp +++ b/src/mathed/MathFactory.cpp @@ -50,7 +50,7 @@ #include "InsetMathXArrow.h" #include "InsetMathXYMatrix.h" #include "MathMacroArgument.h" -#include "MathMacroTable.h" +#include "MacroTable.h" #include "MathParser.h" #include "MathSupport.h" diff --git a/src/mathed/MathMacro.h b/src/mathed/MathMacro.h index 2c455e44c0..e5d4196b97 100644 --- a/src/mathed/MathMacro.h +++ b/src/mathed/MathMacro.h @@ -16,7 +16,7 @@ #include "InsetMathNest.h" #include "MathData.h" #include "InsetMathNest.h" -#include "MathMacroTable.h" +#include "MacroTable.h" namespace lyx { diff --git a/src/mathed/MathMacroTable.cpp b/src/mathed/MathMacroTable.cpp deleted file mode 100644 index 0a60ee44a2..0000000000 --- a/src/mathed/MathMacroTable.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/** - * \file MathMacroTable.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author André Pönitz - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "MathMacroTable.h" -#include "MathMacroTemplate.h" -#include "MathMacroArgument.h" -#include "MathSupport.h" -#include "InsetMathSqrt.h" - -#include "debug.h" -#include "DocIterator.h" - -#include - -#include - - -namespace lyx { - -using std::endl; -using std::istringstream; -using std::map; -using std::pair; -using std::string; -using std::vector; -using std::size_t; - - -MacroData::MacroData() - : numargs_(0), lockCount_(0) -{} - - -MacroData::MacroData(docstring const & def, int numargs, docstring const & disp, string const & requires) - : def_(def), numargs_(numargs), disp_(disp), requires_(requires), lockCount_(0) -{} - - -void MacroData::expand(vector const & args, MathData & to) const -{ - InsetMathSqrt inset; // Hack. Any inset with a cell would do. - // FIXME UNICODE - asArray(disp_.empty() ? def_ : disp_, inset.cell(0)); - //lyxerr << "MathData::expand: args: " << args << endl; - //lyxerr << "MathData::expand: ar: " << inset.cell(0) << endl; - for (DocIterator it = doc_iterator_begin(inset); it; it.forwardChar()) { - if (!it.nextInset()) - continue; - if (it.nextInset()->lyxCode() != InsetBase::MATHMACROARG_CODE) - continue; - //it.cell().erase(it.pos()); - //it.cell().insert(it.pos(), it.nextInset()->asInsetMath() - size_t n = static_cast(it.nextInset())->number(); - if (n <= args.size()) { - it.cell().erase(it.pos()); - it.cell().insert(it.pos(), args[n - 1]); - } - } - //lyxerr << "MathData::expand: res: " << inset.cell(0) << endl; - to = inset.cell(0); -} - - -// The global table. -MacroTable & MacroTable::globalMacros() -{ - static MacroTable theGlobalMacros; - return theGlobalMacros; -} - - -bool MacroTable::has(docstring const & name) const -{ - return find(name) != end(); -} - - -MacroData const & MacroTable::get(docstring const & name) const -{ - const_iterator it = find(name); - BOOST_ASSERT(it != end()); - return it->second; -} - - -void MacroTable::insert(docstring const & name, MacroData const & data) -{ - //lyxerr << "MacroTable::insert: " << to_utf8(name) << endl; - operator[](name) = data; -} - - -void MacroTable::insert(docstring const & def, string const & requires) -{ - //lyxerr << "MacroTable::insert, def: " << to_utf8(def) << endl; - MathMacroTemplate mac(def); - MacroData data = mac.asMacroData(); - data.requires() = requires; - insert(mac.name(), data); -} - - -void MacroTable::dump() -{ - lyxerr << "\n------------------------------------------" << endl; - for (const_iterator it = begin(); it != end(); ++it) - lyxerr << to_utf8(it->first) - << " [" << to_utf8(it->second.def()) << "] : " - << " [" << to_utf8(it->second.disp()) << "] : " - << endl; - lyxerr << "------------------------------------------" << endl; -} - - -} // namespace lyx diff --git a/src/mathed/MathMacroTable.h b/src/mathed/MathMacroTable.h deleted file mode 100644 index 5525beed1c..0000000000 --- a/src/mathed/MathMacroTable.h +++ /dev/null @@ -1,93 +0,0 @@ -// -*- C++ -*- -/** - * \file MathMacroTable.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author André Pönitz - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef MATH_MACROTABLE_H -#define MATH_MACROTABLE_H - -#include "support/docstring.h" - -#include - -#include -#include - -namespace lyx { - -class MathData; - -/// -class MacroData { -public: - /// - MacroData(); - /// - MacroData(docstring const & def, int nargs, docstring const & disp, std::string const &); - /// - docstring def() const { return def_; } - /// - docstring disp() const { return disp_; } - /// - int numargs() const { return numargs_; } - /// replace #1,#2,... by given MathAtom 0,1,.. - void expand(std::vector const & from, MathData & to) const; - /// - std::string requires() const { return requires_; } - /// - std::string & requires() { return requires_; } - /// lock while being drawn - int lock() const { return ++lockCount_; } - /// is it being drawn? - bool locked() const { return lockCount_ != 0; } - /// - void unlock() const { --lockCount_; BOOST_ASSERT(lockCount_ >= 0); } - -private: - /// - docstring def_; - /// - int numargs_; - /// - docstring disp_; - /// - std::string requires_; - /// - mutable int lockCount_; -}; - - -// This contains a table of "global" macros that are always accessible, -// either because they implement a feature of standard LaTeX or some -// hack to display certain contents nicely. - -class MacroTable : public std::map -{ -public: - /// Parse full "\\def..." or "\\newcommand..." or ... - void insert(docstring const & definition, std::string const &); - /// Insert pre-digested macro definition - void insert(docstring const & name, MacroData const & data); - /// Do we have a macro by that name? - bool has(docstring const & name) const; - /// - MacroData const & get(docstring const & name) const; - /// - void dump(); - - /// the global list - static MacroTable & globalMacros(); - /// the local list hack - //static MacroTable & localMacros(); -}; - - -} // namespace lyx - -#endif diff --git a/src/mathed/MathMacroTemplate.h b/src/mathed/MathMacroTemplate.h index 2ed8e87bf5..b657ea4793 100644 --- a/src/mathed/MathMacroTemplate.h +++ b/src/mathed/MathMacroTemplate.h @@ -14,7 +14,7 @@ #define MATH_MACROTEMPLATE_H #include "MathData.h" -#include "MathMacroTable.h" +#include "MacroTable.h" #include "InsetMathNest.h" #include "support/types.h" diff --git a/src/output.cpp b/src/output.cpp index 4e0890db19..0a9e86ee82 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -14,7 +14,7 @@ #include "gettext.h" -#include "frontends/Alert.h" +#include "frontends/alert.h" #include "support/filetools.h" diff --git a/src/text2.cpp b/src/text2.cpp index 8ee99e8c7c..3cc575ea98 100644 --- a/src/text2.cpp +++ b/src/text2.cpp @@ -53,7 +53,7 @@ #include "frontends/FontMetrics.h" -#include "insets/InsetEnv.h" +#include "insets/InsetEnvironment.h" #include "mathed/InsetMathHull.h" diff --git a/src/update_flags.h b/src/update_flags.h new file mode 100644 index 0000000000..b18cabcb1b --- /dev/null +++ b/src/update_flags.h @@ -0,0 +1,40 @@ +// -*- C++ -*- +/** + * \file update_flags.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author The Denmark Cowboys + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef UPDATE_FLAGS_H +#define UPDATE_FLAGS_H + +namespace lyx { + +namespace Update { + enum flags { + None = 0, + FitCursor = 1, + Force = 2, + SinglePar = 4, + MultiParSel = 8, + Decoration = 16 + }; + +inline flags operator|(flags const f, flags const g) +{ + return static_cast(int(f) | int(g)); +} + +inline flags operator&(flags const f, flags const g) +{ + return static_cast(int(f) & int(g)); +} + +} // namespace + +} // namespace lyx +#endif