#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 "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>
/// 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)
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
///
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
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();
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;
- 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;
- statusBar()->showMessage(toqstr(theLyXFunc().viewStatusMessage()));
+ showMessage();
+}
+
+
+void GuiView::showMessage()
+{
+ 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);
}
// is viewed.
KeySymbol sym;
setKeySymbol(&sym, ke);
- theLyXFunc().processKeySym(sym, q_key_state(ke->modifiers()));
+ guiApp->processKeySym(sym, q_key_state(ke->modifiers()));
e->accept();
return true;
}
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::updateTocItem(std::string const & type, DocIterator const & dit)
+void GuiView::updateTocItem(string const & type, DocIterator const & dit)
{
d.toc_models_.updateItem(toqstr(type), dit);
}
}
+#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 (documentBufferView())
- documentBufferView()->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
}
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()
flag.setOnOff(t->isVisible());
break;
+ case LFUN_DROP_LAYOUTS_CHOICE:
+ enable = buf;
+ break;
+
case LFUN_UI_TOGGLE:
flag.setOnOff(isFullScreen());
break;
enable = name == "aboutlyx"
|| name == "file" //FIXME: should be removed.
|| name == "prefs"
- || name == "texinfo";
+ || name == "texinfo"
+ || name == "progress"
+ || name == "compare";
else if (name == "print")
enable = doc_buffer->isExportable("dvi")
&& lyxrc.print_command != "none";
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;
Buffer * b;
if (filename.empty())
- b = newUnnamedFile(templatefile, initpath);
+ b = newUnnamedFile(initpath, to_utf8(_("newfile")), templatefile);
else
b = newFile(filename, templatefile, true);
bool GuiView::closeBuffer()
{
GuiWorkArea * wa = currentMainWorkArea();
+ setCurrentWorkArea(wa);
Buffer & buf = wa->bufferView().buffer();
return wa && closeWorkArea(wa, !buf.parent());
}
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
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 (!close_buffer)
- removeWorkArea(wa);
- else
- theBufferList().release(&buf);
+ if (saveBufferIfNeeded(buf, false)) {
+ theBufferList().release(&buf);
return true;
}
return false;
buf.removeAutosaveFile();
if (hiding)
// revert all changes
- buf.loadLyXFile(buf.fileName());
+ buf.reload();
buf.markClean();
break;
case 2:
void GuiView::reloadBuffer()
{
Buffer * buf = &documentBufferView()->buffer();
- FileName filename = buf->fileName();
- // The user has already confirmed that the changes, if any, should
- // be discarded. So we just release the Buffer and don't call closeBuffer();
- theBufferList().release(buf);
- buf = loadDocument(filename);
- docstring const disp_fn = makeDisplayPath(filename.absFilename());
- docstring str;
- if (buf) {
- buf->updateLabels();
- setBuffer(buf);
- buf->errors("Parse");
- str = bformat(_("Document %1$s reloaded."), disp_fn);
- } else {
- str = bformat(_("Could not reload document %1$s"), disp_fn);
+ 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();
+ }
}
- message(str);
}
void GuiView::dispatchVC(FuncRequest const & cmd)
{
+ // message for statusbar
+ string msg;
Buffer * buffer = documentBufferView()
? &(documentBufferView()->buffer()) : 0;
if (!buffer || !ensureBufferClean(buffer))
break;
if (buffer->lyxvc().inUse() && !buffer->isReadonly()) {
- message(from_utf8(buffer->lyxvc().checkIn()));
- reloadBuffer();
+ msg = buffer->lyxvc().checkIn();
+ if (!msg.empty())
+ reloadBuffer();
}
break;
if (!buffer || !ensureBufferClean(buffer))
break;
if (buffer->lyxvc().inUse()) {
- message(from_utf8(buffer->lyxvc().checkOut()));
+ msg = buffer->lyxvc().checkOut();
reloadBuffer();
}
break;
frontend::Alert::error(_("Revision control error."),
_("Error when setting the locking property."));
} else {
- message(from_utf8(res));
+ msg = res;
reloadBuffer();
}
}
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))
default:
break;
}
+
+ if (!msg.empty())
+ message(from_utf8(msg));
}
{
string file_name;
int row;
- istringstream is(argument);
- is >> file_name >> row;
- file_name = os::internal_path(file_name);
+ 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();
}
+#if (QT_VERSION >= 0x040400)
+static docstring exportAndDestroy(Buffer * buffer, string const & format)
+{
+ bool const success = buffer->doExport(format, true);
+ 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 success = buffer->preview(format);
+ delete buffer;
+ return success
+ ? bformat(_("Successful preview of format: %1$s"), from_utf8(format))
+ : bformat(_("Error previewing format: %1$s"), from_utf8(format));
+}
+#endif
+
+
bool GuiView::dispatch(FuncRequest const & cmd)
{
BufferView * bv = currentBufferView();
return true;
}
+ string const argument = to_utf8(cmd.argument());
+
switch(cmd.action) {
case LFUN_BUFFER_CHILD_OPEN:
openChildDocument(to_utf8(cmd.argument()));
importDocument(to_utf8(cmd.argument()));
break;
+ case LFUN_BUFFER_EXPORT: {
+ if (!doc_buffer)
+ break;
+ if (cmd.argument() == "custom") {
+ lyx::dispatch(FuncRequest(LFUN_DIALOG_SHOW, "sendto"));
+ break;
+ }
+ if (doc_buffer->doExport(argument, false)) {
+ message(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
+ doc_buffer->doExport(format, true);
+#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
+ doc_buffer->preview(format);
+#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
+ 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 =
int const ret = Alert::prompt(_("Revert to saved document?"),
text, 1, 1, _("&Revert"), _("&Cancel"));
- if (ret == 0)
+ if (ret == 0) {
+ doc_buffer->markClean();
reloadBuffer();
+ }
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:
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::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);
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 * createGuiVSpace(GuiView & lv);
Dialog * createGuiViewSource(GuiView & lv);
Dialog * createGuiWrap(GuiView & lv);
+Dialog * createGuiProgressView(GuiView & lv);
+
Dialog * GuiView::build(string const & name)
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 createGuiVSpace(*this);
if (name == "wrap")
return createGuiWrap(*this);
+ if (name == "progress")
+ return createGuiProgressView(*this);
return 0;
}