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);
582 setWindowTitle(qt_("LyX"));
583 setWindowIconText(qt_("LyX"));
585 return QMainWindow::event(e);
588 case QEvent::ShortcutOverride: {
589 if (d.current_work_area_)
590 // Nothing special to do.
591 return QMainWindow::event(e);
593 QKeyEvent * ke = static_cast<QKeyEvent*>(e);
595 // Let Qt handle menu access and the Tab keys to navigate keys to navigate
597 if (ke->modifiers() & Qt::AltModifier || ke->key() == Qt::Key_Tab
598 || ke->key() == Qt::Key_Backtab)
599 return QMainWindow::event(e);
601 // Allow processing of shortcuts that are allowed even when no Buffer
603 theLyXFunc().setLyXView(this);
605 setKeySymbol(&sym, ke);
606 theLyXFunc().processKeySym(sym, q_key_state(ke->modifiers()));
612 return QMainWindow::event(e);
617 bool GuiView::focusNextPrevChild(bool /*next*/)
624 void GuiView::setBusy(bool busy)
626 if (d.current_work_area_) {
627 d.current_work_area_->setUpdatesEnabled(!busy);
629 d.current_work_area_->stopBlinkingCursor();
631 d.current_work_area_->startBlinkingCursor();
635 QApplication::setOverrideCursor(Qt::WaitCursor);
637 QApplication::restoreOverrideCursor();
641 GuiToolbar * GuiView::makeToolbar(ToolbarInfo const & tbinfo, bool newline)
643 GuiToolbar * toolBar = new GuiToolbar(tbinfo, *this);
645 if (tbinfo.flags & ToolbarInfo::TOP) {
647 addToolBarBreak(Qt::TopToolBarArea);
648 addToolBar(Qt::TopToolBarArea, toolBar);
651 if (tbinfo.flags & ToolbarInfo::BOTTOM) {
652 // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
653 #if (QT_VERSION >= 0x040202)
655 addToolBarBreak(Qt::BottomToolBarArea);
657 addToolBar(Qt::BottomToolBarArea, toolBar);
660 if (tbinfo.flags & ToolbarInfo::LEFT) {
661 // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
662 #if (QT_VERSION >= 0x040202)
664 addToolBarBreak(Qt::LeftToolBarArea);
666 addToolBar(Qt::LeftToolBarArea, toolBar);
669 if (tbinfo.flags & ToolbarInfo::RIGHT) {
670 // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
671 #if (QT_VERSION >= 0x040202)
673 addToolBarBreak(Qt::RightToolBarArea);
675 addToolBar(Qt::RightToolBarArea, toolBar);
678 // The following does not work so I cannot restore to exact toolbar location
680 ToolbarSection::ToolbarInfo & tbinfo = LyX::ref().session().toolbars().load(tbinfo.name);
681 toolBar->move(tbinfo.posx, tbinfo.posy);
688 GuiWorkArea * GuiView::workArea(Buffer & buffer)
690 for (int i = 0; i != d.splitter_->count(); ++i) {
691 GuiWorkArea * wa = d.tabWorkArea(i)->workArea(buffer);
699 GuiWorkArea * GuiView::addWorkArea(Buffer & buffer)
702 // Automatically create a TabWorkArea if there are none yet.
703 if (!d.splitter_->count())
706 TabWorkArea * tab_widget = d.currentTabWorkArea();
707 return tab_widget->addWorkArea(buffer, *this);
711 void GuiView::addTabWorkArea()
713 TabWorkArea * twa = new TabWorkArea;
714 QObject::connect(twa, SIGNAL(currentWorkAreaChanged(GuiWorkArea *)),
715 this, SLOT(on_currentWorkAreaChanged(GuiWorkArea *)));
716 d.splitter_->addWidget(twa);
717 d.stack_widget_->setCurrentWidget(d.splitter_);
721 GuiWorkArea const * GuiView::currentWorkArea() const
723 return d.current_work_area_;
727 void GuiView::setCurrentWorkArea(GuiWorkArea * wa)
731 // Changing work area can result from opening a file so
732 // update the toc in any case.
735 d.current_work_area_ = wa;
736 for (int i = 0; i != d.splitter_->count(); ++i) {
737 if (d.tabWorkArea(i)->setCurrentWorkArea(wa))
743 void GuiView::removeWorkArea(GuiWorkArea * wa)
746 if (wa == d.current_work_area_) {
748 disconnectBufferView();
749 hideBufferDependent();
750 d.current_work_area_ = 0;
753 for (int i = 0; i != d.splitter_->count(); ++i) {
754 TabWorkArea * twa = d.tabWorkArea(i);
755 if (!twa->removeWorkArea(wa))
756 // Not found in this tab group.
759 // We found and removed the GuiWorkArea.
761 // No more WorkAreas in this tab group, so delete it.
766 if (d.current_work_area_)
767 // This means that we are not closing the current GuiWorkArea;
770 // Switch to the next GuiWorkArea in the found TabWorkArea.
771 d.current_work_area_ = twa->currentWorkArea();
775 if (d.splitter_->count() == 0)
776 // No more work area, switch to the background widget.
781 void GuiView::setLayoutDialog(GuiLayoutBox * layout)
787 void GuiView::updateLayoutList()
790 d.layout_->updateContents(false);
794 void GuiView::updateToolbars()
796 if (d.current_work_area_) {
798 d.current_work_area_->bufferView().cursor().inMathed();
800 lyx::getStatus(FuncRequest(LFUN_LAYOUT_TABULAR)).enabled();
802 lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).enabled() &&
803 lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).onoff(true);
804 bool const mathmacrotemplate =
805 lyx::getStatus(FuncRequest(LFUN_IN_MATHMACROTEMPLATE)).enabled();
807 d.toolbars_->update(math, table, review, mathmacrotemplate);
809 d.toolbars_->update(false, false, false, false);
811 // update read-only status of open dialogs.
816 Buffer * GuiView::buffer()
818 if (d.current_work_area_)
819 return &d.current_work_area_->bufferView().buffer();
824 Buffer const * GuiView::buffer() const
826 if (d.current_work_area_)
827 return &d.current_work_area_->bufferView().buffer();
832 void GuiView::setBuffer(Buffer * newBuffer)
834 BOOST_ASSERT(newBuffer);
837 GuiWorkArea * wa = workArea(*newBuffer);
839 updateLabels(*newBuffer->masterBuffer());
840 wa = addWorkArea(*newBuffer);
842 //Disconnect the old buffer...there's no new one.
845 connectBuffer(*newBuffer);
846 connectBufferView(wa->bufferView());
847 setCurrentWorkArea(wa);
853 void GuiView::connectBuffer(Buffer & buf)
855 buf.setGuiDelegate(this);
859 void GuiView::disconnectBuffer()
861 if (d.current_work_area_)
862 d.current_work_area_->bufferView().setGuiDelegate(0);
866 void GuiView::connectBufferView(BufferView & bv)
868 bv.setGuiDelegate(this);
872 void GuiView::disconnectBufferView()
874 if (d.current_work_area_)
875 d.current_work_area_->bufferView().setGuiDelegate(0);
879 void GuiView::errors(string const & error_type)
881 ErrorList & el = buffer()->errorList(error_type);
883 showDialog("errorlist", error_type);
887 void GuiView::updateDialog(string const & name, string const & data)
889 if (!isDialogVisible(name))
892 map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
893 if (it == d.dialogs_.end())
896 Dialog * const dialog = it->second.get();
897 if (dialog->isVisibleView())
898 dialog->updateData(data);
902 BufferView * GuiView::view()
904 return d.current_work_area_ ? &d.current_work_area_->bufferView() : 0;
908 void GuiView::updateToc()
910 updateDialog("toc", "");
914 void GuiView::updateEmbeddedFiles()
916 updateDialog("embedding", "");
920 void GuiView::autoSave()
922 LYXERR(Debug::INFO, "Running autoSave()");
925 view()->buffer().autoSave();
929 void GuiView::resetAutosaveTimers()
932 d.autosave_timeout_.restart();
936 FuncStatus GuiView::getStatus(FuncRequest const & cmd)
940 Buffer * buf = buffer();
942 /* In LyX/Mac, when a dialog is open, the menus of the
943 application can still be accessed without giving focus to
944 the main window. In this case, we want to disable the menu
945 entries that are buffer-related.
947 Note that this code is not perfect, as bug 1941 attests:
948 http://bugzilla.lyx.org/show_bug.cgi?id=1941#c4
950 if (cmd.origin == FuncRequest::MENU && !hasFocus())
954 case LFUN_BUFFER_WRITE:
955 enable = buf && (buf->isUnnamed() || !buf->isClean());
958 case LFUN_BUFFER_WRITE_AS:
962 case LFUN_TOOLBAR_TOGGLE:
963 flag.setOnOff(d.toolbars_->visible(cmd.getArg(0)));
966 case LFUN_DIALOG_TOGGLE:
967 flag.setOnOff(isDialogVisible(cmd.getArg(0)));
968 // fall through to set "enable"
969 case LFUN_DIALOG_SHOW: {
970 string const name = cmd.getArg(0);
972 enable = name == "aboutlyx"
973 || name == "file" //FIXME: should be removed.
975 || name == "texinfo";
976 else if (name == "print")
977 enable = buf->isExportable("dvi")
978 && lyxrc.print_command != "none";
979 else if (name == "character") {
983 InsetCode ic = view()->cursor().inset().lyxCode();
984 enable = ic != ERT_CODE && ic != LISTINGS_CODE;
987 else if (name == "symbols") {
988 if (!view() || view()->cursor().inMathed())
991 InsetCode ic = view()->cursor().inset().lyxCode();
992 enable = ic != ERT_CODE && ic != LISTINGS_CODE;
995 else if (name == "latexlog")
996 enable = FileName(buf->logName()).isReadableFile();
997 else if (name == "spellchecker")
998 #if defined (USE_ASPELL) || defined (USE_ISPELL) || defined (USE_PSPELL)
999 enable = !buf->isReadonly();
1003 else if (name == "vclog")
1004 enable = buf->lyxvc().inUse();
1008 case LFUN_DIALOG_UPDATE: {
1009 string const name = cmd.getArg(0);
1011 enable = name == "prefs";
1015 case LFUN_INSET_APPLY: {
1020 string const name = cmd.getArg(0);
1021 Inset * inset = getOpenInset(name);
1023 FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument());
1025 if (!inset->getStatus(view()->cursor(), fr, fs)) {
1026 // Every inset is supposed to handle this
1027 BOOST_ASSERT(false);
1031 FuncRequest fr(LFUN_INSET_INSERT, cmd.argument());
1032 flag |= getStatus(fr);
1034 enable = flag.enabled();
1046 flag.enabled(false);
1052 static FileName selectTemplateFile()
1054 FileDialog dlg(_("Select template file"));
1055 dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
1056 dlg.setButton1(_("Templates|#T#t"), from_utf8(lyxrc.template_path));
1058 FileDialog::Result result =
1059 dlg.open(from_utf8(lyxrc.template_path),
1060 FileFilterList(_("LyX Documents (*.lyx)")),
1063 if (result.first == FileDialog::Later)
1065 if (result.second.empty())
1067 return FileName(to_utf8(result.second));
1071 Buffer * GuiView::loadDocument(FileName const & filename, bool tolastfiles)
1075 Buffer * newBuffer = checkAndLoadLyXFile(filename);
1078 message(_("Document not loaded."));
1083 setBuffer(newBuffer);
1085 // scroll to the position when the file was last closed
1086 if (lyxrc.use_lastfilepos) {
1087 LastFilePosSection::FilePos filepos =
1088 LyX::ref().session().lastFilePos().load(filename);
1089 view()->moveToPosition(filepos.pit, filepos.pos, 0, 0);
1093 LyX::ref().session().lastFiles().add(filename);
1100 void GuiView::openDocument(string const & fname)
1102 string initpath = lyxrc.document_path;
1105 string const trypath = buffer()->filePath();
1106 // If directory is writeable, use this as default.
1107 if (FileName(trypath).isDirWritable())
1113 if (fname.empty()) {
1114 FileDialog dlg(_("Select document to open"), LFUN_FILE_OPEN);
1115 dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
1116 dlg.setButton2(_("Examples|#E#e"),
1117 from_utf8(addPath(package().system_support().absFilename(), "examples")));
1119 FileDialog::Result result =
1120 dlg.open(from_utf8(initpath),
1121 FileFilterList(_("LyX Documents (*.lyx)")),
1124 if (result.first == FileDialog::Later)
1127 filename = to_utf8(result.second);
1129 // check selected filename
1130 if (filename.empty()) {
1131 message(_("Canceled."));
1137 // get absolute path of file and add ".lyx" to the filename if
1139 FileName const fullname =
1140 fileSearch(string(), filename, "lyx", support::may_not_exist);
1141 if (!fullname.empty())
1142 filename = fullname.absFilename();
1144 // if the file doesn't exist, let the user create one
1145 if (!fullname.exists()) {
1146 // the user specifically chose this name. Believe him.
1147 Buffer * const b = newFile(filename, string(), true);
1153 docstring const disp_fn = makeDisplayPath(filename);
1154 message(bformat(_("Opening document %1$s..."), disp_fn));
1157 Buffer * buf = loadDocument(fullname);
1161 buf->errors("Parse");
1162 str2 = bformat(_("Document %1$s opened."), disp_fn);
1164 str2 = bformat(_("Could not open document %1$s"), disp_fn);
1169 // FIXME: clean that
1170 static bool import(GuiView * lv, FileName const & filename,
1171 string const & format, ErrorList & errorList)
1173 FileName const lyxfile(changeExtension(filename.absFilename(), ".lyx"));
1175 string loader_format;
1176 vector<string> loaders = theConverters().loaders();
1177 if (find(loaders.begin(), loaders.end(), format) == loaders.end()) {
1178 for (vector<string>::const_iterator it = loaders.begin();
1179 it != loaders.end(); ++it) {
1180 if (!theConverters().isReachable(format, *it))
1183 string const tofile =
1184 changeExtension(filename.absFilename(),
1185 formats.extension(*it));
1186 if (!theConverters().convert(0, filename, FileName(tofile),
1187 filename, format, *it, errorList))
1189 loader_format = *it;
1192 if (loader_format.empty()) {
1193 frontend::Alert::error(_("Couldn't import file"),
1194 bformat(_("No information for importing the format %1$s."),
1195 formats.prettyName(format)));
1199 loader_format = format;
1201 if (loader_format == "lyx") {
1202 Buffer * buf = lv->loadDocument(lyxfile);
1207 buf->errors("Parse");
1209 Buffer * const b = newFile(lyxfile.absFilename(), string(), true);
1213 bool as_paragraphs = loader_format == "textparagraph";
1214 string filename2 = (loader_format == format) ? filename.absFilename()
1215 : changeExtension(filename.absFilename(),
1216 formats.extension(loader_format));
1217 lv->view()->insertPlaintextFile(FileName(filename2), as_paragraphs);
1218 theLyXFunc().setLyXView(lv);
1219 lyx::dispatch(FuncRequest(LFUN_MARK_OFF));
1226 void GuiView::importDocument(string const & argument)
1229 string filename = split(argument, format, ' ');
1231 LYXERR(Debug::INFO, format << " file: " << filename);
1233 // need user interaction
1234 if (filename.empty()) {
1235 string initpath = lyxrc.document_path;
1237 Buffer const * buf = buffer();
1239 string const trypath = buf->filePath();
1240 // If directory is writeable, use this as default.
1241 if (FileName(trypath).isDirWritable())
1245 docstring const text = bformat(_("Select %1$s file to import"),
1246 formats.prettyName(format));
1248 FileDialog dlg(text, LFUN_BUFFER_IMPORT);
1249 dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
1250 dlg.setButton2(_("Examples|#E#e"),
1251 from_utf8(addPath(package().system_support().absFilename(), "examples")));
1253 docstring filter = formats.prettyName(format);
1256 filter += from_utf8(formats.extension(format));
1259 FileDialog::Result result =
1260 dlg.open(from_utf8(initpath),
1261 FileFilterList(filter),
1264 if (result.first == FileDialog::Later)
1267 filename = to_utf8(result.second);
1269 // check selected filename
1270 if (filename.empty())
1271 message(_("Canceled."));
1274 if (filename.empty())
1277 // get absolute path of file
1278 FileName const fullname(makeAbsPath(filename));
1280 FileName const lyxfile(changeExtension(fullname.absFilename(), ".lyx"));
1282 // Check if the document already is open
1283 Buffer * buf = theBufferList().getBuffer(lyxfile.absFilename());
1286 if (!closeBuffer()) {
1287 message(_("Canceled."));
1292 docstring const displaypath = makeDisplayPath(lyxfile.absFilename(), 30);
1294 // if the file exists already, and we didn't do
1295 // -i lyx thefile.lyx, warn
1296 if (lyxfile.exists() && fullname != lyxfile) {
1298 docstring text = bformat(_("The document %1$s already exists.\n\n"
1299 "Do you want to overwrite that document?"), displaypath);
1300 int const ret = Alert::prompt(_("Overwrite document?"),
1301 text, 0, 1, _("&Overwrite"), _("&Cancel"));
1304 message(_("Canceled."));
1309 message(bformat(_("Importing %1$s..."), displaypath));
1310 ErrorList errorList;
1311 if (import(this, fullname, format, errorList))
1312 message(_("imported."));
1314 message(_("file not imported!"));
1316 // FIXME (Abdel 12/08/06): Is there a need to display the error list here?
1320 void GuiView::newDocument(string const & filename, bool from_template)
1322 FileName initpath(lyxrc.document_path);
1323 Buffer * buf = buffer();
1325 FileName const trypath(buf->filePath());
1326 // If directory is writeable, use this as default.
1327 if (trypath.isDirWritable())
1331 string templatefile = from_template ?
1332 selectTemplateFile().absFilename() : string();
1334 if (filename.empty())
1335 b = newUnnamedFile(templatefile, initpath);
1337 b = newFile(filename, templatefile, true);
1341 // Ensure the cursor is correctly positionned on screen.
1342 view()->showCursor();
1346 void GuiView::insertLyXFile(docstring const & fname)
1348 BufferView * bv = view();
1353 FileName filename(to_utf8(fname));
1355 if (!filename.empty()) {
1356 bv->insertLyXFile(filename);
1360 // Launch a file browser
1362 string initpath = lyxrc.document_path;
1363 string const trypath = bv->buffer().filePath();
1364 // If directory is writeable, use this as default.
1365 if (FileName(trypath).isDirWritable())
1369 FileDialog dlg(_("Select LyX document to insert"), LFUN_FILE_INSERT);
1370 dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
1371 dlg.setButton2(_("Examples|#E#e"),
1372 from_utf8(addPath(package().system_support().absFilename(),
1375 FileDialog::Result result =
1376 dlg.open(from_utf8(initpath),
1377 FileFilterList(_("LyX Documents (*.lyx)")),
1380 if (result.first == FileDialog::Later)
1384 filename.set(to_utf8(result.second));
1386 // check selected filename
1387 if (filename.empty()) {
1388 // emit message signal.
1389 message(_("Canceled."));
1393 bv->insertLyXFile(filename);
1397 void GuiView::insertPlaintextFile(docstring const & fname,
1400 BufferView * bv = view();
1405 FileName filename(to_utf8(fname));
1407 if (!filename.empty()) {
1408 bv->insertPlaintextFile(filename, asParagraph);
1412 FileDialog dlg(_("Select file to insert"), (asParagraph ?
1413 LFUN_FILE_INSERT_PLAINTEXT_PARA : LFUN_FILE_INSERT_PLAINTEXT));
1415 FileDialog::Result result = dlg.open(from_utf8(bv->buffer().filePath()),
1416 FileFilterList(), docstring());
1418 if (result.first == FileDialog::Later)
1422 filename.set(to_utf8(result.second));
1424 // check selected filename
1425 if (filename.empty()) {
1426 // emit message signal.
1427 message(_("Canceled."));
1431 bv->insertPlaintextFile(filename, asParagraph);
1435 bool GuiView::renameBuffer(Buffer & b, docstring const & newname)
1437 FileName fname = b.fileName();
1438 FileName const oldname = fname;
1440 if (!newname.empty()) {
1442 fname = makeAbsPath(to_utf8(newname), oldname.onlyPath().absFilename());
1444 // Switch to this Buffer.
1447 /// No argument? Ask user through dialog.
1449 FileDialog dlg(_("Choose a filename to save document as"),
1450 LFUN_BUFFER_WRITE_AS);
1451 dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path));
1452 dlg.setButton2(_("Templates|#T#t"), from_utf8(lyxrc.template_path));
1454 if (!isLyXFilename(fname.absFilename()))
1455 fname.changeExtension(".lyx");
1457 FileFilterList const filter(_("LyX Documents (*.lyx)"));
1459 FileDialog::Result result =
1460 dlg.save(from_utf8(fname.onlyPath().absFilename()),
1462 from_utf8(fname.onlyFileName()));
1464 if (result.first == FileDialog::Later)
1467 fname.set(to_utf8(result.second));
1472 if (!isLyXFilename(fname.absFilename()))
1473 fname.changeExtension(".lyx");
1476 if (FileName(fname).exists()) {
1477 docstring const file = makeDisplayPath(fname.absFilename(), 30);
1478 docstring text = bformat(_("The document %1$s already "
1479 "exists.\n\nDo you want to "
1480 "overwrite that document?"),
1482 int const ret = Alert::prompt(_("Overwrite document?"),
1483 text, 0, 2, _("&Overwrite"), _("&Rename"), _("&Cancel"));
1486 case 1: return renameBuffer(b, docstring());
1487 case 2: return false;
1491 // Ok, change the name of the buffer
1492 b.setFileName(fname.absFilename());
1494 bool unnamed = b.isUnnamed();
1495 b.setUnnamed(false);
1496 b.saveCheckSum(fname);
1498 if (!saveBuffer(b)) {
1499 b.setFileName(oldname.absFilename());
1500 b.setUnnamed(unnamed);
1501 b.saveCheckSum(oldname);
1509 bool GuiView::saveBuffer(Buffer & b)
1512 return renameBuffer(b, docstring());
1515 LyX::ref().session().lastFiles().add(b.fileName());
1519 // Switch to this Buffer.
1522 // FIXME: we don't tell the user *WHY* the save failed !!
1523 docstring const file = makeDisplayPath(b.absFileName(), 30);
1524 docstring text = bformat(_("The document %1$s could not be saved.\n\n"
1525 "Do you want to rename the document and "
1526 "try again?"), file);
1527 int const ret = Alert::prompt(_("Rename and save?"),
1528 text, 0, 2, _("&Rename"), _("&Retry"), _("&Cancel"));
1531 if (!renameBuffer(b, docstring()))
1540 return saveBuffer(b);
1544 bool GuiView::closeBuffer()
1546 Buffer * buf = buffer();
1547 return buf && closeBuffer(*buf);
1551 bool GuiView::closeBuffer(Buffer & buf)
1553 if (buf.isClean() || buf.paragraphs().empty()) {
1554 theBufferList().release(&buf);
1557 // Switch to this Buffer.
1562 if (buf.isUnnamed())
1563 file = from_utf8(buf.fileName().onlyFileName());
1565 file = buf.fileName().displayName(30);
1567 docstring const text = bformat(_("The document %1$s has unsaved changes."
1568 "\n\nDo you want to save the document or discard the changes?"), file);
1569 int const ret = Alert::prompt(_("Save changed document?"),
1570 text, 0, 2, _("&Save"), _("&Discard"), _("&Cancel"));
1574 if (!saveBuffer(buf))
1578 // if we crash after this we could
1579 // have no autosave file but I guess
1580 // this is really improbable (Jug)
1581 removeAutosaveFile(buf.absFileName());
1587 // save file names to .lyx/session
1588 // if master/slave are both open, do not save slave since it
1589 // will be automatically loaded when the master is loaded
1590 if (buf.masterBuffer() == &buf)
1591 LyX::ref().session().lastOpened().add(buf.fileName());
1593 theBufferList().release(&buf);
1598 bool GuiView::quitWriteAll()
1600 while (!theBufferList().empty()) {
1601 Buffer * b = theBufferList().first();
1602 if (!closeBuffer(*b))
1609 bool GuiView::dispatch(FuncRequest const & cmd)
1611 BufferView * bv = view();
1612 // By default we won't need any update.
1614 bv->cursor().updateFlags(Update::None);
1616 switch(cmd.action) {
1617 case LFUN_FILE_OPEN:
1618 openDocument(to_utf8(cmd.argument()));
1621 case LFUN_BUFFER_IMPORT:
1622 importDocument(to_utf8(cmd.argument()));
1625 case LFUN_BUFFER_SWITCH:
1626 setBuffer(theBufferList().getBuffer(to_utf8(cmd.argument())));
1629 case LFUN_BUFFER_NEXT:
1630 setBuffer(theBufferList().next(buffer()));
1633 case LFUN_BUFFER_PREVIOUS:
1634 setBuffer(theBufferList().previous(buffer()));
1637 case LFUN_COMMAND_EXECUTE: {
1638 bool const show_it = cmd.argument() != "off";
1639 d.toolbars_->showCommandBuffer(show_it);
1642 case LFUN_DROP_LAYOUTS_CHOICE:
1644 d.layout_->showPopup();
1647 case LFUN_MENU_OPEN:
1648 if (QMenu * menu = guiApp->menus().menu(toqstr(cmd.argument())))
1649 menu->exec(QCursor::pos());
1652 case LFUN_FILE_INSERT:
1653 insertLyXFile(cmd.argument());
1655 case LFUN_FILE_INSERT_PLAINTEXT_PARA:
1656 insertPlaintextFile(cmd.argument(), true);
1659 case LFUN_FILE_INSERT_PLAINTEXT:
1660 insertPlaintextFile(cmd.argument(), false);
1663 case LFUN_BUFFER_WRITE:
1665 saveBuffer(bv->buffer());
1668 case LFUN_BUFFER_WRITE_AS:
1670 renameBuffer(bv->buffer(), cmd.argument());
1673 case LFUN_BUFFER_WRITE_ALL: {
1674 Buffer * first = theBufferList().first();
1677 message(_("Saving all documents..."));
1678 // We cannot use a for loop as the buffer list cycles.
1684 LYXERR(Debug::ACTION, "Saved " << b->absFileName());
1685 b = theBufferList().next(b);
1686 } while (b != first);
1687 message(_("All documents saved."));
1691 case LFUN_TOOLBAR_TOGGLE: {
1692 string const name = cmd.getArg(0);
1693 bool const allowauto = cmd.getArg(1) == "allowauto";
1694 // it is possible to get current toolbar status like this,...
1695 // but I decide to obey the order of ToolbarBackend::flags
1696 // and disregard real toolbar status.
1697 // toolbars_->saveToolbarInfo();
1699 // toggle state on/off/auto
1700 d.toolbars_->toggleToolbarState(name, allowauto);
1704 ToolbarInfo * tbi = d.toolbars_->getToolbarInfo(name);
1706 message(bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name)));
1710 if (tbi->flags & ToolbarInfo::ON)
1712 else if (tbi->flags & ToolbarInfo::OFF)
1714 else if (tbi->flags & ToolbarInfo::AUTO)
1717 message(bformat(_("Toolbar \"%1$s\" state set to %2$s"),
1718 _(tbi->gui_name), state));
1722 case LFUN_DIALOG_UPDATE: {
1723 string const name = to_utf8(cmd.argument());
1724 // Can only update a dialog connected to an existing inset
1725 Inset * inset = getOpenInset(name);
1727 FuncRequest fr(LFUN_INSET_DIALOG_UPDATE, cmd.argument());
1728 inset->dispatch(view()->cursor(), fr);
1729 } else if (name == "paragraph") {
1730 lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE));
1731 } else if (name == "prefs") {
1732 updateDialog(name, string());
1737 case LFUN_DIALOG_TOGGLE: {
1738 if (isDialogVisible(cmd.getArg(0)))
1739 dispatch(FuncRequest(LFUN_DIALOG_HIDE, cmd.argument()));
1741 dispatch(FuncRequest(LFUN_DIALOG_SHOW, cmd.argument()));
1745 case LFUN_DIALOG_DISCONNECT_INSET:
1746 disconnectDialog(to_utf8(cmd.argument()));
1749 case LFUN_DIALOG_HIDE: {
1752 guiApp->hideDialogs(to_utf8(cmd.argument()), 0);
1756 case LFUN_DIALOG_SHOW: {
1757 string const name = cmd.getArg(0);
1758 string data = trim(to_utf8(cmd.argument()).substr(name.size()));
1760 if (name == "character") {
1761 data = freefont2string();
1763 showDialog("character", data);
1764 } else if (name == "latexlog") {
1765 Buffer::LogType type;
1766 string const logfile = buffer()->logName(&type);
1768 case Buffer::latexlog:
1771 case Buffer::buildlog:
1775 data += Lexer::quoteString(logfile);
1776 showDialog("log", data);
1777 } else if (name == "vclog") {
1778 string const data = "vc " +
1779 Lexer::quoteString(buffer()->lyxvc().getLogFile());
1780 showDialog("log", data);
1781 } else if (name == "symbols") {
1782 data = bv->cursor().getEncoding()->name();
1784 showDialog("symbols", data);
1786 showDialog(name, data);
1790 case LFUN_INSET_APPLY: {
1791 string const name = cmd.getArg(0);
1792 Inset * inset = getOpenInset(name);
1794 FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument());
1795 inset->dispatch(view()->cursor(), fr);
1797 FuncRequest fr(LFUN_INSET_INSERT, cmd.argument());
1803 case LFUN_UI_TOGGLE:
1815 void GuiView::lfunUiToggle(FuncRequest const & cmd)
1817 string const arg = cmd.getArg(0);
1818 if (arg == "statusbar") {
1819 statusBar()->setVisible(!statusBar()->isVisible());
1822 if (arg == "menubar") {
1823 menuBar()->setVisible(!menuBar()->isVisible());
1826 #if QT_VERSION >= 0x040300
1827 if (arg == "frame") {
1829 getContentsMargins(&l, &t, &r, &b);
1830 //are the frames in default state?
1832 d.current_work_area_->setFrameStyle(QFrame::NoFrame);
1833 setContentsMargins(-2, -2, -2, -2);
1835 d.current_work_area_->setFrameStyle(QFrame::NoFrame);
1836 setContentsMargins(0, 0, 0, 0);
1841 if (arg != "fullscreen") {
1842 message(bformat(_("LFUN_UI_TOGGLE %1$s unknown command!"), from_utf8(arg)));
1846 if (isFullScreen()) {
1848 #if QT_VERSION >= 0x040300
1849 setContentsMargins(0, 0, 0, 0);
1851 for (int i = 0; i != d.splitter_->count(); ++i)
1852 d.tabWorkArea(i)->setFullScreen(false);
1854 statusBar()->show();
1856 statusBar()->hide();
1858 for (int i = 0; i != d.splitter_->count(); ++i)
1859 d.tabWorkArea(i)->setFullScreen(true);
1860 #if QT_VERSION >= 0x040300
1861 setContentsMargins(-2, -2, -2, -2);
1868 Buffer const * GuiView::updateInset(Inset const * inset)
1870 if (!d.current_work_area_)
1874 d.current_work_area_->scheduleRedraw();
1876 return &d.current_work_area_->bufferView().buffer();
1880 void GuiView::restartCursor()
1882 /* When we move around, or type, it's nice to be able to see
1883 * the cursor immediately after the keypress.
1885 if (d.current_work_area_)
1886 d.current_work_area_->startBlinkingCursor();
1888 // Take this occasion to update the toobars and layout list.
1895 // This list should be kept in sync with the list of insets in
1896 // src/insets/Inset.cpp. I.e., if a dialog goes with an inset, the
1897 // dialog should have the same name as the inset.
1899 char const * const dialognames[] = {
1900 "aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character",
1901 "citation", "document", "embedding", "errorlist", "ert", "external", "file",
1902 "findreplace", "float", "graphics", "include", "index", "nomenclature", "label", "log",
1903 "mathdelimiter", "mathmatrix", "note", "paragraph", "prefs", "print",
1904 "ref", "sendto", "spellchecker", "symbols", "tabular", "tabularcreate",
1906 #ifdef HAVE_LIBAIKSAURUS
1910 "texinfo", "toc", "href", "view-source", "vspace", "wrap", "listings" };
1912 char const * const * const end_dialognames =
1913 dialognames + (sizeof(dialognames) / sizeof(char *));
1917 cmpCStr(char const * name) : name_(name) {}
1918 bool operator()(char const * other) {
1919 return strcmp(other, name_) == 0;
1926 bool isValidName(string const & name)
1928 return find_if(dialognames, end_dialognames,
1929 cmpCStr(name.c_str())) != end_dialognames;
1935 void GuiView::resetDialogs()
1937 // Make sure that no LFUN uses any LyXView.
1938 theLyXFunc().setLyXView(0);
1939 // FIXME: the "math panels" toolbar takes an awful lot of time to
1940 // initialise so we don't do that for the time being.
1941 //d.toolbars_->init();
1942 guiApp->menus().fillMenuBar(this);
1944 d.layout_->updateContents(true);
1945 // Now update controls with current buffer.
1946 theLyXFunc().setLyXView(this);
1951 Dialog * GuiView::find_or_build(string const & name)
1953 if (!isValidName(name))
1956 map<string, DialogPtr>::iterator it = d.dialogs_.find(name);
1958 if (it != d.dialogs_.end())
1959 return it->second.get();
1961 Dialog * dialog = build(name);
1962 d.dialogs_[name].reset(dialog);
1963 if (lyxrc.allow_geometry_session)
1964 dialog->restoreSession();
1969 void GuiView::showDialog(string const & name, string const & data,
1976 Dialog * dialog = find_or_build(name);
1978 dialog->showData(data);
1980 d.open_insets_[name] = inset;
1986 bool GuiView::isDialogVisible(string const & name) const
1988 map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
1989 if (it == d.dialogs_.end())
1991 return it->second.get()->isVisibleView();
1995 void GuiView::hideDialog(string const & name, Inset * inset)
1997 // Don't send the signal if we are quitting, because on MSVC it is
1998 // destructed before the cut stack in CutAndPaste.cpp, and this method
1999 // is called from some inset destructor if the cut stack is not empty
2004 map<string, DialogPtr>::const_iterator it = d.dialogs_.find(name);
2005 if (it == d.dialogs_.end())
2008 if (inset && inset != getOpenInset(name))
2011 Dialog * const dialog = it->second.get();
2012 if (dialog->isVisibleView())
2014 d.open_insets_[name] = 0;
2018 void GuiView::disconnectDialog(string const & name)
2020 if (!isValidName(name))
2023 if (d.open_insets_.find(name) != d.open_insets_.end())
2024 d.open_insets_[name] = 0;
2028 Inset * GuiView::getOpenInset(string const & name) const
2030 if (!isValidName(name))
2033 map<string, Inset *>::const_iterator it = d.open_insets_.find(name);
2034 return it == d.open_insets_.end() ? 0 : it->second;
2038 void GuiView::hideAll() const
2040 map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
2041 map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
2043 for(; it != end; ++it)
2044 it->second->hideView();
2048 void GuiView::hideBufferDependent() const
2050 map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
2051 map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
2053 for(; it != end; ++it) {
2054 Dialog * dialog = it->second.get();
2055 if (dialog->isBufferDependent())
2061 void GuiView::updateBufferDependent(bool switched) const
2063 map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
2064 map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
2066 for(; it != end; ++it) {
2067 Dialog * dialog = it->second.get();
2068 if (!dialog->isVisibleView())
2070 if (switched && dialog->isBufferDependent()) {
2071 if (dialog->initialiseParams(""))
2072 dialog->updateView();
2076 // A bit clunky, but the dialog will request
2077 // that the kernel provides it with the necessary
2079 dialog->updateDialog();
2085 void GuiView::checkStatus()
2087 map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
2088 map<string, DialogPtr>::const_iterator end = d.dialogs_.end();
2090 for(; it != end; ++it) {
2091 Dialog * const dialog = it->second.get();
2092 if (dialog && dialog->isVisibleView())
2093 dialog->checkStatus();
2099 // will be replaced by a proper factory...
2100 Dialog * createGuiAbout(GuiView & lv);
2101 Dialog * createGuiBibitem(GuiView & lv);
2102 Dialog * createGuiBibtex(GuiView & lv);
2103 Dialog * createGuiBox(GuiView & lv);
2104 Dialog * createGuiBranch(GuiView & lv);
2105 Dialog * createGuiChanges(GuiView & lv);
2106 Dialog * createGuiCharacter(GuiView & lv);
2107 Dialog * createGuiCitation(GuiView & lv);
2108 Dialog * createGuiDelimiter(GuiView & lv);
2109 Dialog * createGuiDocument(GuiView & lv);
2110 Dialog * createGuiErrorList(GuiView & lv);
2111 Dialog * createGuiERT(GuiView & lv);
2112 Dialog * createGuiExternal(GuiView & lv);
2113 Dialog * createGuiFloat(GuiView & lv);
2114 Dialog * createGuiGraphics(GuiView & lv);
2115 Dialog * createGuiInclude(GuiView & lv);
2116 Dialog * createGuiIndex(GuiView & lv);
2117 Dialog * createGuiLabel(GuiView & lv);
2118 Dialog * createGuiListings(GuiView & lv);
2119 Dialog * createGuiLog(GuiView & lv);
2120 Dialog * createGuiMathMatrix(GuiView & lv);
2121 Dialog * createGuiNomenclature(GuiView & lv);
2122 Dialog * createGuiNote(GuiView & lv);
2123 Dialog * createGuiParagraph(GuiView & lv);
2124 Dialog * createGuiPreferences(GuiView & lv);
2125 Dialog * createGuiPrint(GuiView & lv);
2126 Dialog * createGuiRef(GuiView & lv);
2127 Dialog * createGuiSearch(GuiView & lv);
2128 Dialog * createGuiSendTo(GuiView & lv);
2129 Dialog * createGuiShowFile(GuiView & lv);
2130 Dialog * createGuiSpellchecker(GuiView & lv);
2131 Dialog * createGuiSymbols(GuiView & lv);
2132 Dialog * createGuiTabularCreate(GuiView & lv);
2133 Dialog * createGuiTabular(GuiView & lv);
2134 Dialog * createGuiTexInfo(GuiView & lv);
2135 Dialog * createGuiToc(GuiView & lv);
2136 Dialog * createGuiThesaurus(GuiView & lv);
2137 Dialog * createGuiHyperlink(GuiView & lv);
2138 Dialog * createGuiVSpace(GuiView & lv);
2139 Dialog * createGuiViewSource(GuiView & lv);
2140 Dialog * createGuiWrap(GuiView & lv);
2143 Dialog * GuiView::build(string const & name)
2145 BOOST_ASSERT(isValidName(name));
2147 if (name == "aboutlyx")
2148 return createGuiAbout(*this);
2149 if (name == "bibitem")
2150 return createGuiBibitem(*this);
2151 if (name == "bibtex")
2152 return createGuiBibtex(*this);
2154 return createGuiBox(*this);
2155 if (name == "branch")
2156 return createGuiBranch(*this);
2157 if (name == "changes")
2158 return createGuiChanges(*this);
2159 if (name == "character")
2160 return createGuiCharacter(*this);
2161 if (name == "citation")
2162 return createGuiCitation(*this);
2163 if (name == "document")
2164 return createGuiDocument(*this);
2165 if (name == "errorlist")
2166 return createGuiErrorList(*this);
2168 return createGuiERT(*this);
2169 if (name == "external")
2170 return createGuiExternal(*this);
2172 return createGuiShowFile(*this);
2173 if (name == "findreplace")
2174 return createGuiSearch(*this);
2175 if (name == "float")
2176 return createGuiFloat(*this);
2177 if (name == "graphics")
2178 return createGuiGraphics(*this);
2179 if (name == "include")
2180 return createGuiInclude(*this);
2181 if (name == "index")
2182 return createGuiIndex(*this);
2183 if (name == "nomenclature")
2184 return createGuiNomenclature(*this);
2185 if (name == "label")
2186 return createGuiLabel(*this);
2188 return createGuiLog(*this);
2189 if (name == "view-source")
2190 return createGuiViewSource(*this);
2191 if (name == "mathdelimiter")
2192 return createGuiDelimiter(*this);
2193 if (name == "mathmatrix")
2194 return createGuiMathMatrix(*this);
2196 return createGuiNote(*this);
2197 if (name == "paragraph")
2198 return createGuiParagraph(*this);
2199 if (name == "prefs")
2200 return createGuiPreferences(*this);
2201 if (name == "print")
2202 return createGuiPrint(*this);
2204 return createGuiRef(*this);
2205 if (name == "sendto")
2206 return createGuiSendTo(*this);
2207 if (name == "spellchecker")
2208 return createGuiSpellchecker(*this);
2209 if (name == "symbols")
2210 return createGuiSymbols(*this);
2211 if (name == "tabular")
2212 return createGuiTabular(*this);
2213 if (name == "tabularcreate")
2214 return createGuiTabularCreate(*this);
2215 if (name == "texinfo")
2216 return createGuiTexInfo(*this);
2217 #ifdef HAVE_LIBAIKSAURUS
2218 if (name == "thesaurus")
2219 return createGuiThesaurus(*this);
2222 return createGuiToc(*this);
2224 return createGuiHyperlink(*this);
2225 if (name == "vspace")
2226 return createGuiVSpace(*this);
2228 return createGuiWrap(*this);
2229 if (name == "listings")
2230 return createGuiListings(*this);
2236 } // namespace frontend
2239 #include "GuiView_moc.cpp"