Fix bug #740: Wish for added menu item: File->Close all.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@30882 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Vincent van Ravesteijn 2009-08-06 23:17:16 +00:00
parent 50f884bd44
commit 97efae2561
7 changed files with 101 additions and 76 deletions

View File

@ -46,6 +46,7 @@ Menuset
Submenu "Open Recent|t" "file_lastfiles" Submenu "Open Recent|t" "file_lastfiles"
Separator Separator
Item "Close|C" "buffer-close" Item "Close|C" "buffer-close"
Item "Close All" "buffer-close-all"
Item "Save|S" "buffer-write" Item "Save|S" "buffer-write"
Item "Save As...|A" "buffer-write-as" Item "Save As...|A" "buffer-write-as"
Item "Save All|l" "buffer-write-all" Item "Save All|l" "buffer-write-all"

View File

@ -439,6 +439,7 @@ enum FuncCode
LFUN_BRANCH_ADD_INSERT, LFUN_BRANCH_ADD_INSERT,
// 340 // 340
LFUN_BRANCHES_RENAME, // spitz 20090709 LFUN_BRANCHES_RENAME, // spitz 20090709
LFUN_BUFFER_CLOSE_ALL, // vfr 20090806
LFUN_LASTACTION // end of the table LFUN_LASTACTION // end of the table
}; };

View File

@ -2837,6 +2837,15 @@ void LyXAction::init()
* \endvar * \endvar
*/ */
{ LFUN_BUFFER_CLOSE, "buffer-close", ReadOnly, Buffer }, { LFUN_BUFFER_CLOSE, "buffer-close", ReadOnly, Buffer },
/*!
* \var lyx::FuncCode lyx::LFUN_BUFFER_CLOSE_ALL
* \li Action: Closes all buffers.
* \li Notion: Closes all buffers, asking whether to save it, etc,
if a buffer has been modified.
* \li Syntax: buffer-close_all
* \endvar
*/
{ LFUN_BUFFER_CLOSE_ALL, "buffer-close-all", ReadOnly, Buffer },
/*! /*!
* \var lyx::FuncCode lyx::LFUN_BUFFER_EXPORT * \var lyx::FuncCode lyx::LFUN_BUFFER_EXPORT
* \li Action: Exports the current buffer (document) to the given format. * \li Action: Exports the current buffer (document) to the given format.

View File

@ -633,6 +633,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const
case LFUN_CANCEL: case LFUN_CANCEL:
case LFUN_META_PREFIX: case LFUN_META_PREFIX:
case LFUN_BUFFER_CLOSE: case LFUN_BUFFER_CLOSE:
case LFUN_BUFFER_CLOSE_ALL:
case LFUN_BUFFER_IMPORT: case LFUN_BUFFER_IMPORT:
case LFUN_BUFFER_AUTO_SAVE: case LFUN_BUFFER_AUTO_SAVE:
case LFUN_RECONFIGURE: case LFUN_RECONFIGURE:
@ -879,6 +880,12 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
updateFlags = Update::None; updateFlags = Update::None;
break; break;
case LFUN_BUFFER_CLOSE_ALL:
lyx_view_->closeBufferAll();
buffer = 0;
updateFlags = Update::None;
break;
case LFUN_BUFFER_RELOAD: { case LFUN_BUFFER_RELOAD: {
LASSERT(lyx_view_ && buffer, /**/); LASSERT(lyx_view_ && buffer, /**/);
docstring const file = makeDisplayPath(buffer->absFileName(), 20); docstring const file = makeDisplayPath(buffer->absFileName(), 20);

View File

@ -67,6 +67,8 @@ public:
/// ///
virtual bool closeBuffer() = 0; virtual bool closeBuffer() = 0;
/// ///
virtual bool closeBufferAll(bool tolastopened = false) = 0;
///
virtual bool hasFocus() const = 0; virtual bool hasFocus() const = 0;
/// load a document into the current workarea. /// load a document into the current workarea.

View File

@ -536,83 +536,12 @@ void GuiView::closeEvent(QCloseEvent * close_event)
// it can happen that this event arrives without selecting the view, // it can happen that this event arrives without selecting the view,
// e.g. when clicking the close button on a background window. // e.g. when clicking the close button on a background window.
setFocus(); setFocus();
GuiWorkArea * active_wa = currentMainWorkArea(); if (!closeBufferAll(true)) {
setCurrentWorkArea(active_wa); closing_ = false;
close_event->ignore();
// We might be in a situation that there is still a tabWorkArea, but return;
// there are no tabs anymore. This can happen when we get here after a
// TabWorkArea::lastWorkAreaRemoved() signal. Therefore we count how
// many TabWorkArea's have no documents anymore.
int empty_twa = 0;
// We have to call count() each time, because it can happen that
// more than one splitter will disappear in one iteration (bug 5998).
for (; d.splitter_->count() > empty_twa; ) {
TabWorkArea * twa = d.tabWorkArea(empty_twa);
int twa_count = twa->count();
if (twa->count() == 0)
++empty_twa;
for (; 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()) {
// 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;
}
continue;
}
vector<Buffer *> clist = b->getChildren();
for (vector<Buffer *>::const_iterator it = clist.begin();
it != clist.end(); ++it) {
if ((*it)->isClean())
continue;
Buffer * c = *it;
// If a child is dirty, do not close
// without user intervention
if (!closeBuffer(*c, false)) {
closing_ = false;
close_event->ignore();
return;
}
}
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;
}
}
// 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;
}
}
} }
// Make sure that nothing will use this close to be closed View. // Make sure that nothing will use this close to be closed View.
guiApp->unregisterView(this); guiApp->unregisterView(this);
@ -644,6 +573,80 @@ void GuiView::closeEvent(QCloseEvent * close_event)
} }
bool GuiView::closeBufferAll(bool tolastopened)
{
GuiWorkArea * active_wa = currentMainWorkArea();
setCurrentWorkArea(active_wa);
// We might be in a situation that there is still a tabWorkArea, but
// there are no tabs anymore. This can happen when we get here after a
// TabWorkArea::lastWorkAreaRemoved() signal. Therefore we count how
// many TabWorkArea's have no documents anymore.
int empty_twa = 0;
// We have to call count() each time, because it can happen that
// more than one splitter will disappear in one iteration (bug 5998).
for (; d.splitter_->count() > empty_twa; ) {
TabWorkArea * twa = d.tabWorkArea(empty_twa);
int twa_count = twa->count();
if (twa->count() == 0)
++empty_twa;
for (; 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()) {
// This is a child document, just close the tab
// after saving but keep the file loaded.
if (!closeBuffer(*b, tolastopened, is_active_wa))
return false;
continue;
}
vector<Buffer *> clist = b->getChildren();
for (vector<Buffer *>::const_iterator it = clist.begin();
it != clist.end(); ++it) {
if ((*it)->isClean())
continue;
Buffer * c = *it;
// If a child is dirty, do not close
// without user intervention
if (!closeBuffer(*c, 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;
}
}
// closeBuffer() needs buffer workArea still alive and
// set as currrent one, and destroys it
if (b && !closeBuffer(*b, tolastopened, is_active_wa))
return false;
}
}
return true;
}
void GuiView::dragEnterEvent(QDragEnterEvent * event) void GuiView::dragEnterEvent(QDragEnterEvent * event)
{ {
if (event->mimeData()->hasUrls()) if (event->mimeData()->hasUrls())

View File

@ -297,6 +297,8 @@ private:
bool closeBuffer(Buffer & buf, bool tolastopened = false, bool closeBuffer(Buffer & buf, bool tolastopened = false,
bool mark_active = false); bool mark_active = false);
/// ///
bool closeBufferAll(bool tolastopened = false);
///
enum NextOrPrevious { enum NextOrPrevious {
NEXTBUFFER, NEXTBUFFER,
PREVBUFFER PREVBUFFER