* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
- * \author Lars Gullik Bjønnes
+ * \author Lars Gullik Bjønnes
* \author John Levon
* \author Abdelrazak Younes
- * \author Peter Kümmel
+ * \author Peter Kümmel
*
* Full author contact details are available in file CREDITS.
*/
#include "Dialog.h"
#include "FileDialog.h"
#include "GuiApplication.h"
+#include "GuiCommandBuffer.h"
#include "GuiCompleter.h"
#include "GuiWorkArea.h"
#include "GuiKeySymbol.h"
#include "GuiToolbar.h"
-#include "GuiToolbars.h"
#include "Menus.h"
#include "TocModel.h"
#include "Paragraph.h"
#include "TextClass.h"
#include "Text.h"
-#include "ToolbarBackend.h"
+#include "Toolbars.h"
#include "version.h"
#include "support/lassert.h"
#include "support/debug.h"
+#include "support/ExceptionMessage.h"
#include "support/FileName.h"
#include "support/filetools.h"
#include "support/gettext.h"
QPixmap splash_;
};
-} // namespace anon
+/// Toolbar store providing access to individual toolbars by name.
+typedef std::map<std::string, GuiToolbar *> ToolbarMap;
typedef boost::shared_ptr<Dialog> DialogPtr;
+} // namespace anon
+
+
struct GuiView::GuiViewPrivate
{
GuiViewPrivate()
- : current_work_area_(0), layout_(0), autosave_timeout_(5000),
+ : current_work_area_(0), current_main_work_area_(0),
+ layout_(0), autosave_timeout_(5000),
in_show_(false)
{
// hardcode here the platform specific icon size
- smallIconSize = 14; // scaling problems
- normalIconSize = 20; // ok, default
- bigIconSize = 26; // better for some math icons
+ smallIconSize = 14; // scaling problems
+ normalIconSize = 20; // ok, default
+ bigIconSize = 26; // better for some math icons
splitter_ = new QSplitter;
bg_widget_ = new BackgroundWidget;
delete splitter_;
delete bg_widget_;
delete stack_widget_;
- delete toolbars_;
}
QMenu * toolBarPopup(GuiView * parent)
for (int i = 0; i != splitter_->count(); ++i) {
TabWorkArea * twa = tabWorkArea(i);
- if (current_work_area_ == twa->currentWorkArea())
+ if (current_main_work_area_ == twa->currentWorkArea())
return twa;
}
public:
GuiWorkArea * current_work_area_;
+ GuiWorkArea * current_main_work_area_;
QSplitter * splitter_;
QStackedWidget * stack_widget_;
BackgroundWidget * bg_widget_;
/// view's toolbars
- GuiToolbars * toolbars_;
+ ToolbarMap toolbars_;
/// The main layout box.
/**
* \warning Don't Delete! The layout box is actually owned by
GuiView::GuiView(int id)
- : d(*new GuiViewPrivate), id_(id)
+ : d(*new GuiViewPrivate), id_(id), closing_(false)
{
// GuiToolbars *must* be initialised before the menu bar.
- d.toolbars_ = new GuiToolbars(*this);
+ normalSizedIcons(); // at least on Mac the default is 32 otherwise, which is huge
+ constructToolbars();
// set ourself as the current view. This is needed for the menu bar
// filling, at least for the static special menu item on Mac. Otherwise
// with some window manager under X11.
setMinimumSize(300, 200);
- if (!lyxrc.allow_geometry_session)
- // No session handling, default to a sane size.
- setGeometry(50, 50, 690, 510);
+ if (lyxrc.allow_geometry_session) {
+ // Now take care of session management.
+ if (restoreLayout())
+ return;
+ }
+
+ // no session handling, default to a sane size.
+ setGeometry(50, 50, 690, 510);
+ initToolbars();
+
+ // clear session data if any.
+ QSettings settings;
+ settings.remove("views");
+}
+
+
+GuiView::~GuiView()
+{
+ delete &d;
+}
+
+
+void GuiView::saveLayout() const
+{
+ QSettings settings;
+ settings.beginGroup("views");
+ settings.beginGroup(QString::number(id_));
+#ifdef Q_WS_X11
+ settings.setValue("pos", pos());
+ settings.setValue("size", size());
+#else
+ settings.setValue("geometry", saveGeometry());
+#endif
+ settings.setValue("layout", saveState(0));
+ settings.setValue("icon_size", iconSize());
+}
- // Now take care of session management.
+
+bool GuiView::restoreLayout()
+{
QSettings settings;
- QString const key = "view-" + QString::number(id_);
+ settings.beginGroup("views");
+ settings.beginGroup(QString::number(id_));
+ QString const icon_key = "icon_size";
+ if (!settings.contains(icon_key))
+ return false;
+
+ setIconSize(settings.value(icon_key).toSize());
#ifdef Q_WS_X11
- QPoint pos = settings.value(key + "/pos", QPoint(50, 50)).toPoint();
- QSize size = settings.value(key + "/size", QSize(690, 510)).toSize();
+ QPoint pos = settings.value("pos", QPoint(50, 50)).toPoint();
+ QSize size = settings.value("size", QSize(690, 510)).toSize();
resize(size);
move(pos);
#else
- if (!restoreGeometry(settings.value(key + "/geometry").toByteArray()))
+ if (!restoreGeometry(settings.value("geometry").toByteArray()))
setGeometry(50, 50, 690, 510);
#endif
- setIconSize(settings.value(key + "/icon_size").toSize());
+ // Make sure layout is correctly oriented.
+ setLayoutDirection(qApp->layoutDirection());
+
+ // Allow the toc and view-source dock widget to be restored if needed.
+ findOrBuild("toc", true);
+ findOrBuild("view-source", true);
+
+ if (!restoreState(settings.value("layout").toByteArray(), 0))
+ initToolbars();
+ updateDialogs();
+ return true;
}
-GuiView::~GuiView()
+GuiToolbar * GuiView::toolbar(string const & name)
{
- if (guiApp->currentView() == this)
- guiApp->setCurrentView(0);
- theLyXFunc().setLyXView(0);
-
- delete &d;
+ ToolbarMap::iterator it = d.toolbars_.find(name);
+ if (it != d.toolbars_.end())
+ return it->second;
+
+ LYXERR(Debug::GUI, "Toolbar::display: no toolbar named " << name);
+ message(bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name)));
+ return 0;
+}
+
+
+void GuiView::constructToolbars()
+{
+ ToolbarMap::iterator it = d.toolbars_.begin();
+ for (; it != d.toolbars_.end(); ++it)
+ delete it->second;
+ d.toolbars_.clear();
+ d.layout_ = 0;
+
+ // extracts the toolbars from the backend
+ Toolbars::Infos::iterator cit = guiApp->toolbars().begin();
+ Toolbars::Infos::iterator end = guiApp->toolbars().end();
+ for (; cit != end; ++cit)
+ d.toolbars_[cit->name] = new GuiToolbar(*cit, *this);
+}
+
+
+void GuiView::initToolbars()
+{
+ // extracts the toolbars from the backend
+ Toolbars::Infos::iterator cit = guiApp->toolbars().begin();
+ Toolbars::Infos::iterator end = guiApp->toolbars().end();
+ for (; cit != end; ++cit) {
+ GuiToolbar * tb = toolbar(cit->name);
+ if (!tb)
+ continue;
+ int const visibility = guiApp->toolbars().defaultVisibility(cit->name);
+ bool newline = true;
+ tb->setVisible(false);
+ tb->setVisibility(visibility);
+
+ if (visibility & Toolbars::TOP) {
+ if (newline)
+ addToolBarBreak(Qt::TopToolBarArea);
+ addToolBar(Qt::TopToolBarArea, tb);
+ }
+
+ if (visibility & Toolbars::BOTTOM) {
+ // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
+#if (QT_VERSION >= 0x040202)
+ addToolBarBreak(Qt::BottomToolBarArea);
+#endif
+ addToolBar(Qt::BottomToolBarArea, tb);
+ }
+
+ if (visibility & Toolbars::LEFT) {
+ // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
+#if (QT_VERSION >= 0x040202)
+ addToolBarBreak(Qt::LeftToolBarArea);
+#endif
+ addToolBar(Qt::LeftToolBarArea, tb);
+ }
+
+ if (visibility & Toolbars::RIGHT) {
+ // Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
+#if (QT_VERSION >= 0x040202)
+ addToolBarBreak(Qt::RightToolBarArea);
+#endif
+ addToolBar(Qt::RightToolBarArea, tb);
+ }
+
+ if (visibility & Toolbars::ON)
+ tb->setVisible(true);
+ }
}
void GuiView::setFocus()
{
+ LYXERR(Debug::DEBUG, "GuiView::setFocus()" << this);
+ // Make sure LyXFunc points to the correct view.
+ guiApp->setCurrentView(this);
+ theLyXFunc().setLyXView(this);
+ QMainWindow::setFocus();
if (d.current_work_area_)
d.current_work_area_->setFocus();
- else
- QWidget::setFocus();
}
}
+/** Destroy only all tabbed WorkAreas. Destruction of other WorkAreas
+ ** is responsibility of the container (e.g., dialog)
+ **/
void GuiView::closeEvent(QCloseEvent * close_event)
{
+ LYXERR(Debug::DEBUG, "GuiView::closeEvent()");
+ closing_ = true;
+
// it can happen that this event arrives without selecting the view,
// e.g. when clicking the close button on a background window.
- theLyXFunc().setLyXView(this);
-
- while (Buffer * b = buffer()) {
+ setFocus();
+ setCurrentWorkArea(currentMainWorkArea());
+ while (GuiWorkArea * wa = currentMainWorkArea()) {
+ Buffer * b = &wa->bufferView().buffer();
if (b->parent()) {
// This is a child document, just close the tab after saving
// but keep the file loaded.
if (!saveBuffer(*b)) {
+ closing_ = false;
close_event->ignore();
return;
}
- removeWorkArea(d.current_work_area_);
+ removeWorkArea(wa);
continue;
}
- std::vector<int> const & ids = guiApp->viewIds();
- for (size_type i = 0; i != ids.size(); ++i) {
+ QList<int> const ids = guiApp->viewIds();
+ for (int i = 0; i != ids.size(); ++i) {
if (id_ == ids[i])
continue;
if (guiApp->view(ids[i]).workArea(*b)) {
//saveBuffer(b);
// This buffer is also opened in another view, so
- // but close the associated work area nevertheless.
- removeWorkArea(d.current_work_area_);
- // but don't close it.
+ // close the associated work area...
+ removeWorkArea(wa);
+ // ... but don't close the buffer.
b = 0;
break;
}
}
+ // closeBuffer() needs buffer workArea still alive and set as currrent one, and destroys it
if (b && !closeBuffer(*b, true)) {
+ closing_ = false;
close_event->ignore();
return;
}
}
- // Make sure that no LFUN use this close to be closed View.
- theLyXFunc().setLyXView(0);
+ // Make sure that nothing will use this close to be closed View.
+ guiApp->unregisterView(this);
- // Save toolbars configuration
if (isFullScreen()) {
- d.toolbars_->toggleFullScreen(!isFullScreen());
+ // Switch off fullscreen before closing.
+ toggleFullScreen();
updateDialogs();
}
// Saving fullscreen requires additional tweaks in the toolbar code.
// It wouldn't also work under linux natively.
- if (lyxrc.allow_geometry_session && !isFullScreen()) {
- QSettings settings;
- QString const key = "view-" + QString::number(id_);
-#ifdef Q_WS_X11
- settings.setValue(key + "/pos", pos());
- settings.setValue(key + "/size", size());
-#else
- settings.setValue(key + "/geometry", saveGeometry());
-#endif
- settings.setValue(key + "/icon_size", iconSize());
- d.toolbars_->saveToolbarInfo();
+ if (lyxrc.allow_geometry_session) {
+ // Save this window geometry and layout.
+ saveLayout();
+ // Then the toolbar private states.
+ ToolbarMap::iterator end = d.toolbars_.end();
+ for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it)
+ it->second->saveSession();
// Now take care of all other dialogs:
map<string, DialogPtr>::const_iterator it = d.dialogs_.begin();
for (; it!= d.dialogs_.end(); ++it)
it->second->saveSession();
}
- guiApp->unregisterView(id_);
close_event->accept();
}
}
-void GuiView::dropEvent(QDropEvent* event)
+void GuiView::dropEvent(QDropEvent * event)
{
QList<QUrl> files = event->mimeData()->urls();
if (files.isEmpty())
for (int i = 0; i != files.size(); ++i) {
string const file = os::internal_path(fromqstr(
files.at(i).toLocalFile()));
- if (!file.empty())
- lyx::dispatch(FuncRequest(LFUN_FILE_OPEN, file));
+ if (!file.empty()) {
+ // Asynchronously post the event. DropEvent usually come
+ // from the BufferView. But reloading a file might close
+ // the BufferView from within its own event handler.
+ guiApp->dispatchDelayed(FuncRequest(LFUN_FILE_OPEN, file));
+ event->accept();
+ }
}
}
void GuiView::on_lastWorkAreaRemoved()
{
-#ifdef Q_WS_MACX
- // On Mac close the view if there is no Tab open anymore,
- // but only if no splitter is visible
- if (!lyxrc.open_buffers_in_tabs && d.splitter_->count() == 1) {
- TabWorkArea * twa = qobject_cast<TabWorkArea *>(d.splitter_->widget(0));
- if (twa && twa->count() == 0) {
- // close the view, as no tab is open anymore
- QTimer::singleShot(0, this, SLOT(close()));
- }
- }
-#else
- structureChanged();
- // The document settings needs to be reinitialised.
+ if (closing_)
+ // We already are in a close event. Nothing more to do.
+ return;
+
+ if (d.splitter_->count() > 1)
+ // We have a splitter so don't close anything.
+ return;
+
+ // Reset and updates the dialogs.
+ d.toc_models_.reset(0);
updateDialog("document", "");
updateDialogs();
+
+ resetWindowTitleAndIconText();
+
+ if (lyxrc.open_buffers_in_tabs)
+ // Nothing more to do, the window should stay open.
+ return;
+
+ if (guiApp->viewIds().size() > 1) {
+ close();
+ return;
+ }
+
+#ifdef Q_WS_MACX
+ // On Mac we also close the last window because the application stay
+ // resident in memory. On other platforms we don't close the last
+ // window because this would quit the application.
+ close();
#endif
}
return QMainWindow::event(e);
}
guiApp->setCurrentView(this);
+ theLyXFunc().setLyXView(this);
if (d.current_work_area_) {
BufferView & bv = d.current_work_area_->bufferView();
connectBufferView(bv);
updateDialog("document", "");
updateDialogs();
} else {
- setWindowTitle(qt_("LyX"));
- setWindowIconText(qt_("LyX"));
+ resetWindowTitleAndIconText();
}
setFocus();
return QMainWindow::event(e);
case QEvent::ShortcutOverride: {
+#ifndef Q_WS_X11
+ // FIXME bug 4888
if (isFullScreen() && menuBar()->isHidden()) {
QKeyEvent * ke = static_cast<QKeyEvent*>(e);
// FIXME: we should also try to detect special LyX shortcut such as
- // Alt-P and Alt-M
- if (!(ke->modifiers() & Qt::AltModifier)
- || ke->key() == Qt::Key_Alt)
- return QMainWindow::event(e);
- menuBar()->show();
- // Continue with even.
+ // Alt-P and Alt-M. Right now there is a hack in
+ // GuiWorkArea::processKeySym() that hides again the menubar for
+ // those cases.
+ if (ke->modifiers() & Qt::AltModifier && ke->key() != Qt::Key_Alt)
+ menuBar()->show();
return QMainWindow::event(e);
}
+#endif
- QKeyEvent * ke = static_cast<QKeyEvent*>(e);
if (d.current_work_area_)
// Nothing special to do.
return QMainWindow::event(e);
+ QKeyEvent * ke = static_cast<QKeyEvent*>(e);
// Let Qt handle menu access and the Tab keys to navigate keys to navigate
// between controls.
if (ke->modifiers() & Qt::AltModifier || ke->key() == Qt::Key_Tab
}
}
+void GuiView::resetWindowTitleAndIconText()
+{
+ setWindowTitle(qt_("LyX"));
+ setWindowIconText(qt_("LyX"));
+}
bool GuiView::focusNextPrevChild(bool /*next*/)
{
}
-GuiToolbar * GuiView::makeToolbar(ToolbarInfo const & tbinfo, bool newline)
-{
- GuiToolbar * toolBar = new GuiToolbar(tbinfo, *this);
-
- if (tbinfo.flags & ToolbarInfo::TOP) {
- if (newline)
- addToolBarBreak(Qt::TopToolBarArea);
- addToolBar(Qt::TopToolBarArea, toolBar);
- }
-
- if (tbinfo.flags & ToolbarInfo::BOTTOM) {
-// Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
-#if (QT_VERSION >= 0x040202)
- if (newline)
- addToolBarBreak(Qt::BottomToolBarArea);
-#endif
- addToolBar(Qt::BottomToolBarArea, toolBar);
- }
-
- if (tbinfo.flags & ToolbarInfo::LEFT) {
-// Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
-#if (QT_VERSION >= 0x040202)
- if (newline)
- addToolBarBreak(Qt::LeftToolBarArea);
-#endif
- addToolBar(Qt::LeftToolBarArea, toolBar);
- }
-
- if (tbinfo.flags & ToolbarInfo::RIGHT) {
-// Qt < 4.2.2 cannot handle ToolBarBreak on non-TOP dock.
-#if (QT_VERSION >= 0x040202)
- if (newline)
- addToolBarBreak(Qt::RightToolBarArea);
-#endif
- addToolBar(Qt::RightToolBarArea, toolBar);
- }
-
- // The following does not work so I cannot restore to exact toolbar location
- /*
- ToolbarSection::ToolbarInfo & tbinfo = LyX::ref().session().toolbars().load(tbinfo.name);
- toolBar->move(tbinfo.posx, tbinfo.posy);
- */
-
- return toolBar;
-}
-
-
GuiWorkArea * GuiView::workArea(Buffer & buffer)
{
+ if (currentWorkArea()
+ && ¤tWorkArea()->bufferView().buffer() == &buffer)
+ return (GuiWorkArea *) currentWorkArea();
if (TabWorkArea * twa = d.currentTabWorkArea())
return twa->workArea(buffer);
return 0;
}
+GuiWorkArea * GuiView::currentWorkArea()
+{
+ return d.current_work_area_;
+}
+
+
+GuiWorkArea const * GuiView::currentMainWorkArea() const
+{
+ if (d.currentTabWorkArea() == NULL)
+ return NULL;
+ return d.currentTabWorkArea()->currentWorkArea();
+}
+
+
+GuiWorkArea * GuiView::currentMainWorkArea()
+{
+ if (d.currentTabWorkArea() == NULL)
+ return NULL;
+ return d.currentTabWorkArea()->currentWorkArea();
+}
+
+
void GuiView::setCurrentWorkArea(GuiWorkArea * wa)
{
- LASSERT(wa, /**/);
+ LYXERR(Debug::DEBUG, "Setting current wa: " << wa << endl);
+ if (wa == NULL) {
+ d.current_work_area_ = NULL;
+ d.setBackground();
+ return;
+ }
+ GuiWorkArea * old_gwa = theGuiApp()->currentView()->currentWorkArea();
+ if (old_gwa == wa)
+ return;
+
+ theGuiApp()->setCurrentView(this);
d.current_work_area_ = wa;
for (int i = 0; i != d.splitter_->count(); ++i) {
- if (d.tabWorkArea(i)->setCurrentWorkArea(wa))
+ if (d.tabWorkArea(i)->setCurrentWorkArea(wa)) {
+ //if (d.current_main_work_area_)
+ // d.current_main_work_area_->setFrameStyle(QFrame::NoFrame);
+ d.current_main_work_area_ = wa;
+ //d.current_main_work_area_->setFrameStyle(QFrame::Box | QFrame::Plain);
+ //d.current_main_work_area_->setLineWidth(2);
+ LYXERR(Debug::DEBUG, "Current wa: " << currentWorkArea() << ", Current main wa: " << currentMainWorkArea());
return;
+ }
}
+ LYXERR(Debug::DEBUG, "This is not a tabbed wa");
+ on_currentWorkAreaChanged(wa);
+ BufferView & bv = wa->bufferView();
+ bv.cursor().fixIfBroken();
+ bv.updateMetrics();
+ wa->setUpdatesEnabled(true);
+ LYXERR(Debug::DEBUG, "Current wa: " << currentWorkArea() << ", Current main wa: " << currentMainWorkArea());
}
void GuiView::removeWorkArea(GuiWorkArea * wa)
{
- LASSERT(wa, /**/);
+ LASSERT(wa, return);
if (wa == d.current_work_area_) {
disconnectBuffer();
disconnectBufferView();
d.current_work_area_ = 0;
+ d.current_main_work_area_ = 0;
}
+ bool found_twa = false;
for (int i = 0; i != d.splitter_->count(); ++i) {
TabWorkArea * twa = d.tabWorkArea(i);
- if (!twa->removeWorkArea(wa))
- // Not found in this tab group.
- continue;
-
- // We found and removed the GuiWorkArea.
- if (!twa->count()) {
- // No more WorkAreas in this tab group, so delete it.
- delete twa;
+ if (twa->removeWorkArea(wa)) {
+ // Found in this tab group, and deleted the GuiWorkArea.
+ found_twa = true;
+ if (twa->count() != 0) {
+ if (d.current_work_area_ == 0)
+ // This means that we are closing the current GuiWorkArea, so
+ // switch to the next GuiWorkArea in the found TabWorkArea.
+ setCurrentWorkArea(twa->currentWorkArea());
+ } else {
+ // No more WorkAreas in this tab group, so delete it.
+ delete twa;
+ }
break;
}
+ }
- if (d.current_work_area_)
- // This means that we are not closing the current GuiWorkArea;
- break;
+ // It is not a tabbed work area (i.e., the search work area), so it
+ // should be deleted by other means.
+ LASSERT(found_twa, /* */);
- // Switch to the next GuiWorkArea in the found TabWorkArea.
- d.current_work_area_ = twa->currentWorkArea();
- break;
+ if (d.current_work_area_ == 0) {
+ if (d.splitter_->count() != 0) {
+ TabWorkArea * twa = d.currentTabWorkArea();
+ setCurrentWorkArea(twa->currentWorkArea());
+ } else {
+ // No more work areas, switch to the background widget.
+ setCurrentWorkArea(0);
+ }
}
-
- if (d.splitter_->count() == 0)
- // No more work area, switch to the background widget.
- d.setBackground();
}
void GuiView::updateToolbars()
{
+ ToolbarMap::iterator end = d.toolbars_.end();
if (d.current_work_area_) {
bool const math =
d.current_work_area_->bufferView().cursor().inMathed();
bool const mathmacrotemplate =
lyx::getStatus(FuncRequest(LFUN_IN_MATHMACROTEMPLATE)).enabled();
- d.toolbars_->update(math, table, review, mathmacrotemplate);
+ for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it)
+ it->second->update(math, table, review, mathmacrotemplate);
} else
- d.toolbars_->update(false, false, false, false);
+ for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it)
+ it->second->update(false, false, false, false);
}
void GuiView::setBuffer(Buffer * newBuffer)
{
- LASSERT(newBuffer, /**/);
+ LYXERR(Debug::DEBUG, "Setting buffer: " << newBuffer << std::endl);
+ LASSERT(newBuffer, return);
setBusy(true);
GuiWorkArea * wa = workArea(*newBuffer);
if (wa == 0) {
- updateLabels(*newBuffer->masterBuffer());
+ newBuffer->masterBuffer()->updateLabels();
wa = addWorkArea(*newBuffer);
} else {
//Disconnect the old buffer...there's no new one.
}
+void GuiView::updateTocItem(std::string const & type, DocIterator const & dit)
+{
+ d.toc_models_.updateItem(toqstr(type), dit);
+}
+
+
void GuiView::structureChanged()
{
d.toc_models_.reset(view());
}
-FuncStatus GuiView::getStatus(FuncRequest const & cmd)
+bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
{
- FuncStatus flag;
bool enable = true;
Buffer * buf = buffer();
break;
case LFUN_SPLIT_VIEW:
- enable = buf;
+ if (cmd.getArg(0) == "vertical")
+ enable = buf && (d.splitter_->count() == 1 ||
+ d.splitter_->orientation() == Qt::Vertical);
+ else
+ enable = buf && (d.splitter_->count() == 1 ||
+ d.splitter_->orientation() == Qt::Horizontal);
break;
case LFUN_CLOSE_TAB_GROUP:
break;
case LFUN_TOOLBAR_TOGGLE:
- flag.setOnOff(d.toolbars_->visible(cmd.getArg(0)));
+ if (GuiToolbar * t = toolbar(cmd.getArg(0)))
+ flag.setOnOff(t->isVisible());
break;
case LFUN_UI_TOGGLE:
else if (name == "latexlog")
enable = FileName(buf->logName()).isReadableFile();
else if (name == "spellchecker")
-#if defined (USE_ASPELL) || defined (USE_ISPELL) || defined (USE_PSPELL)
+#if defined (USE_ASPELL)
enable = !buf->isReadonly();
#else
enable = false;
}
case LFUN_INSET_APPLY: {
- if (!buf) {
- enable = false;
- break;
- }
string const name = cmd.getArg(0);
Inset * inset = getOpenInset(name);
if (inset) {
FuncStatus fs;
if (!inset->getStatus(view()->cursor(), fr, fs)) {
// Every inset is supposed to handle this
- LASSERT(false, /**/);
+ LASSERT(false, break);
}
flag |= fs;
} else {
FuncRequest fr(LFUN_INSET_INSERT, cmd.argument());
- flag |= getStatus(fr);
+ flag |= lyx::getStatus(fr);
}
enable = flag.enabled();
break;
enable = false;
break;
- default:
- if (!view()) {
+ case LFUN_COMPLETION_ACCEPT:
+ if (!d.current_work_area_
+ || (!d.current_work_area_->completer().popupVisible()
+ && !d.current_work_area_->completer().inlineVisible()
+ && !d.current_work_area_->completer().completionAvailable()))
enable = false;
- break;
- }
+ break;
+
+ case LFUN_COMPLETION_CANCEL:
+ if (!d.current_work_area_
+ || (!d.current_work_area_->completer().popupVisible()
+ && !d.current_work_area_->completer().inlineVisible()))
+ enable = false;
+ break;
+
+ default:
+ return false;
}
if (!enable)
- flag.enabled(false);
+ flag.setEnabled(false);
- return flag;
+ return true;
}
// scroll to the position when the file was last closed
if (lyxrc.use_lastfilepos) {
LastFilePosSection::FilePos filepos =
- LyX::ref().session().lastFilePos().load(filename);
+ theSession().lastFilePos().load(filename);
view()->moveToPosition(filepos.pit, filepos.pos, 0, 0);
}
if (tolastfiles)
- LyX::ref().session().lastFiles().add(filename);
+ theSession().lastFiles().add(filename);
setBusy(false);
return newBuffer;
dlg.setButton2(qt_("Examples|#E#e"),
toqstr(addPath(package().system_support().absFilename(), "examples")));
+ QStringList filter(qt_("LyX Documents (*.lyx)"));
+ filter << qt_("LyX-1.3.x Documents (*.lyx13)")
+ << qt_("LyX-1.4.x Documents (*.lyx14)")
+ << qt_("LyX-1.5.x Documents (*.lyx15)");
FileDialog::Result result =
- dlg.open(toqstr(initpath), QStringList(qt_("LyX Documents (*.lyx)")));
+ dlg.open(toqstr(initpath), filter);
if (result.first == FileDialog::Later)
return;
if (!fullname.empty())
filename = fullname.absFilename();
+ if (!fullname.onlyPath().isDirectory()) {
+ Alert::warning(_("Invalid filename"),
+ bformat(_("The directory in the given path\n%1$s\ndoes not exists."),
+ from_utf8(fullname.absFilename())));
+ return;
+ }
// if the file doesn't exist, let the user create one
if (!fullname.exists()) {
// the user specifically chose this name. Believe him.
docstring str2;
Buffer * buf = loadDocument(fullname);
if (buf) {
- updateLabels(*buf);
-
+ buf->updateLabels();
setBuffer(buf);
buf->errors("Parse");
str2 = bformat(_("Document %1$s opened."), disp_fn);
+ if (buf->lyxvc().inUse())
+ str2 += " " + from_utf8(buf->lyxvc().versionString()) +
+ " " + _("Version control detected.");
} else {
str2 = bformat(_("Could not open document %1$s"), disp_fn);
}
Buffer * buf = lv->loadDocument(lyxfile);
if (!buf)
return false;
- updateLabels(*buf);
+ buf->updateLabels();
lv->setBuffer(buf);
buf->errors("Parse");
} else {
FileName const lyxfile(support::changeExtension(fullname.absFilename(), ".lyx"));
// Check if the document already is open
- Buffer * buf = theBufferList().getBuffer(lyxfile.absFilename());
+ Buffer * buf = theBufferList().getBuffer(lyxfile);
if (buf) {
setBuffer(buf);
if (!closeBuffer()) {
bool GuiView::saveBuffer(Buffer & b)
{
+ if (workArea(b) && workArea(b)->inDialogMode())
+ return true;
+
if (b.isUnnamed())
return renameBuffer(b, docstring());
if (b.save()) {
- LyX::ref().session().lastFiles().add(b.fileName());
+ theSession().lastFiles().add(b.fileName());
return true;
}
{
// goto bookmark to update bookmark pit.
//FIXME: we should update only the bookmarks related to this buffer!
- for (size_t i = 0; i < LyX::ref().session().bookmarks().size(); ++i)
+ LYXERR(Debug::DEBUG, "GuiView::closeBuffer()");
+ for (size_t i = 0; i < theSession().bookmarks().size(); ++i)
theLyXFunc().gotoBookmark(i+1, false, false);
if (buf.isClean() || buf.paragraphs().empty()) {
if (buf.masterBuffer() == &buf && tolastopened)
- LyX::ref().session().lastOpened().add(buf.fileName());
- theBufferList().release(&buf);
+ theSession().lastOpened().add(buf.fileName());
+ if (buf.parent())
+ // Don't close child documents.
+ removeWorkArea(currentMainWorkArea());
+ else
+ theBufferList().release(&buf);
return true;
}
// Switch to this Buffer.
// if master/slave are both open, do not save slave since it
// will be automatically loaded when the master is loaded
if (buf.masterBuffer() == &buf && tolastopened)
- LyX::ref().session().lastOpened().add(buf.fileName());
+ theSession().lastOpened().add(buf.fileName());
+
+ if (buf.parent())
+ // Don't close child documents.
+ removeWorkArea(currentMainWorkArea());
+ else
+ theBufferList().release(&buf);
- theBufferList().release(&buf);
return true;
}
break;
case LFUN_BUFFER_SWITCH:
- setBuffer(theBufferList().getBuffer(to_utf8(cmd.argument())));
+ setBuffer(theBufferList().getBuffer(FileName(to_utf8(cmd.argument()))));
break;
case LFUN_BUFFER_NEXT:
case LFUN_COMMAND_EXECUTE: {
bool const show_it = cmd.argument() != "off";
- d.toolbars_->showCommandBuffer(show_it);
+ // FIXME: this is a hack, "minibuffer" should not be
+ // hardcoded.
+ if (GuiToolbar * t = toolbar("minibuffer")) {
+ t->setVisible(show_it);
+ if (show_it && t->commandBuffer())
+ t->commandBuffer()->setFocus();
+ }
break;
}
case LFUN_DROP_LAYOUTS_CHOICE:
case LFUN_TOOLBAR_TOGGLE: {
string const name = cmd.getArg(0);
- bool const allowauto = cmd.getArg(1) == "allowauto";
- // it is possible to get current toolbar status like this,...
- // but I decide to obey the order of ToolbarBackend::flags
- // and disregard real toolbar status.
- // toolbars_->saveToolbarInfo();
- //
- // toggle state on/off/auto
- d.toolbars_->toggleToolbarState(name, allowauto);
- // update toolbar
- updateToolbars();
-
- ToolbarInfo * tbi = d.toolbars_->getToolbarInfo(name);
- if (!tbi) {
- message(bformat(_("Unknown toolbar \"%1$s\""), from_utf8(name)));
- break;
- }
- docstring state;
- if (tbi->flags & ToolbarInfo::ON)
- state = _("on");
- else if (tbi->flags & ToolbarInfo::OFF)
- state = _("off");
- else if (tbi->flags & ToolbarInfo::AUTO)
- state = _("auto");
-
- message(bformat(_("Toolbar \"%1$s\" state set to %2$s"),
- _(tbi->gui_name), state));
+ if (GuiToolbar * t = toolbar(name))
+ t->toggle();
break;
}
data = bv->cursor().getEncoding()->name();
if (!data.empty())
showDialog("symbols", data);
+ // bug 5274
+ } else if (name == "prefs" && isFullScreen()) {
+ FuncRequest fr(LFUN_INSET_INSERT, "fullscreen");
+ lfunUiToggle(fr);
+ showDialog("prefs", data);
} else
showDialog(name, data);
break;
}
case LFUN_INSET_APPLY: {
- view()->cursor().recordUndoFullDocument();
string const name = cmd.getArg(0);
Inset * inset = getOpenInset(name);
if (inset) {
+ // put cursor in front of inset.
+ if (!view()->setCursorFromInset(inset))
+ LASSERT(false, break);
+
+ // useful if we are called from a dialog.
+ view()->cursor().beginUndoGroup();
+ view()->cursor().recordUndo();
FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument());
inset->dispatch(view()->cursor(), fr);
+ view()->cursor().endUndoGroup();
} else {
FuncRequest fr(LFUN_INSET_INSERT, cmd.argument());
lyx::dispatch(fr);
setFocus();
break;
- case LFUN_COMPLETION_INLINE:
- if (d.current_work_area_)
- d.current_work_area_->completer().showInline();
- break;
-
case LFUN_SPLIT_VIEW:
if (Buffer * buf = buffer()) {
string const orientation = cmd.getArg(0);
delete twa;
twa = d.currentTabWorkArea();
// Switch to the next GuiWorkArea in the found TabWorkArea.
- d.current_work_area_ = twa? twa->currentWorkArea() : 0;
- if (d.splitter_->count() == 0)
- // No more work area, switch to the background widget.
- d.setBackground();
+ if (twa) {
+ // Make sure the work area is up to date.
+ setCurrentWorkArea(twa->currentWorkArea());
+ } else {
+ setCurrentWorkArea(0);
+ }
}
break;
+ case LFUN_COMPLETION_INLINE:
+ if (d.current_work_area_)
+ d.current_work_area_->completer().showInline();
+ break;
+
case LFUN_COMPLETION_POPUP:
if (d.current_work_area_)
d.current_work_area_->completer().showPopup();
d.current_work_area_->completer().tab();
break;
+ case LFUN_COMPLETION_CANCEL:
+ if (d.current_work_area_) {
+ if (d.current_work_area_->completer().popupVisible())
+ d.current_work_area_->completer().hidePopup();
+ else
+ d.current_work_area_->completer().hideInline();
+ }
+ break;
+
+ case LFUN_COMPLETION_ACCEPT:
+ if (d.current_work_area_)
+ d.current_work_area_->completer().activate();
+ break;
+
+
default:
dispatched = false;
break;
}
+ // Part of automatic menu appearance feature.
if (isFullScreen()) {
if (menuBar()->isVisible())
menuBar()->hide();
return;
}
#endif
- if (arg != "fullscreen") {
- message(bformat("LFUN_UI_TOGGLE " + _("%1$s unknown command!"), from_utf8(arg)));
+ if (arg == "fullscreen") {
+ toggleFullScreen();
return;
}
- if (lyxrc.full_screen_toolbars)
- d.toolbars_->toggleFullScreen(!isFullScreen());
+ message(bformat("LFUN_UI_TOGGLE " + _("%1$s unknown command!"), from_utf8(arg)));
+}
+
+void GuiView::toggleFullScreen()
+{
if (isFullScreen()) {
for (int i = 0; i != d.splitter_->count(); ++i)
d.tabWorkArea(i)->setFullScreen(false);
setContentsMargins(0, 0, 0, 0);
#endif
setWindowState(windowState() ^ Qt::WindowFullScreen);
+ restoreLayout();
menuBar()->show();
statusBar()->show();
} else {
+ // bug 5274
+ hideDialogs("prefs", 0);
for (int i = 0; i != d.splitter_->count(); ++i)
d.tabWorkArea(i)->setFullScreen(true);
#if QT_VERSION >= 0x040300
setContentsMargins(-2, -2, -2, -2);
#endif
+ saveLayout();
setWindowState(windowState() ^ Qt::WindowFullScreen);
statusBar()->hide();
menuBar()->hide();
+ if (lyxrc.full_screen_toolbars) {
+ ToolbarMap::iterator end = d.toolbars_.end();
+ for (ToolbarMap::iterator it = d.toolbars_.begin(); it != end; ++it)
+ it->second->hide();
+ }
}
+
+ // give dialogs like the TOC a chance to adapt
+ updateDialogs();
}
// Take this occasion to update the other GUI elements.
updateDialogs();
+ updateStatusBar();
}
// This list should be kept in sync with the list of insets in
// src/insets/Inset.cpp. I.e., if a dialog goes with an inset, the
// dialog should have the same name as the inset.
+// Changes should be also recorded in LFUN_DIALOG_SHOW doxygen
+// docs in LyXAction.cpp.
char const * const dialognames[] = {
"aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character",
"citation", "document", "errorlist", "ert", "external", "file",
-"findreplace", "float", "graphics", "include", "index", "nomenclature", "label", "log",
+"findreplace", "float", "graphics", "include", "index", "info", "nomenclature", "label", "log",
"mathdelimiter", "mathmatrix", "note", "paragraph", "prefs", "print",
"ref", "sendto", "space", "spellchecker", "symbols", "tabular", "tabularcreate",
"thesaurus",
#endif
-"texinfo", "toc", "href", "view-source", "vspace", "wrap", "listings" };
+"texinfo", "toc", "href", "view-source", "vspace", "wrap", "listings", "findreplaceadv" };
char const * const * const end_dialognames =
dialognames + (sizeof(dialognames) / sizeof(char *));
{
// Make sure that no LFUN uses any LyXView.
theLyXFunc().setLyXView(0);
- // FIXME: the "math panels" toolbar takes an awful lot of time to
- // initialise so we don't do that for the time being.
- //d.toolbars_->init();
- guiApp->menus().fillMenuBar(menuBar(), this);
+ saveLayout();
+ menuBar()->clear();
+ constructToolbars();
+ guiApp->menus().fillMenuBar(menuBar(), this, false);
if (d.layout_)
d.layout_->updateContents(true);
// Now update controls with current buffer.
theLyXFunc().setLyXView(this);
+ restoreLayout();
restartCursor();
}
-Dialog * GuiView::find_or_build(string const & name)
+Dialog * GuiView::findOrBuild(string const & name, bool hide_it)
{
if (!isValidName(name))
return 0;
map<string, DialogPtr>::iterator it = d.dialogs_.find(name);
- if (it != d.dialogs_.end())
+ if (it != d.dialogs_.end()) {
+ if (hide_it)
+ it->second->hideView();
return it->second.get();
+ }
Dialog * dialog = build(name);
d.dialogs_[name].reset(dialog);
if (lyxrc.allow_geometry_session)
dialog->restoreSession();
+ if (hide_it)
+ dialog->hideView();
return dialog;
}
return;
d.in_show_ = true;
- Dialog * dialog = find_or_build(name);
- if (dialog) {
- dialog->showData(data);
- if (inset)
- d.open_insets_[name] = inset;
+ try {
+ Dialog * dialog = findOrBuild(name, false);
+ if (dialog) {
+ dialog->showData(data);
+ if (inset)
+ d.open_insets_[name] = inset;
+ }
+ }
+ catch (ExceptionMessage const & ex) {
+ d.in_show_ = false;
+ throw ex;
}
d.in_show_ = false;
}
}
updateToolbars();
updateLayoutList();
- updateStatusBar();
}
Dialog * createGuiGraphics(GuiView & lv);
Dialog * createGuiHSpace(GuiView & lv);
Dialog * createGuiInclude(GuiView & lv);
+Dialog * createGuiInfo(GuiView & lv);
Dialog * createGuiLabel(GuiView & lv);
Dialog * createGuiListings(GuiView & lv);
Dialog * createGuiLog(GuiView & lv);
Dialog * createGuiPrint(GuiView & lv);
Dialog * createGuiRef(GuiView & lv);
Dialog * createGuiSearch(GuiView & lv);
+Dialog * createGuiSearchAdv(GuiView & lv);
Dialog * createGuiSendTo(GuiView & lv);
Dialog * createGuiShowFile(GuiView & lv);
Dialog * createGuiSpellchecker(GuiView & lv);
Dialog * GuiView::build(string const & name)
{
- LASSERT(isValidName(name), /**/);
+ LASSERT(isValidName(name), return 0);
if (name == "aboutlyx")
return createGuiAbout(*this);
return createGuiShowFile(*this);
if (name == "findreplace")
return createGuiSearch(*this);
+ if (name == "findreplaceadv")
+ return createGuiSearchAdv(*this);
if (name == "float")
return createGuiFloat(*this);
if (name == "graphics")
return createGuiGraphics(*this);
if (name == "include")
return createGuiInclude(*this);
+ if (name == "info")
+ return createGuiInfo(*this);
if (name == "nomenclature")
return createGuiNomenclature(*this);
if (name == "label")
} // namespace frontend
} // namespace lyx
-#include "GuiView_moc.cpp"
+#include "moc_GuiView.cpp"