#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"
#include "version.h"
#include "support/convert.h"
+#include "support/FileName.h"
#include "support/lstrings.h"
#include "support/os.h"
#include "support/Timeout.h"
namespace frontend {
using support::bformat;
+using support::FileName;
+using support::trim;
namespace {
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)
{
string cur_title;
GuiWorkArea * current_work_area_;
- int posx_offset;
- int posy_offset;
-
QSplitter * splitter_;
QStackedWidget * stack_widget_;
BackgroundWidget * bg_widget_;
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_;
// require bv_->text.
updateBufferDependent(true);
updateToolbars();
- updateLayoutChoice(false);
+ updateLayoutList();
updateStatusBar();
}
}
-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_) {
}
+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())));
break;
}
case LFUN_DROP_LAYOUTS_CHOICE:
- d.toolbars_->openLayoutList();
+ if (d.layout_)
+ d.layout_->showPopup();
break;
case LFUN_MENU_OPEN:
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);
*/
if (d.current_work_area_)
d.current_work_area_->startBlinkingCursor();
+
+ // Take this occasion to update the toobars and layout list.
+ updateLayoutList();
+ updateToolbars();
}
namespace {
} // 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))