commit b6b56d85189966dd18223dcc30b3cef1ec6ed39a
Author: Guillaume Munch <[email protected]>
Date: Thu Mar 2 00:41:02 2017 +0100
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(-)
diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp
index e2e6555..d990d79 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<GuiWorkArea *>(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<GuiWorkArea
*>(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 050eae7..dc6ee32 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<GuiWorkArea *>(currentWidget());
+ GuiWorkAreaContainer * wac =
+ dynamic_cast<GuiWorkAreaContainer *>(currentWidget());
+ LATTEST(wac);
+ GuiWorkArea * wa = wac->workArea();
LATTEST(wa);
return wa;
}
+GuiWorkArea const * TabWorkArea::workArea(int index) const
+{
+ return (dynamic_cast<GuiWorkAreaContainer
*>(widget(index)))->workArea();
+}
+
+
GuiWorkArea * TabWorkArea::workArea(int index)
{
- return dynamic_cast<GuiWorkArea *>(widget(index));
+ return (dynamic_cast<GuiWorkAreaContainer
*>(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("<b>The file \"%1\" changed on disk.</b>")
+ .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 a8b7c5a..aa407e1 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 <QAbstractScrollArea>
@@ -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 66a86bb..c110dae 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 0000000..54a05c7
--- /dev/null
+++ b/src/frontends/qt4/ui/WorkAreaUi.ui
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WorkAreaUi</class>
+ <widget class="QWidget" name="WorkAreaUi">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>818</width>
+ <height>69</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="0">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="notificationFrame">
+ <property name="contextMenuPolicy">
+ <enum>Qt::NoContextMenu</enum>
+ </property>
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ <property name="midLineWidth">
+ <number>0</number>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0,0,0">
+ <property name="topMargin">
+ <number>10</number>
+ </property>
+ <property name="bottomMargin">
+ <number>10</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="externalModificationLabel">
+ <property name="text">
+ <string
notr="true"><b>externalModificationLabel</b></string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="reloadPB">
+ <property name="text">
+ <string>&Reload</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="ignorePB">
+ <property name="text">
+ <string>&Ignore</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <includes>
+ <include location="local">qt_i18n.h</include>
+ </includes>
+ <resources/>
+ <connections/>
+</ui>