mirror of
https://github.com/Hopiu/linkchecker.git
synced 2026-03-17 14:30:30 +00:00
181 lines
6.5 KiB
Python
181 lines
6.5 KiB
Python
# -*- coding: iso-8859-1 -*-
|
|
# Copyright (C) 2010-2014 Bastian Kleineidam
|
|
#
|
|
# 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
import os
|
|
import urlparse
|
|
from PyQt4 import QtGui, QtCore
|
|
from .linkchecker_ui_editor import Ui_EditorDialog
|
|
from ..checker.fileurl import get_os_filename
|
|
try:
|
|
from .editor_qsci import ContentTypeLexers, Editor
|
|
except ImportError:
|
|
from .editor_qt import ContentTypeLexers, Editor
|
|
|
|
class EditorWindow (QtGui.QDialog, Ui_EditorDialog):
|
|
"""Editor window."""
|
|
|
|
# emitted after successful save
|
|
saved = QtCore.pyqtSignal(str)
|
|
# emitted after successful load
|
|
loaded = QtCore.pyqtSignal(str)
|
|
|
|
def __init__ (self, parent=None):
|
|
"""Initialize the editor widget."""
|
|
super(EditorWindow, self).__init__(parent)
|
|
self.setupUi(self)
|
|
# filename used for saving
|
|
self.filename = None
|
|
# the Scintilla editor widget
|
|
self.editor = Editor(parent=self.frame)
|
|
layout = QtGui.QVBoxLayout(self.frame)
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
|
layout.addWidget(self.editor)
|
|
# for debugging
|
|
#self.setText(("1234567890"*8) + "\n<html><head>\n<title>x</title>\n</head>\n")
|
|
#lexer = Qsci.QsciLexerHTML()
|
|
#lexer.setFont(self.editor.font())
|
|
#self.editor.setLexer(lexer)
|
|
#self.editor.setCursorPosition(1, 1)
|
|
#self.show()
|
|
|
|
def setContentType (self, content_type):
|
|
"""Choose a lexer according to given content type."""
|
|
lexerclass = ContentTypeLexers.get(content_type.lower())
|
|
self.editor.highlight(lexerclass)
|
|
|
|
def setText (self, text, line=1, col=1):
|
|
"""Set editor text and jump to given line and column."""
|
|
self.editor.setText(text)
|
|
self.editor.setCursorPosition(line-1, col-1)
|
|
self.editor.setModified(False)
|
|
|
|
def setUrl (self, url):
|
|
"""If URL is a file:// URL, store the filename of it as base
|
|
directory for the "save as" dialog."""
|
|
self.basedir = ""
|
|
if url and url.startswith("file://"):
|
|
urlparts = urlparse.urlsplit(url)
|
|
path = get_os_filename(urlparts[2])
|
|
if os.path.exists(path):
|
|
self.basedir = path
|
|
|
|
@QtCore.pyqtSlot()
|
|
def on_actionSave_triggered (self):
|
|
"""Save changed editor contents."""
|
|
if self.editor.isModified() or not self.filename:
|
|
self.save()
|
|
|
|
def closeEvent (self, e=None):
|
|
"""Save settings and remove registered logging handler"""
|
|
if self.editor.isModified():
|
|
# ask if user wants to save
|
|
if self.wants_save():
|
|
if self.save():
|
|
e.accept()
|
|
else:
|
|
# saving error or user canceled
|
|
e.ignore()
|
|
else:
|
|
# discard changes
|
|
e.accept()
|
|
else:
|
|
# unchanged
|
|
e.accept()
|
|
|
|
def wants_save (self):
|
|
"""Ask user if he wants to save changes. Return True if user
|
|
wants to save, else False."""
|
|
dialog = QtGui.QMessageBox(parent=self)
|
|
dialog.setIcon(QtGui.QMessageBox.Question)
|
|
dialog.setWindowTitle(_("Save file?"))
|
|
dialog.setText(_("The document has been modified."))
|
|
dialog.setInformativeText(_("Do you want to save your changes?"))
|
|
dialog.setStandardButtons(QtGui.QMessageBox.Save |
|
|
QtGui.QMessageBox.Discard)
|
|
dialog.setDefaultButton(QtGui.QMessageBox.Save)
|
|
return dialog.exec_() == QtGui.QMessageBox.Save
|
|
|
|
def save (self):
|
|
"""Save editor contents to file."""
|
|
if not self.filename:
|
|
title = _("Save File As")
|
|
res = QtGui.QFileDialog.getSaveFileName(self, title, self.basedir)
|
|
if not res:
|
|
# user canceled
|
|
return
|
|
self.filename = res
|
|
self.setWindowTitle(self.filename)
|
|
else:
|
|
if not os.path.isfile(self.filename):
|
|
return
|
|
if not os.access(self.filename, os.W_OK):
|
|
return
|
|
fh = None
|
|
saved = False
|
|
try:
|
|
try:
|
|
fh = QtCore.QFile(self.filename)
|
|
if not fh.open(QtCore.QIODevice.WriteOnly):
|
|
raise IOError(fh.errorString())
|
|
stream = QtCore.QTextStream(fh)
|
|
stream.setCodec("UTF-8")
|
|
stream << self.editor.text()
|
|
self.editor.setModified(False)
|
|
saved = True
|
|
except (IOError, OSError) as e:
|
|
err = QtGui.QMessageBox(self)
|
|
err.setText(str(e))
|
|
err.exec_()
|
|
finally:
|
|
if fh is not None:
|
|
fh.close()
|
|
if saved:
|
|
self.saved.emit(self.filename)
|
|
return saved
|
|
|
|
def load (self, filename):
|
|
"""Load editor contents from file."""
|
|
if not os.path.isfile(filename):
|
|
return
|
|
if not os.access(filename, os.R_OK):
|
|
return
|
|
self.filename = filename
|
|
if not os.access(filename, os.W_OK):
|
|
title = u"%s (%s)" % (self.filename, _(u"readonly"))
|
|
else:
|
|
title = self.filename
|
|
self.setWindowTitle(title)
|
|
fh = None
|
|
loaded = False
|
|
try:
|
|
try:
|
|
fh = QtCore.QFile(self.filename)
|
|
if not fh.open(QtCore.QIODevice.ReadOnly):
|
|
raise IOError(fh.errorString())
|
|
stream = QtCore.QTextStream(fh)
|
|
stream.setCodec("UTF-8")
|
|
self.setText(stream.readAll())
|
|
loaded = True
|
|
except (IOError, OSError) as e:
|
|
err = QtGui.QMessageBox(self)
|
|
err.setText(str(e))
|
|
err.exec_()
|
|
finally:
|
|
if fh is not None:
|
|
fh.close()
|
|
if loaded:
|
|
self.loaded.emit(self.filename)
|