X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiView.cpp;h=63bd54ec63c476087b971512b96e55f65fe1eb06;hb=d2a96bcdc369b52ae6fb52c5a612bcd9f665231b;hp=c1e05864bcb0a6a330e74cbf63f785e0d73fc9b1;hpb=83661da26ae18082cce96789933b4e5fc1c56ddb;p=lyx.git diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index c1e05864bc..63bd54ec63 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -18,11 +18,13 @@ #include "Dialog.h" #include "FileDialog.h" #include "GuiApplication.h" +#include "GuiCompleter.h" #include "GuiWorkArea.h" #include "GuiKeySymbol.h" #include "GuiToolbar.h" #include "GuiToolbars.h" #include "Menus.h" +#include "TocModel.h" #include "qt_helpers.h" @@ -35,11 +37,11 @@ #include "BufferView.h" #include "Converter.h" #include "Cursor.h" +#include "Encoding.h" #include "ErrorList.h" #include "Format.h" #include "FuncStatus.h" #include "FuncRequest.h" -#include "support/gettext.h" #include "Intl.h" #include "Layout.h" #include "Lexer.h" @@ -53,10 +55,11 @@ #include "ToolbarBackend.h" #include "version.h" +#include "support/lassert.h" #include "support/debug.h" -#include "support/FileFilterList.h" #include "support/FileName.h" #include "support/filetools.h" +#include "support/gettext.h" #include "support/ForkedCalls.h" #include "support/lstrings.h" #include "support/os.h" @@ -87,7 +90,6 @@ #include #include -#include #include #ifdef HAVE_SYS_TIME_H @@ -112,18 +114,19 @@ public: { LYXERR(Debug::GUI, "show banner: " << lyxrc.show_banner); /// The text to be written on top of the pixmap - QString const text = lyx_version ? lyx_version : qt_("unknown version"); + QString const text = lyx_version ? + qt_("version ") + lyx_version : qt_("unknown version"); splash_ = QPixmap(":/images/banner.png"); QPainter pain(&splash_); - pain.setPen(QColor(255, 255, 0)); + pain.setPen(QColor(0, 0, 0)); QFont font; // The font used to display the version info font.setStyleHint(QFont::SansSerif); font.setWeight(QFont::Bold); font.setPointSize(int(toqstr(lyxrc.font_sizes[FONT_SIZE_LARGE]).toDouble())); pain.setFont(font); - pain.drawText(260, 270, text); + pain.drawText(190, 225, text); } void paintEvent(QPaintEvent *) @@ -268,6 +271,9 @@ public: Timeout autosave_timeout_; /// flag against a race condition due to multiclicks, see bug #1119 bool in_show_; + + /// + TocModels toc_models_; }; @@ -277,8 +283,13 @@ GuiView::GuiView(int id) // GuiToolbars *must* be initialised before the menu bar. d.toolbars_ = new GuiToolbars(*this); + // 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 + // they are greyed out. + theLyXFunc().setLyXView(this); + // Fill up the menu bar. - guiApp->menus().fillMenuBar(menuBar(), this); + guiApp->menus().fillMenuBar(menuBar(), this, true); setCentralWidget(d.stack_widget_); @@ -294,8 +305,8 @@ GuiView::GuiView(int id) // We don't want to keep the window in memory if it is closed. setAttribute(Qt::WA_DeleteOnClose, true); -#ifndef Q_WS_MACX - // assign an icon to main form. We do not do it under Qt/Mac, +#if (!defined(Q_WS_WIN) && !defined(Q_WS_MACX)) + // assign an icon to main form. We do not do it under Qt/Win or Qt/Mac, // since the icon is provided in the application bundle. setWindowIcon(QPixmap(":/images/lyx.png")); #endif @@ -331,10 +342,20 @@ GuiView::GuiView(int id) GuiView::~GuiView() { + if (guiApp->currentView() == this) + guiApp->setCurrentView(0); + theLyXFunc().setLyXView(0); + delete &d; } +TocModels & GuiView::tocModels() +{ + return d.toc_models_; +} + + void GuiView::setFocus() { if (d.current_work_area_) @@ -382,8 +403,8 @@ void GuiView::closeEvent(QCloseEvent * close_event) continue; } - std::vector const & ids = guiApp->viewIds(); - for (size_type i = 0; i != ids.size(); ++i) { + QVector const ids = guiApp->viewIds(); + for (int i = 0; i != ids.size(); ++i) { if (id_ == ids[i]) continue; if (guiApp->view(ids[i]).workArea(*b)) { @@ -400,7 +421,7 @@ void GuiView::closeEvent(QCloseEvent * close_event) break; } } - if (b && !closeBuffer(*b)) { + if (b && !closeBuffer(*b, true)) { close_event->ignore(); return; } @@ -412,7 +433,7 @@ void GuiView::closeEvent(QCloseEvent * close_event) // Save toolbars configuration if (isFullScreen()) { d.toolbars_->toggleFullScreen(!isFullScreen()); - updateToolbars(); + updateDialogs(); } // Make sure the timer time out will not trigger a statusbar update. @@ -527,29 +548,34 @@ void GuiView::on_currentWorkAreaChanged(GuiWorkArea * wa) this, SLOT(updateWindowTitle(GuiWorkArea *))); updateWindowTitle(wa); - updateToc(); - // Buffer-dependent dialogs should be updated or - // hidden. This should go here because some dialogs (eg ToC) - // require bv_->text. - updateBufferDependent(true); - updateToolbars(); - updateLayoutList(); - updateStatusBar(); + structureChanged(); + + // The document settings needs to be reinitialised. + updateDialog("document", ""); + + // Buffer-dependent dialogs must be updated. This is done here because + // some dialogs require buffer()->text. + updateDialogs(); } void GuiView::on_lastWorkAreaRemoved() { -#ifdef Q_WS_MAC +#ifdef Q_WS_MACX // On Mac close the view if there is no Tab open anymore, // but only if no splitter is visible - if (d.splitter_->count() == 1) { + if (!lyxrc.open_buffers_in_tabs && d.splitter_->count() == 1) { TabWorkArea * twa = qobject_cast(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. + updateDialog("document", ""); + updateDialogs(); #endif } @@ -595,17 +621,17 @@ bool GuiView::event(QEvent * e) setFocus(); return QMainWindow::event(e); } - guiApp->setCurrentView(*this); + guiApp->setCurrentView(this); if (d.current_work_area_) { BufferView & bv = d.current_work_area_->bufferView(); connectBufferView(bv); connectBuffer(bv.buffer()); // The document structure, name and dialogs might have // changed in another view. - updateBufferDependent(true); - updateToolbars(); - updateLayoutList(); - updateStatusBar(); + structureChanged(); + // The document settings needs to be reinitialised. + updateDialog("document", ""); + updateDialogs(); } else { setWindowTitle(qt_("LyX")); setWindowIconText(qt_("LyX")); @@ -615,12 +641,23 @@ bool GuiView::event(QEvent * e) } case QEvent::ShortcutOverride: { + + if (isFullScreen() && menuBar()->isHidden()) { + QKeyEvent * ke = static_cast(e); + // FIXME: we should also try to detect special LyX shortcut such as + // 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); + } + if (d.current_work_area_) // Nothing special to do. return QMainWindow::event(e); QKeyEvent * ke = static_cast(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 @@ -753,12 +790,7 @@ GuiWorkArea const * GuiView::currentWorkArea() const void GuiView::setCurrentWorkArea(GuiWorkArea * wa) { - BOOST_ASSERT(wa); - - // Changing work area can result from opening a file so - // update the toc in any case. - updateToc(); - + LASSERT(wa, /**/); d.current_work_area_ = wa; for (int i = 0; i != d.splitter_->count(); ++i) { if (d.tabWorkArea(i)->setCurrentWorkArea(wa)) @@ -769,11 +801,10 @@ void GuiView::setCurrentWorkArea(GuiWorkArea * wa) void GuiView::removeWorkArea(GuiWorkArea * wa) { - BOOST_ASSERT(wa); + LASSERT(wa, /**/); if (wa == d.current_work_area_) { disconnectBuffer(); disconnectBufferView(); - hideBufferDependent(); d.current_work_area_ = 0; } @@ -834,9 +865,6 @@ void GuiView::updateToolbars() d.toolbars_->update(math, table, review, mathmacrotemplate); } else d.toolbars_->update(false, false, false, false); - - // update read-only status of open dialogs. - checkStatus(); } @@ -858,7 +886,7 @@ Buffer const * GuiView::buffer() const void GuiView::setBuffer(Buffer * newBuffer) { - BOOST_ASSERT(newBuffer); + LASSERT(newBuffer, /**/); setBusy(true); GuiWorkArea * wa = workArea(*newBuffer); @@ -911,6 +939,15 @@ void GuiView::errors(string const & error_type) } +void GuiView::structureChanged() +{ + d.toc_models_.reset(view()); + // Navigator needs more than a simple update in this case. It needs to be + // rebuilt. + updateDialog("toc", ""); +} + + void GuiView::updateDialog(string const & name, string const & data) { if (!isDialogVisible(name)) @@ -922,7 +959,7 @@ void GuiView::updateDialog(string const & name, string const & data) Dialog * const dialog = it->second.get(); if (dialog->isVisibleView()) - dialog->updateData(data); + dialog->initialiseParams(data); } @@ -932,18 +969,6 @@ BufferView * GuiView::view() } -void GuiView::updateToc() -{ - updateDialog("toc", ""); -} - - -void GuiView::updateEmbeddedFiles() -{ - updateDialog("embedding", ""); -} - - void GuiView::autoSave() { LYXERR(Debug::INFO, "Running autoSave()"); @@ -960,9 +985,8 @@ void GuiView::resetAutosaveTimers() } -FuncStatus GuiView::getStatus(FuncRequest const & cmd) +bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) { - FuncStatus flag; bool enable = true; Buffer * buf = buffer(); @@ -998,6 +1022,10 @@ FuncStatus GuiView::getStatus(FuncRequest const & cmd) flag.setOnOff(d.toolbars_->visible(cmd.getArg(0))); break; + case LFUN_UI_TOGGLE: + flag.setOnOff(isFullScreen()); + break; + case LFUN_DIALOG_TOGGLE: flag.setOnOff(isDialogVisible(cmd.getArg(0))); // fall through to set "enable" @@ -1048,10 +1076,6 @@ FuncStatus GuiView::getStatus(FuncRequest const & cmd) } case LFUN_INSET_APPLY: { - if (!buf) { - enable = false; - break; - } string const name = cmd.getArg(0); Inset * inset = getOpenInset(name); if (inset) { @@ -1059,12 +1083,12 @@ FuncStatus GuiView::getStatus(FuncRequest const & cmd) FuncStatus fs; if (!inset->getStatus(view()->cursor(), fr, fs)) { // Every inset is supposed to handle this - BOOST_ASSERT(false); + LASSERT(false, /**/); } flag |= fs; } else { FuncRequest fr(LFUN_INSET_INSERT, cmd.argument()); - flag |= getStatus(fr); + flag |= lyx::getStatus(fr); } enable = flag.enabled(); break; @@ -1089,16 +1113,13 @@ FuncStatus GuiView::getStatus(FuncRequest const & cmd) break; default: - if (!view()) { - enable = false; - break; - } + return false; } if (!enable) flag.enabled(false); - return flag; + return true; } @@ -1108,9 +1129,8 @@ static FileName selectTemplateFile() dlg.setButton1(qt_("Documents|#o#O"), toqstr(lyxrc.document_path)); dlg.setButton1(qt_("Templates|#T#t"), toqstr(lyxrc.template_path)); - FileDialog::Result result = - dlg.open(toqstr(lyxrc.template_path), - FileFilterList(_("LyX Documents (*.lyx)"))); + FileDialog::Result result = dlg.open(toqstr(lyxrc.template_path), + QStringList(qt_("LyX Documents (*.lyx)"))); if (result.first == FileDialog::Later) return FileName(); @@ -1169,7 +1189,7 @@ void GuiView::openDocument(string const & fname) toqstr(addPath(package().system_support().absFilename(), "examples"))); FileDialog::Result result = - dlg.open(toqstr(initpath), FileFilterList(_("LyX Documents (*.lyx)"))); + dlg.open(toqstr(initpath), QStringList(qt_("LyX Documents (*.lyx)"))); if (result.first == FileDialog::Later) return; @@ -1308,7 +1328,7 @@ void GuiView::importDocument(string const & argument) filter += ')'; FileDialog::Result result = - dlg.open(toqstr(initpath), FileFilterList(filter)); + dlg.open(toqstr(initpath), fileFilters(toqstr(filter))); if (result.first == FileDialog::Later) return; @@ -1324,7 +1344,7 @@ void GuiView::importDocument(string const & argument) return; // get absolute path of file - FileName const fullname(makeAbsPath(filename)); + FileName const fullname(support::makeAbsPath(filename)); FileName const lyxfile(support::changeExtension(fullname.absFilename(), ".lyx")); @@ -1421,9 +1441,8 @@ void GuiView::insertLyXFile(docstring const & fname) toqstr(addPath(package().system_support().absFilename(), "examples"))); - FileDialog::Result result = - dlg.open(toqstr(initpath), - FileFilterList(_("LyX Documents (*.lyx)"))); + FileDialog::Result result = dlg.open(toqstr(initpath), + QStringList(qt_("LyX Documents (*.lyx)"))); if (result.first == FileDialog::Later) return; @@ -1461,7 +1480,7 @@ void GuiView::insertPlaintextFile(docstring const & fname, LFUN_FILE_INSERT_PLAINTEXT_PARA : LFUN_FILE_INSERT_PLAINTEXT)); FileDialog::Result result = dlg.open(toqstr(bv->buffer().filePath()), - FileFilterList()); + QStringList()); if (result.first == FileDialog::Later) return; @@ -1487,7 +1506,7 @@ bool GuiView::renameBuffer(Buffer & b, docstring const & newname) if (!newname.empty()) { // FIXME UNICODE - fname = makeAbsPath(to_utf8(newname), oldname.onlyPath().absFilename()); + fname = support::makeAbsPath(to_utf8(newname), oldname.onlyPath().absFilename()); } else { // Switch to this Buffer. setBuffer(&b); @@ -1502,11 +1521,9 @@ bool GuiView::renameBuffer(Buffer & b, docstring const & newname) if (!isLyXFilename(fname.absFilename())) fname.changeExtension(".lyx"); - FileFilterList const filter(_("LyX Documents (*.lyx)")); - FileDialog::Result result = dlg.save(toqstr(fname.onlyPath().absFilename()), - filter, + QStringList(qt_("LyX Documents (*.lyx)")), toqstr(fname.onlyFileName())); if (result.first == FileDialog::Later) @@ -1596,7 +1613,7 @@ bool GuiView::closeBuffer() } -bool GuiView::closeBuffer(Buffer & buf) +bool GuiView::closeBuffer(Buffer & buf, bool tolastopened) { // goto bookmark to update bookmark pit. //FIXME: we should update only the bookmarks related to this buffer! @@ -1604,7 +1621,7 @@ bool GuiView::closeBuffer(Buffer & buf) theLyXFunc().gotoBookmark(i+1, false, false); if (buf.isClean() || buf.paragraphs().empty()) { - if (buf.masterBuffer() == &buf) + if (buf.masterBuffer() == &buf && tolastopened) LyX::ref().session().lastOpened().add(buf.fileName()); theBufferList().release(&buf); return true; @@ -1646,7 +1663,7 @@ bool GuiView::closeBuffer(Buffer & buf) // save file names to .lyx/session // 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) + if (buf.masterBuffer() == &buf && tolastopened) LyX::ref().session().lastOpened().add(buf.fileName()); theBufferList().release(&buf); @@ -1656,10 +1673,11 @@ bool GuiView::closeBuffer(Buffer & buf) bool GuiView::dispatch(FuncRequest const & cmd) { - BufferView * bv = view(); + BufferView * bv = view(); // By default we won't need any update. if (bv) bv->cursor().updateFlags(Update::None); + bool dispatched = true; switch(cmd.action) { case LFUN_BUFFER_IMPORT: @@ -1722,10 +1740,10 @@ bool GuiView::dispatch(FuncRequest const & cmd) // We cannot use a for loop as the buffer list cycles. Buffer * b = first; do { - if (b->isClean()) - continue; - saveBuffer(*b); - LYXERR(Debug::ACTION, "Saved " << b->absFileName()); + if (!b->isClean()) { + saveBuffer(*b); + LYXERR(Debug::ACTION, "Saved " << b->absFileName()); + } b = theBufferList().next(b); } while (b != first); message(_("All documents saved.")); @@ -1830,6 +1848,7 @@ bool GuiView::dispatch(FuncRequest const & cmd) } case LFUN_INSET_APPLY: { + view()->cursor().recordUndoFullDocument(); string const name = cmd.getArg(0); Inset * inset = getOpenInset(name); if (inset) { @@ -1888,10 +1907,18 @@ bool GuiView::dispatch(FuncRequest const & cmd) break; default: - return false; + dispatched = false; + break; } - return true; + if (isFullScreen()) { + if (menuBar()->isVisible()) + menuBar()->hide(); + if (statusBar()->isVisible()) + statusBar()->hide(); + } + + return dispatched; } @@ -1933,7 +1960,7 @@ void GuiView::lfunUiToggle(FuncRequest const & cmd) } #endif if (arg != "fullscreen") { - message(bformat(_("LFUN_UI_TOGGLE %1$s unknown command!"), from_utf8(arg))); + message(bformat("LFUN_UI_TOGGLE " + _("%1$s unknown command!"), from_utf8(arg))); return; } @@ -1946,7 +1973,7 @@ void GuiView::lfunUiToggle(FuncRequest const & cmd) #if QT_VERSION >= 0x040300 setContentsMargins(0, 0, 0, 0); #endif - showNormal(); + setWindowState(windowState() ^ Qt::WindowFullScreen); menuBar()->show(); statusBar()->show(); } else { @@ -1955,7 +1982,7 @@ void GuiView::lfunUiToggle(FuncRequest const & cmd) #if QT_VERSION >= 0x040300 setContentsMargins(-2, -2, -2, -2); #endif - showFullScreen(); + setWindowState(windowState() ^ Qt::WindowFullScreen); statusBar()->hide(); menuBar()->hide(); } @@ -1983,9 +2010,7 @@ void GuiView::restartCursor() d.current_work_area_->startBlinkingCursor(); // Take this occasion to update the other GUI elements. - updateLayoutList(); - updateToolbars(); - updateStatusBar(); + updateDialogs(); } @@ -2003,10 +2028,10 @@ namespace { char const * const dialognames[] = { "aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character", -"citation", "document", "embedding", "errorlist", "ert", "external", "file", +"citation", "document", "errorlist", "ert", "external", "file", "findreplace", "float", "graphics", "include", "index", "nomenclature", "label", "log", "mathdelimiter", "mathmatrix", "note", "paragraph", "prefs", "print", -"ref", "sendto", "spellchecker", "symbols", "tabular", "tabularcreate", +"ref", "sendto", "space", "spellchecker", "symbols", "tabular", "tabularcreate", #ifdef HAVE_LIBAIKSAURUS "thesaurus", @@ -2143,57 +2168,22 @@ void GuiView::hideAll() const } -void GuiView::hideBufferDependent() const +void GuiView::updateDialogs() { map::const_iterator it = d.dialogs_.begin(); map::const_iterator end = d.dialogs_.end(); for(; it != end; ++it) { Dialog * dialog = it->second.get(); - if (dialog->isBufferDependent()) - dialog->hideView(); - } -} - - -void GuiView::updateBufferDependent(bool switched) const -{ - map::const_iterator it = d.dialogs_.begin(); - map::const_iterator end = d.dialogs_.end(); - - for(; it != end; ++it) { - Dialog * dialog = it->second.get(); - if (!dialog->isVisibleView()) - continue; - if (switched && dialog->isBufferDependent()) { - if (dialog->initialiseParams("")) - dialog->updateView(); - else - dialog->hideView(); - } else { - // A bit clunky, but the dialog will request - // that the kernel provides it with the necessary - // data. - dialog->updateDialog(); - } - } -} - - -void GuiView::checkStatus() -{ - map::const_iterator it = d.dialogs_.begin(); - map::const_iterator end = d.dialogs_.end(); - - for(; it != end; ++it) { - Dialog * const dialog = it->second.get(); if (dialog && dialog->isVisibleView()) dialog->checkStatus(); } + updateToolbars(); + updateLayoutList(); + updateStatusBar(); } - // will be replaced by a proper factory... Dialog * createGuiAbout(GuiView & lv); Dialog * createGuiBibitem(GuiView & lv); @@ -2210,6 +2200,7 @@ Dialog * createGuiERT(GuiView & lv); Dialog * createGuiExternal(GuiView & lv); Dialog * createGuiFloat(GuiView & lv); Dialog * createGuiGraphics(GuiView & lv); +Dialog * createGuiHSpace(GuiView & lv); Dialog * createGuiInclude(GuiView & lv); Dialog * createGuiLabel(GuiView & lv); Dialog * createGuiListings(GuiView & lv); @@ -2239,7 +2230,7 @@ Dialog * createGuiWrap(GuiView & lv); Dialog * GuiView::build(string const & name) { - BOOST_ASSERT(isValidName(name)); + LASSERT(isValidName(name), /**/); if (name == "aboutlyx") return createGuiAbout(*this); @@ -2299,6 +2290,8 @@ Dialog * GuiView::build(string const & name) return createGuiRef(*this); if (name == "sendto") return createGuiSendTo(*this); + if (name == "space") + return createGuiHSpace(*this); if (name == "spellchecker") return createGuiSpellchecker(*this); if (name == "symbols")