]> git.lyx.org Git - features.git/commitdiff
Notification of external modification inspired by gedit
authorGuillaume Munch <gm@lyx.org>
Wed, 1 Mar 2017 23:41:02 +0000 (00:41 +0100)
committerGuillaume Munch <gm@lyx.org>
Fri, 10 Mar 2017 23:50:57 +0000 (00:50 +0100)
src/frontends/qt4/GuiView.cpp
src/frontends/qt4/GuiWorkArea.cpp
src/frontends/qt4/GuiWorkArea.h
src/frontends/qt4/Makefile.am
src/frontends/qt4/ui/WorkAreaUi.ui [new file with mode: 0644]

index e2e6555ca61b3669daac8d754941489aca52eed5..d990d795f1f03baf05a86df94a4bc932feba31e4 100644 (file)
@@ -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);
                }
index 050eae761f186fa50ddeaa384937128fd6d5489f..dc6ee3274a9b418dfc23b202ca0e13bb3f002f3d 100644 (file)
@@ -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
 
index a8b7c5a64d3fadbe20ffdd2427d2386b3034ce0d..aa407e13c0141d6046be1b02a9fcc9b53e33926d 100644 (file)
@@ -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
 
index 66a86bb227f695c2c7077be66f3ff49b987877e9..c110dae70fe77b59c8eeeffff11d76a8a2b511b6 100644 (file)
@@ -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 (file)
index 0000000..54a05c7
--- /dev/null
@@ -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">&lt;b&gt;externalModificationLabel&lt;/b&gt;</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>&amp;Reload</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QPushButton" name="ignorePB">
+        <property name="text">
+         <string>&amp;Ignore</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <includes>
+  <include location="local">qt_i18n.h</include>
+ </includes>
+ <resources/>
+ <connections/>
+</ui>