3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Lars Gullik Bjønnes
8 * \author Abdelrazak Younes
11 * Full author contact details are available in file CREDITS.
19 #include "FileDialog.h"
20 #include "GuiApplication.h"
21 #include "GuiWorkArea.h"
22 #include "GuiKeySymbol.h"
23 #include "GuiToolbar.h"
24 #include "GuiToolbars.h"
27 #include "qt_helpers.h"
29 #include "frontends/alert.h"
31 #include "buffer_funcs.h"
33 #include "BufferList.h"
34 #include "BufferParams.h"
35 #include "BufferView.h"
36 #include "Converter.h"
38 #include "ErrorList.h"
40 #include "FuncRequest.h"
41 #include "support/gettext.h"
49 #include "Paragraph.h"
50 #include "TextClass.h"
52 #include "ToolbarBackend.h"
55 #include "support/debug.h"
56 #include "support/FileFilterList.h"
57 #include "support/FileName.h"
58 #include "support/filetools.h"
59 #include "support/ForkedCalls.h"
60 #include "support/lstrings.h"
61 #include "support/os.h"
62 #include "support/Package.h"
63 #include "support/Timeout.h"
66 #include <QApplication>
67 #include <QCloseEvent>
69 #include <QDesktopWidget>
70 #include <QDragEnterEvent>
77 #include <QPushButton>
81 #include <QStackedWidget>
87 #include <boost/assert.hpp>
88 #include <boost/bind.hpp>
90 #ifdef HAVE_SYS_TIME_H
91 # include <sys/time.h>
98 using namespace lyx::support;
102 extern bool quitting;
108 class BackgroundWidget : public QWidget
113 LYXERR(Debug::GUI, "show banner: " << lyxrc.show_banner);
114 /// The text to be written on top of the pixmap
115 QString const text = lyx_version ? lyx_version : qt_("unknown version");
116 splash_ = QPixmap(":/images/banner.png");
118 QPainter pain(&splash_);
119 pain.setPen(QColor(255, 255, 0));
121 // The font used to display the version info
122 font.setStyleHint(QFont::SansSerif);
123 font.setWeight(QFont::Bold);
124 font.setPointSize(int(toqstr(lyxrc.font_sizes[FONT_SIZE_LARGE]).toDouble()));
126 pain.drawText(260, 270, text);
129 void paintEvent(QPaintEvent *)
131 int x = (width() - splash_.width()) / 2;
132 int y = (height() - splash_.height()) / 2;
134 pain.drawPixmap(x, y, splash_);
144 typedef boost::shared_ptr<Dialog> DialogPtr;
146 struct GuiView::GuiViewPrivate
149 : current_work_area_(0), layout_(0),
150 quitting_by_menu_(false), autosave_timeout_(5000), in_show_(false)
152 // hardcode here the platform specific icon size
153 smallIconSize = 14; // scaling problems
154 normalIconSize = 20; // ok, default
155 bigIconSize = 26; // better for some math icons
157 splitter_ = new QSplitter;
158 bg_widget_ = new BackgroundWidget;
159 stack_widget_ = new QStackedWidget;
160 stack_widget_->addWidget(bg_widget_);
161 stack_widget_->addWidget(splitter_);
169 delete stack_widget_;
173 QMenu * toolBarPopup(GuiView * parent)
175 // FIXME: translation
176 QMenu * menu = new QMenu(parent);
177 QActionGroup * iconSizeGroup = new QActionGroup(parent);
179 QAction * smallIcons = new QAction(iconSizeGroup);
180 smallIcons->setText(qt_("Small-sized icons"));
181 smallIcons->setCheckable(true);
182 QObject::connect(smallIcons, SIGNAL(triggered()),
183 parent, SLOT(smallSizedIcons()));
184 menu->addAction(smallIcons);
186 QAction * normalIcons = new QAction(iconSizeGroup);
187 normalIcons->setText(qt_("Normal-sized icons"));
188 normalIcons->setCheckable(true);
189 QObject::connect(normalIcons, SIGNAL(triggered()),
190 parent, SLOT(normalSizedIcons()));
191 menu->addAction(normalIcons);
193 QAction * bigIcons = new QAction(iconSizeGroup);
194 bigIcons->setText(qt_("Big-sized icons"));
195 bigIcons->setCheckable(true);
196 QObject::connect(bigIcons, SIGNAL(triggered()),
197 parent, SLOT(bigSizedIcons()));
198 menu->addAction(bigIcons);
200 unsigned int cur = parent->iconSize().width();
201 if ( cur == parent->d.smallIconSize)
202 smallIcons->setChecked(true);
203 else if (cur == parent->d.normalIconSize)
204 normalIcons->setChecked(true);
205 else if (cur == parent->d.bigIconSize)
206 bigIcons->setChecked(true);
213 stack_widget_->setCurrentWidget(bg_widget_);
214 bg_widget_->setUpdatesEnabled(true);
217 TabWorkArea * tabWorkArea(int i)
219 return dynamic_cast<TabWorkArea *>(splitter_->widget(i));
222 TabWorkArea * currentTabWorkArea()
224 if (splitter_->count() == 1)
225 // The first TabWorkArea is always the first one, if any.
226 return tabWorkArea(0);
228 TabWorkArea * tab_widget = 0;
229 for (int i = 0; i != splitter_->count(); ++i) {
230 QWidget * w = splitter_->widget(i);
233 tab_widget = dynamic_cast<TabWorkArea *>(w);
242 GuiWorkArea * current_work_area_;
243 QSplitter * splitter_;
244 QStackedWidget * stack_widget_;
245 BackgroundWidget * bg_widget_;
247 GuiToolbars * toolbars_;
248 /// The main layout box.
250 * \warning Don't Delete! The layout box is actually owned by
251 * whichever toolbar contains it. All the GuiView class needs is a
252 * means of accessing it.
254 * FIXME: replace that with a proper model so that we are not limited
255 * to only one dialog.
257 GuiLayoutBox * layout_;
260 map<string, Inset *> open_insets_;
263 map<string, DialogPtr> dialogs_;
265 unsigned int smallIconSize;
266 unsigned int normalIconSize;
267 unsigned int bigIconSize;
269 QTimer statusbar_timer_;
270 /// are we quitting by the menu?
271 bool quitting_by_menu_;
272 /// auto-saving of buffers
273 Timeout autosave_timeout_;
274 /// flag against a race condition due to multiclicks, see bug #1119
279 GuiView::GuiView(int id)
280 : d(*new GuiViewPrivate), id_(id)
282 // GuiToolbars *must* be initialised before the menu bar.
283 d.toolbars_ = new GuiToolbars(*this);
285 // Fill up the menu bar.
286 guiApp->menus().fillMenuBar(this);
288 setCentralWidget(d.stack_widget_);
290 // Start autosave timer
291 if (lyxrc.autosave) {
292 d.autosave_timeout_.timeout.connect(boost::bind(&GuiView::autoSave, this));
293 d.autosave_timeout_.setTimeout(lyxrc.autosave * 1000);
294 d.autosave_timeout_.start();
296 connect(&d.statusbar_timer_, SIGNAL(timeout()),
297 this, SLOT(clearMessage()));
299 // Qt bug? signal lastWindowClosed does not work
300 setAttribute(Qt::WA_QuitOnClose, false);
301 setAttribute(Qt::WA_DeleteOnClose, true);
303 // assign an icon to main form. We do not do it under Qt/Mac,
304 // since the icon is provided in the application bundle.
305 setWindowIcon(QPixmap(":/images/lyx.png"));
309 setAcceptDrops(true);
311 statusBar()->setSizeGripEnabled(true);
313 // Forbid too small unresizable window because it can happen
314 // with some window manager under X11.
315 setMinimumSize(300, 200);
317 if (!lyxrc.allow_geometry_session)
318 // No session handling, default to a sane size.
319 setGeometry(50, 50, 690, 510);
321 // Now take care of session management.
323 QString const key = "view-" + QString::number(id_);
325 QPoint pos = settings.value(key + "/pos", QPoint(50, 50)).toPoint();
326 QSize size = settings.value(key + "/size", QSize(690, 510)).toSize();
330 if (!restoreGeometry(settings.value(key + "/geometry").toByteArray()))
331 setGeometry(50, 50, 690, 510);
333 setIconSize(settings.value(key + "/icon_size").toSize());
343 void GuiView::close()
345 d.quitting_by_menu_ = true;
346 d.current_work_area_ = 0;
347 for (int i = 0; i != d.splitter_->count(); ++i) {
348 TabWorkArea * twa = d.tabWorkArea(i);
352 QMainWindow::close();
353 d.quitting_by_menu_ = false;
357 void GuiView::setFocus()
359 if (d.current_work_area_)
360 d.current_work_area_->setFocus();
366 QMenu * GuiView::createPopupMenu()
368 return d.toolBarPopup(this);
372 void GuiView::showEvent(QShowEvent * e)
374 LYXERR(Debug::GUI, "Passed Geometry "
375 << size().height() << "x" << size().width()
376 << "+" << pos().x() << "+" << pos().y());
378 if (d.splitter_->count() == 0)
379 // No work area, switch to the background widget.
382 QMainWindow::showEvent(e);
386 void GuiView::closeEvent(QCloseEvent * close_event)
388 // we may have been called through the close window button
389 // which bypasses the LFUN machinery.
390 if (!d.quitting_by_menu_ && guiApp->viewCount() == 1) {
391 if (!quitWriteAll()) {
392 close_event->ignore();
397 // Make sure that no LFUN use this close to be closed View.
398 theLyXFunc().setLyXView(0);
399 // Make sure the timer time out will not trigger a statusbar update.
400 d.statusbar_timer_.stop();
402 if (lyxrc.allow_geometry_session) {
404 QString const key = "view-" + QString::number(id_);
406 settings.setValue(key + "/pos", pos());
407 settings.setValue(key + "/size", size());
409 settings.setValue(key + "/geometry", saveGeometry());
411 settings.setValue(key + "/icon_size", iconSize());
412 d.toolbars_->saveToolbarInfo();
413 // Now take care of all other dialogs:
414 map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
415 for (; it!= d.dialogs_.end(); ++it)
416 it->second->saveSession();
419 guiApp->unregisterView(id_);
420 if (guiApp->viewCount() > 0) {
421 // Just close the window and do nothing else if this is not the
423 close_event->accept();
429 // this is the place where we leave the frontend.
430 // it is the only point at which we start quitting.
431 close_event->accept();
432 // quit the event loop
437 void GuiView::dragEnterEvent(QDragEnterEvent * event)
439 if (event->mimeData()->hasUrls())
441 /// \todo Ask lyx-devel is this is enough:
442 /// if (event->mimeData()->hasFormat("text/plain"))
443 /// event->acceptProposedAction();
447 void GuiView::dropEvent(QDropEvent* event)
449 QList<QUrl> files = event->mimeData()->urls();
453 LYXERR(Debug::GUI, "GuiView::dropEvent: got URLs!");
454 for (int i = 0; i != files.size(); ++i) {
455 string const file = os::internal_path(fromqstr(
456 files.at(i).toLocalFile()));
458 lyx::dispatch(FuncRequest(LFUN_FILE_OPEN, file));
463 void GuiView::message(docstring const & str)
465 if (ForkedProcess::iAmAChild())
468 statusBar()->showMessage(toqstr(str));
469 d.statusbar_timer_.stop();
470 d.statusbar_timer_.start(3000);
474 void GuiView::smallSizedIcons()
476 setIconSize(QSize(d.smallIconSize, d.smallIconSize));
480 void GuiView::normalSizedIcons()
482 setIconSize(QSize(d.normalIconSize, d.normalIconSize));
486 void GuiView::bigSizedIcons()
488 setIconSize(QSize(d.bigIconSize, d.bigIconSize));
492 void GuiView::clearMessage()
496 theLyXFunc().setLyXView(this);
497 statusBar()->showMessage(toqstr(theLyXFunc().viewStatusMessage()));
498 d.statusbar_timer_.stop();
502 void GuiView::updateWindowTitle(GuiWorkArea * wa)
504 if (wa != d.current_work_area_)
506 setWindowTitle(qt_("LyX: ") + wa->windowTitle());
507 setWindowIconText(wa->windowIconText());
511 void GuiView::on_currentWorkAreaChanged(GuiWorkArea * wa)
514 disconnectBufferView();
515 connectBufferView(wa->bufferView());
516 connectBuffer(wa->bufferView().buffer());
517 d.current_work_area_ = wa;
518 QObject::connect(wa, SIGNAL(titleChanged(GuiWorkArea *)),
519 this, SLOT(updateWindowTitle(GuiWorkArea *)));
520 updateWindowTitle(wa);
523 // Buffer-dependent dialogs should be updated or
524 // hidden. This should go here because some dialogs (eg ToC)
525 // require bv_->text.
526 updateBufferDependent(true);
533 void GuiView::updateStatusBar()
535 // let the user see the explicit message
536 if (d.statusbar_timer_.isActive())
539 statusBar()->showMessage(toqstr(theLyXFunc().viewStatusMessage()));
543 bool GuiView::hasFocus() const
545 return qApp->activeWindow() == this;
549 bool GuiView::event(QEvent * e)
553 // Useful debug code:
554 //case QEvent::ActivationChange:
555 //case QEvent::WindowDeactivate:
556 //case QEvent::Paint:
557 //case QEvent::Enter:
558 //case QEvent::Leave:
559 //case QEvent::HoverEnter:
560 //case QEvent::HoverLeave:
561 //case QEvent::HoverMove:
562 //case QEvent::StatusTip:
563 //case QEvent::DragEnter:
564 //case QEvent::DragLeave:
568 case QEvent::WindowActivate: {
569 guiApp->setCurrentView(*this);
570 if (d.current_work_area_) {
571 BufferView & bv = d.current_work_area_->bufferView();
572 connectBufferView(bv);
573 connectBuffer(bv.buffer());
574 // The document structure, name and dialogs might have
575 // changed in another view.
576 updateBufferDependent(true);
578 setWindowTitle(qt_("LyX"));
579 setWindowIconText(qt_("LyX"));
581 return QMainWindow::event(e);
584 case QEvent::ShortcutOverride: {
585 if (d.current_work_area_)
586 // Nothing special to do.
587 return QMainWindow::event(e);
589 QKeyEvent * ke = static_cast<QKeyEvent*>(e);
591 // Let Qt handle menu access and the Tab keys to navigate keys to navigate
593 if (ke->modifiers() & Qt::AltModifier || ke->key() == Qt::Key_Tab
594 || ke->key() == Qt::Key_Backtab)
595 return QMainWindow::event(e);
597 // Allow processing of shortcuts that are allowed even when no Buffer
599 theLyXFunc().setLyXView(this);
601 setKeySymbol(&sym, ke);
602 theLyXFunc().processKeySym(sym, q_key_state(ke->modifiers()));
608 return QMainWindow::event(e);
613 bool GuiView::focusNextPrevChild(bool /*next*/)
620 void GuiView::setBusy(bool busy)
622 if (d.current_work_area_) {
623 d.current_work_area_->setUpdatesEnabled(!busy);
625 d.current_work_area_->stopBlinkingCursor();
627 d.current_work_area_->startBlinkingCursor();
631 QApplication::setOverrideCursor(Qt::WaitCursor);
633 QApplication::restoreOverrideCursor();
637 GuiToolbar * GuiView::makeToolbar(ToolbarInfo const & tbinfo, bool newline)
639 GuiToolbar * toolBar = new GuiToolbar(tbinfo, *this);
641 if (tbinfo.flags & ToolbarInfo::TOP) {
643 addToolBarBreak(Qt::TopToolBarArea);
644 addToolBar(Qt::TopToolBarArea, toolBar);
647 if (tbinfo.flags & ToolbarInfo::BOTTOM) {
648 // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
649 #if (QT_VERSION >= 0x040202)
651 addToolBarBreak(Qt::BottomToolBarArea);
653 addToolBar(Qt::BottomToolBarArea, toolBar);
656 if (tbinfo.flags & ToolbarInfo::LEFT) {
657 // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
658 #if (QT_VERSION >= 0x040202)
660 addToolBarBreak(Qt::LeftToolBarArea);
662 addToolBar(Qt::LeftToolBarArea, toolBar);
665 if (tbinfo.flags & ToolbarInfo::RIGHT) {
666 // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
667 #if (QT_VERSION >= 0x040202)
669 addToolBarBreak(Qt::RightToolBarArea);
671 addToolBar(Qt::RightToolBarArea, toolBar);
674 // The following does not work so I cannot restore to exact toolbar location
676 ToolbarSection::ToolbarInfo & tbinfo = LyX::ref().session().toolbars().load(tbinfo.name);
677 toolBar->move(tbinfo.posx, tbinfo.posy);
684 GuiWorkArea * GuiView::workArea(Buffer & buffer)
686 for (int i = 0; i != d.splitter_->count(); ++i) {
687 GuiWorkArea * wa = d.tabWorkArea(i)->workArea(buffer);
695 GuiWorkArea * GuiView::addWorkArea(Buffer & buffer)
698 // Automatically create a TabWorkArea if there are none yet.
699 if (!d.splitter_->count())
702 TabWorkArea * tab_widget = d.currentTabWorkArea();
703 return tab_widget->addWorkArea(buffer, *this);
707 void GuiView::addTabWorkArea()
709 TabWorkArea * twa = new TabWorkArea;
710 QObject::connect(twa, SIGNAL(currentWorkAreaChanged(GuiWorkArea *)),
711 this, SLOT(on_currentWorkAreaChanged(GuiWorkArea *)));
712 d.splitter_->addWidget(twa);
713 d.stack_widget_->setCurrentWidget(d.splitter_);
717 GuiWorkArea const * GuiView::currentWorkArea() const
719 return d.current_work_area_;
723 void GuiView::setCurrentWorkArea(GuiWorkArea * wa)
727 // Changing work area can result from opening a file so
728 // update the toc in any case.
731 d.current_work_area_ = wa;
732 for (int i = 0; i != d.splitter_->count(); ++i) {
733 if (d.tabWorkArea(i)->setCurrentWorkArea(wa))
739 void GuiView::removeWorkArea(GuiWorkArea * wa)
742 if (wa == d.current_work_area_) {
744 disconnectBufferView();
745 hideBufferDependent();
746 d.current_work_area_ = 0;
749 for (int i = 0; i != d.splitter_->count(); ++i) {
750 TabWorkArea * twa = d.tabWorkArea(i);
751 if (!twa->removeWorkArea(wa))
752 // Not found in this tab group.
755 // We found and removed the GuiWorkArea.
757 // No more WorkAreas in this tab group, so delete it.
762 if (d.current_work_area_)
763 // This means that we are not closing the current GuiWorkArea;
766 // Switch to the next GuiWorkArea in the found TabWorkArea.
767 d.current_work_area_ = twa->currentWorkArea();
771 if (d.splitter_->count() == 0)
772 // No more work area, switch to the background widget.
777 void GuiView::setLayoutDialog(GuiLayoutBox * layout)
783 void GuiView::updateLayoutList()
786 d.layout_->updateContents(false);
790 void GuiView::updateToolbars()
792 if (d.current_work_area_) {
794 d.current_work_area_->bufferView().cursor().inMathed();
796 lyx::getStatus(FuncRequest(LFUN_LAYOUT_TABULAR)).enabled();
798 lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).enabled() &&
799 lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).onoff(true);
800 bool const mathmacrotemplate =
801 lyx::getStatus(FuncRequest(LFUN_IN_MATHMACROTEMPLATE)).enabled();
803 d.toolbars_->update(math, table, review, mathmacrotemplate);
805 d.toolbars_->update(false, false, false, false);
807 // update read-only status of open dialogs.
812 Buffer * GuiView::buffer()
814 if (d.current_work_area_)
815 return &d.current_work_area_->bufferView().buffer();
820 Buffer const * GuiView::buffer() const
822 if (d.current_work_area_)
823 return &d.current_work_area_->bufferView().buffer();
828 void GuiView::setBuffer(Buffer * newBuffer)
830 BOOST_ASSERT(newBuffer);
833 GuiWorkArea * wa = workArea(*newBuffer);
835 updateLabels(*newBuffer->masterBuffer());
836 wa = addWorkArea(*newBuffer);
838 //Disconnect the old buffer...there's no new one.
841 connectBuffer(*newBuffer);
842 connectBufferView(wa->bufferView());
843 setCurrentWorkArea(wa);
849 void GuiView::connectBuffer(Buffer & buf)
851 buf.setGuiDelegate(this);
855 void GuiView::disconnectBuffer()
857 if (d.current_work_area_)
858 d.current_work_area_->bufferView().setGuiDelegate(0);
862 void GuiView::connectBufferView(BufferView & bv)
864 bv.setGuiDelegate(this);
868 void GuiView::disconnectBufferView()
870 if (d.current_work_area_)
871 d.current_work_area_->bufferView().setGuiDelegate(0);
875 void GuiView::errors(string const & error_type)
877 ErrorList & el = buffer()->errorList(error_type);
879 showDialog("errorlist", error_type);
883 void GuiView::updateDialog(string const & name, string const & data)
885 if (!isDialogVisible(name))
888 map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
889 if (it == d.dialogs_.end())
892 Dialog * const dialog = it->second.get();
893 if (dialog->isVisibleView())
894 dialog->updateData(data);
898 BufferView * GuiView::view()
900 return d.current_work_area_ ? &d.current_work_area_->bufferView() : 0;
904 void GuiView::updateToc()
906 updateDialog("toc", "");
910 void GuiView::updateEmbeddedFiles()
912 updateDialog("embedding", "");
916 void GuiView::autoSave()
918 LYXERR(Debug::INFO, "Running autoSave()");
921 view()->buffer().autoSave();
925 void GuiView::resetAutosaveTimers()
928 d.autosave_timeout_.restart();
932 FuncStatus GuiView::getStatus(FuncRequest const & cmd)
936 Buffer * buf = buffer();
938 /* In LyX/Mac, when a dialog is open, the menus of the
939 application can still be accessed without giving focus to
940 the main window. In this case, we want to disable the menu
941 entries that are buffer-related.
943 Note that this code is not perfect, as bug 1941 attests:
944 http://bugzilla.lyx.org/show_bug.cgi?id=1941#c4
946 if (cmd.origin == FuncRequest::MENU && !hasFocus())
950 case LFUN_BUFFER_WRITE:
951 enable = buf && (buf->isUnnamed() || !buf->isClean());
954 case LFUN_BUFFER_WRITE_AS:
958 case LFUN_TOOLBAR_TOGGLE:
959 flag.setOnOff(d.toolbars_->visible(cmd.getArg(0)));
962 case LFUN_DIALOG_TOGGLE:
963 flag.setOnOff(isDialogVisible(cmd.getArg(0)));
964 // fall through to set "enable"
965 case LFUN_DIALOG_SHOW: {
966 string const name = cmd.getArg(0);
968 enable = name == "aboutlyx"
969 || name == "file" //FIXME: should be removed.
971 || name == "texinfo";
972 else if (name == "print")
973 enable = buf->isExportable("dvi")
974 && lyxrc.print_command != "none";
975 else if (name == "character") {
979 InsetCode ic = view()->cursor().inset().lyxCode();
980 enable = ic != ERT_CODE && ic != LISTINGS_CODE;
983 else if (name == "latexlog")
984 enable = FileName(buf->logName()).isReadableFile();
985 else if (name == "spellchecker")
986 #if defined (USE_ASPELL) || defined (USE_ISPELL) || defined (USE_PSPELL)
987 enable = !buf->isReadonly();
991 else if (name == "vclog")
992 enable = buf->lyxvc().inUse();
996 case LFUN_DIALOG_UPDATE: {
997 string const name = cmd.getArg(0);
999 enable = name == "prefs";
1003 case LFUN_INSET_APPLY: {
1008 string const name = cmd.getArg(0);
1009 Inset * inset = getOpenInset(name);
1011 FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument());
1013 if (!inset->getStatus(view()->cursor(), fr, fs)) {
1014 // Every inset is supposed to handle this
1015 BOOST_ASSERT(false);
1019 FuncRequest fr(LFUN_INSET_INSERT, cmd.argument());
1020 flag |= getStatus(fr);
1022 enable = flag.enabled();
1034 flag.enabled(false);
1040 static FileName selectTemplateFile()
1042 FileDialog dlg(_("Select template file"));
1043 dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
1044 dlg.setButton1(_("Templates|#T#t"), from_utf8(lyxrc.template_path));
1046 FileDialog::Result result =
1047 dlg.open(from_utf8(lyxrc.template_path),
1048 FileFilterList(_("LyX Documents (*.lyx)")),
1051 if (result.first == FileDialog::Later)
1053 if (result.second.empty())
1055 return FileName(to_utf8(result.second));
1059 Buffer * GuiView::loadDocument(FileName const & filename, bool tolastfiles)
1063 Buffer * newBuffer = checkAndLoadLyXFile(filename);
1066 message(_("Document not loaded."));
1071 setBuffer(newBuffer);
1073 // scroll to the position when the file was last closed
1074 if (lyxrc.use_lastfilepos) {
1075 LastFilePosSection::FilePos filepos =
1076 LyX::ref().session().lastFilePos().load(filename);
1077 view()->moveToPosition(filepos.pit, filepos.pos, 0, 0);
1081 LyX::ref().session().lastFiles().add(filename);
1088 void GuiView::openDocument(string const & fname)
1090 string initpath = lyxrc.document_path;
1093 string const trypath = buffer()->filePath();
1094 // If directory is writeable, use this as default.
1095 if (FileName(trypath).isDirWritable())
1101 if (fname.empty()) {
1102 FileDialog dlg(_("Select document to open"), LFUN_FILE_OPEN);
1103 dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
1104 dlg.setButton2(_("Examples|#E#e"),
1105 from_utf8(addPath(package().system_support().absFilename(), "examples")));
1107 FileDialog::Result result =
1108 dlg.open(from_utf8(initpath),
1109 FileFilterList(_("LyX Documents (*.lyx)")),
1112 if (result.first == FileDialog::Later)
1115 filename = to_utf8(result.second);
1117 // check selected filename
1118 if (filename.empty()) {
1119 message(_("Canceled."));
1125 // get absolute path of file and add ".lyx" to the filename if
1127 FileName const fullname =
1128 fileSearch(string(), filename, "lyx", support::may_not_exist);
1129 if (!fullname.empty())
1130 filename = fullname.absFilename();
1132 // if the file doesn't exist, let the user create one
1133 if (!fullname.exists()) {
1134 // the user specifically chose this name. Believe him.
1135 Buffer * const b = newFile(filename, string(), true);
1141 docstring const disp_fn = makeDisplayPath(filename);
1142 message(bformat(_("Opening document %1$s..."), disp_fn));
1145 Buffer * buf = loadDocument(fullname);
1149 buf->errors("Parse");
1150 str2 = bformat(_("Document %1$s opened."), disp_fn);
1152 str2 = bformat(_("Could not open document %1$s"), disp_fn);
1157 // FIXME: clean that
1158 static bool import(LyXView * lv, FileName const & filename,
1159 string const & format, ErrorList & errorList)
1161 docstring const displaypath = makeDisplayPath(filename.absFilename());
1162 lv->message(bformat(_("Importing %1$s..."), displaypath));
1164 FileName const lyxfile(changeExtension(filename.absFilename(), ".lyx"));
1166 string loader_format;
1167 vector<string> loaders = theConverters().loaders();
1168 if (find(loaders.begin(), loaders.end(), format) == loaders.end()) {
1169 for (vector<string>::const_iterator it = loaders.begin();
1170 it != loaders.end(); ++it) {
1171 if (theConverters().isReachable(format, *it)) {
1172 string const tofile =
1173 changeExtension(filename.absFilename(),
1174 formats.extension(*it));
1175 if (!theConverters().convert(0, filename, FileName(tofile),
1176 filename, format, *it, errorList))
1178 loader_format = *it;
1182 if (loader_format.empty()) {
1183 frontend::Alert::error(_("Couldn't import file"),
1184 bformat(_("No information for importing the format %1$s."),
1185 formats.prettyName(format)));
1189 loader_format = format;
1192 if (loader_format == "lyx") {
1193 Buffer * buf = lv->loadDocument(lyxfile);
1196 lv->message(_("file not imported!"));
1201 buf->errors("Parse");
1203 Buffer * const b = newFile(lyxfile.absFilename(), string(), true);
1208 bool as_paragraphs = loader_format == "textparagraph";
1209 string filename2 = (loader_format == format) ? filename.absFilename()
1210 : changeExtension(filename.absFilename(),
1211 formats.extension(loader_format));
1212 lv->view()->insertPlaintextFile(FileName(filename2), as_paragraphs);
1213 theLyXFunc().setLyXView(lv);
1214 lyx::dispatch(FuncRequest(LFUN_MARK_OFF));
1218 lv->message(_("imported."));
1223 void GuiView::importDocument(string const & argument)
1226 string filename = split(argument, format, ' ');
1228 LYXERR(Debug::INFO, format << " file: " << filename);
1230 // need user interaction
1231 if (filename.empty()) {
1232 string initpath = lyxrc.document_path;
1234 Buffer const * buf = buffer();
1236 string const trypath = buf->filePath();
1237 // If directory is writeable, use this as default.
1238 if (FileName(trypath).isDirWritable())
1242 docstring const text = bformat(_("Select %1$s file to import"),
1243 formats.prettyName(format));
1245 FileDialog dlg(text, LFUN_BUFFER_IMPORT);
1246 dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
1247 dlg.setButton2(_("Examples|#E#e"),
1248 from_utf8(addPath(package().system_support().absFilename(), "examples")));
1250 docstring filter = formats.prettyName(format);
1253 filter += from_utf8(formats.extension(format));
1256 FileDialog::Result result =
1257 dlg.open(from_utf8(initpath),
1258 FileFilterList(filter),
1261 if (result.first == FileDialog::Later)
1264 filename = to_utf8(result.second);
1266 // check selected filename
1267 if (filename.empty())
1268 message(_("Canceled."));
1271 if (filename.empty())
1274 // get absolute path of file
1275 FileName const fullname(makeAbsPath(filename));
1277 FileName const lyxfile(changeExtension(fullname.absFilename(), ".lyx"));
1279 // Check if the document already is open
1280 Buffer * buf = theBufferList().getBuffer(lyxfile.absFilename());
1283 if (!closeBuffer()) {
1284 message(_("Canceled."));
1289 // if the file exists already, and we didn't do
1290 // -i lyx thefile.lyx, warn
1291 if (lyxfile.exists() && fullname != lyxfile) {
1292 docstring const file = makeDisplayPath(lyxfile.absFilename(), 30);
1294 docstring text = bformat(_("The document %1$s already exists.\n\n"
1295 "Do you want to overwrite that document?"), file);
1296 int const ret = Alert::prompt(_("Overwrite document?"),
1297 text, 0, 1, _("&Overwrite"), _("&Cancel"));
1300 message(_("Canceled."));
1305 ErrorList errorList;
1306 import(this, fullname, format, errorList);
1307 // FIXME (Abdel 12/08/06): Is there a need to display the error list here?
1311 void GuiView::newDocument(string const & filename, bool from_template)
1313 FileName initpath(lyxrc.document_path);
1314 Buffer * buf = buffer();
1316 FileName const trypath(buf->filePath());
1317 // If directory is writeable, use this as default.
1318 if (trypath.isDirWritable())
1322 string templatefile = from_template ?
1323 selectTemplateFile().absFilename() : string();
1325 if (filename.empty())
1326 b = newUnnamedFile(templatefile, initpath);
1328 b = newFile(filename, templatefile, true);
1332 // Ensure the cursor is correctly positionned on screen.
1333 view()->showCursor();
1337 void GuiView::insertLyXFile(docstring const & fname)
1339 BufferView * bv = view();
1344 FileName filename(to_utf8(fname));
1346 if (!filename.empty()) {
1347 bv->insertLyXFile(filename);
1351 // Launch a file browser
1353 string initpath = lyxrc.document_path;
1354 string const trypath = bv->buffer().filePath();
1355 // If directory is writeable, use this as default.
1356 if (FileName(trypath).isDirWritable())
1360 FileDialog dlg(_("Select LyX document to insert"), LFUN_FILE_INSERT);
1361 dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
1362 dlg.setButton2(_("Examples|#E#e"),
1363 from_utf8(addPath(package().system_support().absFilename(),
1366 FileDialog::Result result =
1367 dlg.open(from_utf8(initpath),
1368 FileFilterList(_("LyX Documents (*.lyx)")),
1371 if (result.first == FileDialog::Later)
1375 filename.set(to_utf8(result.second));
1377 // check selected filename
1378 if (filename.empty()) {
1379 // emit message signal.
1380 message(_("Canceled."));
1384 bv->insertLyXFile(filename);
1388 void GuiView::insertPlaintextFile(docstring const & fname,
1391 BufferView * bv = view();
1396 FileName filename(to_utf8(fname));
1398 if (!filename.empty()) {
1399 bv->insertPlaintextFile(filename, asParagraph);
1403 FileDialog dlg(_("Select file to insert"), (asParagraph ?
1404 LFUN_FILE_INSERT_PLAINTEXT_PARA : LFUN_FILE_INSERT_PLAINTEXT));
1406 FileDialog::Result result = dlg.open(from_utf8(bv->buffer().filePath()),
1407 FileFilterList(), docstring());
1409 if (result.first == FileDialog::Later)
1413 filename.set(to_utf8(result.second));
1415 // check selected filename
1416 if (filename.empty()) {
1417 // emit message signal.
1418 message(_("Canceled."));
1422 bv->insertPlaintextFile(filename, asParagraph);
1426 bool GuiView::renameBuffer(Buffer & b, docstring const & newname)
1428 FileName fname = b.fileName();
1429 FileName const oldname = fname;
1431 if (!newname.empty()) {
1433 fname = makeAbsPath(to_utf8(newname), oldname.onlyPath().absFilename());
1435 // Switch to this Buffer.
1438 /// No argument? Ask user through dialog.
1440 FileDialog dlg(_("Choose a filename to save document as"),
1441 LFUN_BUFFER_WRITE_AS);
1442 dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
1443 dlg.setButton2(_("Templates|#T#t"), from_utf8(lyxrc.template_path));
1445 if (!isLyXFilename(fname.absFilename()))
1446 fname.changeExtension(".lyx");
1448 FileFilterList const filter(_("LyX Documents (*.lyx)"));
1450 FileDialog::Result result =
1451 dlg.save(from_utf8(fname.onlyPath().absFilename()),
1453 from_utf8(fname.onlyFileName()));
1455 if (result.first == FileDialog::Later)
1458 fname.set(to_utf8(result.second));
1463 if (!isLyXFilename(fname.absFilename()))
1464 fname.changeExtension(".lyx");
1467 if (FileName(fname).exists()) {
1468 docstring const file = makeDisplayPath(fname.absFilename(), 30);
1469 docstring text = bformat(_("The document %1$s already "
1470 "exists.\n\nDo you want to "
1471 "overwrite that document?"),
1473 int const ret = Alert::prompt(_("Overwrite document?"),
1474 text, 0, 2, _("&Overwrite"), _("&Rename"), _("&Cancel"));
1477 case 1: return renameBuffer(b, docstring());
1478 case 2: return false;
1482 // Ok, change the name of the buffer
1483 b.setFileName(fname.absFilename());
1485 bool unnamed = b.isUnnamed();
1486 b.setUnnamed(false);
1487 b.saveCheckSum(fname);
1489 if (!saveBuffer(b)) {
1490 b.setFileName(oldname.absFilename());
1491 b.setUnnamed(unnamed);
1492 b.saveCheckSum(oldname);
1500 bool GuiView::saveBuffer(Buffer & b)
1503 return renameBuffer(b, docstring());
1506 LyX::ref().session().lastFiles().add(b.fileName());
1510 // Switch to this Buffer.
1513 // FIXME: we don't tell the user *WHY* the save failed !!
1514 docstring const file = makeDisplayPath(b.absFileName(), 30);
1515 docstring text = bformat(_("The document %1$s could not be saved.\n\n"
1516 "Do you want to rename the document and "
1517 "try again?"), file);
1518 int const ret = Alert::prompt(_("Rename and save?"),
1519 text, 0, 2, _("&Rename"), _("&Retry"), _("&Cancel"));
1522 if (!renameBuffer(b, docstring()))
1531 return saveBuffer(b);
1535 bool GuiView::closeBuffer()
1537 Buffer * buf = buffer();
1538 return buf && closeBuffer(*buf);
1542 bool GuiView::closeBuffer(Buffer & buf)
1544 if (buf.isClean() || buf.paragraphs().empty()) {
1545 theBufferList().release(&buf);
1548 // Switch to this Buffer.
1553 if (buf.isUnnamed())
1554 file = from_utf8(buf.fileName().onlyFileName());
1556 file = buf.fileName().displayName(30);
1558 docstring const text = bformat(_("The document %1$s has unsaved changes."
1559 "\n\nDo you want to save the document or discard the changes?"), file);
1560 int const ret = Alert::prompt(_("Save changed document?"),
1561 text, 0, 2, _("&Save"), _("&Discard"), _("&Cancel"));
1565 if (!saveBuffer(buf))
1569 // if we crash after this we could
1570 // have no autosave file but I guess
1571 // this is really improbable (Jug)
1572 removeAutosaveFile(buf.absFileName());
1578 // save file names to .lyx/session
1579 // if master/slave are both open, do not save slave since it
1580 // will be automatically loaded when the master is loaded
1581 if (buf.masterBuffer() == &buf)
1582 LyX::ref().session().lastOpened().add(buf.fileName());
1584 theBufferList().release(&buf);
1589 bool GuiView::quitWriteAll()
1591 while (!theBufferList().empty()) {
1592 Buffer * b = theBufferList().first();
1593 if (!closeBuffer(*b))
1600 bool GuiView::dispatch(FuncRequest const & cmd)
1602 BufferView * bv = view();
1603 // By default we won't need any update.
1605 bv->cursor().updateFlags(Update::None);
1607 switch(cmd.action) {
1608 case LFUN_FILE_OPEN:
1609 openDocument(to_utf8(cmd.argument()));
1612 case LFUN_BUFFER_IMPORT:
1613 importDocument(to_utf8(cmd.argument()));
1616 case LFUN_BUFFER_SWITCH:
1617 setBuffer(theBufferList().getBuffer(to_utf8(cmd.argument())));
1620 case LFUN_BUFFER_NEXT:
1621 setBuffer(theBufferList().next(buffer()));
1624 case LFUN_BUFFER_PREVIOUS:
1625 setBuffer(theBufferList().previous(buffer()));
1628 case LFUN_COMMAND_EXECUTE: {
1629 bool const show_it = cmd.argument() != "off";
1630 d.toolbars_->showCommandBuffer(show_it);
1633 case LFUN_DROP_LAYOUTS_CHOICE:
1635 d.layout_->showPopup();
1638 case LFUN_MENU_OPEN:
1639 if (QMenu * menu = guiApp->menus().menu(toqstr(cmd.argument())))
1640 menu->exec(QCursor::pos());
1643 case LFUN_FILE_INSERT:
1644 insertLyXFile(cmd.argument());
1646 case LFUN_FILE_INSERT_PLAINTEXT_PARA:
1647 insertPlaintextFile(cmd.argument(), true);
1650 case LFUN_FILE_INSERT_PLAINTEXT:
1651 insertPlaintextFile(cmd.argument(), false);
1654 case LFUN_BUFFER_WRITE:
1656 saveBuffer(bv->buffer());
1659 case LFUN_BUFFER_WRITE_AS:
1661 renameBuffer(bv->buffer(), cmd.argument());
1664 case LFUN_BUFFER_WRITE_ALL: {
1665 Buffer * first = theBufferList().first();
1668 message(_("Saving all documents..."));
1669 // We cannot use a for loop as the buffer list cycles.
1675 LYXERR(Debug::ACTION, "Saved " << b->absFileName());
1676 b = theBufferList().next(b);
1677 } while (b != first);
1678 message(_("All documents saved."));
1682 case LFUN_TOOLBAR_TOGGLE: {
1683 string const name = cmd.getArg(0);
1684 bool const allowauto = cmd.getArg(1) == "allowauto";
1685 // it is possible to get current toolbar status like this,...
1686 // but I decide to obey the order of ToolbarBackend::flags
1687 // and disregard real toolbar status.
1688 // toolbars_->saveToolbarInfo();
1690 // toggle state on/off/auto
1691 d.toolbars_->toggleToolbarState(name, allowauto);
1695 ToolbarInfo * tbi = d.toolbars_->getToolbarInfo(name);
1697 message(bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name)));
1701 if (tbi->flags & ToolbarInfo::ON)
1703 else if (tbi->flags & ToolbarInfo::OFF)
1705 else if (tbi->flags & ToolbarInfo::AUTO)
1708 message(bformat(_("Toolbar \"%1$s\" state set to %2$s"),
1709 _(tbi->gui_name), state));
1713 case LFUN_DIALOG_UPDATE: {
1714 string const name = to_utf8(cmd.argument());
1715 // Can only update a dialog connected to an existing inset
1716 Inset * inset = getOpenInset(name);
1718 FuncRequest fr(LFUN_INSET_DIALOG_UPDATE, cmd.argument());
1719 inset->dispatch(view()->cursor(), fr);
1720 } else if (name == "paragraph") {
1721 lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE));
1722 } else if (name == "prefs") {
1723 updateDialog(name, string());
1728 case LFUN_DIALOG_TOGGLE: {
1729 if (isDialogVisible(cmd.getArg(0)))
1730 dispatch(FuncRequest(LFUN_DIALOG_HIDE, cmd.argument()));
1732 dispatch(FuncRequest(LFUN_DIALOG_SHOW, cmd.argument()));
1736 case LFUN_DIALOG_DISCONNECT_INSET:
1737 disconnectDialog(to_utf8(cmd.argument()));
1740 case LFUN_DIALOG_HIDE: {
1743 guiApp->hideDialogs(to_utf8(cmd.argument()), 0);
1747 case LFUN_DIALOG_SHOW: {
1748 string const name = cmd.getArg(0);
1749 string data = trim(to_utf8(cmd.argument()).substr(name.size()));
1751 if (name == "character") {
1752 data = freefont2string();
1754 showDialog("character", data);
1755 } else if (name == "latexlog") {
1756 Buffer::LogType type;
1757 string const logfile = buffer()->logName(&type);
1759 case Buffer::latexlog:
1762 case Buffer::buildlog:
1766 data += Lexer::quoteString(logfile);
1767 showDialog("log", data);
1768 } else if (name == "vclog") {
1769 string const data = "vc " +
1770 Lexer::quoteString(buffer()->lyxvc().getLogFile());
1771 showDialog("log", data);
1773 showDialog(name, data);
1777 case LFUN_INSET_APPLY: {
1778 string const name = cmd.getArg(0);
1779 Inset * inset = getOpenInset(name);
1781 FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument());
1782 inset->dispatch(view()->cursor(), fr);
1784 FuncRequest fr(LFUN_INSET_INSERT, cmd.argument());
1798 Buffer const * GuiView::updateInset(Inset const * inset)
1800 if (!d.current_work_area_)
1804 d.current_work_area_->scheduleRedraw();
1806 return &d.current_work_area_->bufferView().buffer();
1810 void GuiView::restartCursor()
1812 /* When we move around, or type, it's nice to be able to see
1813 * the cursor immediately after the keypress.
1815 if (d.current_work_area_)
1816 d.current_work_area_->startBlinkingCursor();
1818 // Take this occasion to update the toobars and layout list.
1825 // This list should be kept in sync with the list of insets in
1826 // src/insets/Inset.cpp. I.e., if a dialog goes with an inset, the
1827 // dialog should have the same name as the inset.
1829 char const * const dialognames[] = {
1830 "aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character",
1831 "citation", "document", "embedding", "errorlist", "ert", "external", "file",
1832 "findreplace", "float", "graphics", "include", "index", "nomenclature", "label", "log",
1833 "mathdelimiter", "mathmatrix", "note", "paragraph",
1834 "prefs", "print", "ref", "sendto", "spellchecker","tabular", "tabularcreate",
1836 #ifdef HAVE_LIBAIKSAURUS
1840 "texinfo", "toc", "href", "view-source", "vspace", "wrap", "listings" };
1842 char const * const * const end_dialognames =
1843 dialognames + (sizeof(dialognames) / sizeof(char *));
1847 cmpCStr(char const * name) : name_(name) {}
1848 bool operator()(char const * other) {
1849 return strcmp(other, name_) == 0;
1856 bool isValidName(string const & name)
1858 return find_if(dialognames, end_dialognames,
1859 cmpCStr(name.c_str())) != end_dialognames;
1865 void GuiView::resetDialogs()
1867 // Make sure that no LFUN uses any LyXView.
1868 theLyXFunc().setLyXView(0);
1869 // FIXME: the "math panels" toolbar takes an awful lot of time to
1870 // initialise so we don't do that for the time being.
1871 //d.toolbars_->init();
1872 guiApp->menus().fillMenuBar(this);
1874 d.layout_->updateContents(true);
1875 // Now update controls with current buffer.
1876 theLyXFunc().setLyXView(this);
1881 Dialog * GuiView::find_or_build(string const & name)
1883 if (!isValidName(name))
1886 map<string, DialogPtr>::iterator it = d.dialogs_.find(name);
1888 if (it != d.dialogs_.end())
1889 return it->second.get();
1891 Dialog * dialog = build(name);
1892 d.dialogs_[name].reset(dialog);
1893 if (lyxrc.allow_geometry_session)
1894 dialog->restoreSession();
1899 void GuiView::showDialog(string const & name, string const & data,
1906 Dialog * dialog = find_or_build(name);
1908 dialog->showData(data);
1910 d.open_insets_[name] = inset;
1916 bool GuiView::isDialogVisible(string const & name) const
1918 map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
1919 if (it == d.dialogs_.end())
1921 return it->second.get()->isVisibleView();
1925 void GuiView::hideDialog(string const & name, Inset * inset)
1927 // Don't send the signal if we are quitting, because on MSVC it is
1928 // destructed before the cut stack in CutAndPaste.cpp, and this method
1929 // is called from some inset destructor if the cut stack is not empty
1934 map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
1935 if (it == d.dialogs_.end())
1938 if (inset && inset != getOpenInset(name))
1941 Dialog * const dialog = it->second.get();
1942 if (dialog->isVisibleView())
1944 d.open_insets_[name] = 0;
1948 void GuiView::disconnectDialog(string const & name)
1950 if (!isValidName(name))
1953 if (d.open_insets_.find(name) != d.open_insets_.end())
1954 d.open_insets_[name] = 0;
1958 Inset * GuiView::getOpenInset(string const & name) const
1960 if (!isValidName(name))
1963 map<string, Inset *>::const_iterator it = d.open_insets_.find(name);
1964 return it == d.open_insets_.end() ? 0 : it->second;
1968 void GuiView::hideAll() const
1970 map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
1971 map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
1973 for(; it != end; ++it)
1974 it->second->hideView();
1978 void GuiView::hideBufferDependent() const
1980 map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
1981 map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
1983 for(; it != end; ++it) {
1984 Dialog * dialog = it->second.get();
1985 if (dialog->isBufferDependent())
1991 void GuiView::updateBufferDependent(bool switched) const
1993 map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
1994 map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
1996 for(; it != end; ++it) {
1997 Dialog * dialog = it->second.get();
1998 if (!dialog->isVisibleView())
2000 if (switched && dialog->isBufferDependent()) {
2001 if (dialog->initialiseParams(""))
2002 dialog->updateView();
2006 // A bit clunky, but the dialog will request
2007 // that the kernel provides it with the necessary
2009 dialog->updateDialog();
2015 void GuiView::checkStatus()
2017 map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
2018 map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
2020 for(; it != end; ++it) {
2021 Dialog * const dialog = it->second.get();
2022 if (dialog && dialog->isVisibleView())
2023 dialog->checkStatus();
2029 // will be replaced by a proper factory...
2030 Dialog * createGuiAbout(GuiView & lv);
2031 Dialog * createGuiBibitem(GuiView & lv);
2032 Dialog * createGuiBibtex(GuiView & lv);
2033 Dialog * createGuiBox(GuiView & lv);
2034 Dialog * createGuiBranch(GuiView & lv);
2035 Dialog * createGuiChanges(GuiView & lv);
2036 Dialog * createGuiCharacter(GuiView & lv);
2037 Dialog * createGuiCitation(GuiView & lv);
2038 Dialog * createGuiDelimiter(GuiView & lv);
2039 Dialog * createGuiDocument(GuiView & lv);
2040 Dialog * createGuiErrorList(GuiView & lv);
2041 Dialog * createGuiERT(GuiView & lv);
2042 Dialog * createGuiExternal(GuiView & lv);
2043 Dialog * createGuiFloat(GuiView & lv);
2044 Dialog * createGuiGraphics(GuiView & lv);
2045 Dialog * createGuiInclude(GuiView & lv);
2046 Dialog * createGuiIndex(GuiView & lv);
2047 Dialog * createGuiLabel(GuiView & lv);
2048 Dialog * createGuiListings(GuiView & lv);
2049 Dialog * createGuiLog(GuiView & lv);
2050 Dialog * createGuiMathMatrix(GuiView & lv);
2051 Dialog * createGuiNomenclature(GuiView & lv);
2052 Dialog * createGuiNote(GuiView & lv);
2053 Dialog * createGuiParagraph(GuiView & lv);
2054 Dialog * createGuiPreferences(GuiView & lv);
2055 Dialog * createGuiPrint(GuiView & lv);
2056 Dialog * createGuiRef(GuiView & lv);
2057 Dialog * createGuiSearch(GuiView & lv);
2058 Dialog * createGuiSendTo(GuiView & lv);
2059 Dialog * createGuiShowFile(GuiView & lv);
2060 Dialog * createGuiSpellchecker(GuiView & lv);
2061 Dialog * createGuiTabularCreate(GuiView & lv);
2062 Dialog * createGuiTabular(GuiView & lv);
2063 Dialog * createGuiTexInfo(GuiView & lv);
2064 Dialog * createGuiToc(GuiView & lv);
2065 Dialog * createGuiThesaurus(GuiView & lv);
2066 Dialog * createGuiHyperlink(GuiView & lv);
2067 Dialog * createGuiVSpace(GuiView & lv);
2068 Dialog * createGuiViewSource(GuiView & lv);
2069 Dialog * createGuiWrap(GuiView & lv);
2072 Dialog * GuiView::build(string const & name)
2074 BOOST_ASSERT(isValidName(name));
2076 if (name == "aboutlyx")
2077 return createGuiAbout(*this);
2078 if (name == "bibitem")
2079 return createGuiBibitem(*this);
2080 if (name == "bibtex")
2081 return createGuiBibtex(*this);
2083 return createGuiBox(*this);
2084 if (name == "branch")
2085 return createGuiBranch(*this);
2086 if (name == "changes")
2087 return createGuiChanges(*this);
2088 if (name == "character")
2089 return createGuiCharacter(*this);
2090 if (name == "citation")
2091 return createGuiCitation(*this);
2092 if (name == "document")
2093 return createGuiDocument(*this);
2094 if (name == "errorlist")
2095 return createGuiErrorList(*this);
2097 return createGuiERT(*this);
2098 if (name == "external")
2099 return createGuiExternal(*this);
2101 return createGuiShowFile(*this);
2102 if (name == "findreplace")
2103 return createGuiSearch(*this);
2104 if (name == "float")
2105 return createGuiFloat(*this);
2106 if (name == "graphics")
2107 return createGuiGraphics(*this);
2108 if (name == "include")
2109 return createGuiInclude(*this);
2110 if (name == "index")
2111 return createGuiIndex(*this);
2112 if (name == "nomenclature")
2113 return createGuiNomenclature(*this);
2114 if (name == "label")
2115 return createGuiLabel(*this);
2117 return createGuiLog(*this);
2118 if (name == "view-source")
2119 return createGuiViewSource(*this);
2120 if (name == "mathdelimiter")
2121 return createGuiDelimiter(*this);
2122 if (name == "mathmatrix")
2123 return createGuiMathMatrix(*this);
2125 return createGuiNote(*this);
2126 if (name == "paragraph")
2127 return createGuiParagraph(*this);
2128 if (name == "prefs")
2129 return createGuiPreferences(*this);
2130 if (name == "print")
2131 return createGuiPrint(*this);
2133 return createGuiRef(*this);
2134 if (name == "sendto")
2135 return createGuiSendTo(*this);
2136 if (name == "spellchecker")
2137 return createGuiSpellchecker(*this);
2138 if (name == "tabular")
2139 return createGuiTabular(*this);
2140 if (name == "tabularcreate")
2141 return createGuiTabularCreate(*this);
2142 if (name == "texinfo")
2143 return createGuiTexInfo(*this);
2144 #ifdef HAVE_LIBAIKSAURUS
2145 if (name == "thesaurus")
2146 return createGuiThesaurus(*this);
2149 return createGuiToc(*this);
2151 return createGuiHyperlink(*this);
2152 if (name == "vspace")
2153 return createGuiVSpace(*this);
2155 return createGuiWrap(*this);
2156 if (name == "listings")
2157 return createGuiListings(*this);
2163 } // namespace frontend
2166 #include "GuiView_moc.cpp"