lyx_mirror/src/frontends/LyXView.C

459 lines
9.7 KiB
C++
Raw Normal View History

/**
* \file LyXView.C
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Lars Gullik Bj<EFBFBD>nnes
* \author John Levon
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "LyXView.h"
#include "Dialogs.h"
#include "Timeout.h"
#include "Toolbars.h"
#include "Menubar.h"
#include "WorkArea.h"
#include "Gui.h"
#include "buffer.h"
#include "bufferparams.h"
#include "BufferView.h"
#include "bufferview_funcs.h"
#include "cursor.h"
#include "debug.h"
This commit creates a error_lists map member inside the Buffer class. I had no choice but to use string for the map key. This is because the only information that could be passed to the controller is a string. With this new architecture, persistent error lists are now possible. * Buffer - errorList_, addError(), : deleted - std::map<std::string, ErrorList> errorLists_ : new member - errorList(std::string const & type): associated accessors * buffer_funcs.C - bufferErrors(Buffer const & buf, TeXErrors const & terr): now needs a third errorList argument - bufferErrors(Buffer const & buf, ErrorList const & el): deleted. * Converter - convert(): now needs an ErrorList argument instead of filling the Buffer errorList member directly. - runLaTeX(): ditto - scanLog(): ditto * CutAndPaste.C - pasteParagraphList(): ditto - pasteSelection(): ditto * lyxtext.h/text.C - readParagraph(): ditto - LyXText::read(): ditto * importer: - Importer::Import(): ditto * BufferView_pimpl.C - loadLyXFile(): send the Buffer::errors() signal instead of calling LyXView::showErrorList() directly. * exporter.C - Export(): send the Buffer::errors() signal instead of calling LyXView::showErrorList() directly in lyxfunc.C * ControlErrorList.C - initialiseParams(): translation operation transfered here from LyXView::showErrorList(). * LyXView.C - LoadLyXFile(): add a showErrorList("Parse") call. - showErrorList(): simplified due to code transferred to the ControlErrorList. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14652 a592a061-630c-0410-9148-cb99ea01b6c8
2006-08-13 16:16:43 +00:00
#include "errorlist.h"
#include "funcrequest.h"
#include "gettext.h"
#include "intl.h"
#include "lyx_cb.h"
#include "lyxfunc.h"
#include "lyxrc.h"
#include "lyxtext.h"
#include "MenuBackend.h"
#include "paragraph.h"
#include "controllers/ControlCommandBuffer.h"
#include "support/lstrings.h"
#include "support/filetools.h" // OnlyFilename()
#include <boost/bind.hpp>
namespace lyx {
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
using frontend::WorkArea;
using support::bformat;
using support::FileName;
using support::makeDisplayPath;
using support::onlyFilename;
using std::endl;
using std::string;
using lyx::frontend::ControlCommandBuffer;
string current_layout;
LyXView::LyXView(int id)
: work_area_(0),
toolbars_(new Toolbars(*this)),
autosave_timeout_(new Timeout(5000)),
dialogs_(new Dialogs(*this)),
controlcommand_(new ControlCommandBuffer(*this)), id_(id)
{
// Start autosave timer
if (lyxrc.autosave) {
autosave_timeout_->timeout.connect(boost::bind(&LyXView::autoSave, this));
autosave_timeout_->setTimeout(lyxrc.autosave * 1000);
autosave_timeout_->start();
}
}
LyXView::~LyXView()
{
disconnectBuffer();
}
// FIXME, there's only one WorkArea per LyXView possible for now.
void LyXView::setWorkArea(WorkArea * work_area)
{
BOOST_ASSERT(work_area);
work_area_ = work_area;
work_area_ids_.clear();
work_area_ids_.push_back(work_area_->id());
}
// FIXME, there's only one WorkArea per LyXView possible for now.
WorkArea const * LyXView::currentWorkArea() const
{
return work_area_;
}
// FIXME, there's only one WorkArea per LyXView possible for now.
WorkArea * LyXView::currentWorkArea()
{
return work_area_;
}
Buffer * LyXView::buffer() const
{
BOOST_ASSERT(work_area_);
return work_area_->bufferView().buffer();
}
void LyXView::setBuffer(Buffer * b)
{
busy(true);
BOOST_ASSERT(work_area_);
if (work_area_->bufferView().buffer())
disconnectBuffer();
if (!b)
getDialogs().hideBufferDependent();
work_area_->bufferView().setBuffer(b);
// Make sure the TOC is updated before anything else.
updateToc();
if (work_area_->bufferView().buffer()) {
// Buffer-dependent dialogs should be updated or
// hidden. This should go here because some dialogs (eg ToC)
// require bv_->text.
getDialogs().updateBufferDependent(true);
connectBuffer(*work_area_->bufferView().buffer());
}
if (quitting)
return;
updateMenubar();
updateToolbars();
updateLayoutChoice();
updateWindowTitle();
updateStatusBar();
updateTab();
busy(false);
work_area_->redraw();
}
bool LyXView::loadLyXFile(FileName const & filename, bool tolastfiles)
{
busy(true);
BOOST_ASSERT(work_area_);
if (work_area_->bufferView().buffer())
disconnectBuffer();
bool loaded = work_area_->bufferView().loadLyXFile(filename, tolastfiles);
This commit creates a error_lists map member inside the Buffer class. I had no choice but to use string for the map key. This is because the only information that could be passed to the controller is a string. With this new architecture, persistent error lists are now possible. * Buffer - errorList_, addError(), : deleted - std::map<std::string, ErrorList> errorLists_ : new member - errorList(std::string const & type): associated accessors * buffer_funcs.C - bufferErrors(Buffer const & buf, TeXErrors const & terr): now needs a third errorList argument - bufferErrors(Buffer const & buf, ErrorList const & el): deleted. * Converter - convert(): now needs an ErrorList argument instead of filling the Buffer errorList member directly. - runLaTeX(): ditto - scanLog(): ditto * CutAndPaste.C - pasteParagraphList(): ditto - pasteSelection(): ditto * lyxtext.h/text.C - readParagraph(): ditto - LyXText::read(): ditto * importer: - Importer::Import(): ditto * BufferView_pimpl.C - loadLyXFile(): send the Buffer::errors() signal instead of calling LyXView::showErrorList() directly. * exporter.C - Export(): send the Buffer::errors() signal instead of calling LyXView::showErrorList() directly in lyxfunc.C * ControlErrorList.C - initialiseParams(): translation operation transfered here from LyXView::showErrorList(). * LyXView.C - LoadLyXFile(): add a showErrorList("Parse") call. - showErrorList(): simplified due to code transferred to the ControlErrorList. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14652 a592a061-630c-0410-9148-cb99ea01b6c8
2006-08-13 16:16:43 +00:00
updateToc();
updateMenubar();
updateToolbars();
updateLayoutChoice();
updateWindowTitle();
updateTab();
if (loaded) {
connectBuffer(*work_area_->bufferView().buffer());
showErrorList("Parse");
}
updateStatusBar();
busy(false);
work_area_->redraw();
return loaded;
}
void LyXView::connectBuffer(Buffer & buf)
{
This commit transfer the ErrorList handling from LyXView to Buffer. It also removes the need for the error signal and simplify the kerbel <-> frontend communication. I think it should speed-up _significantly_ the latex compilation for example in case of problematic files. TODO 1: All occurrences of "LyXView::showErrorList()" in the "kernel" should be replaced by a boost signal emission (Buffer::errors()). This signal is already connected to this showErrorList() slot. TODO 2: The ErrorList mechanism is used wrongly in a number of place, most notably in "Converter.C". Instead of replacing the ErrorList in the "Buffer" class, the "Converter" class should maintain its own list instead and connect directly to the LyXView::showErrorList() slot. Buffer: * errorList_: new private member and associated access methods. * setErrorList(): new accessor method. * addError(): apend an error to the errorList_. * error(): deleted. * errors(): new boost signal, unused for now. Shall be used instead of LyXView::showErrorList(). LyXView: * getErrorList(), addError(), errorlist_, errorConnection_: deleted. * errorsConnection_: new boost connection for the Buffer::errors() signal. lyx_main.C: * LyX::exec2(): manually print all errors. BufferView.h: remove unneeded ErrorList forward declaration. BufferView::pimpl::menuInsertLyXFile(): delete Buffer::error() connection and add a FIXME comment text.C: Use Buffer::addError() instead of Buffer::error() signal emission. ControlErrorList.C: get the ErrorList from the Buffer instead of LyXView git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14467 a592a061-630c-0410-9148-cb99ea01b6c8
2006-07-15 22:43:37 +00:00
if (errorsConnection_.connected())
disconnectBuffer();
BOOST_ASSERT(work_area_);
bufferChangedConnection_ =
buf.changed.connect(
boost::bind(&WorkArea::redraw, work_area_));
bufferStructureChangedConnection_ =
buf.structureChanged.connect(
boost::bind(&LyXView::updateToc, this));
This commit transfer the ErrorList handling from LyXView to Buffer. It also removes the need for the error signal and simplify the kerbel <-> frontend communication. I think it should speed-up _significantly_ the latex compilation for example in case of problematic files. TODO 1: All occurrences of "LyXView::showErrorList()" in the "kernel" should be replaced by a boost signal emission (Buffer::errors()). This signal is already connected to this showErrorList() slot. TODO 2: The ErrorList mechanism is used wrongly in a number of place, most notably in "Converter.C". Instead of replacing the ErrorList in the "Buffer" class, the "Converter" class should maintain its own list instead and connect directly to the LyXView::showErrorList() slot. Buffer: * errorList_: new private member and associated access methods. * setErrorList(): new accessor method. * addError(): apend an error to the errorList_. * error(): deleted. * errors(): new boost signal, unused for now. Shall be used instead of LyXView::showErrorList(). LyXView: * getErrorList(), addError(), errorlist_, errorConnection_: deleted. * errorsConnection_: new boost connection for the Buffer::errors() signal. lyx_main.C: * LyX::exec2(): manually print all errors. BufferView.h: remove unneeded ErrorList forward declaration. BufferView::pimpl::menuInsertLyXFile(): delete Buffer::error() connection and add a FIXME comment text.C: Use Buffer::addError() instead of Buffer::error() signal emission. ControlErrorList.C: get the ErrorList from the Buffer instead of LyXView git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14467 a592a061-630c-0410-9148-cb99ea01b6c8
2006-07-15 22:43:37 +00:00
errorsConnection_ =
buf.errors.connect(
boost::bind(&LyXView::showErrorList, this, _1));
messageConnection_ =
buf.message.connect(
boost::bind(&LyXView::message, this, _1));
busyConnection_ =
buf.busy.connect(
boost::bind(&LyXView::busy, this, _1));
titleConnection_ =
buf.updateTitles.connect(
boost::bind(&LyXView::updateWindowTitle, this));
timerConnection_ =
buf.resetAutosaveTimers.connect(
boost::bind(&LyXView::resetAutosaveTimer, this));
readonlyConnection_ =
buf.readonly.connect(
boost::bind(&LyXView::showReadonly, this, _1));
closingConnection_ =
buf.closing.connect(
boost::bind(&LyXView::setBuffer, this, (Buffer *)0));
}
void LyXView::disconnectBuffer()
{
errorsConnection_.disconnect();
bufferChangedConnection_.disconnect();
bufferStructureChangedConnection_.disconnect();
messageConnection_.disconnect();
busyConnection_.disconnect();
titleConnection_.disconnect();
timerConnection_.disconnect();
readonlyConnection_.disconnect();
closingConnection_.disconnect();
layout_changed_connection_.disconnect();
}
void LyXView::connectBufferView(BufferView & bv)
{
show_dialog_connection_ = bv.showDialog.connect(
boost::bind(&LyXView::showDialog, this, _1));
show_dialog_with_data_connection_ = bv.showDialogWithData.connect(
boost::bind(&LyXView::showDialogWithData, this, _1, _2));
show_inset_dialog_connection_ = bv.showInsetDialog.connect(
boost::bind(&LyXView::showInsetDialog, this, _1, _2, _3));
update_dialog_connection_ = bv.updateDialog.connect(
boost::bind(&LyXView::updateDialog, this, _1, _2));
layout_changed_connection_ = bv.layoutChanged.connect(
boost::bind(&Toolbars::setLayout, toolbars_.get(), _1));
}
void LyXView::disconnectBufferView()
{
show_dialog_connection_.disconnect();
show_dialog_with_data_connection_.disconnect();
show_inset_dialog_connection_.disconnect();
update_dialog_connection_.disconnect();
}
This commit creates a error_lists map member inside the Buffer class. I had no choice but to use string for the map key. This is because the only information that could be passed to the controller is a string. With this new architecture, persistent error lists are now possible. * Buffer - errorList_, addError(), : deleted - std::map<std::string, ErrorList> errorLists_ : new member - errorList(std::string const & type): associated accessors * buffer_funcs.C - bufferErrors(Buffer const & buf, TeXErrors const & terr): now needs a third errorList argument - bufferErrors(Buffer const & buf, ErrorList const & el): deleted. * Converter - convert(): now needs an ErrorList argument instead of filling the Buffer errorList member directly. - runLaTeX(): ditto - scanLog(): ditto * CutAndPaste.C - pasteParagraphList(): ditto - pasteSelection(): ditto * lyxtext.h/text.C - readParagraph(): ditto - LyXText::read(): ditto * importer: - Importer::Import(): ditto * BufferView_pimpl.C - loadLyXFile(): send the Buffer::errors() signal instead of calling LyXView::showErrorList() directly. * exporter.C - Export(): send the Buffer::errors() signal instead of calling LyXView::showErrorList() directly in lyxfunc.C * ControlErrorList.C - initialiseParams(): translation operation transfered here from LyXView::showErrorList(). * LyXView.C - LoadLyXFile(): add a showErrorList("Parse") call. - showErrorList(): simplified due to code transferred to the ControlErrorList. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14652 a592a061-630c-0410-9148-cb99ea01b6c8
2006-08-13 16:16:43 +00:00
void LyXView::showErrorList(string const & error_type)
{
This commit creates a error_lists map member inside the Buffer class. I had no choice but to use string for the map key. This is because the only information that could be passed to the controller is a string. With this new architecture, persistent error lists are now possible. * Buffer - errorList_, addError(), : deleted - std::map<std::string, ErrorList> errorLists_ : new member - errorList(std::string const & type): associated accessors * buffer_funcs.C - bufferErrors(Buffer const & buf, TeXErrors const & terr): now needs a third errorList argument - bufferErrors(Buffer const & buf, ErrorList const & el): deleted. * Converter - convert(): now needs an ErrorList argument instead of filling the Buffer errorList member directly. - runLaTeX(): ditto - scanLog(): ditto * CutAndPaste.C - pasteParagraphList(): ditto - pasteSelection(): ditto * lyxtext.h/text.C - readParagraph(): ditto - LyXText::read(): ditto * importer: - Importer::Import(): ditto * BufferView_pimpl.C - loadLyXFile(): send the Buffer::errors() signal instead of calling LyXView::showErrorList() directly. * exporter.C - Export(): send the Buffer::errors() signal instead of calling LyXView::showErrorList() directly in lyxfunc.C * ControlErrorList.C - initialiseParams(): translation operation transfered here from LyXView::showErrorList(). * LyXView.C - LoadLyXFile(): add a showErrorList("Parse") call. - showErrorList(): simplified due to code transferred to the ControlErrorList. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14652 a592a061-630c-0410-9148-cb99ea01b6c8
2006-08-13 16:16:43 +00:00
ErrorList & el = buffer()->errorList(error_type);
if (!el.empty()) {
getDialogs().show("errorlist", error_type);
}
}
void LyXView::showDialog(string const & name)
{
getDialogs().show(name);
}
void LyXView::showDialogWithData(string const & name, string const & data)
{
getDialogs().show(name, data);
}
void LyXView::showInsetDialog(string const & name, string const & data,
InsetBase * inset)
{
getDialogs().show(name, data, inset);
}
void LyXView::updateDialog(string const & name, string const & data)
{
if (getDialogs().visible(name))
getDialogs().update(name, data);
}
void LyXView::showReadonly(bool)
{
updateWindowTitle();
getDialogs().updateBufferDependent(false);
}
BufferView * LyXView::view() const
{
BOOST_ASSERT(work_area_);
return &work_area_->bufferView();
}
void LyXView::updateToc()
{
updateDialog("toc", "");
}
void LyXView::updateToolbars()
{
BOOST_ASSERT(work_area_);
bool const math =
work_area_->bufferView().cursor().inMathed();
bool const table =
lyx::getStatus(FuncRequest(LFUN_LAYOUT_TABULAR)).enabled();
bool const review =
lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).enabled() &&
lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).onoff(true);
toolbars_->update(math, table, review);
// update redaonly status of open dialogs. This could also be in
// updateMenubar(), but since updateToolbars() and updateMenubar()
// are always called together it is only here.
getDialogs().checkStatus();
}
ToolbarBackend::Flags LyXView::getToolbarState(string const & name)
{
return toolbars_->getToolbarState(name);
}
void LyXView::toggleToolbarState(string const & name)
{
// it is possible to get current toolbar status like this,...
// but I decide to obey the order of ToolbarBackend::flags
// and disregard real toolbar status.
// toolbars_->saveToolbarInfo();
//
// toggle state on/off/auto
toolbars_->toggleToolbarState(name);
// update toolbar
updateToolbars();
}
void LyXView::updateMenubar()
{
menubar_->update();
}
void LyXView::autoSave()
{
lyxerr[Debug::INFO] << "Running autoSave()" << endl;
if (view()->buffer())
lyx::autoSave(view());
}
void LyXView::resetAutosaveTimer()
{
if (lyxrc.autosave)
autosave_timeout_->restart();
}
void LyXView::updateLayoutChoice()
{
// Don't show any layouts without a buffer
if (!view()->buffer()) {
toolbars_->clearLayoutList();
return;
}
// Update the layout display
if (toolbars_->updateLayoutList(buffer()->params().textclass)) {
current_layout = buffer()->params().getLyXTextClass().defaultLayoutName();
}
BOOST_ASSERT(work_area_);
if (work_area_->bufferView().cursor().inMathed())
return;
string const & layout =
work_area_->bufferView().cursor().paragraph().layout()->name();
if (layout != current_layout) {
toolbars_->setLayout(layout);
current_layout = layout;
}
}
void LyXView::updateWindowTitle()
{
docstring maximize_title = lyx::from_ascii("LyX");
docstring minimize_title = lyx::from_ascii("LyX");
if (view()->buffer()) {
string const cur_title = buffer()->fileName();
if (!cur_title.empty()) {
maximize_title += ": " + makeDisplayPath(cur_title, 30);
minimize_title = lyx::from_utf8(onlyFilename(cur_title));
if (!buffer()->isClean()) {
maximize_title += _(" (changed)");
minimize_title += lyx::char_type('*');
}
if (buffer()->isReadonly())
maximize_title += _(" (read only)");
}
}
setWindowTitle(maximize_title, minimize_title);
updateTab();
}
void LyXView::dispatch(FuncRequest const & cmd)
{
theLyXFunc().setLyXView(this);
lyx::dispatch(cmd);
}
Buffer const * const LyXView::updateInset(InsetBase const * inset) const
{
Buffer const * buffer_ptr = 0;
if (inset) {
BOOST_ASSERT(work_area_);
work_area_->scheduleRedraw();
buffer_ptr = work_area_->bufferView().buffer();
}
return buffer_ptr;
}
} // namespace lyx