]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiView.cpp
Introducing GuiMenubar::init() to avoid destructing the object in order to re-initial...
[lyx.git] / src / frontends / qt4 / GuiView.cpp
index 7415abc94fc965f0c4e7977c8da4a21d13388e6f..66ed4feccf20a3a701f07db5625580d9d449bad2 100644 (file)
@@ -43,9 +43,11 @@ using std::string;
 #include "gettext.h"
 #include "Intl.h"
 #include "Layout.h"
+#include "Lexer.h"
 #include "LyXFunc.h"
 #include "LyX.h"
 #include "LyXRC.h"
+#include "LyXVC.h"
 #include "MenuBackend.h"
 #include "Paragraph.h"
 #include "TextClass.h"
@@ -54,6 +56,7 @@ using std::string;
 #include "version.h"
 
 #include "support/convert.h"
+#include "support/FileName.h"
 #include "support/lstrings.h"
 #include "support/os.h"
 #include "support/Timeout.h"
@@ -100,6 +103,8 @@ extern bool quitting;
 namespace frontend {
 
 using support::bformat;
+using support::FileName;
+using support::trim;
 
 namespace {
 
@@ -150,7 +155,7 @@ typedef boost::shared_ptr<Dialog> DialogPtr;
 struct GuiView::GuiViewPrivate
 {
        GuiViewPrivate()
-               : current_work_area_(0), posx_offset(0), posy_offset(0),
+               : current_work_area_(0), layout_(0),
                autosave_timeout_(new Timeout(5000)), quitting_by_menu_(false),
                in_show_(false)
        {
@@ -258,9 +263,6 @@ public:
        string cur_title;
 
        GuiWorkArea * current_work_area_;
-       int posx_offset;
-       int posy_offset;
-
        QSplitter * splitter_;
        QStackedWidget * stack_widget_;
        BackgroundWidget * bg_widget_;
@@ -268,8 +270,16 @@ public:
        GuiMenubar * menubar_;
        /// view's toolbars
        GuiToolbars * toolbars_;
-       ///
-       docstring current_layout;
+       /// The main layout box.
+       /** 
+        * \warning Don't Delete! The layout box is actually owned by
+        * whichever toolbar contains it. All the GuiView class needs is a
+        * means of accessing it.
+        *
+        * FIXME: replace that with a proper model so that we are not limited
+        * to only one dialog.
+        */
+       GuiLayoutBox * layout_;
 
        ///
        std::map<std::string, Inset *> open_insets_;
@@ -533,7 +543,7 @@ void GuiView::on_currentWorkAreaChanged(GuiWorkArea * wa)
        // require bv_->text.
        updateBufferDependent(true);
        updateToolbars();
-       updateLayoutChoice(false);
+       updateLayoutList();
        updateStatusBar();
 }
 
@@ -782,34 +792,19 @@ void GuiView::removeWorkArea(GuiWorkArea * work_area)
 }
 
 
-void GuiView::updateLayoutChoice(bool force)
+void GuiView::setLayoutDialog(GuiLayoutBox * layout)
 {
-       // Don't show any layouts without a buffer
-       if (!buffer()) {
-               d.toolbars_->clearLayoutList();
-               return;
-       }
-
-       // Update the layout display
-       if (d.toolbars_->updateLayoutList(buffer()->params().getTextClassPtr(), force)) {
-               d.current_layout = buffer()->params().getTextClass().defaultLayoutName();
-       }
-
-       docstring const & layout = d.current_work_area_->bufferView().cursor().
-               innerParagraph().layout()->name();
-
-       if (layout != d.current_layout) {
-               d.toolbars_->setLayout(layout);
-               d.current_layout = layout;
-       }
+       d.layout_ = layout;
 }
 
 
-bool GuiView::isToolbarVisible(std::string const & id)
+void GuiView::updateLayoutList()
 {
-       return d.toolbars_->visible(id);
+       if (d.layout_)
+               d.layout_->updateContents(false);
 }
 
+
 void GuiView::updateToolbars()
 {
        if (d.current_work_area_) {
@@ -950,8 +945,86 @@ void GuiView::resetAutosaveTimers()
 }
 
 
+FuncStatus GuiView::getStatus(FuncRequest const & cmd)
+{
+       FuncStatus flag;
+       bool enable = true;
+       Buffer * buf = buffer();
+
+       /* In LyX/Mac, when a dialog is open, the menus of the
+          application can still be accessed without giving focus to
+          the main window. In this case, we want to disable the menu
+          entries that are buffer-related.
+
+          Note that this code is not perfect, as bug 1941 attests:
+          http://bugzilla.lyx.org/show_bug.cgi?id=1941#c4
+       */
+       if (cmd.origin == FuncRequest::MENU && !hasFocus())
+               buf = 0;
+
+       switch(cmd.action) {
+       case LFUN_TOOLBAR_TOGGLE:
+               flag.setOnOff(d.toolbars_->visible(cmd.getArg(0)));
+               break;
+
+       case LFUN_DIALOG_TOGGLE:
+               flag.setOnOff(isDialogVisible(cmd.getArg(0)));
+               // fall through to set "enable"
+       case LFUN_DIALOG_SHOW: {
+               string const name = cmd.getArg(0);
+               if (!buf)
+                       enable = name == "aboutlyx"
+                               || name == "file" //FIXME: should be removed.
+                               || name == "prefs"
+                               || name == "texinfo";
+               else if (name == "print")
+                       enable = buf->isExportable("dvi")
+                               && lyxrc.print_command != "none";
+               else if (name == "character") {
+                       if (!view())
+                               enable = false;
+                       else {
+                               InsetCode ic = view()->cursor().inset().lyxCode();
+                               enable = ic != ERT_CODE && ic != LISTINGS_CODE;
+                       }
+               }
+               else if (name == "latexlog")
+                       enable = FileName(buf->logName()).isFileReadable();
+               else if (name == "spellchecker")
+#if defined (USE_ASPELL) || defined (USE_ISPELL) || defined (USE_PSPELL)
+                       enable = !buf->isReadonly();
+#else
+                       enable = false;
+#endif
+               else if (name == "vclog")
+                       enable = buf->lyxvc().inUse();
+               break;
+       }
+
+       case LFUN_DIALOG_UPDATE: {
+               string const name = cmd.getArg(0);
+               if (!buf)
+                       enable = name == "prefs";
+               break;
+       }
+
+       default:
+               if (!view()) {
+                       enable = false;
+                       break;
+               }
+       }
+
+       if (!enable)
+               flag.enabled(false);
+
+       return flag;
+}
+
+
 void GuiView::dispatch(FuncRequest const & cmd)
 {
+       Buffer * buf = buffer();
        switch(cmd.action) {
                case LFUN_BUFFER_SWITCH:
                        setBuffer(theBufferList().getBuffer(to_utf8(cmd.argument())));
@@ -963,7 +1036,8 @@ void GuiView::dispatch(FuncRequest const & cmd)
                        break;
                }
                case LFUN_DROP_LAYOUTS_CHOICE:
-                       d.toolbars_->openLayoutList();
+                       if (d.layout_)
+                               d.layout_->showPopup();
                        break;
 
                case LFUN_MENU_OPEN:
@@ -1001,6 +1075,70 @@ void GuiView::dispatch(FuncRequest const & cmd)
                        break;
                }
 
+               case LFUN_DIALOG_UPDATE: {
+                       string const name = to_utf8(cmd.argument());
+                       // Can only update a dialog connected to an existing inset
+                       Inset * inset = getOpenInset(name);
+                       if (inset) {
+                               FuncRequest fr(LFUN_INSET_DIALOG_UPDATE, cmd.argument());
+                               inset->dispatch(view()->cursor(), fr);
+                       } else if (name == "paragraph") {
+                               lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE));
+                       } else if (name == "prefs") {
+                               updateDialog(name, string());
+                       }
+                       break;
+               }
+
+               case LFUN_DIALOG_TOGGLE: {
+                       if (isDialogVisible(cmd.getArg(0)))
+                               dispatch(FuncRequest(LFUN_DIALOG_HIDE, cmd.argument()));
+                       else
+                               dispatch(FuncRequest(LFUN_DIALOG_SHOW, cmd.argument()));
+                       break;
+               }
+
+               case LFUN_DIALOG_DISCONNECT_INSET:
+                       disconnectDialog(to_utf8(cmd.argument()));
+                       break;
+
+               case LFUN_DIALOG_HIDE: {
+                       if (quitting)
+                               break;
+                       guiApp->hideDialogs(to_utf8(cmd.argument()), 0);
+                       break;
+               }
+
+               case LFUN_DIALOG_SHOW: {
+                       string const name = cmd.getArg(0);
+                       string data = trim(to_utf8(cmd.argument()).substr(name.size()));
+
+                       if (name == "character") {
+                               data = freefont2string();
+                               if (!data.empty())
+                                       showDialog("character", data);
+                       } else if (name == "latexlog") {
+                               Buffer::LogType type; 
+                               string const logfile = buf->logName(&type);
+                               switch (type) {
+                               case Buffer::latexlog:
+                                       data = "latex ";
+                                       break;
+                               case Buffer::buildlog:
+                                       data = "literate ";
+                                       break;
+                               }
+                               data += Lexer::quoteString(logfile);
+                               showDialog("log", data);
+                       } else if (name == "vclog") {
+                               string const data = "vc " +
+                                       Lexer::quoteString(buf->lyxvc().getLogFile());
+                               showDialog("log", data);
+                       } else
+                               showDialog(name, data);
+                       break;
+               }
+
                default:
                        theLyXFunc().setLyXView(this);
                        lyx::dispatch(cmd);
@@ -1027,6 +1165,10 @@ void GuiView::restartCursor()
         */
        if (d.current_work_area_)
                d.current_work_area_->startBlinkingCursor();
+
+       // Take this occasion to update the toobars and layout list.
+       updateLayoutList();
+       updateToolbars();
 }
 
 namespace {
@@ -1071,6 +1213,17 @@ bool isValidName(string const & name)
 } // namespace anon
 
 
+void GuiView::resetDialogs()
+{
+       // Make sure that no LFUN uses any LyXView.
+       theLyXFunc().setLyXView(0);
+       d.toolbars_->init();
+       d.menubar_->init();
+       if (d.layout_)
+               d.layout_->updateContents(true);
+}
+
+
 Dialog * GuiView::find_or_build(string const & name)
 {
        if (!isValidName(name))