#include "GuiView.h"
#include "Dialog.h"
+#include "DispatchResult.h"
#include "FileDialog.h"
#include "FontLoader.h"
#include "GuiApplication.h"
#include "GuiCommandBuffer.h"
#include "GuiCompleter.h"
-#include "GuiWorkArea.h"
#include "GuiKeySymbol.h"
#include "GuiToc.h"
#include "GuiToolbar.h"
+#include "GuiWorkArea.h"
#include "LayoutBox.h"
#include "Menus.h"
#include "TocModel.h"
#include "Intl.h"
#include "Layout.h"
#include "Lexer.h"
-#include "LyXFunc.h"
+#include "LyXAction.h"
#include "LyX.h"
#include "LyXRC.h"
#include "LyXVC.h"
#include "support/FileName.h"
#include "support/filetools.h"
#include "support/gettext.h"
+#include "support/filetools.h"
#include "support/ForkedCalls.h"
#include "support/lassert.h"
#include "support/lstrings.h"
#include "support/os.h"
#include "support/Package.h"
+#include "support/Path.h"
+#include "support/Systemcall.h"
#include "support/Timeout.h"
+#include "support/ProgressInterface.h"
+#include "GuiProgress.h"
#include <QAction>
#include <QApplication>
#include <QSplitter>
#include <QStackedWidget>
#include <QStatusBar>
+#include <QTime>
#include <QTimer>
#include <QToolBar>
#include <QUrl>
#include <QScrollBar>
+#define EXPORT_in_THREAD 1
+
+
+// QtConcurrent was introduced in Qt 4.4
+#if (QT_VERSION >= 0x040400)
+#include <QFuture>
+#include <QFutureWatcher>
+#include <QtConcurrentRun>
+#endif
+
#include <boost/bind.hpp>
+#include <sstream>
+
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
font.setPointSize(int(toqstr(lyxrc.font_sizes[FONT_SIZE_LARGE]).toDouble()));
pain.setFont(font);
pain.drawText(260, 15, text);
+ setFocusPolicy(Qt::StrongFocus);
}
void paintEvent(QPaintEvent *)
pain.drawPixmap(x, y, splash_);
}
+ void keyPressEvent(QKeyEvent * ev)
+ {
+ KeySymbol sym;
+ setKeySymbol(&sym, ev);
+ if (sym.isOK()) {
+ guiApp->processKeySym(sym, q_key_state(ev->modifiers()));
+ ev->accept();
+ } else {
+ ev->ignore();
+ }
+ }
+
private:
QPixmap splash_;
};
/// Toolbar store providing access to individual toolbars by name.
-typedef std::map<std::string, GuiToolbar *> ToolbarMap;
+typedef map<string, GuiToolbar *> ToolbarMap;
typedef boost::shared_ptr<Dialog> DialogPtr;
struct GuiView::GuiViewPrivate
{
- GuiViewPrivate()
- : current_work_area_(0), current_main_work_area_(0),
+ GuiViewPrivate(GuiView * gv)
+ : gv_(gv), current_work_area_(0), current_main_work_area_(0),
layout_(0), autosave_timeout_(5000),
in_show_(false)
{
stack_widget_->addWidget(bg_widget_);
stack_widget_->addWidget(splitter_);
setBackground();
+ progress_ = new GuiProgress(gv);
}
~GuiViewPrivate()
delete splitter_;
delete bg_widget_;
delete stack_widget_;
+ delete progress_;
}
QMenu * toolBarPopup(GuiView * parent)
{
stack_widget_->setCurrentWidget(bg_widget_);
bg_widget_->setUpdatesEnabled(true);
+ bg_widget_->setFocus();
}
TabWorkArea * tabWorkArea(int i)
return tabWorkArea(0);
}
+#if (QT_VERSION >= 0x040400)
+ void setPreviewFuture(QFuture<docstring> const & f)
+ {
+ if (preview_watcher_.isRunning()) {
+ // we prefer to cancel this preview in order to keep a snappy
+ // interface.
+ return;
+ }
+ preview_watcher_.setFuture(f);
+ }
+#endif
+
public:
+ GuiView * gv_;
GuiWorkArea * current_work_area_;
GuiWorkArea * current_main_work_area_;
QSplitter * splitter_;
BackgroundWidget * bg_widget_;
/// view's toolbars
ToolbarMap toolbars_;
+ ProgressInterface* progress_;
/// The main layout box.
/**
* \warning Don't Delete! The layout box is actually owned by
*/
LayoutBox * layout_;
- ///
- map<string, Inset *> open_insets_;
-
///
map<string, DialogPtr> dialogs_;
///
TocModels toc_models_;
+
+#if (QT_VERSION >= 0x040400)
+ ///
+ QFutureWatcher<docstring> autosave_watcher_;
+ QFutureWatcher<docstring> preview_watcher_;
+#else
+ struct DummyWatcher { bool isRunning(){return false;} };
+ DummyWatcher preview_watcher_;
+#endif
};
GuiView::GuiView(int id)
- : d(*new GuiViewPrivate), id_(id), closing_(false)
+ : d(*new GuiViewPrivate(this)), id_(id), closing_(false)
{
// GuiToolbars *must* be initialised before the menu bar.
normalSizedIcons(); // at least on Mac the default is 32 otherwise, which is huge
// set ourself as the current view. This is needed for the menu bar
// filling, at least for the static special menu item on Mac. Otherwise
// they are greyed out.
- theLyXFunc().setLyXView(this);
+ guiApp->setCurrentView(this);
// Fill up the menu bar.
guiApp->menus().fillMenuBar(menuBar(), this, true);
setWindowIcon(getPixmap("images/", "lyx", "png"));
#endif
+#if (QT_VERSION >= 0x040300)
+ // use tabbed dock area for multiple docks
+ // (such as "source" and "messages")
+ setDockOptions(QMainWindow::ForceTabbedDocks);
+#endif
+
// For Drag&Drop.
setAcceptDrops(true);
statusBar()->setSizeGripEnabled(true);
+ updateStatusBar();
+
+#if (QT_VERSION >= 0x040400)
+ connect(&d.autosave_watcher_, SIGNAL(finished()), this,
+ SLOT(threadFinished()));
+ connect(&d.preview_watcher_, SIGNAL(finished()), this,
+ SLOT(threadFinished()));
+#endif
+
+ connect(this, SIGNAL(triggerShowDialog(QString const &, QString const &, Inset *)),
+ SLOT(doShowDialog(QString const &, QString const &, Inset *)));
// Forbid too small unresizable window because it can happen
// with some window manager under X11.
}
+void GuiView::threadFinished()
+{
+#if (QT_VERSION >= 0x040400)
+ QFutureWatcher<docstring> const * watcher =
+ static_cast<QFutureWatcher<docstring> const *>(sender());
+ message(watcher->result());
+#endif
+}
+
+
void GuiView::saveLayout() const
{
QSettings settings;
dialog->prepareView();
if ((dialog = findOrBuild("view-source", true)))
dialog->prepareView();
+ if ((dialog = findOrBuild("progress", true)))
+ dialog->prepareView();
if (!restoreState(settings.value("layout").toByteArray(), 0))
initToolbars();
return it->second;
LYXERR(Debug::GUI, "Toolbar::display: no toolbar named " << name);
- message(bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name)));
return 0;
}
if (!tb)
continue;
int const visibility = guiApp->toolbars().defaultVisibility(cit->name);
- bool newline = true;
+ bool newline = !(visibility & Toolbars::SAMEROW);
tb->setVisible(false);
tb->setVisibility(visibility);
if (visibility & Toolbars::BOTTOM) {
// Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
#if (QT_VERSION >= 0x040202)
- addToolBarBreak(Qt::BottomToolBarArea);
+ if (newline)
+ addToolBarBreak(Qt::BottomToolBarArea);
#endif
addToolBar(Qt::BottomToolBarArea, tb);
}
if (visibility & Toolbars::LEFT) {
// Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
#if (QT_VERSION >= 0x040202)
- addToolBarBreak(Qt::LeftToolBarArea);
+ if (newline)
+ addToolBarBreak(Qt::LeftToolBarArea);
#endif
addToolBar(Qt::LeftToolBarArea, tb);
}
if (visibility & Toolbars::RIGHT) {
// Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
#if (QT_VERSION >= 0x040202)
- addToolBarBreak(Qt::RightToolBarArea);
+ if (newline)
+ addToolBarBreak(Qt::RightToolBarArea);
#endif
addToolBar(Qt::RightToolBarArea, tb);
}
void GuiView::setFocus()
{
LYXERR(Debug::DEBUG, "GuiView::setFocus()" << this);
- // Make sure LyXFunc points to the correct view.
- guiApp->setCurrentView(this);
- theLyXFunc().setLyXView(this);
QMainWindow::setFocus();
- if (d.current_work_area_)
- d.current_work_area_->setFocus();
+}
+
+
+void GuiView::focusInEvent(QFocusEvent * e)
+{
+ LYXERR(Debug::DEBUG, "GuiView::focusInEvent()" << this);
+ QMainWindow::focusInEvent(e);
+ // Make sure guiApp points to the correct view.
+ guiApp->setCurrentView(this);
+ if (currentMainWorkArea())
+ currentMainWorkArea()->setFocus();
+ else if (currentWorkArea())
+ currentWorkArea()->setFocus();
+ else
+ d.bg_widget_->setFocus();
}
for (int i = 0; i != files.size(); ++i) {
string const file = os::internal_path(fromqstr(
files.at(i).toLocalFile()));
- if (!file.empty()) {
- // Asynchronously post the event. DropEvent usually come
- // from the BufferView. But reloading a file might close
- // the BufferView from within its own event handler.
- guiApp->dispatchDelayed(FuncRequest(LFUN_FILE_OPEN, file));
- event->accept();
+ if (file.empty())
+ continue;
+
+ string const ext = support::getExtension(file);
+ vector<const Format *> found_formats;
+
+ // Find all formats that have the correct extension.
+ vector<const Format *> const & import_formats
+ = theConverters().importableFormats();
+ vector<const Format *>::const_iterator it = import_formats.begin();
+ for (; it != import_formats.end(); ++it)
+ if ((*it)->extension() == ext)
+ found_formats.push_back(*it);
+
+ FuncRequest cmd;
+ if (found_formats.size() >= 1) {
+ if (found_formats.size() > 1) {
+ //FIXME: show a dialog to choose the correct importable format
+ LYXERR(Debug::FILES,
+ "Multiple importable formats found, selecting first");
+ }
+ string const arg = found_formats[0]->name() + " " + file;
+ cmd = FuncRequest(LFUN_BUFFER_IMPORT, arg);
+ }
+ else {
+ //FIXME: do we have to explicitly check whether it's a lyx file?
+ LYXERR(Debug::FILES,
+ "No formats found, trying to open it as a lyx file");
+ cmd = FuncRequest(LFUN_FILE_OPEN, file);
}
+
+ // Asynchronously post the event. DropEvent usually comes
+ // from the BufferView. But reloading a file might close
+ // the BufferView from within its own event handler.
+ guiApp->dispatchDelayed(cmd);
+ event->accept();
}
}
{
if (ForkedProcess::iAmAChild())
return;
+
+ // call is moved to GUI-thread by GuiProgress
+ d.progress_->appendMessage(toqstr(str));
+}
+
- statusBar()->showMessage(toqstr(str));
+void GuiView::updateMessage(QString const & str)
+{
+ statusBar()->showMessage(str);
d.statusbar_timer_.stop();
d.statusbar_timer_.start(3000);
}
void GuiView::clearMessage()
{
- if (!hasFocus())
- return;
- theLyXFunc().setLyXView(this);
- statusBar()->showMessage(toqstr(theLyXFunc().viewStatusMessage()));
+ // FIXME: This code was introduced in r19643 to fix bug #4123. However,
+ // the hasFocus function mostly returns false, even if the focus is on
+ // a workarea in this view.
+ //if (!hasFocus())
+ // return;
+ showMessage();
d.statusbar_timer_.stop();
}
void GuiView::updateWindowTitle(GuiWorkArea * wa)
{
- if (wa != d.current_work_area_)
+ if (wa != d.current_work_area_
+ || wa->bufferView().buffer().isInternal())
return;
setWindowTitle(qt_("LyX: ") + wa->windowTitle());
setWindowIconText(wa->windowIconText());
updateDialogs();
resetWindowTitleAndIconText();
+ updateStatusBar();
if (lyxrc.open_buffers_in_tabs)
// Nothing more to do, the window should stay open.
if (d.statusbar_timer_.isActive())
return;
- theLyXFunc().setLyXView(this);
- statusBar()->showMessage(toqstr(theLyXFunc().viewStatusMessage()));
+ showMessage();
}
-bool GuiView::hasFocus() const
+void GuiView::showMessage()
{
- return qApp->activeWindow() == this;
+ QString msg = toqstr(theGuiApp()->viewStatusMessage());
+ if (msg.isEmpty()) {
+ BufferView const * bv = currentBufferView();
+ if (bv)
+ msg = toqstr(bv->cursor().currentState());
+ else
+ msg = qt_("Welcome to LyX!");
+ }
+ statusBar()->showMessage(msg);
}
// break;
case QEvent::WindowActivate: {
- if (this == guiApp->currentView()) {
+ GuiView * old_view = guiApp->currentView();
+ if (this == old_view) {
setFocus();
return QMainWindow::event(e);
}
+ if (old_view && old_view->currentBufferView()) {
+ // save current selection to the selection buffer to allow
+ // middle-button paste in this window.
+ cap::saveSelection(old_view->currentBufferView()->cursor());
+ }
guiApp->setCurrentView(this);
- theLyXFunc().setLyXView(this);
if (d.current_work_area_) {
BufferView & bv = d.current_work_area_->bufferView();
connectBufferView(bv);
}
}
#endif
-
- if (d.current_work_area_)
- // Nothing special to do.
- return QMainWindow::event(e);
-
- QKeyEvent * ke = static_cast<QKeyEvent*>(e);
- // Let Qt handle menu access and the Tab keys to navigate keys to navigate
- // between controls.
- if (ke->modifiers() & Qt::AltModifier || ke->key() == Qt::Key_Tab
- || ke->key() == Qt::Key_Backtab)
- return QMainWindow::event(e);
-
- // Allow processing of shortcuts that are allowed even when no Buffer
- // is viewed.
- theLyXFunc().setLyXView(this);
- KeySymbol sym;
- setKeySymbol(&sym, ke);
- theLyXFunc().processKeySym(sym, q_key_state(ke->modifiers()));
- e->accept();
- return true;
+ return QMainWindow::event(e);
}
default:
if (old_gwa == wa)
return;
- if (view())
- cap::saveSelection(view()->cursor());
+ if (currentBufferView())
+ cap::saveSelection(currentBufferView()->cursor());
theGuiApp()->setCurrentView(this);
d.current_work_area_ = wa;
}
-Buffer * GuiView::buffer()
-{
- if (d.current_work_area_)
- return &d.current_work_area_->bufferView().buffer();
- return 0;
-}
-
-
-Buffer const * GuiView::buffer() const
-{
- if (d.current_work_area_)
- return &d.current_work_area_->bufferView().buffer();
- return 0;
-}
-
-
void GuiView::setBuffer(Buffer * newBuffer)
{
- LYXERR(Debug::DEBUG, "Setting buffer: " << newBuffer << std::endl);
+ LYXERR(Debug::DEBUG, "Setting buffer: " << newBuffer << endl);
LASSERT(newBuffer, return);
setBusy(true);
void GuiView::errors(string const & error_type, bool from_master)
{
ErrorList & el = from_master ?
- buffer()->masterBuffer()->errorList(error_type)
- : buffer()->errorList(error_type);
+ documentBufferView()->buffer().masterBuffer()->errorList(error_type)
+ : documentBufferView()->buffer().errorList(error_type);
string data = error_type;
if (from_master)
data = "from_master|" + error_type;
}
-void GuiView::updateTocItem(std::string const & type, DocIterator const & dit)
+void GuiView::updateTocItem(string const & type, DocIterator const & dit)
{
d.toc_models_.updateItem(toqstr(type), dit);
}
void GuiView::structureChanged()
{
- d.toc_models_.reset(view());
+ d.toc_models_.reset(documentBufferView());
// Navigator needs more than a simple update in this case. It needs to be
// rebuilt.
updateDialog("toc", "");
}
-BufferView * GuiView::view()
+BufferView * GuiView::documentBufferView()
+{
+ return currentMainWorkArea()
+ ? ¤tMainWorkArea()->bufferView()
+ : 0;
+}
+
+
+BufferView const * GuiView::documentBufferView() const
+{
+ return currentMainWorkArea()
+ ? ¤tMainWorkArea()->bufferView()
+ : 0;
+}
+
+
+BufferView * GuiView::currentBufferView()
+{
+ return d.current_work_area_ ? &d.current_work_area_->bufferView() : 0;
+}
+
+
+BufferView const * GuiView::currentBufferView() const
{
return d.current_work_area_ ? &d.current_work_area_->bufferView() : 0;
}
+#if (QT_VERSION >= 0x040400)
+static docstring saveAndDestroyBuffer(Buffer * buffer, FileName const & fname)
+{
+ bool failed = true;
+ FileName const tmp_ret = FileName::tempName("lyxauto");
+ if (!tmp_ret.empty()) {
+ if (buffer->writeFile(tmp_ret))
+ failed = !tmp_ret.moveTo(fname);
+ }
+ if (failed) {
+ // failed to write/rename tmp_ret so try writing direct
+ failed = buffer->writeFile(fname);
+ }
+ delete buffer;
+ return failed
+ ? _("Automatic save failed!")
+ : _("Automatic save done.");
+}
+#endif
+
+
void GuiView::autoSave()
{
LYXERR(Debug::INFO, "Running autoSave()");
- if (buffer())
- view()->buffer().autoSave();
+ Buffer * buffer = documentBufferView()
+ ? &documentBufferView()->buffer() : 0;
+ if (!buffer)
+ return;
+
+#if (QT_VERSION >= 0x040400)
+ QFuture<docstring> f = QtConcurrent::run(saveAndDestroyBuffer, buffer->clone(),
+ buffer->getAutosaveFilename());
+ d.autosave_watcher_.setFuture(f);
+#else
+ buffer->autoSave();
+#endif
}
bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
{
bool enable = true;
- Buffer * buf = buffer();
+ Buffer * buf = currentBufferView()
+ ? ¤tBufferView()->buffer() : 0;
+ Buffer * doc_buffer = documentBufferView()
+ ? &(documentBufferView()->buffer()) : 0;
+
+ // Check whether we need a buffer
+ if (!lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer) && !buf) {
+ // no, exit directly
+ flag.message(from_utf8(N_("Command not allowed with"
+ "out any document open")));
+ flag.setEnabled(false);
+ return true;
+ }
if (cmd.origin == FuncRequest::TOC) {
GuiToc * toc = static_cast<GuiToc*>(findOrBuild("toc", false));
FuncStatus fs;
- if (toc->getStatus(view()->cursor(), cmd, fs))
+ if (toc->getStatus(documentBufferView()->cursor(), cmd, fs))
flag |= fs;
else
flag.setEnabled(false);
}
switch(cmd.action) {
+ case LFUN_BUFFER_IMPORT:
+ break;
+
+ case LFUN_MASTER_BUFFER_UPDATE:
+ case LFUN_MASTER_BUFFER_VIEW:
+ enable = doc_buffer && doc_buffer->parent() != 0
+ && !d.preview_watcher_.isRunning();
+ break;
+
+ case LFUN_BUFFER_UPDATE:
+ case LFUN_BUFFER_VIEW: {
+ if (!doc_buffer || d.preview_watcher_.isRunning()) {
+ enable = false;
+ break;
+ }
+ string format = to_utf8(cmd.argument());
+ if (cmd.argument().empty())
+ format = doc_buffer->getDefaultOutputFormat();
+ enable = doc_buffer->isExportableFormat(format);
+ break;
+ }
+
+ case LFUN_BUFFER_RELOAD:
+ enable = doc_buffer && !doc_buffer->isUnnamed()
+ && doc_buffer->fileName().exists()
+ && (!doc_buffer->isClean()
+ || doc_buffer->isExternallyModified(Buffer::timestamp_method));
+ break;
+
+ case LFUN_BUFFER_CHILD_OPEN:
+ enable = doc_buffer;
+ break;
+
case LFUN_BUFFER_WRITE:
- enable = buf && (buf->isUnnamed() || !buf->isClean());
+ enable = doc_buffer && (doc_buffer->isUnnamed() || !doc_buffer->isClean());
+ break;
+
+ //FIXME: This LFUN should be moved to GuiApplication.
+ case LFUN_BUFFER_WRITE_ALL: {
+ // We enable the command only if there are some modified buffers
+ Buffer * first = theBufferList().first();
+ enable = false;
+ if (!first)
+ break;
+ Buffer * b = first;
+ // We cannot use a for loop as the buffer list is a cycle.
+ do {
+ if (!b->isClean()) {
+ enable = true;
+ break;
+ }
+ b = theBufferList().next(b);
+ } while (b != first);
break;
+ }
case LFUN_BUFFER_WRITE_AS:
- enable = buf;
+ enable = doc_buffer;
+ break;
+
+ case LFUN_BUFFER_CLOSE:
+ enable = doc_buffer;
break;
case LFUN_BUFFER_CLOSE_ALL:
case LFUN_SPLIT_VIEW:
if (cmd.getArg(0) == "vertical")
- enable = buf && (d.splitter_->count() == 1 ||
+ enable = doc_buffer && (d.splitter_->count() == 1 ||
d.splitter_->orientation() == Qt::Vertical);
else
- enable = buf && (d.splitter_->count() == 1 ||
+ enable = doc_buffer && (d.splitter_->count() == 1 ||
d.splitter_->orientation() == Qt::Horizontal);
break;
enable = d.currentTabWorkArea();
break;
- case LFUN_TOOLBAR_TOGGLE:
- if (GuiToolbar * t = toolbar(cmd.getArg(0)))
+ case LFUN_TOOLBAR_TOGGLE: {
+ string const name = cmd.getArg(0);
+ if (GuiToolbar * t = toolbar(name))
flag.setOnOff(t->isVisible());
+ else {
+ enable = false;
+ docstring const msg =
+ bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name));
+ flag.message(msg);
+ }
+ break;
+ }
+
+ case LFUN_DROP_LAYOUTS_CHOICE:
+ enable = buf;
break;
case LFUN_UI_TOGGLE:
flag.setOnOff(isFullScreen());
break;
+ case LFUN_DIALOG_DISCONNECT_INSET:
+ break;
+
+ case LFUN_DIALOG_HIDE:
+ // FIXME: should we check if the dialog is shown?
+ break;
+
case LFUN_DIALOG_TOGGLE:
flag.setOnOff(isDialogVisible(cmd.getArg(0)));
// fall through to set "enable"
case LFUN_DIALOG_SHOW: {
string const name = cmd.getArg(0);
- if (!buf)
+ if (!doc_buffer)
enable = name == "aboutlyx"
|| name == "file" //FIXME: should be removed.
|| name == "prefs"
- || name == "texinfo";
+ || name == "texinfo"
+ || name == "progress"
+ || name == "compare";
else if (name == "print")
- enable = buf->isExportable("dvi")
+ enable = doc_buffer->isExportable("dvi")
&& lyxrc.print_command != "none";
else if (name == "character" || name == "symbols") {
- if (buf->isReadonly() || !view() || !view()->cursor().inTexted())
+ if (!buf || buf->isReadonly()
+ || !currentBufferView()->cursor().inTexted())
enable = false;
else {
// FIXME we should consider passthru
// paragraphs too.
- Inset const & in = view()->cursor().inset();
+ Inset const & in = currentBufferView()->cursor().inset();
enable = !in.getLayout().isPassThru();
}
}
else if (name == "latexlog")
- enable = FileName(buf->logName()).isReadableFile();
+ enable = FileName(doc_buffer->logName()).isReadableFile();
else if (name == "spellchecker")
- enable = theSpellChecker() && !buf->isReadonly();
+ enable = theSpellChecker() && !doc_buffer->isReadonly();
else if (name == "vclog")
- enable = buf->lyxvc().inUse();
+ enable = doc_buffer->lyxvc().inUse();
break;
}
break;
}
- case LFUN_INSET_APPLY: {
- string const name = cmd.getArg(0);
- Inset * inset = getOpenInset(name);
- if (inset) {
- FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument());
- FuncStatus fs;
- if (!inset->getStatus(view()->cursor(), fr, fs)) {
- // Every inset is supposed to handle this
- LASSERT(false, break);
- }
- flag |= fs;
- } else {
- FuncRequest fr(LFUN_INSET_INSERT, cmd.argument());
- flag |= lyx::getStatus(fr);
- }
- enable = flag.enabled();
+ case LFUN_COMMAND_EXECUTE:
+ case LFUN_MESSAGE:
+ case LFUN_MENU_OPEN:
+ // Nothing to check.
break;
- }
case LFUN_COMPLETION_INLINE:
if (!d.current_work_area_
- || !d.current_work_area_->completer().inlinePossible(view()->cursor()))
+ || !d.current_work_area_->completer().inlinePossible(
+ currentBufferView()->cursor()))
enable = false;
break;
case LFUN_COMPLETION_POPUP:
if (!d.current_work_area_
- || !d.current_work_area_->completer().popupPossible(view()->cursor()))
+ || !d.current_work_area_->completer().popupPossible(
+ currentBufferView()->cursor()))
enable = false;
break;
case LFUN_COMPLETION_COMPLETE:
if (!d.current_work_area_
- || !d.current_work_area_->completer().inlinePossible(view()->cursor()))
+ || !d.current_work_area_->completer().inlinePossible(
+ currentBufferView()->cursor()))
enable = false;
break;
break;
case LFUN_BUFFER_ZOOM_OUT:
- enable = buf && lyxrc.zoom > 10;
+ enable = doc_buffer && lyxrc.zoom > 10;
break;
case LFUN_BUFFER_ZOOM_IN:
- enable = buf;
+ enable = doc_buffer;
+ break;
+
+ case LFUN_BUFFER_NEXT:
+ case LFUN_BUFFER_PREVIOUS:
+ // FIXME: should we check is there is an previous or next buffer?
+ break;
+ case LFUN_BUFFER_SWITCH:
+ // toggle on the current buffer, but do not toggle off
+ // the other ones (is that a good idea?)
+ if (doc_buffer
+ && to_utf8(cmd.argument()) == doc_buffer->absFileName())
+ flag.setOnOff(true);
+ break;
+
+ case LFUN_VC_REGISTER:
+ enable = doc_buffer && !doc_buffer->lyxvc().inUse();
+ break;
+ case LFUN_VC_CHECK_IN:
+ enable = doc_buffer && doc_buffer->lyxvc().checkInEnabled();
+ break;
+ case LFUN_VC_CHECK_OUT:
+ enable = doc_buffer && doc_buffer->lyxvc().checkOutEnabled();
+ break;
+ case LFUN_VC_LOCKING_TOGGLE:
+ enable = doc_buffer && !doc_buffer->isReadonly()
+ && doc_buffer->lyxvc().lockingToggleEnabled();
+ flag.setOnOff(enable && doc_buffer->lyxvc().locking());
+ break;
+ case LFUN_VC_REVERT:
+ enable = doc_buffer && doc_buffer->lyxvc().inUse();
+ break;
+ case LFUN_VC_UNDO_LAST:
+ enable = doc_buffer && doc_buffer->lyxvc().undoLastEnabled();
+ break;
+ case LFUN_VC_REPO_UPDATE:
+ enable = doc_buffer && doc_buffer->lyxvc().inUse();
+ break;
+ case LFUN_VC_COMMAND: {
+ if (cmd.argument().empty())
+ enable = false;
+ if (!doc_buffer && contains(cmd.getArg(0), 'D'))
+ enable = false;
+ break;
+ }
+ case LFUN_VC_COMPARE:
+ enable = doc_buffer && !cmd.argument().empty()
+ && doc_buffer->lyxvc().prepareFileRevisionEnabled();
+ break;
+
+ case LFUN_SERVER_GOTO_FILE_ROW:
break;
default:
if (lyxrc.use_lastfilepos) {
LastFilePosSection::FilePos filepos =
theSession().lastFilePos().load(filename);
- view()->moveToPosition(filepos.pit, filepos.pos, 0, 0);
+ documentBufferView()->moveToPosition(filepos.pit, filepos.pos, 0, 0);
}
if (tolastfiles)
{
string initpath = lyxrc.document_path;
- if (buffer()) {
- string const trypath = buffer()->filePath();
+ if (documentBufferView()) {
+ string const trypath = documentBufferView()->buffer().filePath();
// If directory is writeable, use this as default.
if (FileName(trypath).isDirWritable())
initpath = trypath;
string filename2 = (loader_format == format) ? filename.absFilename()
: support::changeExtension(filename.absFilename(),
formats.extension(loader_format));
- lv->view()->insertPlaintextFile(FileName(filename2), as_paragraphs);
- theLyXFunc().setLyXView(lv);
+ lv->currentBufferView()->insertPlaintextFile(FileName(filename2),
+ as_paragraphs);
+ guiApp->setCurrentView(lv);
lyx::dispatch(FuncRequest(LFUN_MARK_OFF));
}
// need user interaction
if (filename.empty()) {
string initpath = lyxrc.document_path;
-
- Buffer const * buf = buffer();
- if (buf) {
- string const trypath = buf->filePath();
+ if (documentBufferView()) {
+ string const trypath = documentBufferView()->buffer().filePath();
// If directory is writeable, use this as default.
if (FileName(trypath).isDirWritable())
initpath = trypath;
void GuiView::newDocument(string const & filename, bool from_template)
{
FileName initpath(lyxrc.document_path);
- Buffer * buf = buffer();
- if (buf) {
- FileName const trypath(buf->filePath());
+ if (documentBufferView()) {
+ FileName const trypath(documentBufferView()->buffer().filePath());
// If directory is writeable, use this as default.
if (trypath.isDirWritable())
initpath = trypath;
Buffer * b;
if (filename.empty())
- b = newUnnamedFile(templatefile, initpath);
+ b = newUnnamedFile(initpath, to_utf8(_("newfile")), templatefile);
else
b = newFile(filename, templatefile, true);
// If no new document could be created, it is unsure
// whether there is a valid BufferView.
- if (view())
+ if (currentBufferView())
// Ensure the cursor is correctly positioned on screen.
- view()->showCursor();
+ currentBufferView()->showCursor();
}
void GuiView::insertLyXFile(docstring const & fname)
{
- BufferView * bv = view();
+ BufferView * bv = documentBufferView();
if (!bv)
return;
void GuiView::insertPlaintextFile(docstring const & fname,
bool asParagraph)
{
- BufferView * bv = view();
+ BufferView * bv = documentBufferView();
if (!bv)
return;
bool GuiView::closeBuffer()
{
GuiWorkArea * wa = currentMainWorkArea();
+ setCurrentWorkArea(wa);
Buffer & buf = wa->bufferView().buffer();
return wa && closeWorkArea(wa, !buf.parent());
}
bool GuiView::closeWorkAreaAll()
{
- // To write in the session file which workarea was active.
- GuiWorkArea * active_wa = currentMainWorkArea();
- setCurrentWorkArea(active_wa);
+ setCurrentWorkArea(currentMainWorkArea());
// We might be in a situation that there is still a tabWorkArea, but
// there are no tabs anymore. This can happen when we get here after a
++empty_twa;
else {
setCurrentWorkArea(twa->currentWorkArea());
- if (!closeTabWorkArea(twa, active_wa))
+ if (!closeTabWorkArea(twa))
return false;
}
}
}
-bool GuiView::closeWorkArea(GuiWorkArea * wa, bool close_buffer,
- bool is_active)
+bool GuiView::closeWorkArea(GuiWorkArea * wa, bool close_buffer)
{
+ if (!wa)
+ return false;
+
Buffer & buf = wa->bufferView().buffer();
+ if (close_buffer)
+ return closeBuffer(buf);
+ else {
+ if (!inMultiTabs(wa))
+ if (!saveBufferIfNeeded(buf, true))
+ return false;
+ removeWorkArea(wa);
+ return true;
+ }
+}
+
+
+bool GuiView::closeBuffer(Buffer & buf)
+{
// If we are in a close_event all children will be closed in some time,
// so no need to do it here. This will ensure that the children end up
// in the session file in the correct order. If we close the master
// buffer, we can close or release the child buffers here too.
- if (close_buffer && !closing_) {
- vector<Buffer *> clist = buf.getChildren();
+ if (!closing_) {
+ vector<Buffer *> clist = buf.getChildren(false);
for (vector<Buffer *>::const_iterator it = clist.begin();
it != clist.end(); ++it) {
// If a child is dirty, do not close
//FIXME: we should update only the bookmarks related to this buffer!
LYXERR(Debug::DEBUG, "GuiView::closeBuffer()");
for (size_t i = 0; i < theSession().bookmarks().size(); ++i)
- theLyXFunc().gotoBookmark(i+1, false, false);
-
- // if we are only hiding the buffer and there are multiple views
- // of the buffer, then we do not need to ensure a clean buffer.
- bool const allow_dirty = inMultiTabs(wa) && !close_buffer;
-
- if (allow_dirty || saveBufferIfNeeded(buf, !close_buffer)) {
- // save in sessions if requested
- // do not save childs if their master
- // is opened as well
- if (closing_)
- theSession().lastOpened().add(buf.fileName(), is_active);
- if (!close_buffer)
- removeWorkArea(wa);
- else
- theBufferList().release(&buf);
+ guiApp->gotoBookmark(i+1, false, false);
+
+ if (saveBufferIfNeeded(buf, false)) {
+ theBufferList().release(&buf);
return true;
}
return false;
}
-bool GuiView::closeTabWorkArea(TabWorkArea * twa, GuiWorkArea * main_work_area)
+bool GuiView::closeTabWorkArea(TabWorkArea * twa)
{
while (twa == d.currentTabWorkArea()) {
twa->setCurrentIndex(twa->count()-1);
GuiWorkArea * wa = twa->currentWorkArea();
- bool const is_active_wa = main_work_area == wa;
Buffer & b = wa->bufferView().buffer();
// We only want to close the buffer if the same buffer is not visible
bool const close_buffer =
!inMultiViews(wa) && !b.parent() && closing_;
- if (!closeWorkArea(wa, close_buffer, is_active_wa))
+ if (!closeWorkArea(wa, close_buffer))
return false;
}
return true;
buf.removeAutosaveFile();
if (hiding)
// revert all changes
- buf.loadLyXFile(buf.fileName());
+ buf.reload();
buf.markClean();
break;
case 2:
void GuiView::gotoNextOrPreviousBuffer(NextOrPrevious np)
{
- Buffer * const curbuf = buffer();
+ Buffer * const curbuf = documentBufferView()
+ ? &documentBufferView()->buffer() : 0;
Buffer * nextbuf = curbuf;
while (true) {
if (np == NEXTBUFFER)
}
-bool GuiView::dispatch(FuncRequest const & cmd)
+/// make sure the document is saved
+static bool ensureBufferClean(Buffer * buffer)
+{
+ LASSERT(buffer, return false);
+ if (buffer->isClean() && !buffer->isUnnamed())
+ return true;
+
+ docstring const file = buffer->fileName().displayName(30);
+ docstring title;
+ docstring text;
+ if (!buffer->isUnnamed()) {
+ text = bformat(_("The document %1$s has unsaved "
+ "changes.\n\nDo you want to save "
+ "the document?"), file);
+ title = _("Save changed document?");
+
+ } else {
+ text = bformat(_("The document %1$s has not been "
+ "saved yet.\n\nDo you want to save "
+ "the document?"), file);
+ title = _("Save new document?");
+ }
+ int const ret = Alert::prompt(title, text, 0, 1, _("&Save"), _("&Cancel"));
+
+ if (ret == 0)
+ dispatch(FuncRequest(LFUN_BUFFER_WRITE));
+
+ return buffer->isClean() && !buffer->isUnnamed();
+}
+
+
+void GuiView::reloadBuffer()
+{
+ Buffer * buf = &documentBufferView()->buffer();
+ buf->reload();
+}
+
+
+void GuiView::checkExternallyModifiedBuffers()
+{
+ BufferList::iterator bit = theBufferList().begin();
+ BufferList::iterator const bend = theBufferList().end();
+ for (; bit != bend; ++bit) {
+ if ((*bit)->fileName().exists()
+ && (*bit)->isExternallyModified(Buffer::checksum_method)) {
+ docstring text = bformat(_("Document \n%1$s\n has been externally modified."
+ " Reload now? Any local changes will be lost."),
+ from_utf8((*bit)->absFileName()));
+ int const ret = Alert::prompt(_("Reload externally changed document?"),
+ text, 0, 1, _("&Reload"), _("&Cancel"));
+ if (!ret)
+ (*bit)->reload();
+ }
+ }
+}
+
+
+//FIXME use a DispatchResult object to transmit messages
+void GuiView::dispatchVC(FuncRequest const & cmd)
+{
+ // message for statusbar
+ string msg;
+ Buffer * buffer = documentBufferView()
+ ? &(documentBufferView()->buffer()) : 0;
+
+ switch (cmd.action) {
+ case LFUN_VC_REGISTER:
+ if (!buffer || !ensureBufferClean(buffer))
+ break;
+ if (!buffer->lyxvc().inUse()) {
+ if (buffer->lyxvc().registrer())
+ reloadBuffer();
+ }
+ break;
+
+ case LFUN_VC_CHECK_IN:
+ if (!buffer || !ensureBufferClean(buffer))
+ break;
+ if (buffer->lyxvc().inUse() && !buffer->isReadonly()) {
+ msg = buffer->lyxvc().checkIn();
+ if (!msg.empty())
+ reloadBuffer();
+ }
+ break;
+
+ case LFUN_VC_CHECK_OUT:
+ if (!buffer || !ensureBufferClean(buffer))
+ break;
+ if (buffer->lyxvc().inUse()) {
+ msg = buffer->lyxvc().checkOut();
+ reloadBuffer();
+ }
+ break;
+
+ case LFUN_VC_LOCKING_TOGGLE:
+ LASSERT(buffer, return);
+ if (!ensureBufferClean(buffer) || buffer->isReadonly())
+ break;
+ if (buffer->lyxvc().inUse()) {
+ string res = buffer->lyxvc().lockingToggle();
+ if (res.empty()) {
+ frontend::Alert::error(_("Revision control error."),
+ _("Error when setting the locking property."));
+ } else {
+ msg = res;
+ reloadBuffer();
+ }
+ }
+ break;
+
+ case LFUN_VC_REVERT:
+ LASSERT(buffer, return);
+ buffer->lyxvc().revert();
+ reloadBuffer();
+ break;
+
+ case LFUN_VC_UNDO_LAST:
+ LASSERT(buffer, return);
+ buffer->lyxvc().undoLast();
+ reloadBuffer();
+ break;
+
+ case LFUN_VC_REPO_UPDATE:
+ LASSERT(buffer, return);
+ if (ensureBufferClean(buffer)) {
+ msg = buffer->lyxvc().repoUpdate();
+ checkExternallyModifiedBuffers();
+ }
+ break;
+
+ case LFUN_VC_COMMAND: {
+ string flag = cmd.getArg(0);
+ if (buffer && contains(flag, 'R') && !ensureBufferClean(buffer))
+ break;
+ docstring message;
+ if (contains(flag, 'M')) {
+ if (!Alert::askForText(message, _("LyX VC: Log Message")))
+ break;
+ }
+ string path = cmd.getArg(1);
+ if (contains(path, "$$p") && buffer)
+ path = subst(path, "$$p", buffer->filePath());
+ LYXERR(Debug::LYXVC, "Directory: " << path);
+ FileName pp(path);
+ if (!pp.isReadableDirectory()) {
+ lyxerr << _("Directory is not accessible.") << endl;
+ break;
+ }
+ support::PathChanger p(pp);
+
+ string command = cmd.getArg(2);
+ if (command.empty())
+ break;
+ if (buffer) {
+ command = subst(command, "$$i", buffer->absFileName());
+ command = subst(command, "$$p", buffer->filePath());
+ }
+ command = subst(command, "$$m", to_utf8(message));
+ LYXERR(Debug::LYXVC, "Command: " << command);
+ Systemcall one;
+ one.startscript(Systemcall::Wait, command);
+
+ if (!buffer)
+ break;
+ if (contains(flag, 'I'))
+ buffer->markDirty();
+ if (contains(flag, 'R'))
+ reloadBuffer();
+
+ break;
+ }
+
+ case LFUN_VC_COMPARE: {
+
+ string rev1 = cmd.getArg(0);
+ string f1, f2;
+
+ // f1
+ if (!buffer->lyxvc().prepareFileRevision(rev1, f1))
+ break;
+
+ if (isStrInt(rev1) && convert<int>(rev1) <= 0) {
+ f2 = buffer->absFileName();
+ } else {
+ string rev2 = cmd.getArg(1);
+ if (rev2.empty())
+ break;
+ // f2
+ if (!buffer->lyxvc().prepareFileRevision(rev2, f2))
+ break;
+ }
+ // FIXME We need to call comparison feature here
+ // I'm not sure whether with or without dialog.
+ // (Gui)Compare::compare(f1, f2);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (!msg.empty())
+ message(from_utf8(msg));
+}
+
+
+void GuiView::openChildDocument(string const & fname)
{
- BufferView * bv = view();
+ LASSERT(documentBufferView(), return);
+ Buffer & buffer = documentBufferView()->buffer();
+ FileName const filename = support::makeAbsPath(fname, buffer.filePath());
+ documentBufferView()->saveBookmark(false);
+ Buffer * child = 0;
+ bool parsed = false;
+ if (theBufferList().exists(filename)) {
+ child = theBufferList().getBuffer(filename);
+ } else {
+ message(bformat(_("Opening child document %1$s..."),
+ makeDisplayPath(filename.absFilename())));
+ child = loadDocument(filename, false);
+ parsed = true;
+ }
+ if (!child)
+ return;
+
+ // Set the parent name of the child document.
+ // This makes insertion of citations and references in the child work,
+ // when the target is in the parent or another child document.
+ child->setParent(&buffer);
+ child->masterBuffer()->updateLabels();
+ setBuffer(child);
+ if (parsed)
+ child->errors("Parse");
+}
+
+
+bool GuiView::goToFileRow(string const & argument)
+{
+ string file_name;
+ int row;
+ size_t i = argument.find_last_of(' ');
+ if (i != string::npos) {
+ file_name = os::internal_path(trim(argument.substr(0, i)));
+ istringstream is(argument.substr(i + 1));
+ is >> row;
+ if (is.fail())
+ i = string::npos;
+ }
+ if (i == string::npos) {
+ LYXERR0("Wrong argument: " << argument);
+ return false;
+ }
+ Buffer * buf = 0;
+ string const abstmp = package().temp_dir().absFilename();
+ string const realtmp = package().temp_dir().realPath();
+ // We have to use os::path_prefix_is() here, instead of
+ // simply prefixIs(), because the file name comes from
+ // an external application and may need case adjustment.
+ if (os::path_prefix_is(file_name, abstmp, os::CASE_ADJUSTED)
+ || os::path_prefix_is(file_name, realtmp, os::CASE_ADJUSTED)) {
+ // Needed by inverse dvi search. If it is a file
+ // in tmpdir, call the apropriated function.
+ // If tmpdir is a symlink, we may have the real
+ // path passed back, so we correct for that.
+ if (!prefixIs(file_name, abstmp))
+ file_name = subst(file_name, realtmp, abstmp);
+ buf = theBufferList().getBufferFromTmp(file_name);
+ } else {
+ // Must replace extension of the file to be .lyx
+ // and get full path
+ FileName const s = fileSearch(string(),
+ support::changeExtension(file_name, ".lyx"), "lyx");
+ // Either change buffer or load the file
+ if (theBufferList().exists(s))
+ buf = theBufferList().getBuffer(s);
+ else if (s.exists()) {
+ buf = loadDocument(s);
+ buf->updateLabels();
+ buf->errors("Parse");
+ } else {
+ message(bformat(
+ _("File does not exist: %1$s"),
+ makeDisplayPath(file_name)));
+ return false;
+ }
+ }
+ setBuffer(buf);
+ documentBufferView()->setCursorFromRow(row);
+ return true;
+}
+
+
+#if (QT_VERSION >= 0x040400)
+static docstring exportAndDestroy(Buffer * buffer, string const & format)
+{
+ bool const update_unincluded =
+ buffer->params().maintain_unincluded_children
+ && !buffer->params().getIncludedChildren().empty();
+ bool const success = buffer->doExport(format, true, update_unincluded);
+ delete buffer;
+ return success
+ ? bformat(_("Successful export to format: %1$s"), from_utf8(format))
+ : bformat(_("Error exporting to format: %1$s"), from_utf8(format));
+}
+
+
+static docstring previewAndDestroy(Buffer * buffer, string const & format)
+{
+ bool const update_unincluded =
+ buffer->params().maintain_unincluded_children
+ && !buffer->params().getIncludedChildren().empty();
+ bool const success = buffer->preview(format, update_unincluded);
+ delete buffer;
+ return success
+ ? bformat(_("Successful preview of format: %1$s"), from_utf8(format))
+ : bformat(_("Error previewing format: %1$s"), from_utf8(format));
+}
+#endif
+
+
+void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
+{
+ BufferView * bv = currentBufferView();
// By default we won't need any update.
- if (bv)
- bv->cursor().updateFlags(Update::None);
- bool dispatched = true;
+ dr.update(Update::None);
+ // assume cmd will be dispatched
+ dr.dispatched(true);
+
+ Buffer * doc_buffer = documentBufferView()
+ ? &(documentBufferView()->buffer()) : 0;
if (cmd.origin == FuncRequest::TOC) {
GuiToc * toc = static_cast<GuiToc*>(findOrBuild("toc", false));
+ // FIXME: do we need to pass a DispatchResult object here?
toc->doDispatch(bv->cursor(), cmd);
- return true;
+ return;
}
+ string const argument = to_utf8(cmd.argument());
+
switch(cmd.action) {
+ case LFUN_BUFFER_CHILD_OPEN:
+ openChildDocument(to_utf8(cmd.argument()));
+ break;
+
case LFUN_BUFFER_IMPORT:
importDocument(to_utf8(cmd.argument()));
break;
+ case LFUN_BUFFER_EXPORT: {
+ if (!doc_buffer)
+ break;
+ // GCC only sees strfwd.h when building merged
+ if (::lyx::operator==(cmd.argument(), "custom")) {
+ dispatch(FuncRequest(LFUN_DIALOG_SHOW, "sendto"),
+ dr);
+ break;
+ }
+ if (doc_buffer->doExport(argument, false)) {
+ dr.setError(true);
+ dr.setMessage(bformat(_("Error exporting to format: %1$s."),
+ cmd.argument()));
+ }
+ break;
+ }
+
+ case LFUN_BUFFER_UPDATE: {
+ if (!doc_buffer)
+ break;
+ string format = argument;
+ if (argument.empty())
+ format = doc_buffer->getDefaultOutputFormat();
+#if EXPORT_in_THREAD && (QT_VERSION >= 0x040400)
+ d.progress_->clearMessages();
+ message(_("Exporting ..."));
+ QFuture<docstring> f = QtConcurrent::run(exportAndDestroy,
+ doc_buffer->clone(), format);
+ d.setPreviewFuture(f);
+#else
+ bool const update_unincluded =
+ doc_buffer->params().maintain_unincluded_children
+ && !doc_buffer->params().getIncludedChildren().empty();
+ doc_buffer->doExport(format, true, update_unincluded);
+#endif
+ break;
+ }
+ case LFUN_BUFFER_VIEW: {
+ if (!doc_buffer)
+ break;
+ string format = argument;
+ if (argument.empty())
+ format = doc_buffer->getDefaultOutputFormat();
+#if EXPORT_in_THREAD && (QT_VERSION >= 0x040400)
+ d.progress_->clearMessages();
+ message(_("Previewing ..."));
+ QFuture<docstring> f = QtConcurrent::run(previewAndDestroy,
+ doc_buffer->clone(), format);
+ d.setPreviewFuture(f);
+#else
+ bool const update_unincluded =
+ doc_buffer->params().maintain_unincluded_children
+ && !doc_buffer->params().getIncludedChildren().empty();
+ doc_buffer->preview(format, update_unincluded);
+#endif
+ break;
+ }
+ case LFUN_MASTER_BUFFER_UPDATE: {
+ if (!doc_buffer)
+ break;
+ string format = argument;
+ Buffer const * master = doc_buffer->masterBuffer();
+ if (argument.empty())
+ format = master->getDefaultOutputFormat();
+#if EXPORT_in_THREAD && (QT_VERSION >= 0x040400)
+ QFuture<docstring> f = QtConcurrent::run(exportAndDestroy,
+ master->clone(), format);
+ d.setPreviewFuture(f);
+#else
+ bool const update_unincluded =
+ master->params().maintain_unincluded_children
+ && !master->params().getIncludedChildren().empty();
+ master->doExport(format, true);
+#endif
+ break;
+ }
+ case LFUN_MASTER_BUFFER_VIEW: {
+ string format = argument;
+ Buffer const * master = doc_buffer->masterBuffer();
+ if (argument.empty())
+ format = master->getDefaultOutputFormat();
+#if EXPORT_in_THREAD && (QT_VERSION >= 0x040400)
+ QFuture<docstring> f = QtConcurrent::run(previewAndDestroy,
+ master->clone(), format);
+ d.setPreviewFuture(f);
+#else
+ master->preview(format);
+#endif
+ break;
+ }
case LFUN_BUFFER_SWITCH:
if (FileName::isAbsolute(to_utf8(cmd.argument()))) {
Buffer * buffer =
theBufferList().getBuffer(FileName(to_utf8(cmd.argument())));
if (buffer)
setBuffer(buffer);
- else
- bv->cursor().message(_("Document not loaded"));
+ else {
+ dr.setError(true);
+ dr.setMessage(_("Document not loaded"));
+ }
}
break;
insertPlaintextFile(cmd.argument(), false);
break;
+ case LFUN_BUFFER_RELOAD: {
+ LASSERT(doc_buffer, break);
+ docstring const file = makeDisplayPath(doc_buffer->absFileName(), 20);
+ docstring text = bformat(_("Any changes will be lost. Are you sure "
+ "you want to revert to the saved version of the document %1$s?"), file);
+ int const ret = Alert::prompt(_("Revert to saved document?"),
+ text, 1, 1, _("&Revert"), _("&Cancel"));
+
+ if (ret == 0) {
+ doc_buffer->markClean();
+ reloadBuffer();
+ }
+ break;
+ }
+
case LFUN_BUFFER_WRITE:
- if (bv)
- saveBuffer(bv->buffer());
+ LASSERT(doc_buffer, break);
+ saveBuffer(*doc_buffer);
break;
case LFUN_BUFFER_WRITE_AS:
- if (bv)
- renameBuffer(bv->buffer(), cmd.argument());
+ LASSERT(doc_buffer, break);
+ renameBuffer(*doc_buffer, cmd.argument());
break;
case LFUN_BUFFER_WRITE_ALL: {
}
b = theBufferList().next(b);
} while (b != first);
- message(_("All documents saved."));
+ dr.setMessage(_("All documents saved."));
break;
}
+ case LFUN_BUFFER_CLOSE:
+ closeBuffer();
+ break;
+
+ case LFUN_BUFFER_CLOSE_ALL:
+ closeBufferAll();
+ break;
+
case LFUN_TOOLBAR_TOGGLE: {
string const name = cmd.getArg(0);
if (GuiToolbar * t = toolbar(name))
case LFUN_DIALOG_UPDATE: {
string const name = to_utf8(cmd.argument());
- // Can only update a dialog connected to an existing inset
- Inset * inset = getOpenInset(name);
- if (inset) {
+ if (currentBufferView()) {
+ Inset * inset = currentBufferView()->editedInset(name);
+ // Can only update a dialog connected to an existing inset
+ if (!inset)
+ break;
+ // FIXME: get rid of this indirection; GuiView ask the inset
+ // if he is kind enough to update itself...
FuncRequest fr(LFUN_INSET_DIALOG_UPDATE, cmd.argument());
- inset->dispatch(view()->cursor(), fr);
+ //FIXME: pass DispatchResult here?
+ inset->dispatch(currentBufferView()->cursor(), fr);
} else if (name == "paragraph") {
lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE));
} else if (name == "prefs" || name == "document") {
case LFUN_DIALOG_TOGGLE: {
if (isDialogVisible(cmd.getArg(0)))
- dispatch(FuncRequest(LFUN_DIALOG_HIDE, cmd.argument()));
+ dispatch(FuncRequest(LFUN_DIALOG_HIDE, cmd.argument()), dr);
else
- dispatch(FuncRequest(LFUN_DIALOG_SHOW, cmd.argument()));
+ dispatch(FuncRequest(LFUN_DIALOG_SHOW, cmd.argument()), dr);
break;
}
showDialog("character", data);
} else if (name == "latexlog") {
Buffer::LogType type;
- string const logfile = buffer()->logName(&type);
+ string const logfile = doc_buffer->logName(&type);
switch (type) {
case Buffer::latexlog:
data = "latex ";
showDialog("log", data);
} else if (name == "vclog") {
string const data = "vc " +
- Lexer::quoteString(buffer()->lyxvc().getLogFile());
+ Lexer::quoteString(doc_buffer->lyxvc().getLogFile());
showDialog("log", data);
} else if (name == "symbols") {
data = bv->cursor().getEncoding()->name();
showDialog("symbols", data);
// bug 5274
} else if (name == "prefs" && isFullScreen()) {
- FuncRequest fr(LFUN_INSET_INSERT, "fullscreen");
- lfunUiToggle(fr);
+ lfunUiToggle("fullscreen");
showDialog("prefs", data);
} else
showDialog(name, data);
break;
}
- case LFUN_INSET_APPLY: {
- string const name = cmd.getArg(0);
- Inset * inset = getOpenInset(name);
- if (inset) {
- // put cursor in front of inset.
- if (!view()->setCursorFromInset(inset)) {
- LASSERT(false, break);
- }
-
- // useful if we are called from a dialog.
- view()->cursor().beginUndoGroup();
- view()->cursor().recordUndo();
- FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument());
- inset->dispatch(view()->cursor(), fr);
- view()->cursor().endUndoGroup();
- } else {
- FuncRequest fr(LFUN_INSET_INSERT, cmd.argument());
- lyx::dispatch(fr);
- }
+ case LFUN_MESSAGE:
+ dr.setMessage(cmd.argument());
break;
- }
- case LFUN_UI_TOGGLE:
- lfunUiToggle(cmd);
+ case LFUN_UI_TOGGLE: {
+ string arg = cmd.getArg(0);
+ if (!lfunUiToggle(arg)) {
+ docstring const msg = "ui-toggle " + _("%1$s unknown command!");
+ dr.setMessage(bformat(msg, from_utf8(arg)));
+ }
// Make sure the keyboard focus stays in the work area.
setFocus();
break;
+ }
- case LFUN_SPLIT_VIEW:
- if (Buffer * buf = buffer()) {
- string const orientation = cmd.getArg(0);
- d.splitter_->setOrientation(orientation == "vertical"
- ? Qt::Vertical : Qt::Horizontal);
- TabWorkArea * twa = addTabWorkArea();
- GuiWorkArea * wa = twa->addWorkArea(*buf, *this);
- setCurrentWorkArea(wa);
- }
+ case LFUN_SPLIT_VIEW: {
+ LASSERT(doc_buffer, break);
+ string const orientation = cmd.getArg(0);
+ d.splitter_->setOrientation(orientation == "vertical"
+ ? Qt::Vertical : Qt::Horizontal);
+ TabWorkArea * twa = addTabWorkArea();
+ GuiWorkArea * wa = twa->addWorkArea(*doc_buffer, *this);
+ setCurrentWorkArea(wa);
break;
-
+ }
case LFUN_CLOSE_TAB_GROUP:
if (TabWorkArea * twa = d.currentTabWorkArea()) {
- closeTabWorkArea(twa, false);
+ closeTabWorkArea(twa);
d.current_work_area_ = 0;
twa = d.currentTabWorkArea();
// Switch to the next GuiWorkArea in the found TabWorkArea.
lyx::dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE));
break;
+ case LFUN_VC_REGISTER:
+ case LFUN_VC_CHECK_IN:
+ case LFUN_VC_CHECK_OUT:
+ case LFUN_VC_REPO_UPDATE:
+ case LFUN_VC_LOCKING_TOGGLE:
+ case LFUN_VC_REVERT:
+ case LFUN_VC_UNDO_LAST:
+ case LFUN_VC_COMMAND:
+ case LFUN_VC_COMPARE:
+ dispatchVC(cmd);
+ break;
+
+ case LFUN_SERVER_GOTO_FILE_ROW:
+ goToFileRow(to_utf8(cmd.argument()));
+ break;
+
default:
- dispatched = false;
+ dr.dispatched(false);
break;
}
statusBar()->hide();
}
- return dispatched;
+ return;
}
-void GuiView::lfunUiToggle(FuncRequest const & cmd)
+bool GuiView::lfunUiToggle(string const & ui_component)
{
- string const arg = cmd.getArg(0);
- if (arg == "scrollbar") {
+ if (ui_component == "scrollbar") {
// hide() is of no help
if (d.current_work_area_->verticalScrollBarPolicy() ==
Qt::ScrollBarAlwaysOff)
else
d.current_work_area_->setVerticalScrollBarPolicy(
Qt::ScrollBarAlwaysOff);
- return;
- }
- if (arg == "statusbar") {
+ } else if (ui_component == "statusbar") {
statusBar()->setVisible(!statusBar()->isVisible());
- return;
- }
- if (arg == "menubar") {
+ } else if (ui_component == "menubar") {
menuBar()->setVisible(!menuBar()->isVisible());
- return;
- }
+ } else
#if QT_VERSION >= 0x040300
- if (arg == "frame") {
+ if (ui_component == "frame") {
int l, t, r, b;
getContentsMargins(&l, &t, &r, &b);
//are the frames in default state?
} else {
setContentsMargins(0, 0, 0, 0);
}
- return;
- }
+ } else
#endif
- if (arg == "fullscreen") {
+ if (ui_component == "fullscreen") {
toggleFullScreen();
- return;
- }
-
- message(bformat("LFUN_UI_TOGGLE " + _("%1$s unknown command!"), from_utf8(arg)));
+ } else
+ return false;
+ return true;
}
char const * const dialognames[] = {
"aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character",
-"citation", "document", "errorlist", "ert", "external", "file", "findreplace",
-"findreplaceadv", "float", "graphics", "href", "include", "index",
-"index_print", "info", "listings", "label", "log", "mathdelimiter",
+"citation", "compare", "document", "errorlist", "ert", "external", "file",
+"findreplace", "findreplaceadv", "float", "graphics", "href", "include",
+"index", "index_print", "info", "listings", "label", "log", "mathdelimiter",
"mathmatrix", "mathspace", "nomenclature", "nomencl_print", "note",
"paragraph", "phantom", "prefs", "print", "ref", "sendto", "space",
"spellchecker", "symbols", "tabular", "tabularcreate", "thesaurus", "texinfo",
-"toc", "view-source", "vspace", "wrap" };
+"toc", "view-source", "vspace", "wrap", "progress"};
char const * const * const end_dialognames =
dialognames + (sizeof(dialognames) / sizeof(char *));
void GuiView::resetDialogs()
{
- // Make sure that no LFUN uses any LyXView.
- theLyXFunc().setLyXView(0);
+ // Make sure that no LFUN uses any GuiView.
+ guiApp->setCurrentView(0);
saveLayout();
menuBar()->clear();
constructToolbars();
guiApp->menus().fillMenuBar(menuBar(), this, false);
d.layout_->updateContents(true);
// Now update controls with current buffer.
- theLyXFunc().setLyXView(this);
+ guiApp->setCurrentView(this);
restoreLayout();
restartCursor();
}
void GuiView::showDialog(string const & name, string const & data,
Inset * inset)
+{
+ triggerShowDialog(toqstr(name), toqstr(data), inset);
+}
+
+
+void GuiView::doShowDialog(QString const & qname, QString const & qdata,
+ Inset * inset)
{
if (d.in_show_)
return;
+ const string name = fromqstr(qname);
+ const string data = fromqstr(qdata);
+
d.in_show_ = true;
try {
Dialog * dialog = findOrBuild(name, false);
if (dialog) {
dialog->showData(data);
- if (inset)
- d.open_insets_[name] = inset;
+ if (inset && currentBufferView())
+ currentBufferView()->editInset(name, inset);
}
}
catch (ExceptionMessage const & ex) {
if (it == d.dialogs_.end())
return;
- if (inset && inset != getOpenInset(name))
+ if (inset && currentBufferView()
+ && inset != currentBufferView()->editedInset(name))
return;
Dialog * const dialog = it->second.get();
if (dialog->isVisibleView())
dialog->hideView();
- d.open_insets_[name] = 0;
+ if (currentBufferView())
+ currentBufferView()->editInset(name, 0);
}
{
if (!isValidName(name))
return;
-
- if (d.open_insets_.find(name) != d.open_insets_.end())
- d.open_insets_[name] = 0;
-}
-
-
-Inset * GuiView::getOpenInset(string const & name) const
-{
- if (!isValidName(name))
- return 0;
-
- map<string, Inset *>::const_iterator it = d.open_insets_.find(name);
- return it == d.open_insets_.end() ? 0 : it->second;
+ if (currentBufferView())
+ currentBufferView()->editInset(name, 0);
}
for(; it != end; ++it) {
Dialog * dialog = it->second.get();
- if (dialog && dialog->isVisibleView())
- dialog->checkStatus();
+ if (dialog) {
+ if (dialog->isBufferDependent() && !documentBufferView())
+ hideDialog(fromqstr(dialog->name()), 0);
+ else if (dialog->isVisibleView())
+ dialog->checkStatus();
+ }
}
updateToolbars();
updateLayoutList();
}
+Dialog * createDialog(GuiView & lv, string const & name);
// will be replaced by a proper factory...
Dialog * createGuiAbout(GuiView & lv);
Dialog * createGuiBibitem(GuiView & lv);
Dialog * createGuiBibtex(GuiView & lv);
-Dialog * createGuiBox(GuiView & lv);
Dialog * createGuiBranch(GuiView & lv);
Dialog * createGuiChanges(GuiView & lv);
Dialog * createGuiCharacter(GuiView & lv);
Dialog * createGuiCitation(GuiView & lv);
+Dialog * createGuiCompare(GuiView & lv);
Dialog * createGuiDelimiter(GuiView & lv);
Dialog * createGuiDocument(GuiView & lv);
Dialog * createGuiErrorList(GuiView & lv);
-Dialog * createGuiERT(GuiView & lv);
Dialog * createGuiExternal(GuiView & lv);
-Dialog * createGuiFloat(GuiView & lv);
Dialog * createGuiGraphics(GuiView & lv);
Dialog * createGuiInclude(GuiView & lv);
Dialog * createGuiIndex(GuiView & lv);
-Dialog * createGuiInfo(GuiView & lv);
Dialog * createGuiLabel(GuiView & lv);
Dialog * createGuiListings(GuiView & lv);
Dialog * createGuiLog(GuiView & lv);
Dialog * createGuiSpellchecker(GuiView & lv);
Dialog * createGuiSymbols(GuiView & lv);
Dialog * createGuiTabularCreate(GuiView & lv);
-Dialog * createGuiTabular(GuiView & lv);
Dialog * createGuiTexInfo(GuiView & lv);
Dialog * createGuiTextHSpace(GuiView & lv);
Dialog * createGuiToc(GuiView & lv);
Dialog * createGuiThesaurus(GuiView & lv);
Dialog * createGuiHyperlink(GuiView & lv);
-Dialog * createGuiVSpace(GuiView & lv);
Dialog * createGuiViewSource(GuiView & lv);
Dialog * createGuiWrap(GuiView & lv);
+Dialog * createGuiProgressView(GuiView & lv);
+
Dialog * GuiView::build(string const & name)
{
LASSERT(isValidName(name), return 0);
+ Dialog * dialog = createDialog(*this, name);
+ if (dialog)
+ return dialog;
+
if (name == "aboutlyx")
return createGuiAbout(*this);
if (name == "bibitem")
return createGuiBibitem(*this);
if (name == "bibtex")
return createGuiBibtex(*this);
- if (name == "box")
- return createGuiBox(*this);
if (name == "branch")
return createGuiBranch(*this);
if (name == "changes")
return createGuiCharacter(*this);
if (name == "citation")
return createGuiCitation(*this);
+ if (name == "compare")
+ return createGuiCompare(*this);
if (name == "document")
return createGuiDocument(*this);
if (name == "errorlist")
return createGuiErrorList(*this);
- if (name == "ert")
- return createGuiERT(*this);
if (name == "external")
return createGuiExternal(*this);
if (name == "file")
return createGuiSearch(*this);
if (name == "findreplaceadv")
return createGuiSearchAdv(*this);
- if (name == "float")
- return createGuiFloat(*this);
if (name == "graphics")
return createGuiGraphics(*this);
if (name == "href")
return createGuiIndex(*this);
if (name == "index_print")
return createGuiPrintindex(*this);
- if (name == "info")
- return createGuiInfo(*this);
if (name == "label")
return createGuiLabel(*this);
if (name == "listings")
return createGuiSpellchecker(*this);
if (name == "symbols")
return createGuiSymbols(*this);
- if (name == "tabular")
- return createGuiTabular(*this);
if (name == "tabularcreate")
return createGuiTabularCreate(*this);
if (name == "texinfo")
return createGuiToc(*this);
if (name == "view-source")
return createGuiViewSource(*this);
- if (name == "vspace")
- return createGuiVSpace(*this);
if (name == "wrap")
return createGuiWrap(*this);
+ if (name == "progress")
+ return createGuiProgressView(*this);
return 0;
}