1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
# This file is part of the Frescobaldi project, http://www.frescobaldi.org/
#
# Copyright (c) 2008 - 2014 by Wilbert Berendsen
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# See http://www.gnu.org/licenses/ for more information.
"""
This module monitors open documents for changes on disk (overwrite or move and
delete operations) by external programs.
The documentwatcher module is used to do the actual monitoring work,
this module checks if a touched file really changed and pops up the window
if needed.
"""
from PyQt5.QtCore import QSettings, QTimer
def enabled():
"""Return whether watching documents is enabled by the user."""
return QSettings().value("externalchanges/enabled", True, bool)
def setEnabled(enable):
"""Enable or disable watching documents, saves the setting."""
if enabled() != bool(enable):
QSettings().setValue("externalchanges/enabled", bool(enable))
setup()
def setup():
"""Start or stop the document watching according to the settings."""
import documentwatcher
if enabled():
documentwatcher.documentChangedOnDisk.connect(slotDocumentChanged)
documentwatcher.start()
else:
documentwatcher.documentChangedOnDisk.disconnect(slotDocumentChanged)
documentwatcher.stop()
def changedDocuments():
"""Return a list of really changed Documents.
When a document is not modified and the file on disk is exactly the same,
the document is not considered having been changed on disk.
"""
import documentwatcher
for w in documentwatcher.DocumentWatcher.instances():
d = w.document()
if w.changed and not d.isModified():
filename = d.url().toLocalFile()
if filename:
try:
with open(filename, 'rb') as diskfile:
if diskfile.read() == d.encodedText():
w.changed = False
except (OSError, IOError):
pass
return [w.document() for w in documentwatcher.DocumentWatcher.instances()
if w.changed]
def display(documents):
"""Diplay the window showing the specified Documents."""
from . import widget
window = widget.window()
window.setDocuments(documents)
window.show()
def displayChangedDocuments():
"""Display the window, even if there are no changed files."""
display(changedDocuments())
def checkChangedDocuments():
"""Display the window if there are changed files."""
docs = changedDocuments()
if docs:
display(docs)
# timer to wait before really looking at the changed files, a file could
# probably still be changing.
_timer = QTimer(singleShot=True, timeout=checkChangedDocuments)
def slotDocumentChanged(document):
"""Called when a document is changed."""
_timer.start(500)
# initial setup
if enabled():
setup()
|