#include "GuiKeySymbol.h"
#include "GuiToc.h"
#include "GuiToolbar.h"
+#include "LayoutBox.h"
#include "Menus.h"
#include "TocModel.h"
#include "BufferView.h"
#include "Converter.h"
#include "Cursor.h"
+#include "CutAndPaste.h"
#include "Encoding.h"
#include "ErrorList.h"
#include "Format.h"
* FIXME: replace that with a proper model so that we are not limited
* to only one dialog.
*/
- GuiLayoutBox * layout_;
+ LayoutBox * layout_;
///
map<string, Inset *> open_insets_;
resize(size);
move(pos);
#else
- if (!restoreGeometry(settings.value("geometry").toByteArray()))
- setGeometry(50, 50, 690, 510);
+ // Work-around for bug #6034: the window ends up in an undetermined
+ // state when trying to restore a maximized window when it is
+ // already maximized.
+ if (!(windowState() & Qt::WindowMaximized))
+ if (!restoreGeometry(settings.value("geometry").toByteArray()))
+ setGeometry(50, 50, 690, 510);
#endif
// Make sure layout is correctly oriented.
setLayoutDirection(qApp->layoutDirection());
for (; it != d.toolbars_.end(); ++it)
delete it->second;
d.toolbars_.clear();
- d.layout_ = 0;
+
+ // I don't like doing this here, but the standard toolbar
+ // destroys this object when it's destroyed itself (vfr)
+ d.layout_ = new LayoutBox(*this);
+ d.stack_widget_->addWidget(d.layout_);
+ d.layout_->move(0,0);
// extracts the toolbars from the backend
Toolbars::Infos::iterator cit = guiApp->toolbars().begin();
// it can happen that this event arrives without selecting the view,
// e.g. when clicking the close button on a background window.
setFocus();
+ if (!closeBufferAll(true)) {
+ closing_ = false;
+ close_event->ignore();
+ return;
+ }
+
+ // Make sure that nothing will use this to be closed View.
+ guiApp->unregisterView(this);
+
+ if (isFullScreen()) {
+ // Switch off fullscreen before closing.
+ toggleFullScreen();
+ updateDialogs();
+ }
+
+ // Make sure the timer time out will not trigger a statusbar update.
+ d.statusbar_timer_.stop();
+
+ // Saving fullscreen requires additional tweaks in the toolbar code.
+ // It wouldn't also work under linux natively.
+ 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();
+ }
+
+ close_event->accept();
+}
+
+
+bool GuiView::closeBufferAll(bool tolastopened)
+{
GuiWorkArea * active_wa = currentMainWorkArea();
setCurrentWorkArea(active_wa);
if (twa->count() == 0)
++empty_twa;
- for (; twa_count; --twa_count) {
+ for (; twa == d.tabWorkArea(empty_twa) && twa_count; --twa_count) {
twa->setCurrentIndex(twa_count-1);
GuiWorkArea * wa = twa->currentWorkArea();
bool const is_active_wa = active_wa == wa;
- Buffer * b = &wa->bufferView().buffer();
- if (b->parent()) {
+ 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 (!closeBuffer(*b, true, is_active_wa)) {
- closing_ = false;
- close_event->ignore();
- return;
- }
+ if (!closeWorkArea(wa, false, tolastopened, is_active_wa))
+ return false;
continue;
}
- vector<Buffer *> clist = b->getChildren();
+ vector<Buffer *> clist = b.getChildren();
for (vector<Buffer *>::const_iterator it = clist.begin();
it != clist.end(); ++it) {
if ((*it)->isClean())
Buffer * c = *it;
// If a child is dirty, do not close
// without user intervention
- if (!closeBuffer(*c, false)) {
- closing_ = false;
- close_event->ignore();
- return;
- }
+ //FIXME: should buffers be closed or not?
+ if (!closeWorkArea(workArea(*c), false, false))
+ return false;
}
- 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)) {
- // FIXME 1: should we put an alert box here
- // that the buffer is viewed elsewhere?
- // FIXME 2: should we try to save this buffer in any case?
- //saveBuffer(b);
-
- // This buffer is also opened in another view, so
- // close the associated work area...
- removeWorkArea(wa);
- // ... but don't close the buffer.
- b = 0;
- break;
- }
- }
+ // We only want to close the buffer if the same buffer is not in
+ // another view.
+ bool const close_buffer = !inMultiViews(wa);
+
// closeBuffer() needs buffer workArea still alive and
// set as currrent one, and destroys it
- if (b && !closeBuffer(*b, true, is_active_wa)) {
- closing_ = false;
- close_event->ignore();
- return;
- }
+ if (!closeWorkArea(wa, close_buffer, tolastopened, is_active_wa))
+ return false;
}
}
- // Make sure that nothing will use this close to be closed View.
- guiApp->unregisterView(this);
-
- if (isFullScreen()) {
- // Switch off fullscreen before closing.
- toggleFullScreen();
- updateDialogs();
- }
-
- // Make sure the timer time out will not trigger a statusbar update.
- d.statusbar_timer_.stop();
-
- // Saving fullscreen requires additional tweaks in the toolbar code.
- // It wouldn't also work under linux natively.
- 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();
- }
-
- close_event->accept();
+ return true;
}
if (old_gwa == wa)
return;
+ if (view())
+ cap::saveSelection(view()->cursor());
+
theGuiApp()->setCurrentView(this);
d.current_work_area_ = wa;
for (int i = 0; i != d.splitter_->count(); ++i) {
}
-void GuiView::setLayoutDialog(GuiLayoutBox * layout)
+LayoutBox * GuiView::getLayoutDialog() const
{
- d.layout_ = layout;
+ return d.layout_;
}
enable = buf;
break;
+ case LFUN_BUFFER_CLOSE_ALL: {
+ enable = false;
+ BufferList::iterator it = theBufferList().begin();
+ BufferList::iterator end = theBufferList().end();
+ int visible_buffers = 0;
+ for (; it != end; ++it) {
+ if (workArea(**it))
+ ++visible_buffers;
+ if (visible_buffers > 1) {
+ enable = true;
+ break;
+ }
+ }
+ break;
+ }
+
case LFUN_SPLIT_VIEW:
if (cmd.getArg(0) == "vertical")
enable = buf && (d.splitter_->count() == 1 ||
enable = buf->isExportable("dvi")
&& lyxrc.print_command != "none";
else if (name == "character" || name == "symbols") {
- if (!view() || !view()->cursor().inTexted())
+ if (buf->isReadonly() || !view() || !view()->cursor().inTexted())
enable = false;
else {
// FIXME we should consider passthru
}
+bool GuiView::hideWorkArea(GuiWorkArea * wa)
+{
+ return closeWorkArea(wa, false);
+}
+
+
bool GuiView::closeBuffer()
{
- Buffer * buf = buffer();
- return buf && closeBuffer(*buf);
+ GuiWorkArea * wa = currentMainWorkArea();
+ Buffer & buf = wa->bufferView().buffer();
+ return wa && closeWorkArea(wa, !buf.parent());
}
-bool GuiView::closeBuffer(Buffer & buf, bool tolastopened, bool mark_active)
+bool GuiView::closeWorkArea(GuiWorkArea * wa, bool close_buffer,
+ bool tolastopened, bool mark_active)
{
// goto bookmark to update bookmark pit.
//FIXME: we should update only the bookmarks related to this buffer!
for (size_t i = 0; i < theSession().bookmarks().size(); ++i)
theLyXFunc().gotoBookmark(i+1, false, false);
- if (buf.isClean() || buf.paragraphs().empty()) {
+ // if we are only hiding the buffer and there are multiple views
+ // of the buffer, then we do not need to ensure a clean buffer.
+ bool const allow_dirty = inMultiTabs(wa) && !close_buffer;
+
+ Buffer & buf = wa->bufferView().buffer();
+ if (allow_dirty || saveBufferIfNeeded(buf, !close_buffer)) {
// save in sessions if requested
// do not save childs if their master
// is opened as well
if (tolastopened)
theSession().lastOpened().add(buf.fileName(), mark_active);
- if (buf.parent())
- // Don't close child documents.
- removeWorkArea(currentMainWorkArea());
+ if (!close_buffer)
+ removeWorkArea(wa);
else
theBufferList().release(&buf);
return true;
}
+ return false;
+}
+
+
+bool GuiView::saveBufferIfNeeded(Buffer & buf, bool hiding)
+{
+ if (buf.isClean() || buf.paragraphs().empty())
+ return true;
+
// Switch to this Buffer.
setBuffer(&buf);
raise();
activateWindow();
- docstring const text = bformat(_("The document %1$s has unsaved changes."
- "\n\nDo you want to save the document or discard the changes?"), file);
- int const ret = Alert::prompt(_("Save changed document?"),
- text, 0, 2, _("&Save"), _("&Discard"), _("&Cancel"));
+ int ret;
+ if (hiding && buf.isUnnamed()) {
+ docstring const text = bformat(_("The document %1$s has not been "
+ "saved yet.\n\nDo you want to save "
+ "the document?"), file);
+ ret = Alert::prompt(_("Save new document?"),
+ text, 0, 1, _("&Save"), _("&Cancel"));
+ if (ret == 1)
+ ++ret;
+ } else {
+ docstring const text = bformat(_("The document %1$s has unsaved changes."
+ "\n\nDo you want to save the document or discard the changes?"), file);
+ ret = Alert::prompt(_("Save changed document?"),
+ text, 0, 2, _("&Save"), _("&Discard"), _("&Cancel"));
+ }
switch (ret) {
case 0:
// have no autosave file but I guess
// this is really improbable (Jug)
buf.removeAutosaveFile();
+ if (hiding) {
+ // revert all changes
+ buf.loadLyXFile(buf.fileName());
+ buf.markClean();
+ }
break;
case 2:
return false;
}
+ return true;
+}
- // save file names to .lyx/session
- if (tolastopened)
- theSession().lastOpened().add(buf.fileName(), mark_active);
- if (buf.parent())
- // Don't close child documents.
- removeWorkArea(currentMainWorkArea());
- else
- theBufferList().release(&buf);
+bool GuiView::inMultiTabs(GuiWorkArea * wa)
+{
+ Buffer & buf = wa->bufferView().buffer();
- return true;
+ for (int i = 0; i != d.splitter_->count(); ++i) {
+ GuiWorkArea * wa_ = d.tabWorkArea(i)->workArea(buf);
+ if (wa_ && wa_ != wa)
+ return true;
+ }
+ return inMultiViews(wa);
+}
+
+
+bool GuiView::inMultiViews(GuiWorkArea * wa)
+{
+ QList<int> const ids = guiApp->viewIds();
+ Buffer & buf = wa->bufferView().buffer();
+
+ int found_twa = 0;
+ for (int i = 0; i != ids.size() && found_twa <= 1; ++i) {
+ if (id_ == ids[i])
+ continue;
+
+ if (guiApp->view(ids[i]).workArea(buf))
+ return true;
+ }
+ return false;
}
break;
}
case LFUN_DROP_LAYOUTS_CHOICE:
- if (d.layout_)
- d.layout_->showPopup();
+ d.layout_->showPopup();
break;
case LFUN_MENU_OPEN:
case LFUN_CLOSE_TAB_GROUP:
if (TabWorkArea * twa = d.currentTabWorkArea()) {
delete twa;
+ d.current_work_area_ = 0;
twa = d.currentTabWorkArea();
// Switch to the next GuiWorkArea in the found TabWorkArea.
if (twa) {
menuBar()->clear();
constructToolbars();
guiApp->menus().fillMenuBar(menuBar(), this, false);
- if (d.layout_)
- d.layout_->updateContents(true);
+ d.layout_->updateContents(true);
// Now update controls with current buffer.
theLyXFunc().setLyXView(this);
restoreLayout();