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>
78 #include <QPushButton>
82 #include <QStackedWidget>
88 #include <boost/assert.hpp>
89 #include <boost/bind.hpp>
91 #ifdef HAVE_SYS_TIME_H
92 # include <sys/time.h>
99 using namespace lyx::support;
103 extern bool quitting;
109 class BackgroundWidget : public QWidget
114 LYXERR(Debug::GUI, "show banner: " << lyxrc.show_banner);
115 /// The text to be written on top of the pixmap
116 QString const text = lyx_version ? lyx_version : qt_("unknown version");
117 splash_ = QPixmap(":/images/banner.png");
119 QPainter pain(&splash_);
120 pain.setPen(QColor(255, 255, 0));
122 // The font used to display the version info
123 font.setStyleHint(QFont::SansSerif);
124 font.setWeight(QFont::Bold);
125 font.setPointSize(int(toqstr(lyxrc.font_sizes[FONT_SIZE_LARGE]).toDouble()));
127 pain.drawText(260, 270, text);
130 void paintEvent(QPaintEvent *)
132 int x = (width() - splash_.width()) / 2;
133 int y = (height() - splash_.height()) / 2;
135 pain.drawPixmap(x, y, splash_);
145 typedef boost::shared_ptr<Dialog> DialogPtr;
147 struct GuiView::GuiViewPrivate
150 : current_work_area_(0), layout_(0),
151 quitting_by_menu_(false), autosave_timeout_(5000), in_show_(false)
153 // hardcode here the platform specific icon size
154 smallIconSize = 14; // scaling problems
155 normalIconSize = 20; // ok, default
156 bigIconSize = 26; // better for some math icons
158 splitter_ = new QSplitter;
159 bg_widget_ = new BackgroundWidget;
160 stack_widget_ = new QStackedWidget;
161 stack_widget_->addWidget(bg_widget_);
162 stack_widget_->addWidget(splitter_);
170 delete stack_widget_;
174 QMenu * toolBarPopup(GuiView * parent)
176 // FIXME: translation
177 QMenu * menu = new QMenu(parent);
178 QActionGroup * iconSizeGroup = new QActionGroup(parent);
180 QAction * smallIcons = new QAction(iconSizeGroup);
181 smallIcons->setText(qt_("Small-sized icons"));
182 smallIcons->setCheckable(true);
183 QObject::connect(smallIcons, SIGNAL(triggered()),
184 parent, SLOT(smallSizedIcons()));
185 menu->addAction(smallIcons);
187 QAction * normalIcons = new QAction(iconSizeGroup);
188 normalIcons->setText(qt_("Normal-sized icons"));
189 normalIcons->setCheckable(true);
190 QObject::connect(normalIcons, SIGNAL(triggered()),
191 parent, SLOT(normalSizedIcons()));
192 menu->addAction(normalIcons);
194 QAction * bigIcons = new QAction(iconSizeGroup);
195 bigIcons->setText(qt_("Big-sized icons"));
196 bigIcons->setCheckable(true);
197 QObject::connect(bigIcons, SIGNAL(triggered()),
198 parent, SLOT(bigSizedIcons()));
199 menu->addAction(bigIcons);
201 unsigned int cur = parent->iconSize().width();
202 if ( cur == parent->d.smallIconSize)
203 smallIcons->setChecked(true);
204 else if (cur == parent->d.normalIconSize)
205 normalIcons->setChecked(true);
206 else if (cur == parent->d.bigIconSize)
207 bigIcons->setChecked(true);
214 stack_widget_->setCurrentWidget(bg_widget_);
215 bg_widget_->setUpdatesEnabled(true);
218 TabWorkArea * tabWorkArea(int i)
220 return dynamic_cast<TabWorkArea *>(splitter_->widget(i));
223 TabWorkArea * currentTabWorkArea()
225 if (splitter_->count() == 1)
226 // The first TabWorkArea is always the first one, if any.
227 return tabWorkArea(0);
229 TabWorkArea * tab_widget = 0;
230 for (int i = 0; i != splitter_->count(); ++i) {
231 QWidget * w = splitter_->widget(i);
234 tab_widget = dynamic_cast<TabWorkArea *>(w);
243 GuiWorkArea * current_work_area_;
244 QSplitter * splitter_;
245 QStackedWidget * stack_widget_;
246 BackgroundWidget * bg_widget_;
248 GuiToolbars * toolbars_;
249 /// The main layout box.
251 * \warning Don't Delete! The layout box is actually owned by
252 * whichever toolbar contains it. All the GuiView class needs is a
253 * means of accessing it.
255 * FIXME: replace that with a proper model so that we are not limited
256 * to only one dialog.
258 GuiLayoutBox * layout_;
261 map<string, Inset *> open_insets_;
264 map<string, DialogPtr> dialogs_;
266 unsigned int smallIconSize;
267 unsigned int normalIconSize;
268 unsigned int bigIconSize;
270 QTimer statusbar_timer_;
271 /// are we quitting by the menu?
272 bool quitting_by_menu_;
273 /// auto-saving of buffers
274 Timeout autosave_timeout_;
275 /// flag against a race condition due to multiclicks, see bug #1119
280 GuiView::GuiView(int id)
281 : d(*new GuiViewPrivate), id_(id)
283 // GuiToolbars *must* be initialised before the menu bar.
284 d.toolbars_ = new GuiToolbars(*this);
286 // Fill up the menu bar.
287 guiApp->menus().fillMenuBar(this);
289 setCentralWidget(d.stack_widget_);
291 // Start autosave timer
292 if (lyxrc.autosave) {
293 d.autosave_timeout_.timeout.connect(boost::bind(&GuiView::autoSave, this));
294 d.autosave_timeout_.setTimeout(lyxrc.autosave * 1000);
295 d.autosave_timeout_.start();
297 connect(&d.statusbar_timer_, SIGNAL(timeout()),
298 this, SLOT(clearMessage()));
300 // Qt bug? signal lastWindowClosed does not work
301 setAttribute(Qt::WA_QuitOnClose, false);
302 setAttribute(Qt::WA_DeleteOnClose, true);
304 // assign an icon to main form. We do not do it under Qt/Mac,
305 // since the icon is provided in the application bundle.
306 setWindowIcon(QPixmap(":/images/lyx.png"));
310 setAcceptDrops(true);
312 statusBar()->setSizeGripEnabled(true);
314 // Forbid too small unresizable window because it can happen
315 // with some window manager under X11.
316 setMinimumSize(300, 200);
318 if (!lyxrc.allow_geometry_session)
319 // No session handling, default to a sane size.
320 setGeometry(50, 50, 690, 510);
322 // Now take care of session management.
324 QString const key = "view-" + QString::number(id_);
326 QPoint pos = settings.value(key + "/pos", QPoint(50, 50)).toPoint();
327 QSize size = settings.value(key + "/size", QSize(690, 510)).toSize();
331 if (!restoreGeometry(settings.value(key + "/geometry").toByteArray()))
332 setGeometry(50, 50, 690, 510);
334 setIconSize(settings.value(key + "/icon_size").toSize());
344 void GuiView::close()
346 d.quitting_by_menu_ = true;
347 d.current_work_area_ = 0;
348 for (int i = 0; i != d.splitter_->count(); ++i) {
349 TabWorkArea * twa = d.tabWorkArea(i);
353 QMainWindow::close();
354 d.quitting_by_menu_ = false;
358 void GuiView::setFocus()
360 if (d.current_work_area_)
361 d.current_work_area_->setFocus();
367 QMenu * GuiView::createPopupMenu()
369 return d.toolBarPopup(this);
373 void GuiView::showEvent(QShowEvent * e)
375 LYXERR(Debug::GUI, "Passed Geometry "
376 << size().height() << "x" << size().width()
377 << "+" << pos().x() << "+" << pos().y());
379 if (d.splitter_->count() == 0)
380 // No work area, switch to the background widget.
383 QMainWindow::showEvent(e);
387 void GuiView::closeEvent(QCloseEvent * close_event)
389 // we may have been called through the close window button
390 // which bypasses the LFUN machinery.
391 if (!d.quitting_by_menu_ && guiApp->viewCount() == 1) {
392 if (!quitWriteAll()) {
393 close_event->ignore();
398 // Make sure that no LFUN use this close to be closed View.
399 theLyXFunc().setLyXView(0);
400 // Make sure the timer time out will not trigger a statusbar update.
401 d.statusbar_timer_.stop();
403 if (lyxrc.allow_geometry_session) {
405 QString const key = "view-" + QString::number(id_);
407 settings.setValue(key + "/pos", pos());
408 settings.setValue(key + "/size", size());
410 settings.setValue(key + "/geometry", saveGeometry());
412 settings.setValue(key + "/icon_size", iconSize());
413 d.toolbars_->saveToolbarInfo();
414 // Now take care of all other dialogs:
415 map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
416 for (; it!= d.dialogs_.end(); ++it)
417 it->second->saveSession();
420 guiApp->unregisterView(id_);
421 if (guiApp->viewCount() > 0) {
422 // Just close the window and do nothing else if this is not the
424 close_event->accept();
430 // this is the place where we leave the frontend.
431 // it is the only point at which we start quitting.
432 close_event->accept();
433 // quit the event loop
438 void GuiView::dragEnterEvent(QDragEnterEvent * event)
440 if (event->mimeData()->hasUrls())
442 /// \todo Ask lyx-devel is this is enough:
443 /// if (event->mimeData()->hasFormat("text/plain"))
444 /// event->acceptProposedAction();
448 void GuiView::dropEvent(QDropEvent* event)
450 QList<QUrl> files = event->mimeData()->urls();
454 LYXERR(Debug::GUI, "GuiView::dropEvent: got URLs!");
455 for (int i = 0; i != files.size(); ++i) {
456 string const file = os::internal_path(fromqstr(
457 files.at(i).toLocalFile()));
459 lyx::dispatch(FuncRequest(LFUN_FILE_OPEN, file));
464 void GuiView::message(docstring const & str)
466 if (ForkedProcess::iAmAChild())
469 statusBar()->showMessage(toqstr(str));
470 d.statusbar_timer_.stop();
471 d.statusbar_timer_.start(3000);
475 void GuiView::smallSizedIcons()
477 setIconSize(QSize(d.smallIconSize, d.smallIconSize));
481 void GuiView::normalSizedIcons()
483 setIconSize(QSize(d.normalIconSize, d.normalIconSize));
487 void GuiView::bigSizedIcons()
489 setIconSize(QSize(d.bigIconSize, d.bigIconSize));
493 void GuiView::clearMessage()
497 theLyXFunc().setLyXView(this);
498 statusBar()->showMessage(toqstr(theLyXFunc().viewStatusMessage()));
499 d.statusbar_timer_.stop();
503 void GuiView::updateWindowTitle(GuiWorkArea * wa)
505 if (wa != d.current_work_area_)
507 setWindowTitle(qt_("LyX: ") + wa->windowTitle());
508 setWindowIconText(wa->windowIconText());
512 void GuiView::on_currentWorkAreaChanged(GuiWorkArea * wa)
515 disconnectBufferView();
516 connectBufferView(wa->bufferView());
517 connectBuffer(wa->bufferView().buffer());
518 d.current_work_area_ = wa;
519 QObject::connect(wa, SIGNAL(titleChanged(GuiWorkArea *)),
520 this, SLOT(updateWindowTitle(GuiWorkArea *)));
521 updateWindowTitle(wa);
524 // Buffer-dependent dialogs should be updated or
525 // hidden. This should go here because some dialogs (eg ToC)
526 // require bv_->text.
527 updateBufferDependent(true);
534 void GuiView::updateStatusBar()
536 // let the user see the explicit message
537 if (d.statusbar_timer_.isActive())
540 statusBar()->showMessage(toqstr(theLyXFunc().viewStatusMessage()));
544 bool GuiView::hasFocus() const
546 return qApp->activeWindow() == this;
550 bool GuiView::event(QEvent * e)
554 // Useful debug code:
555 //case QEvent::ActivationChange:
556 //case QEvent::WindowDeactivate:
557 //case QEvent::Paint:
558 //case QEvent::Enter:
559 //case QEvent::Leave:
560 //case QEvent::HoverEnter:
561 //case QEvent::HoverLeave:
562 //case QEvent::HoverMove:
563 //case QEvent::StatusTip:
564 //case QEvent::DragEnter:
565 //case QEvent::DragLeave:
569 case QEvent::WindowActivate: {
570 guiApp->setCurrentView(*this);
571 if (d.current_work_area_) {
572 BufferView & bv = d.current_work_area_->bufferView();
573 connectBufferView(bv);
574 connectBuffer(bv.buffer());
575 // The document structure, name and dialogs might have
576 // changed in another view.
577 updateBufferDependent(true);
579 setWindowTitle(qt_("LyX"));
580 setWindowIconText(qt_("LyX"));
582 return QMainWindow::event(e);
585 case QEvent::ShortcutOverride: {
586 if (d.current_work_area_)
587 // Nothing special to do.
588 return QMainWindow::event(e);
590 QKeyEvent * ke = static_cast<QKeyEvent*>(e);
592 // Let Qt handle menu access and the Tab keys to navigate keys to navigate
594 if (ke->modifiers() & Qt::AltModifier || ke->key() == Qt::Key_Tab
595 || ke->key() == Qt::Key_Backtab)
596 return QMainWindow::event(e);
598 // Allow processing of shortcuts that are allowed even when no Buffer
600 theLyXFunc().setLyXView(this);
602 setKeySymbol(&sym, ke);
603 theLyXFunc().processKeySym(sym, q_key_state(ke->modifiers()));
609 return QMainWindow::event(e);
614 bool GuiView::focusNextPrevChild(bool /*next*/)
621 void GuiView::setBusy(bool busy)
623 if (d.current_work_area_) {
624 d.current_work_area_->setUpdatesEnabled(!busy);
626 d.current_work_area_->stopBlinkingCursor();
628 d.current_work_area_->startBlinkingCursor();
632 QApplication::setOverrideCursor(Qt::WaitCursor);
634 QApplication::restoreOverrideCursor();
638 GuiToolbar * GuiView::makeToolbar(ToolbarInfo const & tbinfo, bool newline)
640 GuiToolbar * toolBar = new GuiToolbar(tbinfo, *this);
642 if (tbinfo.flags & ToolbarInfo::TOP) {
644 addToolBarBreak(Qt::TopToolBarArea);
645 addToolBar(Qt::TopToolBarArea, toolBar);
648 if (tbinfo.flags & ToolbarInfo::BOTTOM) {
649 // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
650 #if (QT_VERSION >= 0x040202)
652 addToolBarBreak(Qt::BottomToolBarArea);
654 addToolBar(Qt::BottomToolBarArea, toolBar);
657 if (tbinfo.flags & ToolbarInfo::LEFT) {
658 // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
659 #if (QT_VERSION >= 0x040202)
661 addToolBarBreak(Qt::LeftToolBarArea);
663 addToolBar(Qt::LeftToolBarArea, toolBar);
666 if (tbinfo.flags & ToolbarInfo::RIGHT) {
667 // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
668 #if (QT_VERSION >= 0x040202)
670 addToolBarBreak(Qt::RightToolBarArea);
672 addToolBar(Qt::RightToolBarArea, toolBar);
675 // The following does not work so I cannot restore to exact toolbar location
677 ToolbarSection::ToolbarInfo & tbinfo = LyX::ref().session().toolbars().load(tbinfo.name);
678 toolBar->move(tbinfo.posx, tbinfo.posy);
685 GuiWorkArea * GuiView::workArea(Buffer & buffer)
687 for (int i = 0; i != d.splitter_->count(); ++i) {
688 GuiWorkArea * wa = d.tabWorkArea(i)->workArea(buffer);
696 GuiWorkArea * GuiView::addWorkArea(Buffer & buffer)
699 // Automatically create a TabWorkArea if there are none yet.
700 if (!d.splitter_->count())
703 TabWorkArea * tab_widget = d.currentTabWorkArea();
704 return tab_widget->addWorkArea(buffer, *this);
708 void GuiView::addTabWorkArea()
710 TabWorkArea * twa = new TabWorkArea;
711 QObject::connect(twa, SIGNAL(currentWorkAreaChanged(GuiWorkArea *)),
712 this, SLOT(on_currentWorkAreaChanged(GuiWorkArea *)));
713 d.splitter_->addWidget(twa);
714 d.stack_widget_->setCurrentWidget(d.splitter_);
718 GuiWorkArea const * GuiView::currentWorkArea() const
720 return d.current_work_area_;
724 void GuiView::setCurrentWorkArea(GuiWorkArea * wa)
728 // Changing work area can result from opening a file so
729 // update the toc in any case.
732 d.current_work_area_ = wa;
733 for (int i = 0; i != d.splitter_->count(); ++i) {
734 if (d.tabWorkArea(i)->setCurrentWorkArea(wa))
740 void GuiView::removeWorkArea(GuiWorkArea * wa)
743 if (wa == d.current_work_area_) {
745 disconnectBufferView();
746 hideBufferDependent();
747 d.current_work_area_ = 0;
750 for (int i = 0; i != d.splitter_->count(); ++i) {
751 TabWorkArea * twa = d.tabWorkArea(i);
752 if (!twa->removeWorkArea(wa))
753 // Not found in this tab group.
756 // We found and removed the GuiWorkArea.
758 // No more WorkAreas in this tab group, so delete it.
763 if (d.current_work_area_)
764 // This means that we are not closing the current GuiWorkArea;
767 // Switch to the next GuiWorkArea in the found TabWorkArea.
768 d.current_work_area_ = twa->currentWorkArea();
772 if (d.splitter_->count() == 0)
773 // No more work area, switch to the background widget.
778 void GuiView::setLayoutDialog(GuiLayoutBox * layout)
784 void GuiView::updateLayoutList()
787 d.layout_->updateContents(false);
791 void GuiView::updateToolbars()
793 if (d.current_work_area_) {
795 d.current_work_area_->bufferView().cursor().inMathed();
797 lyx::getStatus(FuncRequest(LFUN_LAYOUT_TABULAR)).enabled();
799 lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).enabled() &&
800 lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).onoff(true);
801 bool const mathmacrotemplate =
802 lyx::getStatus(FuncRequest(LFUN_IN_MATHMACROTEMPLATE)).enabled();
804 d.toolbars_->update(math, table, review, mathmacrotemplate);
806 d.toolbars_->update(false, false, false, false);
808 // update read-only status of open dialogs.
813 Buffer * GuiView::buffer()
815 if (d.current_work_area_)
816 return &d.current_work_area_->bufferView().buffer();
821 Buffer const * GuiView::buffer() const
823 if (d.current_work_area_)
824 return &d.current_work_area_->bufferView().buffer();
829 void GuiView::setBuffer(Buffer * newBuffer)
831 BOOST_ASSERT(newBuffer);
834 GuiWorkArea * wa = workArea(*newBuffer);
836 updateLabels(*newBuffer->masterBuffer());
837 wa = addWorkArea(*newBuffer);
839 //Disconnect the old buffer...there's no new one.
842 connectBuffer(*newBuffer);
843 connectBufferView(wa->bufferView());
844 setCurrentWorkArea(wa);
850 void GuiView::connectBuffer(Buffer & buf)
852 buf.setGuiDelegate(this);
856 void GuiView::disconnectBuffer()
858 if (d.current_work_area_)
859 d.current_work_area_->bufferView().setGuiDelegate(0);
863 void GuiView::connectBufferView(BufferView & bv)
865 bv.setGuiDelegate(this);
869 void GuiView::disconnectBufferView()
871 if (d.current_work_area_)
872 d.current_work_area_->bufferView().setGuiDelegate(0);
876 void GuiView::errors(string const & error_type)
878 ErrorList & el = buffer()->errorList(error_type);
880 showDialog("errorlist", error_type);
884 void GuiView::updateDialog(string const & name, string const & data)
886 if (!isDialogVisible(name))
889 map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
890 if (it == d.dialogs_.end())
893 Dialog * const dialog = it->second.get();
894 if (dialog->isVisibleView())
895 dialog->updateData(data);
899 BufferView * GuiView::view()
901 return d.current_work_area_ ? &d.current_work_area_->bufferView() : 0;
905 void GuiView::updateToc()
907 updateDialog("toc", "");
911 void GuiView::updateEmbeddedFiles()
913 updateDialog("embedding", "");
917 void GuiView::autoSave()
919 LYXERR(Debug::INFO, "Running autoSave()");
922 view()->buffer().autoSave();
926 void GuiView::resetAutosaveTimers()
929 d.autosave_timeout_.restart();
933 FuncStatus GuiView::getStatus(FuncRequest const & cmd)
937 Buffer * buf = buffer();
939 /* In LyX/Mac, when a dialog is open, the menus of the
940 application can still be accessed without giving focus to
941 the main window. In this case, we want to disable the menu
942 entries that are buffer-related.
944 Note that this code is not perfect, as bug 1941 attests:
945 http://bugzilla.lyx.org/show_bug.cgi?id=1941#c4
947 if (cmd.origin == FuncRequest::MENU && !hasFocus())
951 case LFUN_BUFFER_WRITE:
952 enable = buf && (buf->isUnnamed() || !buf->isClean());
955 case LFUN_BUFFER_WRITE_AS:
959 case LFUN_TOOLBAR_TOGGLE:
960 flag.setOnOff(d.toolbars_->visible(cmd.getArg(0)));
963 case LFUN_DIALOG_TOGGLE:
964 flag.setOnOff(isDialogVisible(cmd.getArg(0)));
965 // fall through to set "enable"
966 case LFUN_DIALOG_SHOW: {
967 string const name = cmd.getArg(0);
969 enable = name == "aboutlyx"
970 || name == "file" //FIXME: should be removed.
972 || name == "texinfo";
973 else if (name == "print")
974 enable = buf->isExportable("dvi")
975 && lyxrc.print_command != "none";
976 else if (name == "character") {
980 InsetCode ic = view()->cursor().inset().lyxCode();
981 enable = ic != ERT_CODE && ic != LISTINGS_CODE;
984 else if (name == "symbols") {
985 if (!view() || view()->cursor().inMathed())
988 InsetCode ic = view()->cursor().inset().lyxCode();
989 enable = ic != ERT_CODE && ic != LISTINGS_CODE;
992 else if (name == "latexlog")
993 enable = FileName(buf->logName()).isReadableFile();
994 else if (name == "spellchecker")
995 #if defined (USE_ASPELL) || defined (USE_ISPELL) || defined (USE_PSPELL)
996 enable = !buf->isReadonly();
1000 else if (name == "vclog")
1001 enable = buf->lyxvc().inUse();
1005 case LFUN_DIALOG_UPDATE: {
1006 string const name = cmd.getArg(0);
1008 enable = name == "prefs";
1012 case LFUN_INSET_APPLY: {
1017 string const name = cmd.getArg(0);
1018 Inset * inset = getOpenInset(name);
1020 FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument());
1022 if (!inset->getStatus(view()->cursor(), fr, fs)) {
1023 // Every inset is supposed to handle this
1024 BOOST_ASSERT(false);
1028 FuncRequest fr(LFUN_INSET_INSERT, cmd.argument());
1029 flag |= getStatus(fr);
1031 enable = flag.enabled();
1043 flag.enabled(false);
1049 static FileName selectTemplateFile()
1051 FileDialog dlg(_("Select template file"));
1052 dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
1053 dlg.setButton1(_("Templates|#T#t"), from_utf8(lyxrc.template_path));
1055 FileDialog::Result result =
1056 dlg.open(from_utf8(lyxrc.template_path),
1057 FileFilterList(_("LyX Documents (*.lyx)")),
1060 if (result.first == FileDialog::Later)
1062 if (result.second.empty())
1064 return FileName(to_utf8(result.second));
1068 Buffer * GuiView::loadDocument(FileName const & filename, bool tolastfiles)
1072 Buffer * newBuffer = checkAndLoadLyXFile(filename);
1075 message(_("Document not loaded."));
1080 setBuffer(newBuffer);
1082 // scroll to the position when the file was last closed
1083 if (lyxrc.use_lastfilepos) {
1084 LastFilePosSection::FilePos filepos =
1085 LyX::ref().session().lastFilePos().load(filename);
1086 view()->moveToPosition(filepos.pit, filepos.pos, 0, 0);
1090 LyX::ref().session().lastFiles().add(filename);
1097 void GuiView::openDocument(string const & fname)
1099 string initpath = lyxrc.document_path;
1102 string const trypath = buffer()->filePath();
1103 // If directory is writeable, use this as default.
1104 if (FileName(trypath).isDirWritable())
1110 if (fname.empty()) {
1111 FileDialog dlg(_("Select document to open"), LFUN_FILE_OPEN);
1112 dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
1113 dlg.setButton2(_("Examples|#E#e"),
1114 from_utf8(addPath(package().system_support().absFilename(), "examples")));
1116 FileDialog::Result result =
1117 dlg.open(from_utf8(initpath),
1118 FileFilterList(_("LyX Documents (*.lyx)")),
1121 if (result.first == FileDialog::Later)
1124 filename = to_utf8(result.second);
1126 // check selected filename
1127 if (filename.empty()) {
1128 message(_("Canceled."));
1134 // get absolute path of file and add ".lyx" to the filename if
1136 FileName const fullname =
1137 fileSearch(string(), filename, "lyx", support::may_not_exist);
1138 if (!fullname.empty())
1139 filename = fullname.absFilename();
1141 // if the file doesn't exist, let the user create one
1142 if (!fullname.exists()) {
1143 // the user specifically chose this name. Believe him.
1144 Buffer * const b = newFile(filename, string(), true);
1150 docstring const disp_fn = makeDisplayPath(filename);
1151 message(bformat(_("Opening document %1$s..."), disp_fn));
1154 Buffer * buf = loadDocument(fullname);
1158 buf->errors("Parse");
1159 str2 = bformat(_("Document %1$s opened."), disp_fn);
1161 str2 = bformat(_("Could not open document %1$s"), disp_fn);
1166 // FIXME: clean that
1167 static bool import(GuiView * lv, FileName const & filename,
1168 string const & format, ErrorList & errorList)
1170 FileName const lyxfile(changeExtension(filename.absFilename(), ".lyx"));
1172 string loader_format;
1173 vector<string> loaders = theConverters().loaders();
1174 if (find(loaders.begin(), loaders.end(), format) == loaders.end()) {
1175 for (vector<string>::const_iterator it = loaders.begin();
1176 it != loaders.end(); ++it) {
1177 if (!theConverters().isReachable(format, *it))
1180 string const tofile =
1181 changeExtension(filename.absFilename(),
1182 formats.extension(*it));
1183 if (!theConverters().convert(0, filename, FileName(tofile),
1184 filename, format, *it, errorList))
1186 loader_format = *it;
1189 if (loader_format.empty()) {
1190 frontend::Alert::error(_("Couldn't import file"),
1191 bformat(_("No information for importing the format %1$s."),
1192 formats.prettyName(format)));
1196 loader_format = format;
1198 if (loader_format == "lyx") {
1199 Buffer * buf = lv->loadDocument(lyxfile);
1204 buf->errors("Parse");
1206 Buffer * const b = newFile(lyxfile.absFilename(), string(), true);
1210 bool as_paragraphs = loader_format == "textparagraph";
1211 string filename2 = (loader_format == format) ? filename.absFilename()
1212 : changeExtension(filename.absFilename(),
1213 formats.extension(loader_format));
1214 lv->view()->insertPlaintextFile(FileName(filename2), as_paragraphs);
1215 theLyXFunc().setLyXView(lv);
1216 lyx::dispatch(FuncRequest(LFUN_MARK_OFF));
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 docstring const displaypath = makeDisplayPath(lyxfile.absFilename(), 30);
1291 // if the file exists already, and we didn't do
1292 // -i lyx thefile.lyx, warn
1293 if (lyxfile.exists() && fullname != lyxfile) {
1295 docstring text = bformat(_("The document %1$s already exists.\n\n"
1296 "Do you want to overwrite that document?"), displaypath);
1297 int const ret = Alert::prompt(_("Overwrite document?"),
1298 text, 0, 1, _("&Overwrite"), _("&Cancel"));
1301 message(_("Canceled."));
1306 message(bformat(_("Importing %1$s..."), displaypath));
1307 ErrorList errorList;
1308 if (import(this, fullname, format, errorList))
1309 message(_("imported."));
1311 message(_("file not imported!"));
1313 // FIXME (Abdel 12/08/06): Is there a need to display the error list here?
1317 void GuiView::newDocument(string const & filename, bool from_template)
1319 FileName initpath(lyxrc.document_path);
1320 Buffer * buf = buffer();
1322 FileName const trypath(buf->filePath());
1323 // If directory is writeable, use this as default.
1324 if (trypath.isDirWritable())
1328 string templatefile = from_template ?
1329 selectTemplateFile().absFilename() : string();
1331 if (filename.empty())
1332 b = newUnnamedFile(templatefile, initpath);
1334 b = newFile(filename, templatefile, true);
1338 // Ensure the cursor is correctly positionned on screen.
1339 view()->showCursor();
1343 void GuiView::insertLyXFile(docstring const & fname)
1345 BufferView * bv = view();
1350 FileName filename(to_utf8(fname));
1352 if (!filename.empty()) {
1353 bv->insertLyXFile(filename);
1357 // Launch a file browser
1359 string initpath = lyxrc.document_path;
1360 string const trypath = bv->buffer().filePath();
1361 // If directory is writeable, use this as default.
1362 if (FileName(trypath).isDirWritable())
1366 FileDialog dlg(_("Select LyX document to insert"), LFUN_FILE_INSERT);
1367 dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
1368 dlg.setButton2(_("Examples|#E#e"),
1369 from_utf8(addPath(package().system_support().absFilename(),
1372 FileDialog::Result result =
1373 dlg.open(from_utf8(initpath),
1374 FileFilterList(_("LyX Documents (*.lyx)")),
1377 if (result.first == FileDialog::Later)
1381 filename.set(to_utf8(result.second));
1383 // check selected filename
1384 if (filename.empty()) {
1385 // emit message signal.
1386 message(_("Canceled."));
1390 bv->insertLyXFile(filename);
1394 void GuiView::insertPlaintextFile(docstring const & fname,
1397 BufferView * bv = view();
1402 FileName filename(to_utf8(fname));
1404 if (!filename.empty()) {
1405 bv->insertPlaintextFile(filename, asParagraph);
1409 FileDialog dlg(_("Select file to insert"), (asParagraph ?
1410 LFUN_FILE_INSERT_PLAINTEXT_PARA : LFUN_FILE_INSERT_PLAINTEXT));
1412 FileDialog::Result result = dlg.open(from_utf8(bv->buffer().filePath()),
1413 FileFilterList(), docstring());
1415 if (result.first == FileDialog::Later)
1419 filename.set(to_utf8(result.second));
1421 // check selected filename
1422 if (filename.empty()) {
1423 // emit message signal.
1424 message(_("Canceled."));
1428 bv->insertPlaintextFile(filename, asParagraph);
1432 bool GuiView::renameBuffer(Buffer & b, docstring const & newname)
1434 FileName fname = b.fileName();
1435 FileName const oldname = fname;
1437 if (!newname.empty()) {
1439 fname = makeAbsPath(to_utf8(newname), oldname.onlyPath().absFilename());
1441 // Switch to this Buffer.
1444 /// No argument? Ask user through dialog.
1446 FileDialog dlg(_("Choose a filename to save document as"),
1447 LFUN_BUFFER_WRITE_AS);
1448 dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
1449 dlg.setButton2(_("Templates|#T#t"), from_utf8(lyxrc.template_path));
1451 if (!isLyXFilename(fname.absFilename()))
1452 fname.changeExtension(".lyx");
1454 FileFilterList const filter(_("LyX Documents (*.lyx)"));
1456 FileDialog::Result result =
1457 dlg.save(from_utf8(fname.onlyPath().absFilename()),
1459 from_utf8(fname.onlyFileName()));
1461 if (result.first == FileDialog::Later)
1464 fname.set(to_utf8(result.second));
1469 if (!isLyXFilename(fname.absFilename()))
1470 fname.changeExtension(".lyx");
1473 if (FileName(fname).exists()) {
1474 docstring const file = makeDisplayPath(fname.absFilename(), 30);
1475 docstring text = bformat(_("The document %1$s already "
1476 "exists.\n\nDo you want to "
1477 "overwrite that document?"),
1479 int const ret = Alert::prompt(_("Overwrite document?"),
1480 text, 0, 2, _("&Overwrite"), _("&Rename"), _("&Cancel"));
1483 case 1: return renameBuffer(b, docstring());
1484 case 2: return false;
1488 // Ok, change the name of the buffer
1489 b.setFileName(fname.absFilename());
1491 bool unnamed = b.isUnnamed();
1492 b.setUnnamed(false);
1493 b.saveCheckSum(fname);
1495 if (!saveBuffer(b)) {
1496 b.setFileName(oldname.absFilename());
1497 b.setUnnamed(unnamed);
1498 b.saveCheckSum(oldname);
1506 bool GuiView::saveBuffer(Buffer & b)
1509 return renameBuffer(b, docstring());
1512 LyX::ref().session().lastFiles().add(b.fileName());
1516 // Switch to this Buffer.
1519 // FIXME: we don't tell the user *WHY* the save failed !!
1520 docstring const file = makeDisplayPath(b.absFileName(), 30);
1521 docstring text = bformat(_("The document %1$s could not be saved.\n\n"
1522 "Do you want to rename the document and "
1523 "try again?"), file);
1524 int const ret = Alert::prompt(_("Rename and save?"),
1525 text, 0, 2, _("&Rename"), _("&Retry"), _("&Cancel"));
1528 if (!renameBuffer(b, docstring()))
1537 return saveBuffer(b);
1541 bool GuiView::closeBuffer()
1543 Buffer * buf = buffer();
1544 return buf && closeBuffer(*buf);
1548 bool GuiView::closeBuffer(Buffer & buf)
1550 if (buf.isClean() || buf.paragraphs().empty()) {
1551 theBufferList().release(&buf);
1554 // Switch to this Buffer.
1559 if (buf.isUnnamed())
1560 file = from_utf8(buf.fileName().onlyFileName());
1562 file = buf.fileName().displayName(30);
1564 docstring const text = bformat(_("The document %1$s has unsaved changes."
1565 "\n\nDo you want to save the document or discard the changes?"), file);
1566 int const ret = Alert::prompt(_("Save changed document?"),
1567 text, 0, 2, _("&Save"), _("&Discard"), _("&Cancel"));
1571 if (!saveBuffer(buf))
1575 // if we crash after this we could
1576 // have no autosave file but I guess
1577 // this is really improbable (Jug)
1578 removeAutosaveFile(buf.absFileName());
1584 // save file names to .lyx/session
1585 // if master/slave are both open, do not save slave since it
1586 // will be automatically loaded when the master is loaded
1587 if (buf.masterBuffer() == &buf)
1588 LyX::ref().session().lastOpened().add(buf.fileName());
1590 theBufferList().release(&buf);
1595 bool GuiView::quitWriteAll()
1597 while (!theBufferList().empty()) {
1598 Buffer * b = theBufferList().first();
1599 if (!closeBuffer(*b))
1606 bool GuiView::dispatch(FuncRequest const & cmd)
1608 BufferView * bv = view();
1609 // By default we won't need any update.
1611 bv->cursor().updateFlags(Update::None);
1613 switch(cmd.action) {
1614 case LFUN_FILE_OPEN:
1615 openDocument(to_utf8(cmd.argument()));
1618 case LFUN_BUFFER_IMPORT:
1619 importDocument(to_utf8(cmd.argument()));
1622 case LFUN_BUFFER_SWITCH:
1623 setBuffer(theBufferList().getBuffer(to_utf8(cmd.argument())));
1626 case LFUN_BUFFER_NEXT:
1627 setBuffer(theBufferList().next(buffer()));
1630 case LFUN_BUFFER_PREVIOUS:
1631 setBuffer(theBufferList().previous(buffer()));
1634 case LFUN_COMMAND_EXECUTE: {
1635 bool const show_it = cmd.argument() != "off";
1636 d.toolbars_->showCommandBuffer(show_it);
1639 case LFUN_DROP_LAYOUTS_CHOICE:
1641 d.layout_->showPopup();
1644 case LFUN_MENU_OPEN:
1645 if (QMenu * menu = guiApp->menus().menu(toqstr(cmd.argument())))
1646 menu->exec(QCursor::pos());
1649 case LFUN_FILE_INSERT:
1650 insertLyXFile(cmd.argument());
1652 case LFUN_FILE_INSERT_PLAINTEXT_PARA:
1653 insertPlaintextFile(cmd.argument(), true);
1656 case LFUN_FILE_INSERT_PLAINTEXT:
1657 insertPlaintextFile(cmd.argument(), false);
1660 case LFUN_BUFFER_WRITE:
1662 saveBuffer(bv->buffer());
1665 case LFUN_BUFFER_WRITE_AS:
1667 renameBuffer(bv->buffer(), cmd.argument());
1670 case LFUN_BUFFER_WRITE_ALL: {
1671 Buffer * first = theBufferList().first();
1674 message(_("Saving all documents..."));
1675 // We cannot use a for loop as the buffer list cycles.
1681 LYXERR(Debug::ACTION, "Saved " << b->absFileName());
1682 b = theBufferList().next(b);
1683 } while (b != first);
1684 message(_("All documents saved."));
1688 case LFUN_TOOLBAR_TOGGLE: {
1689 string const name = cmd.getArg(0);
1690 bool const allowauto = cmd.getArg(1) == "allowauto";
1691 // it is possible to get current toolbar status like this,...
1692 // but I decide to obey the order of ToolbarBackend::flags
1693 // and disregard real toolbar status.
1694 // toolbars_->saveToolbarInfo();
1696 // toggle state on/off/auto
1697 d.toolbars_->toggleToolbarState(name, allowauto);
1701 ToolbarInfo * tbi = d.toolbars_->getToolbarInfo(name);
1703 message(bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name)));
1707 if (tbi->flags & ToolbarInfo::ON)
1709 else if (tbi->flags & ToolbarInfo::OFF)
1711 else if (tbi->flags & ToolbarInfo::AUTO)
1714 message(bformat(_("Toolbar \"%1$s\" state set to %2$s"),
1715 _(tbi->gui_name), state));
1719 case LFUN_DIALOG_UPDATE: {
1720 string const name = to_utf8(cmd.argument());
1721 // Can only update a dialog connected to an existing inset
1722 Inset * inset = getOpenInset(name);
1724 FuncRequest fr(LFUN_INSET_DIALOG_UPDATE, cmd.argument());
1725 inset->dispatch(view()->cursor(), fr);
1726 } else if (name == "paragraph") {
1727 lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE));
1728 } else if (name == "prefs") {
1729 updateDialog(name, string());
1734 case LFUN_DIALOG_TOGGLE: {
1735 if (isDialogVisible(cmd.getArg(0)))
1736 dispatch(FuncRequest(LFUN_DIALOG_HIDE, cmd.argument()));
1738 dispatch(FuncRequest(LFUN_DIALOG_SHOW, cmd.argument()));
1742 case LFUN_DIALOG_DISCONNECT_INSET:
1743 disconnectDialog(to_utf8(cmd.argument()));
1746 case LFUN_DIALOG_HIDE: {
1749 guiApp->hideDialogs(to_utf8(cmd.argument()), 0);
1753 case LFUN_DIALOG_SHOW: {
1754 string const name = cmd.getArg(0);
1755 string data = trim(to_utf8(cmd.argument()).substr(name.size()));
1757 if (name == "character") {
1758 data = freefont2string();
1760 showDialog("character", data);
1761 } else if (name == "latexlog") {
1762 Buffer::LogType type;
1763 string const logfile = buffer()->logName(&type);
1765 case Buffer::latexlog:
1768 case Buffer::buildlog:
1772 data += Lexer::quoteString(logfile);
1773 showDialog("log", data);
1774 } else if (name == "vclog") {
1775 string const data = "vc " +
1776 Lexer::quoteString(buffer()->lyxvc().getLogFile());
1777 showDialog("log", data);
1778 } else if (name == "symbols") {
1779 data = bv->cursor().getEncoding()->name();
1781 showDialog("symbols", data);
1783 showDialog(name, data);
1787 case LFUN_INSET_APPLY: {
1788 string const name = cmd.getArg(0);
1789 Inset * inset = getOpenInset(name);
1791 FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument());
1792 inset->dispatch(view()->cursor(), fr);
1794 FuncRequest fr(LFUN_INSET_INSERT, cmd.argument());
1800 case LFUN_MENUBAR_TOGGLE:
1801 menuBar()->setVisible(!menuBar()->isVisible());
1804 case LFUN_STATUSBAR_TOGGLE:
1805 statusBar()->setVisible(!statusBar()->isVisible());
1816 Buffer const * GuiView::updateInset(Inset const * inset)
1818 if (!d.current_work_area_)
1822 d.current_work_area_->scheduleRedraw();
1824 return &d.current_work_area_->bufferView().buffer();
1828 void GuiView::restartCursor()
1830 /* When we move around, or type, it's nice to be able to see
1831 * the cursor immediately after the keypress.
1833 if (d.current_work_area_)
1834 d.current_work_area_->startBlinkingCursor();
1836 // Take this occasion to update the toobars and layout list.
1843 // This list should be kept in sync with the list of insets in
1844 // src/insets/Inset.cpp. I.e., if a dialog goes with an inset, the
1845 // dialog should have the same name as the inset.
1847 char const * const dialognames[] = {
1848 "aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character",
1849 "citation", "document", "embedding", "errorlist", "ert", "external", "file",
1850 "findreplace", "float", "graphics", "include", "index", "nomenclature", "label", "log",
1851 "mathdelimiter", "mathmatrix", "note", "paragraph", "prefs", "print",
1852 "ref", "sendto", "spellchecker", "symbols", "tabular", "tabularcreate",
1854 #ifdef HAVE_LIBAIKSAURUS
1858 "texinfo", "toc", "href", "view-source", "vspace", "wrap", "listings" };
1860 char const * const * const end_dialognames =
1861 dialognames + (sizeof(dialognames) / sizeof(char *));
1865 cmpCStr(char const * name) : name_(name) {}
1866 bool operator()(char const * other) {
1867 return strcmp(other, name_) == 0;
1874 bool isValidName(string const & name)
1876 return find_if(dialognames, end_dialognames,
1877 cmpCStr(name.c_str())) != end_dialognames;
1883 void GuiView::resetDialogs()
1885 // Make sure that no LFUN uses any LyXView.
1886 theLyXFunc().setLyXView(0);
1887 // FIXME: the "math panels" toolbar takes an awful lot of time to
1888 // initialise so we don't do that for the time being.
1889 //d.toolbars_->init();
1890 guiApp->menus().fillMenuBar(this);
1892 d.layout_->updateContents(true);
1893 // Now update controls with current buffer.
1894 theLyXFunc().setLyXView(this);
1899 Dialog * GuiView::find_or_build(string const & name)
1901 if (!isValidName(name))
1904 map<string, DialogPtr>::iterator it = d.dialogs_.find(name);
1906 if (it != d.dialogs_.end())
1907 return it->second.get();
1909 Dialog * dialog = build(name);
1910 d.dialogs_[name].reset(dialog);
1911 if (lyxrc.allow_geometry_session)
1912 dialog->restoreSession();
1917 void GuiView::showDialog(string const & name, string const & data,
1924 Dialog * dialog = find_or_build(name);
1926 dialog->showData(data);
1928 d.open_insets_[name] = inset;
1934 bool GuiView::isDialogVisible(string const & name) const
1936 map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
1937 if (it == d.dialogs_.end())
1939 return it->second.get()->isVisibleView();
1943 void GuiView::hideDialog(string const & name, Inset * inset)
1945 // Don't send the signal if we are quitting, because on MSVC it is
1946 // destructed before the cut stack in CutAndPaste.cpp, and this method
1947 // is called from some inset destructor if the cut stack is not empty
1952 map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
1953 if (it == d.dialogs_.end())
1956 if (inset && inset != getOpenInset(name))
1959 Dialog * const dialog = it->second.get();
1960 if (dialog->isVisibleView())
1962 d.open_insets_[name] = 0;
1966 void GuiView::disconnectDialog(string const & name)
1968 if (!isValidName(name))
1971 if (d.open_insets_.find(name) != d.open_insets_.end())
1972 d.open_insets_[name] = 0;
1976 Inset * GuiView::getOpenInset(string const & name) const
1978 if (!isValidName(name))
1981 map<string, Inset *>::const_iterator it = d.open_insets_.find(name);
1982 return it == d.open_insets_.end() ? 0 : it->second;
1986 void GuiView::hideAll() const
1988 map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
1989 map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
1991 for(; it != end; ++it)
1992 it->second->hideView();
1996 void GuiView::hideBufferDependent() const
1998 map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
1999 map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
2001 for(; it != end; ++it) {
2002 Dialog * dialog = it->second.get();
2003 if (dialog->isBufferDependent())
2009 void GuiView::updateBufferDependent(bool switched) const
2011 map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
2012 map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
2014 for(; it != end; ++it) {
2015 Dialog * dialog = it->second.get();
2016 if (!dialog->isVisibleView())
2018 if (switched && dialog->isBufferDependent()) {
2019 if (dialog->initialiseParams(""))
2020 dialog->updateView();
2024 // A bit clunky, but the dialog will request
2025 // that the kernel provides it with the necessary
2027 dialog->updateDialog();
2033 void GuiView::checkStatus()
2035 map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
2036 map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
2038 for(; it != end; ++it) {
2039 Dialog * const dialog = it->second.get();
2040 if (dialog && dialog->isVisibleView())
2041 dialog->checkStatus();
2047 // will be replaced by a proper factory...
2048 Dialog * createGuiAbout(GuiView & lv);
2049 Dialog * createGuiBibitem(GuiView & lv);
2050 Dialog * createGuiBibtex(GuiView & lv);
2051 Dialog * createGuiBox(GuiView & lv);
2052 Dialog * createGuiBranch(GuiView & lv);
2053 Dialog * createGuiChanges(GuiView & lv);
2054 Dialog * createGuiCharacter(GuiView & lv);
2055 Dialog * createGuiCitation(GuiView & lv);
2056 Dialog * createGuiDelimiter(GuiView & lv);
2057 Dialog * createGuiDocument(GuiView & lv);
2058 Dialog * createGuiErrorList(GuiView & lv);
2059 Dialog * createGuiERT(GuiView & lv);
2060 Dialog * createGuiExternal(GuiView & lv);
2061 Dialog * createGuiFloat(GuiView & lv);
2062 Dialog * createGuiGraphics(GuiView & lv);
2063 Dialog * createGuiInclude(GuiView & lv);
2064 Dialog * createGuiIndex(GuiView & lv);
2065 Dialog * createGuiLabel(GuiView & lv);
2066 Dialog * createGuiListings(GuiView & lv);
2067 Dialog * createGuiLog(GuiView & lv);
2068 Dialog * createGuiMathMatrix(GuiView & lv);
2069 Dialog * createGuiNomenclature(GuiView & lv);
2070 Dialog * createGuiNote(GuiView & lv);
2071 Dialog * createGuiParagraph(GuiView & lv);
2072 Dialog * createGuiPreferences(GuiView & lv);
2073 Dialog * createGuiPrint(GuiView & lv);
2074 Dialog * createGuiRef(GuiView & lv);
2075 Dialog * createGuiSearch(GuiView & lv);
2076 Dialog * createGuiSendTo(GuiView & lv);
2077 Dialog * createGuiShowFile(GuiView & lv);
2078 Dialog * createGuiSpellchecker(GuiView & lv);
2079 Dialog * createGuiSymbols(GuiView & lv);
2080 Dialog * createGuiTabularCreate(GuiView & lv);
2081 Dialog * createGuiTabular(GuiView & lv);
2082 Dialog * createGuiTexInfo(GuiView & lv);
2083 Dialog * createGuiToc(GuiView & lv);
2084 Dialog * createGuiThesaurus(GuiView & lv);
2085 Dialog * createGuiHyperlink(GuiView & lv);
2086 Dialog * createGuiVSpace(GuiView & lv);
2087 Dialog * createGuiViewSource(GuiView & lv);
2088 Dialog * createGuiWrap(GuiView & lv);
2091 Dialog * GuiView::build(string const & name)
2093 BOOST_ASSERT(isValidName(name));
2095 if (name == "aboutlyx")
2096 return createGuiAbout(*this);
2097 if (name == "bibitem")
2098 return createGuiBibitem(*this);
2099 if (name == "bibtex")
2100 return createGuiBibtex(*this);
2102 return createGuiBox(*this);
2103 if (name == "branch")
2104 return createGuiBranch(*this);
2105 if (name == "changes")
2106 return createGuiChanges(*this);
2107 if (name == "character")
2108 return createGuiCharacter(*this);
2109 if (name == "citation")
2110 return createGuiCitation(*this);
2111 if (name == "document")
2112 return createGuiDocument(*this);
2113 if (name == "errorlist")
2114 return createGuiErrorList(*this);
2116 return createGuiERT(*this);
2117 if (name == "external")
2118 return createGuiExternal(*this);
2120 return createGuiShowFile(*this);
2121 if (name == "findreplace")
2122 return createGuiSearch(*this);
2123 if (name == "float")
2124 return createGuiFloat(*this);
2125 if (name == "graphics")
2126 return createGuiGraphics(*this);
2127 if (name == "include")
2128 return createGuiInclude(*this);
2129 if (name == "index")
2130 return createGuiIndex(*this);
2131 if (name == "nomenclature")
2132 return createGuiNomenclature(*this);
2133 if (name == "label")
2134 return createGuiLabel(*this);
2136 return createGuiLog(*this);
2137 if (name == "view-source")
2138 return createGuiViewSource(*this);
2139 if (name == "mathdelimiter")
2140 return createGuiDelimiter(*this);
2141 if (name == "mathmatrix")
2142 return createGuiMathMatrix(*this);
2144 return createGuiNote(*this);
2145 if (name == "paragraph")
2146 return createGuiParagraph(*this);
2147 if (name == "prefs")
2148 return createGuiPreferences(*this);
2149 if (name == "print")
2150 return createGuiPrint(*this);
2152 return createGuiRef(*this);
2153 if (name == "sendto")
2154 return createGuiSendTo(*this);
2155 if (name == "spellchecker")
2156 return createGuiSpellchecker(*this);
2157 if (name == "symbols")
2158 return createGuiSymbols(*this);
2159 if (name == "tabular")
2160 return createGuiTabular(*this);
2161 if (name == "tabularcreate")
2162 return createGuiTabularCreate(*this);
2163 if (name == "texinfo")
2164 return createGuiTexInfo(*this);
2165 #ifdef HAVE_LIBAIKSAURUS
2166 if (name == "thesaurus")
2167 return createGuiThesaurus(*this);
2170 return createGuiToc(*this);
2172 return createGuiHyperlink(*this);
2173 if (name == "vspace")
2174 return createGuiVSpace(*this);
2176 return createGuiWrap(*this);
2177 if (name == "listings")
2178 return createGuiListings(*this);
2184 } // namespace frontend
2187 #include "GuiView_moc.cpp"