From b6b56d85189966dd18223dcc30b3cef1ec6ed39a Mon Sep 17 00:00:00 2001 From: Guillaume Munch Date: Thu, 2 Mar 2017 00:41:02 +0100 Subject: [PATCH] Notification of external modification inspired by gedit --- src/frontends/qt4/GuiView.cpp | 8 +-- src/frontends/qt4/GuiWorkArea.cpp | 98 ++++++++++++++++++++++++--- src/frontends/qt4/GuiWorkArea.h | 29 ++++++++ src/frontends/qt4/Makefile.am | 1 + src/frontends/qt4/ui/WorkAreaUi.ui | 103 +++++++++++++++++++++++++++++ 5 files changed, 226 insertions(+), 13 deletions(-) create mode 100644 src/frontends/qt4/ui/WorkAreaUi.ui diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index e2e6555ca6..d990d795f1 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -1352,13 +1352,13 @@ double GuiView::pixelRatio() const return 1.0; #endif } - - + + GuiWorkArea * GuiView::workArea(int index) { if (TabWorkArea * twa = d.currentTabWorkArea()) if (index < twa->count()) - return dynamic_cast(twa->widget(index)); + return twa->workArea(index); return 0; } @@ -2767,7 +2767,7 @@ void GuiView::writeSession() const { for (int i = 0; i < d.splitter_->count(); ++i) { TabWorkArea * twa = d.tabWorkArea(i); for (int j = 0; j < twa->count(); ++j) { - GuiWorkArea * wa = static_cast(twa->widget(j)); + GuiWorkArea * wa = twa->workArea(j); Buffer & buf = wa->bufferView().buffer(); theSession().lastOpened().add(buf.fileName(), wa == active_wa); } diff --git a/src/frontends/qt4/GuiWorkArea.cpp b/src/frontends/qt4/GuiWorkArea.cpp index 050eae761f..dc6ee3274a 100644 --- a/src/frontends/qt4/GuiWorkArea.cpp +++ b/src/frontends/qt4/GuiWorkArea.cpp @@ -1688,15 +1688,24 @@ GuiWorkArea * TabWorkArea::currentWorkArea() if (count() == 0) return 0; - GuiWorkArea * wa = dynamic_cast(currentWidget()); + GuiWorkAreaContainer * wac = + dynamic_cast(currentWidget()); + LATTEST(wac); + GuiWorkArea * wa = wac->workArea(); LATTEST(wa); return wa; } +GuiWorkArea const * TabWorkArea::workArea(int index) const +{ + return (dynamic_cast(widget(index)))->workArea(); +} + + GuiWorkArea * TabWorkArea::workArea(int index) { - return dynamic_cast(widget(index)); + return (dynamic_cast(widget(index)))->workArea(); } @@ -1717,18 +1726,27 @@ GuiWorkArea * TabWorkArea::workArea(Buffer & buffer) void TabWorkArea::closeAll() { while (count()) { - GuiWorkArea * wa = workArea(0); - LASSERT(wa, return); + QWidget * wac = widget(0); + LASSERT(wac, return); removeTab(0); - delete wa; + delete wac; } } +int TabWorkArea::indexOfWorkArea(GuiWorkArea * w) const +{ + for (int index = 0; index < count(); ++index) + if (workArea(index) == w) + return index; + return -1; +} + + bool TabWorkArea::setCurrentWorkArea(GuiWorkArea * work_area) { LASSERT(work_area, return false); - int index = indexOf(work_area); + int index = indexOfWorkArea(work_area); if (index == -1) return false; @@ -1747,12 +1765,13 @@ bool TabWorkArea::setCurrentWorkArea(GuiWorkArea * work_area) GuiWorkArea * TabWorkArea::addWorkArea(Buffer & buffer, GuiView & view) { GuiWorkArea * wa = new GuiWorkArea(buffer, view); + GuiWorkAreaContainer * wac = new GuiWorkAreaContainer(wa); wa->setUpdatesEnabled(false); // Hide tabbar if there's no tab (avoid a resize and a flashing tabbar // when hiding it again below). if (!(currentWorkArea() && currentWorkArea()->isFullScreen())) showBar(count() > 0); - addTab(wa, wa->windowTitle()); + addTab(wac, wa->windowTitle()); QObject::connect(wa, SIGNAL(titleChanged(GuiWorkArea *)), this, SLOT(updateTabTexts())); if (currentWorkArea() && currentWorkArea()->isFullScreen()) @@ -1770,13 +1789,14 @@ GuiWorkArea * TabWorkArea::addWorkArea(Buffer & buffer, GuiView & view) bool TabWorkArea::removeWorkArea(GuiWorkArea * work_area) { LASSERT(work_area, return false); - int index = indexOf(work_area); + int index = indexOfWorkArea(work_area); if (index == -1) return false; work_area->setUpdatesEnabled(false); + QWidget * wac = widget(index); removeTab(index); - delete work_area; + delete wac; if (count()) { // make sure the next work area is enabled. @@ -2180,6 +2200,66 @@ void DragTabBar::dropEvent(QDropEvent * event) } +GuiWorkAreaContainer::GuiWorkAreaContainer(GuiWorkArea * wa, QWidget * parent) + : QWidget(parent), wa_(wa) +{ + LASSERT(wa, return); + Ui::WorkAreaUi::setupUi(this); + layout()->addWidget(wa); + connect(wa, SIGNAL(titleChanged(GuiWorkArea *)), + this, SLOT(updateDisplay())); + connect(reloadPB, SIGNAL(clicked()), this, SLOT(reload())); + connect(ignorePB, SIGNAL(clicked()), this, SLOT(ignore())); + QPalette const & pal = notificationFrame->palette(); + QPalette newpal(pal.color(QPalette::Active, QPalette::HighlightedText), + pal.color(QPalette::Active, QPalette::Highlight)); + notificationFrame->setPalette(newpal); + updateDisplay(); +} + + +void GuiWorkAreaContainer::updateDisplay() +{ + if (!wa_) + notificationFrame->hide(); + + Buffer const & buf = wa_->bufferView().buffer(); + notificationFrame->setHidden(!buf.notifiesExternalModification()); + QString const label = QString("The file \"%1\" changed on disk.") + .arg(toqstr(buf.fileName().displayName())); + externalModificationLabel->setText(label); +} + + +void GuiWorkAreaContainer::dispatch(FuncRequest f) const +{ + if (!wa_) + return; + lyx::dispatch(FuncRequest(LFUN_BUFFER_SWITCH, + wa_->bufferView().buffer().absFileName())); + lyx::dispatch(f); +} + + +void GuiWorkAreaContainer::reload() const +{ + dispatch(FuncRequest(LFUN_BUFFER_RELOAD)); +} + + +void GuiWorkAreaContainer::ignore() const +{ + dispatch(FuncRequest(LFUN_BUFFER_EXTERNAL_MODIFICATION_CLEAR)); +} + + +void GuiWorkAreaContainer::mouseDoubleClickEvent(QMouseEvent * event) +{ + // prevent TabWorkArea from opening a new buffer on double click + event->accept(); +} + + } // namespace frontend } // namespace lyx diff --git a/src/frontends/qt4/GuiWorkArea.h b/src/frontends/qt4/GuiWorkArea.h index a8b7c5a64d..aa407e13c0 100644 --- a/src/frontends/qt4/GuiWorkArea.h +++ b/src/frontends/qt4/GuiWorkArea.h @@ -13,6 +13,8 @@ #ifndef WORKAREA_H #define WORKAREA_H +#include "ui_WorkAreaUi.h" + #include "frontends/WorkArea.h" #include @@ -31,6 +33,7 @@ class QWidget; namespace lyx { class Buffer; +class FuncRequest; namespace frontend { @@ -206,6 +209,7 @@ public: bool removeWorkArea(GuiWorkArea *); GuiWorkArea * currentWorkArea(); GuiWorkArea * workArea(Buffer & buffer); + GuiWorkArea const * workArea(int index) const; GuiWorkArea * workArea(int index); void paintEvent(QPaintEvent *); @@ -237,6 +241,8 @@ private Q_SLOTS: void mouseReleaseEvent(QMouseEvent * me); /// void mouseDoubleClickEvent(QMouseEvent * event); + /// + int indexOfWorkArea(GuiWorkArea * w) const; private: /// true if position is a tab (rather than the blank space in tab bar) @@ -276,6 +282,29 @@ Q_SIGNALS: void tabMoveRequested(int fromIndex, int toIndex); }; + +class GuiWorkAreaContainer : public QWidget, public Ui::WorkAreaUi +{ + Q_OBJECT + GuiWorkArea * const wa_; + void dispatch(FuncRequest f) const; + +private Q_SLOTS: + void updateDisplay(); + void reload() const; + void ignore() const; + +protected: + void mouseDoubleClickEvent(QMouseEvent * event); //override + +public: + /// + GuiWorkAreaContainer(GuiWorkArea * wa, QWidget * parent = 0); + GuiWorkArea * workArea() const { return wa_; } +}; + + + } // namespace frontend } // namespace lyx diff --git a/src/frontends/qt4/Makefile.am b/src/frontends/qt4/Makefile.am index 66a86bb227..c110dae70f 100644 --- a/src/frontends/qt4/Makefile.am +++ b/src/frontends/qt4/Makefile.am @@ -355,6 +355,7 @@ UIFILES = \ ToggleWarningUi.ui \ ViewSourceUi.ui \ VSpaceUi.ui \ + WorkAreaUi.ui \ WrapUi.ui nodist_liblyxqt4_a_SOURCES = Resources.cpp diff --git a/src/frontends/qt4/ui/WorkAreaUi.ui b/src/frontends/qt4/ui/WorkAreaUi.ui new file mode 100644 index 0000000000..54a05c7175 --- /dev/null +++ b/src/frontends/qt4/ui/WorkAreaUi.ui @@ -0,0 +1,103 @@ + + + WorkAreaUi + + + + 0 + 0 + 818 + 69 + + + + + 2 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::NoContextMenu + + + true + + + QFrame::NoFrame + + + QFrame::Plain + + + 0 + + + 0 + + + + 10 + + + 10 + + + + + <b>externalModificationLabel</b> + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &Reload + + + + + + + &Ignore + + + + + + + + + + qt_i18n.h + + + + -- 2.39.2