From 0b427a538c85b999f95cbdb2f77867198c5ef9cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= Date: Thu, 24 Dec 2020 19:57:28 +0000 Subject: [PATCH 01/37] revert commits 6724664..f4af13a , except commits 6724664 (Updated license file), 0f0d6f6 (Add a copyright file), ef3ea6a (Use one central .gitignore) all others are revert to have teythoon branch is work much better | * f4af13a 2013-08-04 02:19 phobie Fix: three lines missed in the last commit | * 88c9e93 2013-08-04 01:22 phobie Remove PyQt v3 style wrapper classes Fix: implement missing helpHelpAction in the regex library | * ef3ea6a 2013-08-03 11:07 phobie Use one central .gitignore file Added ignores for qm files and some build dirs | * 937a5e6 2013-08-03 11:04 phobie Removed binary file from source (kodos_pl.qm) Remove unused ui file (resultsBA.ui) Bugfix for pylupdate4 to update all ts files (kodos.pro) | * 0f0d6f6 2013-08-03 10:26 phobie Add a copyright file to list all contributors | * 3ec49fe 2013-08-02 17:39 phobie simplify and unify PyQt4 module loading | * 2491196 2013-08-02 12:16 phobie Use relative imports for Kodos modules Fallback to pickle if cPickle is not available Address all pyflakes issues: * Avoid star imports * Replace unset variable qApp by QApplication * Do not set unused variables * Comment out unused and buggy RecentFiles.move() function | * 40b6f19 2013-08-01 15:11 phobie Implement PEPs: PEP 3101: format strings with format() instead of '%' PEP 3105: print as function instead of statement PEP 3110: exceptions with 'as' instead of ',' (With this change Kodos depends on Python >=2.6) | * 4725328 2013-07-31 18:22 phobie Add modelines (in vi, emacs and jEdit format) [see http://www.wireshark.org/tools/modelines.html] Seperate module imports (into built-in, installed and Kodos) Add separation lines | * f14090d 2013-07-30 18:56 phobie Use return in all functions. (Zen of Python: Explicit is better than implicit.) | * 6724664 2013-07-30 17:07 phobie Updated license file (fixed address and changed Library to Lesser when referencing to LGPL) --- kodos | 407 +++++++++++++------------------------- kodos.pro | 7 +- modules/Makefile | 2 +- modules/about.py | 27 +-- modules/debug.py | 9 +- modules/flags.py | 22 +-- modules/help.py | 50 ++--- modules/newUserDialog.py | 28 --- modules/parseRegexLib.py | 21 +- modules/prefs.py | 68 ++----- modules/recent_files.py | 48 ++--- modules/reference.py | 41 ++-- modules/referenceBA.ui | 10 +- modules/regexLibrary.py | 51 ++--- modules/regexLibraryBA.ui | 6 - modules/reportBug.py | 101 ++++------ modules/status_bar.py | 38 ++-- modules/tooltip.py | 64 ++---- modules/urlDialog.py | 54 ++--- modules/util.py | 64 ++---- py2exe-setup.py | 32 +-- scripts/bapro2qtpro.py | 39 ++-- scripts/pyuicfix.py | 32 ++- setup.py | 25 +-- 24 files changed, 379 insertions(+), 867 deletions(-) delete mode 100644 modules/newUserDialog.py diff --git a/kodos b/kodos index 05eb857..8446047 100755 --- a/kodos +++ b/kodos @@ -1,59 +1,46 @@ #!/usr/bin/env python -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: +# -*- coding: utf-8 -*- +# kodos.py: -*- Python -*- DESCRIPTIVE TEXT. -#-----------------------------------------------------------------------------# -# Built-in modules - -import os import sys -import re +import os import string +import re +import cPickle import types import getopt import urllib import signal -try: - # Python 2.x: try to use cPickle if available - import cPickle as pickle -except ImportError: - # Python 3.x: pickle imports cPickle internally - import pickle - -#-----------------------------------------------------------------------------# -# Installed modules try: - from PyQt4 import QtGui, QtCore + from PyQt4.QtGui import * + from PyQt4.QtCore import * except: sys.exit("""Could not locate the PyQt module. Please make sure that you have installed PyQt for the version of Python that you are running.""") -#-----------------------------------------------------------------------------# -# Kodos modules - -# make sure that this script can find kodos specific modules +### make sure that this script can find kodos specific modules ### from distutils.sysconfig import get_python_lib + sys.path.append(os.path.join(get_python_lib(), "kodos")) -from modules.kodosBA import Ui_KodosBA -from modules.util import (findFile, launch_browser, kodos_toolbar_logo, - saveWindowSettings, restoreWindowSettings) -from modules.about import About -from modules.help import Help -from modules.status_bar import Status_Bar -from modules.reference import Reference -from modules.prefs import Preferences +################################################################### + +from modules.kodosBA import * +from modules.util import * +from modules.about import * +import modules.help as help +from modules.status_bar import * +from modules.reference import * +from modules.prefs import * from modules.reportBug import reportBugWindow from modules.version import VERSION from modules.recent_files import RecentFiles from modules.urlDialog import URLDialog from modules.regexLibrary import RegexLibrary -from modules.newUserDialog import NewUserDialog +from modules.newUserDialogBA import NewUserDialog from modules.flags import reFlag, reFlagList -#-----------------------------------------------------------------------------# # match status MATCH_NA = 0 @@ -79,8 +66,8 @@ STATE_EDITED = 1 GEO = "kodos_geometry" # colors for normal & examination mode -QCOLOR_WHITE = QtGui.QColor(QtCore.Qt.white) # normal -QCOLOR_YELLOW = QtGui.QColor(255,255,127) # examine +QCOLOR_WHITE = QColor(Qt.white) # normal +QCOLOR_YELLOW = QColor(255,255,127) # examine try: signal.SIGALRM @@ -95,10 +82,9 @@ except: # ############################################################################## -class Kodos(QtGui.QMainWindow, Ui_KodosBA): - def __init__(self, filename, debug, parent=None, f=QtCore.Qt.WindowFlags()): - QtGui.QMainWindow.__init__(self, parent, f) - self.setupUi(self) +class Kodos(KodosBA): + def __init__(self, filename, debug): + KodosBA.__init__(self) self.debug = debug self.regex = "" @@ -126,39 +112,36 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): self.MSG_FAIL = self.tr("Pattern does not match") - self.statusPixmapsDict = { - MATCH_NA: QtGui.QPixmap(":images/yellow.png"), - MATCH_OK: QtGui.QPixmap(":images/green.png"), - MATCH_FAIL: QtGui.QPixmap(":images/red.png"), - MATCH_PAUSED: QtGui.QPixmap(":images/pause.png"), - } + self.statusPixmapsDict = { MATCH_NA: QPixmap(":images/yellow.png"), + MATCH_OK: QPixmap(":images/green.png"), + MATCH_FAIL: QPixmap(":images/red.png"), + MATCH_PAUSED: QPixmap(":images/pause.png"), + } self.updateStatus(self.MSG_NA, MATCH_NA) self.reFlags = reFlagList([ - reFlag("re.IGNORECASE", "i", self.ignorecaseCheckBox), - reFlag("re.MULTILINE", "m", self.multilineCheckBox), - reFlag("re.DOTALL", "s", self.dotallCheckBox), - reFlag("re.VERBOSE", "x", self.verboseCheckBox), - reFlag("re.LOCALE", "L", self.localeCheckBox), - reFlag("re.UNICODE", "u", self.unicodeCheckBox), - ]) + reFlag("re.IGNORECASE", "i", self.ignorecaseCheckBox), + reFlag("re.MULTILINE", "m", self.multilineCheckBox), + reFlag("re.DOTALL", "s", self.dotallCheckBox), + reFlag("re.VERBOSE", "x", self.verboseCheckBox), + reFlag("re.LOCALE", "L", self.localeCheckBox), + reFlag("re.UNICODE", "u", self.unicodeCheckBox), + ]) self.reFlags.clearAll() restoreWindowSettings(self, GEO) self.show() - self.prefs = Preferences(autoload=1, parent=self) - self.recent_files = RecentFiles( - self, - self.prefs.recentFilesSpinBox.value(), - self.debug - ) + self.prefs = Preferences(self, 1) + self.recent_files = RecentFiles(self, + self.prefs.recentFilesSpinBox.value(), + self.debug) if filename and self.openFile(filename): - QtGui.QApplication.processEvents() + qApp.processEvents() self.fileMenu.triggered.connect(self.fileMenuHandler) @@ -167,28 +150,24 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): else: self.hide_replace_widgets() self.checkIfNewUser() - return def checkIfNewUser(self): - s = QtCore.QSettings() + s = QSettings() if s.value('New User', "true").toPyObject() != "false": self.newuserdialog = NewUserDialog() self.newuserdialog.show() s.setValue('New User', "false") - return def createStatusBar(self): self.status_bar = Status_Bar(self, FALSE, "") - return def updateStatus(self, status_string, status_value, duration=0, replace=FALSE, tooltip=''): pixmap = self.statusPixmapsDict.get(status_value) self.status_bar.set_message(status_string, duration, replace, tooltip, pixmap) - return def fileMenuHandler(self, menuid): @@ -196,23 +175,19 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): fn = str(menuid.text()) if self.openFile(fn): self.recent_files.add(fn) - return def prefsSaved(self): - if self.debug: print("prefsSaved slot") + if self.debug: print "prefsSaved slot" self.recent_files.setNumShown(self.prefs.recentFilesSpinBox.value()) - return def kodos_edited_slot(self): # invoked whenever the user has edited something self.editstate = STATE_EDITED - return def checkbox_slot(self): self.process_regex() - return def set_flags(self, flags): @@ -220,7 +195,6 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): # this is used when loading a saved file for f in self.reFlags: f.checkBox.setChecked(flags & f.reFlag) - return def get_flags_string(self): @@ -250,7 +224,7 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): def pause(self): self.is_paused = not self.is_paused - if self.debug: print("is_paused: {0}".format(self.is_paused)) + if self.debug: print "is_paused:", self.is_paused if self.is_paused: self.update_results(self.MSG_PAUSED, MATCH_PAUSED) @@ -259,12 +233,11 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): else: self.process_regex() self.matchNumberSpinBox.setEnabled(1) - return def examine(self): self.is_examined = not self.is_examined - if self.debug: print("is_examined: {0}".format(self.is_examined)) + if self.debug: print "is_examined:", self.is_examined if self.is_examined: color = QCOLOR_YELLOW @@ -280,7 +253,7 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): try: m = re.search(regex, self.matchstring, self.reFlags.allFlagsORed()) if m: - if self.debug: print("examined regex: {0}".format(regex)) + if self.debug: print "examined regex:", regex self.__refresh_regex_widget(color, regex) return except: @@ -294,11 +267,10 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): self.stringMultiLineEdit.setReadOnly(0) self.replaceTextEdit.setReadOnly(0) self.__refresh_regex_widget(color, regex) - return def __refresh_regex_widget(self, base_qcolor, regex): - pal = QtGui.QPalette() + pal = QPalette() pal.setColor(pal.Base, base_qcolor) self.regexMultiLineEdit.setPalette(pal) @@ -306,42 +278,31 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): self.regexMultiLineEdit.clear() self.regexMultiLineEdit.blockSignals(0) self.regexMultiLineEdit.setPlainText(regex) - return def match_num_slot(self, num): self.match_num = num self.process_regex() - return def replace_num_slot(self, num): self.replace_num = num self.process_regex() - return def regex_changed_slot(self): self.regex = unicode(self.regexMultiLineEdit.toPlainText()) self.process_regex() - return def string_changed_slot(self): self.matchstring = unicode(self.stringMultiLineEdit.toPlainText()) self.process_regex() - return - def helpContents(self, x = None): pass #FIXME - return - - def helpIndex(self, x = None): pass #FIXME - return - def hide_replace_widgets(self): self.spacerLabel.hide() @@ -349,8 +310,6 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): self.replaceNumberSpinBox.hide() self.replaceTextBrowser.clear() self.replaceTextBrowser.setDisabled(TRUE) - return - def show_replace_widgets(self): self.spacerLabel.show() @@ -358,8 +317,6 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): self.replaceNumberSpinBox.show() self.replaceNumberSpinBox.setEnabled(TRUE) self.replaceTextBrowser.setEnabled(TRUE) - return - def replace_changed_slot(self): self.replace = unicode(self.replaceTextEdit.toPlainText()) @@ -368,12 +325,10 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): self.hide_replace_widgets() else: self.show_replace_widgets() - return def update_results(self, msg, val): self.updateStatus(msg, val) - return def populate_group_table(self, tuples): @@ -385,10 +340,9 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): self.groupTable.setRowCount(rows) row = 0 for t in tuples: - self.groupTable.setItem(row, 0, QtGui.QTableWidgetItem(t[1])) - self.groupTable.setItem(row, 1, QtGui.QTableWidgetItem(t[2])) + self.groupTable.setItem(row, 0, QTableWidgetItem(t[1])) + self.groupTable.setItem(row, 1, QTableWidgetItem(t[2])) row += 1 - return def populate_code_textbrowser(self): @@ -424,34 +378,29 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): named_grps = 0 for grp in self.group_tuples: i += 1 - code += "group_{0} = match_obj.group({0})\n".format(i) + code += "group_%d = match_obj.group(%d)\n" % (i, i) if grp[1]: named_grps = 1 if named_grps: code += "\n# Retrieve group(s) by name\n" for grp in self.group_tuples: if grp[1]: - code += "{0} = match_obj.group('{0}')\n".format(grp[1]) + code += "%s = match_obj.group('%s')\n" % (grp[1], grp[1]) code += "\n" if self.replace: code += "# Replace string\n" - code += "newstr = compile_obj.subn('{0}', {1})\n".format( - self.replace, self.replace_num - ) + code += "newstr = compile_obj.subn('%s', %d)\n" % (self.replace, + self.replace_num) self.codeTextBrowser.setPlainText(code) - return def colorize_strings(self, strings, widget, cursorOffset=0): widget.clear() - colors = ( - QtGui.QBrush(QtGui.QColor(QtCore.Qt.black)), - QtGui.QBrush(QtGui.QColor(QtCore.Qt.blue)), - ) + colors = (QBrush(QColor(Qt.black)), QBrush(QColor(Qt.blue)) ) cur = widget.textCursor() format = cur.charFormat() @@ -467,7 +416,6 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): cur.setPosition(pos) widget.setTextCursor(cur) widget.centerCursor() - return def populate_match_textbrowser(self, startpos, endpos): @@ -485,7 +433,6 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): strings = [pre, match, post] self.colorize_strings(strings, self.matchTextBrowser, 1) - return def populate_replace_textbrowser(self, spans, nummatches, compile_obj): @@ -525,7 +472,6 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): break self.colorize_strings(strings, self.replaceTextBrowser) - return def populate_matchAll_textbrowser(self, spans): @@ -549,7 +495,6 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): strings.append(text[span[1]:]) self.colorize_strings(strings, self.matchAllTextBrowser) - return def clear_results(self): @@ -564,7 +509,6 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): self.replaceNumberSpinBox.setEnabled(FALSE) self.replaceTextBrowser.clear() self.matchAllTextBrowser.clear() - return def process_regex(self): @@ -600,7 +544,7 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): match_obj = compile_obj.search(self.matchstring) - except Exception as e: + except Exception, e: self.update_results(unicode(e), MATCH_FAIL) return @@ -635,10 +579,10 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): group_nums[compile_obj.groupindex[key]] = key if self.debug: - print("group_nums: {0}".format(group_nums)) - print("grp index: {0}".format(compile_obj.groupindex)) - print("groups: {0}".format(match_obj.groups())) - print("span: {0}".format(match_obj.span())) + print "group_nums:", group_nums + print "grp index: ", compile_obj.groupindex + print "groups:", match_obj.groups() + print "span: ", match_obj.span() # create group_tuple in the form: (group #, group name, group matches) g = allmatches[match_index] @@ -660,18 +604,14 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): str_matches = unicode(self.tr("matches")) if len(allmatches) == 1: - status = "{0} ({1} 1 {2})".format( - str_pattern_matches, - str_found, - str_match, - ) + status = "%s (%s 1 %s)" % (str_pattern_matches, + str_found, + str_match) else: - status = "{0} ({1} {2} {3})".format( - str_pattern_matches, - str_found, - len(allmatches), - str_matches, - ) + status = "%s (%s %d %s)" % (str_pattern_matches, + str_found, + len(allmatches), + str_matches) self.update_results(status, MATCH_OK) self.populate_code_textbrowser() @@ -680,7 +620,6 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): if self.replace: self.populate_replace_textbrowser(spans, len(allmatches), compile_obj) self.populate_matchAll_textbrowser(spans) - return def findAllSpans(self, compile_obj): @@ -721,7 +660,6 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): except: pass ev.accept() - return def fileNew(self): @@ -734,36 +672,29 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): self.replaceTextEdit.setPlainText("") self.set_flags(0) self.editstate = STATE_UNEDITED - return def importURL(self): - self.urldialog = URLDialog(url=self.url, parent=self) + self.urldialog = URLDialog(self, self.url) self.urldialog.urlImported.connect(self.urlImported) - return def urlImported(self, html, url): self.url = url self.stringMultiLineEdit.setPlainText(html) - return def importFile(self): - fn = QtGui.QFileDialog.getOpenFileName( - self, - self.tr("Import File"), - self.filename, - self.tr("All (*)") - ) + fn = QFileDialog.getOpenFileName(self, + self.tr("Import File"), + self.filename, + self.tr("All (*)")) if fn.isEmpty(): - self.updateStatus( - self.tr("A file was not selected for import"), - -1, - 5, - TRUE - ) + self.updateStatus(self.tr("A file was not selected for import"), + -1, + 5, + TRUE) return None filename = str(fn) @@ -778,24 +709,20 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): data = fp.read() fp.close() self.stringMultiLineEdit.setPlainText(data) - return def fileOpen(self): filename = self.filename if filename == None: filename = "" - fn = QtGui.QFileDialog.getOpenFileName( - self, - self.tr("Open Kodos File"), - filename, - self.tr("Kodos file (*.kds);;All (*)") - ) + fn = QFileDialog.getOpenFileName(self, + self.tr("Open Kodos File"), + filename, + self.tr("Kodos file (*.kds);;All (*)")) if not fn.isEmpty(): filename = str(fn) if self.openFile(filename): self.recent_files.add(filename) - return def openFile(self, filename): @@ -812,16 +739,15 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): return None try: - u = pickle.Unpickler(fp) + u = cPickle.Unpickler(fp) self.regex = u.load() self.matchstring = u.load() flags = u.load() - except Exception as e: #FIXME: don't catch everything + except Exception, e: #FIXME: don't catch everything if self.debug: - print(unicode(e)) - msg = unicode( - self.tr("Error reading from file: {filename}") - ).format(filename=filename) + print unicode(e) + msg = "%s %s" % (unicode(self.tr("Error reading from file:")), + filename) self.updateStatus(msg, -1, 5, TRUE) return 0 @@ -841,9 +767,7 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): self.replaceTextEdit.setPlainText(replace) self.filename = filename - msg = unicode(self.tr("{filename} loaded successfully")).format( - filename=filename - ) + msg = "%s %s" % (filename, unicode(self.tr("loaded successfully"))) self.updateStatus(msg, -1, 5, TRUE) self.editstate = STATE_UNEDITED return 1 @@ -853,17 +777,15 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): filename = self.filename if filename == None: filename = "" - filedialog = QtGui.QFileDialog( - self, - self.tr("Save Kodos File"), - filename, - "Kodos file (*.kds);;All (*)" - ) - filedialog.setAcceptMode(QtGui.QFileDialog.AcceptSave) + filedialog = QFileDialog(self, + self.tr("Save Kodos File"), + filename, + "Kodos file (*.kds);;All (*)") + filedialog.setAcceptMode(QFileDialog.AcceptSave) filedialog.setDefaultSuffix("kds") ok = filedialog.exec_() - if ok == QtGui.QDialog.Rejected: + if ok == QDialog.Rejected: self.updateStatus(self.tr("No file selected to save"), -1, 5, TRUE) return @@ -871,7 +793,6 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): self.filename = filename self.fileSave() - return def fileSave(self): @@ -882,31 +803,27 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): try: fp = open(self.filename, "w") except: - msg = unicode(self.tr( - "Could not open file for writing: {filename}" - )).format(filename=self.filename) + msg = "%s: %s" % (unicode(self.tr("Could not open file for writing:")), + self.filename) self.updateStatus(msg, -1, 5, TRUE) return None self.editstate = STATE_UNEDITED - p = pickle.Pickler(fp) + p = cPickle.Pickler(fp) p.dump(self.regex) p.dump(self.matchstring) p.dump(self.reFlags.allFlagsORed()) p.dump(self.replace) fp.close() - msg = unicode(self.tr("{filename} successfully saved")).format( - filename=unicode(self.filename) - ) + msg = "%s %s" % (unicode(self.filename), + unicode(self.tr("successfully saved"))) self.updateStatus(msg, -1, 5, TRUE) self.recent_files.add(self.filename) - return def paste_symbol(self, symbol): self.regexMultiLineEdit.insertPlainText(symbol) - return def process_embedded_flags(self, regex): @@ -925,26 +842,23 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): f.embed() else: f.deembed() - return def checkEditState(self): if self.editstate == STATE_EDITED: message = self.tr("You have made changes. Would you like to save them before continuing?") - prompt = QtGui.QMessageBox.warning( - None, - self.tr("Save changes?"), - message, - QtGui.QMessageBox.Save | - QtGui.QMessageBox.Cancel | - QtGui.QMessageBox.Discard - ) + prompt = QMessageBox.warning(None, + self.tr("Save changes?"), + message, + QMessageBox.Save | + QMessageBox.Cancel | + QMessageBox.Discard) - if prompt == QtGui.QMessageBox.Cancel: + if prompt == QMessageBox.Cancel: return False - if prompt == QtGui.QMessageBox.Save: + if prompt == QMessageBox.Save: self.fileSave() if not self.filename: self.checkEditState() @@ -967,7 +881,6 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): except KeyError: pass self.editstate = STATE_UNEDITED - return def revert_file_slot(self): @@ -979,11 +892,10 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): return self.openFile(self.filename) - return def getWidget(self): - widget = QtGui.QApplication.focusWidget() + widget = qApp.focusWidget() if (widget == self.regexMultiLineEdit or widget == self.stringMultiLineEdit or widget == self.replaceTextEdit or @@ -997,56 +909,42 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): # execute the methodstr of widget only if widget # is one of the editable widgets OR if the method # may be applied to any widget. - widget = QtGui.QApplication.focusWidget() + widget = qApp.focusWidget() if anywidget or ( widget == self.regexMultiLineEdit or widget == self.stringMultiLineEdit or widget == self.replaceTextEdit or widget == self.codeTextBrowser): try: - eval("widget.{0}".format(methodstr)) + eval("widget.%s" % methodstr) except: pass - return def editUndo(self): self.widgetMethod("undo()") - return - def editRedo(self): self.widgetMethod("redo()") - return - def editCopy(self): self.widgetMethod("copy()", 1) - return - def editCut(self): self.widgetMethod("cut()") - return - def editPaste(self): self.widgetMethod("paste()") - return def preferences(self): self.prefs.showPrefsDialog() self.prefs.prefsSaved.connect(self.prefsSaved) - return - def setfont(self, font): self.regexMultiLineEdit.setFont(font) self.stringMultiLineEdit.setFont(font) self.replaceTextEdit.setFont(font) - return - def setMatchFont(self, font): self.groupTable.setFont(font) @@ -1054,7 +952,6 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): self.matchAllTextBrowser.setFont(font) self.replaceTextBrowser.setFont(font) self.codeTextBrowser.setFont(font) - return def getfont(self): @@ -1066,32 +963,27 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): def helpHelp(self): - self.helpWindow = Help(filename="kodos.html", parent=self) - return + self.helpWindow = help.Help(self, "kodos.html") def helpPythonRegex(self): - self.helpWindow = Help(filename=os.path.join("python", "module-re.html"), parent=self) - return + self.helpWindow = help.Help(self, os.path.join("python", "module-re.html")) def helpRegexLib(self): f = os.path.join("help", "regex-lib.xml") - self.regexlibwin = RegexLibrary(filename=f, parent=self) + self.regexlibwin = RegexLibrary(f) self.regexlibwin.pasteRegexLib.connect(self.pasteFromRegexLib) self.regexlibwin.show() - return def helpAbout(self): self.aboutWindow = About() self.aboutWindow.show() - return def kodos_website(self): self.launch_browser_wrapper("http://kodos.sourceforge.net") - return def check_for_update(self): @@ -1112,35 +1004,28 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): if match_obj: latest_version = match_obj.group('version') if latest_version == VERSION: - QtGui.QMessageBox.information( - None, - self.tr("No Update is Available"), - unicode(self.tr( - "You are currently using the latest version of Kodos ({version})" - )).format(version=VERSION) - ) + QMessageBox.information(None, + self.tr("No Update is Available"), + unicode(self.tr("You are currently using the latest version of Kodos")) + " (%s)" % VERSION) else: - message = "{0}\n\n{1}\n{2}\n\n{3}\n".format( - unicode(self.tr("There is a newer version of Kodos available.")), - unicode(self.tr("You are using version: {version}." - )).format(version=VERSION), - unicode(self.tr("The latest version is: {version}." - )).format(version=latest_version), - unicode(self.tr("Press OK to launch browser")), - ) + message = "%s\n\n%s: %s.\n%s: %s.\n\n%s\n" % \ + (unicode(self.tr("There is a newer version of Kodos available.")), + unicode(self.tr("You are using version:")), + VERSION, + unicode(self.tr("The latest version is:")), + latest_version, + unicode(self.tr("Press OK to launch browser"))) self.launch_browser_wrapper(url, self.tr("Kodos Update Available"), message) else: - message = "{0}\n\n{1}".format( - unicode(self.tr("Unable to get version info from Sourceforge.")), - unicode(self.tr("Press OK to launch browser")), - ) + message = "%s.\n\n%s" % \ + (unicode(self.tr("Unable to get version info from Sourceforge")), + unicode(self.tr("Press OK to launch browser"))) self.launch_browser_wrapper(url, self.tr("Unknown version available"), message) - return def launch_browser_wrapper(self, url, caption=None, message=None): @@ -1152,19 +1037,16 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): self.status_bar.set_message(self.tr("Cancelled web browser launch"), 3, TRUE) - return def reference_guide(self): self.ref_win = Reference(self) self.ref_win.pasteSymbol.connect(self.paste_symbol) self.ref_win.show() - return def report_bug(self): self.bug_report_win = reportBugWindow(self) - return ############################################################################## @@ -1173,15 +1055,14 @@ class Kodos(QtGui.QMainWindow, Ui_KodosBA): ############################################################################## def usage(): - print("kodos.py [-f filename | --file=filename ] [ -d debug | --debug=debug ] [ -k kodos_dir ]") - print('') - print(" -f filename | --filename=filename : Load filename on startup") - print(" -d debug | --debug=debug : Set debug to this debug level") - print(" -k kodos_dir : Path containing Kodos images & help subdirs") - print(" -l locale | --locale=locale : 2-letter locale (eg. en)") - print('') - return - + print "kodos.py [-f filename | --file=filename ] [ -d debug | --debug=debug ] [ -k kodos_dir ]" + print + print " -f filename | --filename=filename : Load filename on startup" + print " -d debug | --debug=debug : Set debug to this debug level" + print " -k kodos_dir : Path containing Kodos images & help subdirs" + print " -l locale | --locale=locale : 2-letter locale (eg. en)" + print + sys.exit(0) def main(): filename = None @@ -1195,23 +1076,20 @@ def main(): ["file=", "debug=", "help", "locale="]) except: - print("\nInvalid command line option detected.") + print "\nInvalid command line option detected." usage() - return 2 for opt, arg in opts: if opt in ('-h', '-?', '--help'): usage() - return 0 if opt == '-k': kodos_dir = arg if opt in ('-d', '--debug'): try: debug = int(arg) except: - print("debug value must be an integer") + print "debug value must be an integer" usage() - return 2 if opt in ('-f', '--file'): filename = arg if opt in ('-l', '--locale'): @@ -1219,20 +1097,20 @@ def main(): os.environ['KODOS_DIR'] = kodos_dir - qApp = QtGui.QApplication(sys.argv) + qApp = QApplication(sys.argv) qApp.setOrganizationName("kodos") qApp.setApplicationName("kodos") qApp.setOrganizationDomain("kodos.sourceforge.net") if locale not in (None, 'en'): - localefile = "kodos_{0}.qm".format(locale or QtCore.QTextCodec.locale()) + localefile = "kodos_%s.qm" % (locale or QTextCodec.locale()) localepath = findFile(os.path.join("translations", localefile)) if debug: - print("locale changed to: {0}".format(locale)) - print(localefile) - print(localepath) + print "locale changed to:", locale + print localefile + print localepath - translator = QtCore.QTranslator(qApp) + translator = QTranslator(qApp) translator.load(localepath) qApp.installTranslator(translator) @@ -1241,10 +1119,9 @@ def main(): kodos.show() - return qApp.exec_() + sys.exit(qApp.exec_()) -if __name__ == '__main__': - sys.exit(main()) -#-----------------------------------------------------------------------------# +if __name__ == '__main__': + main() diff --git a/kodos.pro b/kodos.pro index db176a6..1e375b9 100644 --- a/kodos.pro +++ b/kodos.pro @@ -16,15 +16,16 @@ SOURCES = kodos modules/version.py TRANSLATIONS = translations/kodos_en.ts \ - translations/kodos_de.ts \ - translations/kodos_pl.ts + translations/kodos_pl.ts \ + translations/kodos_sv.ts FORMS = modules/aboutBA.ui \ modules/helpBA.ui \ modules/kodosBA.ui \ - modules/newUserDialogBA.ui \ + modules/newUserDialogBA.ui modules/prefsBA.ui \ modules/referenceBA.ui \ modules/regexLibraryBA.ui \ modules/reportBugBA.ui \ + modules/resultsBA.ui \ modules/urlDialogBA.ui diff --git a/modules/Makefile b/modules/Makefile index 0a7f167..f7b1fe7 100644 --- a/modules/Makefile +++ b/modules/Makefile @@ -7,4 +7,4 @@ clean: $(RM) -vf *.pyc %.py: %.ui - pyuic4 --from-imports -o $*.py $< + pyuic4 -w -o $*.py $< diff --git a/modules/about.py b/modules/about.py index 1edc1c5..8864760 100644 --- a/modules/about.py +++ b/modules/about.py @@ -1,26 +1,11 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: +# -*- coding: utf-8 -*- +# about.py: -*- Python -*- DESCRIPTIVE TEXT. -#-----------------------------------------------------------------------------# -# Installed modules - -from PyQt4 import QtGui, QtCore - -#-----------------------------------------------------------------------------# -# Kodos modules - -from .aboutBA import Ui_AboutBA +from . import aboutBA from . import version -#-----------------------------------------------------------------------------# - -class About(QtGui.QDialog, Ui_AboutBA): - def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()): - QtGui.QDialog.__init__(self, parent, f) - self.setupUi(self) - +class About(aboutBA.AboutBA): + def __init__(self): + aboutBA.AboutBA.__init__(self) self.versionLabel.setText(version.VERSION) - return -#-----------------------------------------------------------------------------# diff --git a/modules/debug.py b/modules/debug.py index 0b3cbb4..32fd790 100755 --- a/modules/debug.py +++ b/modules/debug.py @@ -1,9 +1,6 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: +# debug.py: -*- Python -*- DESCRIPTIVE TEXT. -#-----------------------------------------------------------------------------# -# DEBUGGING CONSTANTS +################################# DEBUGGING CONSTANTS ###################################### # debugging constants ... set debug to one of these # if adding new debug levels make sure the new ones are @@ -35,5 +32,3 @@ # use a bitwise or (|) to use multiple debug levels # debug = DEBUG_AUTO_COMPLETE | DEBUG_SESSION debug = DEBUG_NONE - -#-----------------------------------------------------------------------------# diff --git a/modules/flags.py b/modules/flags.py index 0b8f802..adaf0e4 100644 --- a/modules/flags.py +++ b/modules/flags.py @@ -1,16 +1,8 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: - -#-----------------------------------------------------------------------------# -# Built-in modules - +# coding=utf-8 from __future__ import print_function, absolute_import, unicode_literals import re -#-----------------------------------------------------------------------------# - class reFlag(object): def __init__(self, flag_name, short_flag, checkbox): if not flag_name.startswith('re.'): @@ -21,15 +13,11 @@ def __init__(self, flag_name, short_flag, checkbox): self.shortFlag = short_flag self.checkBox = checkbox self.preEmbedState = None - return - def clear(self): self.preEmbedState = None self.checkBox.setEnabled(True) self.checkBox.setChecked(False) - return - def embed(self): """Set the state of the checkbox to show that it @@ -38,16 +26,12 @@ def embed(self): self.preEmbedState = self.checkBox.isChecked() self.checkBox.setChecked(True) self.checkBox.setDisabled(True) - return - def deembed(self): if self.preEmbedState != None: self.checkBox.setEnabled(True) self.checkBox.setChecked(self.preEmbedState) self.preEmbedState = None - return - class reFlagList(list): def allFlagsORed(self): @@ -57,10 +41,6 @@ def allFlagsORed(self): ret |= f.reFlag return ret - def clearAll(self): for f in self: f.clear() - return - -#-----------------------------------------------------------------------------# diff --git a/modules/help.py b/modules/help.py index d31296c..b8b79c8 100755 --- a/modules/help.py +++ b/modules/help.py @@ -1,24 +1,13 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: - -#-----------------------------------------------------------------------------# -# Built-in modules +# -*- coding: utf-8 -*- +# help.py: -*- Python -*- DESCRIPTIVE TEXT. import os -#-----------------------------------------------------------------------------# -# Installed modules - -from PyQt4 import QtGui, QtCore - -#-----------------------------------------------------------------------------# -# Kodos modules +from PyQt4 import QtGui +from PyQt4 import QtCore from . import util -from .helpBA import Ui_HelpBA - -#-----------------------------------------------------------------------------# +from helpBA import HelpBA class textbrowser(QtGui.QTextBrowser): # reimplemented textbrowser that filters out external sources @@ -26,7 +15,6 @@ class textbrowser(QtGui.QTextBrowser): def __init__(self, parent=None, name=None): self.parent = parent QtGui.QTextBrowser.__init__(self) - return def setSource(self, src): @@ -36,57 +24,51 @@ def setSource(self, src): return QtGui.QTextBrowser.setSource(self, QtCore.QUrl(src)) - return -class Help(QtGui.QMainWindow, Ui_HelpBA): - def __init__(self, filename, parent=None, f=QtCore.Qt.WindowFlags()): - QtGui.QMainWindow.__init__(self, parent, f) - self.setupUi(self) + + +class Help(HelpBA): + def __init__(self, parent, filename): + HelpBA.__init__(self, parent) self.setGeometry(100, 50, 800, 600) + self.textBrowser = textbrowser(self) absPath = self.getHelpFile(filename) + self.setCentralWidget(self.textBrowser) self.textBrowser.setSource(absPath) + self.fwdAvailable = 0 self.show() - return def exitSlot(self): self.close() - return - def backSlot(self): self.textBrowser.backward() - return - def forwardSlot(self): self.textBrowser.forward() - return - def homeSlot(self): self.textBrowser.home() - return + def setForwardAvailable(self, bool): self.fwdAvailable = bool - return def forwardHandler(self): if self.fwdAvailable: self.textBrowser.forward() - return - def getHelpFile(self, filename): f = util.findFile(os.path.join("help", filename)) return f -#-----------------------------------------------------------------------------# + + diff --git a/modules/newUserDialog.py b/modules/newUserDialog.py deleted file mode 100644 index 227c158..0000000 --- a/modules/newUserDialog.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: - -#-----------------------------------------------------------------------------# -# Built-in modules - -from __future__ import absolute_import, print_function, unicode_literals - -#-----------------------------------------------------------------------------# -# Installed modules - -from PyQt4 import QtGui, QtCore - -#-----------------------------------------------------------------------------# -# Kodos modules - -from .newUserDialogBA import Ui_NewUserDialog - -#-----------------------------------------------------------------------------# - -class NewUserDialog(QtGui.QDialog, Ui_NewUserDialog): - def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()): - QtGui.QDialog.__init__(self, parent, f) - - self.setupUi(self) - -#-----------------------------------------------------------------------------# diff --git a/modules/parseRegexLib.py b/modules/parseRegexLib.py index 4f55955..d58c233 100644 --- a/modules/parseRegexLib.py +++ b/modules/parseRegexLib.py @@ -1,19 +1,7 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: - -#-----------------------------------------------------------------------------# -# Built-in modules - import re import os +from util import findFile -#-----------------------------------------------------------------------------# -# Kodos modules - -from .util import findFile - -#-----------------------------------------------------------------------------# rx_entry = re.compile(r"(?P.*?)", re.DOTALL) @@ -42,8 +30,6 @@ def __init__(self, filename): self.data = data else: self.data = "" - return - def parse(self, data=""): if not data: data = self.data @@ -64,13 +50,12 @@ def parse(self, data=""): return dicts - if __name__ == '__main__': path = findFile(os.path.join("help", "regex-lib.xml")) x = ParseRegexLib(path) dicts = x.parse() - print(dicts) + print dicts + -#-----------------------------------------------------------------------------# diff --git a/modules/prefs.py b/modules/prefs.py index cc62aeb..56ea409 100644 --- a/modules/prefs.py +++ b/modules/prefs.py @@ -1,34 +1,23 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: +# -*- coding: utf-8 -*- +# prefs.py: -*- Python -*- DESCRIPTIVE TEXT. -#-----------------------------------------------------------------------------# -# Installed modules +from PyQt4.QtCore import pyqtSignal, QSettings +from PyQt4.QtGui import QDialog, QFontDialog +from prefsBA import PrefsBA +import help -from PyQt4 import QtGui, QtCore +class Preferences(PrefsBA): -#-----------------------------------------------------------------------------# -# Kodos modules + prefsSaved = pyqtSignal() -from .prefsBA import Ui_PrefsBA -from .help import Help - -#-----------------------------------------------------------------------------# - -class Preferences(QtGui.QDialog, Ui_PrefsBA): - - prefsSaved = QtCore.pyqtSignal() + def __init__(self, parent, autoload=0): + self.parent = parent + PrefsBA.__init__(self, parent) - def __init__(self, autoload=0, parent=None, f=QtCore.Qt.WindowFlags()): - QtGui.QDialog.__init__(self, parent, f) - self.setupUi(self) + self.settings = QSettings() - self.parent = parent - self.settings = QtCore.QSettings() if autoload: self.load() - return - def load(self): for preference in self.settings.childKeys(): @@ -42,10 +31,9 @@ def load(self): self.emailServerEdit.setText(setting.toPyObject()) if preference == 'Recent Files Count': self.recentFilesSpinBox.setValue(int(setting.toPyObject())) - except Exception: - print("Loading of configuration key {0} failed.".format(preference)) + except Exception, e: + print "Loading of configuration key", preference, "failed." self.settings.remove(preference) - return def save(self): @@ -56,14 +44,10 @@ def save(self): self.settings.sync() self.prefsSaved.emit() - return - def setFontButtonText(self, button, font): - #self.fontButton.setText("{0} {1}".format(str(font.family()), font.pointSize())) - button.setText("{0} {1}".format(str(font.family()), font.pointSize())) - return - + #self.fontButton.setText("%s %s" % (str(font.family()),font.pointSize() )) + button.setText("%s %s" % (str(font.family()),font.pointSize() )) def showPrefsDialog(self): f = self.parent.getfont() @@ -75,40 +59,28 @@ def showPrefsDialog(self): self.setFontButtonText(self.fontButtonMatch, f) self.show() - return - def font_slot(self): - (font, ok) = QtGui.QFontDialog.getFont(self.fontButton.font()) + (font, ok) = QFontDialog.getFont(self.fontButton.font()) if ok: self.fontButton.setFont(font) self.setFontButtonText(self.fontButton, font) - return - def match_font_slot(self): - (font, ok) = QtGui.QFontDialog.getFont(self.fontButtonMatch.font()) + (font, ok) = QFontDialog.getFont(self.fontButtonMatch.font()) if ok: self.fontButtonMatch.setFont(font) self.setFontButtonText(self.fontButtonMatch, font) - return - def apply_slot(self): self.parent.setfont(self.fontButton.font()) self.parent.setMatchFont(self.fontButtonMatch.font()) self.save() - return - def accept(self): self.apply_slot() - QtGui.QDialog.accept(self) - return - + QDialog.accept(self) def help_slot(self): - self.helpWindow = Help(filename="prefs.html", parent=self) - return + self.helpWindow = help.Help(self, "prefs.html") -#-----------------------------------------------------------------------------# diff --git a/modules/recent_files.py b/modules/recent_files.py index 83cb3a7..31b7dc8 100644 --- a/modules/recent_files.py +++ b/modules/recent_files.py @@ -1,13 +1,7 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: +# -*- coding: utf-8 -*- -#-----------------------------------------------------------------------------# -# Installed modules - -from PyQt4 import QtGui, QtCore - -#-----------------------------------------------------------------------------# +from PyQt4.QtGui import QIcon, QPixmap +from PyQt4.QtCore import QSettings MAX_SIZE = 50 # max number of files to retain @@ -19,14 +13,11 @@ def __init__(self, parent, numShown=5, debug=None): self.__recent_files = [] self.__indecies = [] self.load() - return - def load(self): - settings = QtCore.QSettings() - # PyQt-BUG: beginReadArray() should return array size but returns always 0 - # as a workaround we loop until a value is "None". - settings.beginReadArray("RecentFiles") + settings = QSettings() + cnt = settings.beginReadArray("RecentFiles") + # PyQt bug: cnt is always 0, workaround with "None" test below i = -1 while True: i += 1 @@ -36,23 +27,21 @@ def load(self): if s == None: break self.__recent_files.append(str(s)) - except Exception as e: - print("Loading of recent file entry {0} failed.".format(i)) - if self.debug: print(e) + except Exception, e: + print "Loading of recent file entry", i, "failed." + if self.debug: print e settings.remove("Filename") settings.endArray() - if self.debug: print("recent_files: {0}".format(self.__recent_files)) + if self.debug: print "recent_files:", self.__recent_files self.addToMenu() - return - def save(self): # truncate list if necessary self.__recent_files = self.__recent_files[:MAX_SIZE] - s = QtCore.QSettings() + s = QSettings() s.beginWriteArray("RecentFiles") cnt = 0 for f in self.__recent_files: @@ -60,8 +49,6 @@ def save(self): s.setValue("Filename", f) cnt += 1 s.sync() - return - def add(self, filename): try: @@ -72,7 +59,6 @@ def add(self, filename): self.__recent_files.insert(0, filename) self.save() self.addToMenu() - return def clearMenu(self): @@ -82,7 +68,6 @@ def clearMenu(self): # clear list of menu entry indecies self.__indecies = [] - return def addToMenu(self, clear=1): @@ -93,11 +78,10 @@ def addToMenu(self, clear=1): for i in range(num): filename = self.__recent_files[i] idx = self.parent.fileMenu.addAction( - QtGui.QIcon(QtGui.QPixmap(":images/document-open-recent.png")), + QIcon(QPixmap(":images/document-open-recent.png")), filename) self.__indecies.insert(0, idx) - return def setNumShown(self, numShown): @@ -108,21 +92,18 @@ def setNumShown(self, numShown): self.clearMenu() self.numShown = ns self.addToMenu(0) - return def isRecentFile(self, menuid): return menuid in self.__indecies -""" def move(self, filename, menuid): # fix me.... menu = self.parent.fileMenu idx = menu.indexOf(self.__indecies[0]) menu.removeItem(menuid) - # FIXME there is no QIconSet - menu.insertItem(QIconSet(QtGui.QPixmap(":images/document-open-recent.png")), + menu.insertItem(QIconSet(QPixmap(":images/document-open-recent.png")), filename, -1, idx) @@ -131,7 +112,4 @@ def move(self, filename, menuid): except: pass self.__indecies.insert(0, filename) - return -""" -#-----------------------------------------------------------------------------# diff --git a/modules/reference.py b/modules/reference.py index 9ee2e63..85c2627 100644 --- a/modules/reference.py +++ b/modules/reference.py @@ -1,40 +1,27 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: +# -*- coding: utf-8 -*- +# reference.py: -*- Python -*- DESCRIPTIVE TEXT. -#-----------------------------------------------------------------------------# -# Installed modules - -from PyQt4 import QtGui, QtCore - -#-----------------------------------------------------------------------------# -# Kodos modules - -from .referenceBA import Ui_ReferenceBA -from .util import kodos_toolbar_logo, restoreWindowSettings, saveWindowSettings - -#-----------------------------------------------------------------------------# +from PyQt4.QtCore import pyqtSignal +from referenceBA import ReferenceBA +from util import kodos_toolbar_logo, restoreWindowSettings, saveWindowSettings GEO = "regex-ref_geometry" -class Reference(QtGui.QMainWindow, Ui_ReferenceBA): +class Reference(ReferenceBA): - pasteSymbol = QtCore.pyqtSignal(str) - - def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()): - QtGui.QMainWindow.__init__(self, parent, f) - self.setupUi(self) + pasteSymbol = pyqtSignal(str) + def __init__(self, parent): + ReferenceBA.__init__(self, None) self.parent = parent + restoreWindowSettings(self, GEO) kodos_toolbar_logo(self.toolBar) - return def closeEvent(self, ev): saveWindowSettings(self, GEO) ev.accept() - return def editPaste(self): @@ -44,16 +31,10 @@ def editPaste(self): symbol = str(list_view_item.text(0)) self.pasteSymbol.emit(symbol) - return - def help_help_slot(self): + def help_slot(self): self.parent.helpHelp() - return - def help_python_slot(self): self.parent.helpPythonRegex() - return - -#-----------------------------------------------------------------------------# diff --git a/modules/referenceBA.ui b/modules/referenceBA.ui index be51648..b1c67e7 100644 --- a/modules/referenceBA.ui +++ b/modules/referenceBA.ui @@ -357,7 +357,7 @@ &Help - + @@ -612,7 +612,7 @@ helpAboutAction - + :/images/help.png:/images/help.png @@ -624,7 +624,7 @@ Help - helpHelpAction + helpAction @@ -677,10 +677,10 @@ - helpHelpAction + helpAction activated() ReferenceBA - help_help_slot() + help_slot() -1 diff --git a/modules/regexLibrary.py b/modules/regexLibrary.py index 0ab0a2a..13af979 100644 --- a/modules/regexLibrary.py +++ b/modules/regexLibrary.py @@ -1,57 +1,40 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: - -#-----------------------------------------------------------------------------# -# Installed modules - -from PyQt4 import QtGui, QtCore - -#-----------------------------------------------------------------------------# -# Kodos modules - -from .regexLibraryBA import Ui_RegexLibraryBA -from .parseRegexLib import ParseRegexLib -from .util import restoreWindowSettings, saveWindowSettings, kodos_toolbar_logo - -#-----------------------------------------------------------------------------# +# -*- coding: utf-8 -*- +from PyQt4.QtCore import pyqtSignal +from regexLibraryBA import RegexLibraryBA +from parseRegexLib import ParseRegexLib +from util import restoreWindowSettings, saveWindowSettings, kodos_toolbar_logo GEO = "regex-lib_geometry" -class RegexLibrary(QtGui.QMainWindow, Ui_RegexLibraryBA): - - pasteRegexLib = QtCore.pyqtSignal(dict) +class RegexLibrary(RegexLibraryBA): - def __init__(self, filename, parent=None, f=QtCore.Qt.WindowFlags()): - QtGui.QMainWindow.__init__(self, parent, f) - self.setupUi(self) + pasteRegexLib = pyqtSignal(dict) + def __init__(self, filename): + RegexLibraryBA.__init__(self, None) self.filename = filename - self.parent = parent self.selected = None + self.parseXML() + self.populateListBox() kodos_toolbar_logo(self.toolBar) - restoreWindowSettings(self, GEO) - return + restoreWindowSettings(self, GEO) def closeEvent(self, ev): saveWindowSettings(self, GEO) ev.accept() - return def parseXML(self): parser = ParseRegexLib(self.filename) self.xml_dicts = parser.parse() - return def populateListBox(self): for d in self.xml_dicts: self.descriptionListBox.addItem(d.get('desc', "")) - return def descSelectedSlot(self, qlistboxitem): @@ -59,7 +42,6 @@ def descSelectedSlot(self, qlistboxitem): itemnum = self.descriptionListBox.currentRow() self.populateSelected(self.xml_dicts[itemnum]) - return def populateSelected(self, xml_dict): @@ -67,16 +49,13 @@ def populateSelected(self, xml_dict): self.contribEdit.setText(xml_dict.get("contrib", "")) self.noteTextBrowser.setPlainText(xml_dict.get('note', "")) self.selected = xml_dict - return def editPaste(self): if self.selected: self.pasteRegexLib.emit(self.selected) - return - def help_help_slot(self): - self.parent.helpHelp() - return -#-----------------------------------------------------------------------------# + + + diff --git a/modules/regexLibraryBA.ui b/modules/regexLibraryBA.ui index e603017..ecd6673 100644 --- a/modules/regexLibraryBA.ui +++ b/modules/regexLibraryBA.ui @@ -224,12 +224,6 @@ - - helpHelpAction - activated() - RegexLibraryBA - help_help_slot() - descSelectedSlot() diff --git a/modules/reportBug.py b/modules/reportBug.py index 9333bc4..e4351e4 100644 --- a/modules/reportBug.py +++ b/modules/reportBug.py @@ -1,55 +1,37 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: - -#-----------------------------------------------------------------------------# -# Built-in modules - +# -*- coding: utf-8 -*- +# reportBug.py: -*- Python -*- DESCRIPTIVE TEXT. + +from reportBugBA import reportBugBA +from util import * +from PyQt4.QtGui import * +from PyQt4.QtCore import * +from PyQt4 import * import sys import string import smtplib - -#-----------------------------------------------------------------------------# -# Installed modules - -from PyQt4 import QtGui, QtCore - -#-----------------------------------------------------------------------------# -# Kodos modules - -from .reportBugBA import Ui_reportBugBA -from .util import kodos_toolbar_logo -from .version import VERSION - -#-----------------------------------------------------------------------------# +from version import VERSION AUTHOR_ADDR = "phil_schwartz@users.sourceforge.net" -class reportBug(QtGui.QWidget, Ui_reportBugBA): - def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()): - QtGui.QWidget.__init__(self, parent, f) - self.setupUi(self) - +class reportBug(reportBugBA): + def __init__(self, parent=None, name=None): + reportBugBA.__init__(self, parent) self.parent = parent self.kodos_main = parent.kodos_main self.populate() - return def populate(self): self.OSEdit.setText(sys.platform) pyvers = string.replace(sys.version, "\n", " - ") self.pythonVersionEdit.setText(pyvers) - self.PyQtVersionEdit.setText(QtCore.QT_VERSION_STR) + self.PyQtVersionEdit.setText(QT_VERSION_STR) self.regexMultiLineEdit.setPlainText(self.kodos_main.regexMultiLineEdit.toPlainText()) self.stringMultiLineEdit.setPlainText(self.kodos_main.stringMultiLineEdit.toPlainText()) - return def cancel_slot(self): self.parent.close() - return - def submit_slot(self): addr = str(self.emailAddressEdit.text()) @@ -59,54 +41,47 @@ def submit_slot(self): "can contact you. Your email address will not " "be used for any other purposes.") - QtGui.QMessageBox.information( - None, - self.tr("You must supply a valid email address"), - msg - ) + QMessageBox.information(None, + self.tr("You must supply a valid email address"), + msg) return msg = "Subject: Kodos bug report\n\n" - msg += "Kodos Version: {0}\n".format(VERSION) - msg += "Operating System: {0}\n".format(unicode(self.OSEdit.text())) - msg += "Python Version: {0}\n".format(unicode(self.pythonVersionEdit.text())) - msg += "PyQt Version: {0}\n".format(unicode(self.PyQtVersionEdit.text())) + msg += "Kodos Version: %s\n" % VERSION + msg += "Operating System: %s\n" % unicode(self.OSEdit.text()) + msg += "Python Version: %s\n" % unicode(self.pythonVersionEdit.text()) + msg += "PyQt Version: %s\n" % unicode(self.PyQtVersionEdit.text()) msg += "\n" + "=" * 70 + "\n" - msg += "Regex:\n{0}\n".format(unicode(self.regexMultiLineEdit.text())) + msg += "Regex:\n%s\n" % unicode(self.regexMultiLineEdit.text()) msg += "=" * 70 + "\n" - msg += "String:\n{0}\n".format(unicode(self.stringMultiLineEdit.text())) + msg += "String:\n%s\n" % unicode(self.stringMultiLineEdit.text()) msg += "=" * 70 + "\n" - msg += "Comments:\n{0}\n".format(unicode(self.commentsMultiLineEdit.text())) + msg += "Comments:\n%s\n" % unicode(self.commentsMultiLineEdit.text()) email_server = unicode(self.kodos_main.prefs.emailServerEdit.text()) or "localhost" try: server = smtplib.SMTP(email_server) server.sendmail(addr, AUTHOR_ADDR, msg) server.quit() - QtGui.QMessageBox.information( - None, - self.tr("Bug report sent"), - self.tr("Your bug report has been sent.") - ) + QMessageBox.information(None, + self.tr("Bug report sent"), + self.tr("Your bug report has been sent.")) self.parent.close() - except Exception as e: - QtGui.QMessageBox.information( - None, - self.tr("An exception occurred sending bug report"), - str(e) - ) - return + except Exception, e: + QMessageBox.information(None, + self.tr("An exception occurred sending bug report"), + str(e)) -class reportBugWindow(QtGui.QMainWindow): +class reportBugWindow(QMainWindow): def __init__(self, kodos_main): self.kodos_main = kodos_main - QtGui.QMainWindow.__init__(self, kodos_main) + QMainWindow.__init__(self, kodos_main)#, Qt.Window | Qt.WA_DeleteOnClose) self.setGeometry(100, 50, 800, 600) self.setWindowTitle(self.tr("Report a Bug")) - self.setWindowIcon(QtGui.QIcon(QtGui.QPixmap(":images/kodos_icon.png"))) + self.setWindowIcon(QIcon(QPixmap(":images/kodos_icon.png"))) - self.bug_report = reportBug(parent=self) + self.bug_report = reportBug(self) self.setCentralWidget(self.bug_report) @@ -114,20 +89,16 @@ def __init__(self, kodos_main): self.createToolBar() self.show() - return def createMenu(self): self.menubar = self.menuBar() self.filemenu = self.menubar.addMenu(self.tr("&File")) - self.filemenu.addAction(self.tr("&Close"), self, QtCore.SLOT("close()")) - return + self.filemenu.addAction(self.tr("&Close"), self, SLOT("close()")) def createToolBar(self): - toolbar = QtGui.QToolBar() + toolbar = QToolBar() self.addToolBar(toolbar) self.logolabel = kodos_toolbar_logo(toolbar) - return -#-----------------------------------------------------------------------------# diff --git a/modules/status_bar.py b/modules/status_bar.py index 0e8298f..e0ba25a 100644 --- a/modules/status_bar.py +++ b/modules/status_bar.py @@ -1,49 +1,39 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: +# -*- coding: utf-8 -*- +# status_bar.py: -*- Python -*- DESCRIPTIVE TEXT. -#-----------------------------------------------------------------------------# -# Installed modules - -from PyQt4 import QtGui, QtCore - -#-----------------------------------------------------------------------------# -# Kodos modules - -from .tooltip import Tooltip -from .util import TRUE, FALSE - -#-----------------------------------------------------------------------------# +from tooltip import Tooltip +from util import TRUE, FALSE +from PyQt4.QtCore import QTimer +from PyQt4.QtGui import QPixmap, QLabel, QProgressBar class Status_Bar: def __init__(self, parent, progress_bar=FALSE, message=''): self.parent = parent self.statusBar = parent.statusBar() - self.__statusTimer = QtCore.QTimer(self.parent) + self.__statusTimer = QTimer(self.parent) self.__statusTimer.timeout.connect(self.reset_message) - self.__statusLabel = QtGui.QLabel("msg", self.statusBar) + self.__statusLabel = QLabel("msg", self.statusBar) self.tooltip = Tooltip('') self.tooltip.addWidget(self.__statusLabel) self.last_status_message = '' - pixmap = QtGui.QPixmap(":images/yellow.png") + pixmap = QPixmap(":images/yellow.png") - self.pixmapLabel = QtGui.QLabel("image", self.statusBar) + self.pixmapLabel = QLabel("image", self.statusBar) self.pixmapLabel.setPixmap(pixmap) self.statusBar.addWidget(self.pixmapLabel) self.statusBar.addWidget(self.__statusLabel) if progress_bar: - self.progressBar = QtGui.QProgressBar(self.statusBar) + self.progressBar = QProgressBar(self.statusBar) self.statusBar.addWidget(self.progressBar, 1, TRUE) if message: self.set_message(message) - return def set_message(self, message='', duration=0, replace=FALSE, tooltip='', pixmap=''): @@ -72,7 +62,7 @@ def set_message(self, message='', duration=0, replace=FALSE, tooltip='', pixmap= if pixmap: self.pixmapLabel.setPixmap(pixmap) - return + def reset_message(self): @@ -81,10 +71,8 @@ def reset_message(self): self.__statusLabel.setText(self.last_status_message) else: self.__statusLabel.setText('') - return + def geometry(self): return self.statusBar.geometry() - -#-----------------------------------------------------------------------------# diff --git a/modules/tooltip.py b/modules/tooltip.py index 51e646b..ae3dd8e 100644 --- a/modules/tooltip.py +++ b/modules/tooltip.py @@ -1,73 +1,51 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: +# -*- coding: utf-8 -*- +# tooltip.py: -*- Python -*- DESCRIPTIVE TEXT. -#-----------------------------------------------------------------------------# -# Installed modules +from PyQt4.QtGui import * +from PyQt4.QtCore import * +from util import * -from PyQt4 import QtGui, QtCore - -#-----------------------------------------------------------------------------# -# Kodos modules - -from .util import FALSE - -#-----------------------------------------------------------------------------# - -class Tooltip(QtGui.QLabel): +class Tooltip(QLabel): def __init__(self, text, bgcolor="#ffd700",fgcolor="#000000",delay=1000): self.delay = delay - QtGui.QLabel.__init__( - self, - None, - QtCore.Qt.WindowStaysOnTopHint | - QtCore.Qt.FramelessWindowHint | - QtCore.Qt.Tool - ) + QLabel.__init__(self, None, Qt.WindowStaysOnTopHint + | Qt.FramelessWindowHint + | Qt.Tool) self.setMargin(1) self.setIndent(0) - self.setFrameStyle(QtGui.QFrame.Plain | QtGui.QFrame.Box) + self.setFrameStyle(QFrame.Plain | QFrame.Box) self.setLineWidth(1) self.setText(text) self.adjustSize() # set the pallete... - pal = QtGui.QPalette() - pal.setColor(QtGui.QPalette.Active, QtGui.QPalette.Window, - QtGui.QColor(bgcolor)) - pal.setColor(QtGui.QPalette.Active, QtGui.QPalette.WindowText, - QtGui.QColor(fgcolor)) - pal.setColor(QtGui.QPalette.Inactive, QtGui.QPalette.Window, - QtGui.QColor(bgcolor)) - pal.setColor(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText, - QtGui.QColor(fgcolor)) + pal = QPalette() + pal.setColor(QPalette.Active, QPalette.Window, QColor(bgcolor)) + pal.setColor(QPalette.Active, QPalette.WindowText, QColor(fgcolor)) + pal.setColor(QPalette.Inactive, QPalette.Window, QColor(bgcolor)) + pal.setColor(QPalette.Inactive, QPalette.WindowText, QColor(fgcolor)) self.setPalette(pal) self.enter_timer_id = None self.leave_timer_id = None - return def set_tooltip(self, text): self.text = text self.setText(text) - return def clear_tooltip(self): self.text = '' self.setText('') - return def addWidget(self, widget): widget.installEventFilter(self) - return def removeWidget(self, widget): widget.removeEventFilter(self) - return def killCustomTimers( self ): @@ -77,7 +55,6 @@ def killCustomTimers( self ): if self.leave_timer_id: self.killTimer( self.leave_timer_id ) self.leave_timer_id = None - return def timerEvent( self, ev ): @@ -86,16 +63,15 @@ def timerEvent( self, ev ): elif ev.timerId() == self.leave_timer_id: self.tooltip_close() self.killCustomTimers() - return def eventFilter(self, obj, ev): type = ev.type() - if type == QtCore.QEvent.Enter: + if type == QEvent.Enter: self.killCustomTimers() self.enter_timer_id = self.startTimer(self.delay) self.event_widget = obj - elif type == QtCore.QEvent.Leave: + elif type == QEvent.Leave: self.killCustomTimers() self.leave_timer_id = self.startTimer(self.delay) self.event_widget = None @@ -108,17 +84,13 @@ def tooltip_open(self): try: pos = self.event_widget.mapToGlobal( - QtCore.QPoint(0, self.event_widget.height())) + QPoint(0, self.event_widget.height())) self.move(pos.x(), pos.y()) self.show() self.setFixedSize( self.sizeHint() ) except: pass - return def tooltip_close(self): self.hide() - return - -#-----------------------------------------------------------------------------# diff --git a/modules/urlDialog.py b/modules/urlDialog.py index e3c99ab..1900bf2 100644 --- a/modules/urlDialog.py +++ b/modules/urlDialog.py @@ -1,56 +1,33 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: - -#-----------------------------------------------------------------------------# -# Built-in modules - +# -*- coding: utf-8 -*- +from PyQt4.QtCore import pyqtSignal +from PyQt4.QtGui import QMessageBox +from urlDialogBA import URLDialogBA +import help import urllib -#-----------------------------------------------------------------------------# -# Installed modules - -from PyQt4 import QtGui, QtCore - -#-----------------------------------------------------------------------------# -# Kodos modules - -from .urlDialogBA import Ui_URLDialogBA -from . import help - -#-----------------------------------------------------------------------------# -class URLDialog(QtGui.QDialog, Ui_URLDialogBA): +class URLDialog(URLDialogBA): - urlImported = QtCore.pyqtSignal(str, str) - - def __init__(self, url=None, parent=None, f=QtCore.Qt.WindowFlags()): - QtGui.QDialog.__init__(self, parent, f) - self.setupUi(self) + urlImported = pyqtSignal(str, str) + def __init__(self, parent, url=None): + URLDialogBA.__init__(self, parent) if url: self.URLTextEdit.setPlainText(url) - self.show() - return + self.show() def help_slot(self): self.helpWindow = help.Help(self, "importURL.html") - return - def ok_slot(self): url = str(self.URLTextEdit.toPlainText()) try: fp = urllib.urlopen(url) lines = fp.readlines() - except Exception as e: - QtGui.QMessageBox.information( - None, - "Failed to open URL", - "Could not open the specified URL. Please check to ensure \ - that you have entered the correct URL.\n\n{0}".format(str(e)) - ) + except Exception, e: + QMessageBox.information(None, "Failed to open URL", + "Could not open the specified URL. Please check to ensure that you have entered the correct URL.\n\n%s" % str(e)) return @@ -58,7 +35,4 @@ def ok_slot(self): self.urlImported.emit(html, url) - self.accept() - return - -#-----------------------------------------------------------------------------# + URLDialogBA.accept(self) diff --git a/modules/util.py b/modules/util.py index 4485238..2fca4f0 100644 --- a/modules/util.py +++ b/modules/util.py @@ -1,25 +1,14 @@ -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: - -#-----------------------------------------------------------------------------# -# Built-in modules +# -*- coding: utf-8 -*- +# util.py: -*- Python -*- DESCRIPTIVE TEXT. import os +import os.path import sys +from debug import * import webbrowser -#-----------------------------------------------------------------------------# -# Installed modules - -from PyQt4 import QtGui, QtCore - -#-----------------------------------------------------------------------------# -# Kodos modules - -from .debug import debug, DEBUG_PIXMAP - -#-----------------------------------------------------------------------------# +from PyQt4.QtGui import * +from PyQt4.QtCore import * # QT constants that should be defined FALSE = 0 @@ -40,40 +29,33 @@ def getPixmap(fileStr, fileType="PNG", dir="images"): image = getAppPath() + os.sep + dir + os.sep + fileStr - if debug & DEBUG_PIXMAP: print("image: {0}".format(image)) + if debug & DEBUG_PIXMAP: print "image:", image - pixmap = QtGui.QPixmap(image, fileType) + pixmap = QPixmap(image, fileType) pixmap.setMask(pixmap.createHeuristicMask(1)) return pixmap - def kodos_toolbar_logo(toolbar): # hack to move logo to right - blanklabel = QtGui.QLabel() - blanklabel.setSizePolicy(QtGui.QSizePolicy.Expanding, - QtGui.QSizePolicy.Preferred) + blanklabel = QLabel() + blanklabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) - logolabel = QtGui.QLabel("kodos_logo") - logolabel.setPixmap(QtGui.QPixmap(":/images/kodos_icon.png")) + logolabel = QLabel("kodos_logo") + logolabel.setPixmap(QPixmap(":/images/kodos_icon.png")) toolbar.addWidget(blanklabel) toolbar.addWidget(logolabel) return logolabel - def saveWindowSettings(window, filename): - settings = QtCore.QSettings() + settings = QSettings() settings.setValue(window.objectName(), window.saveGeometry()) - return - def restoreWindowSettings(window, filename): - settings = QtCore.QSettings() + settings = QSettings() window.restoreGeometry(settings.value(window.objectName()).toByteArray()) - return - def findFile(filename): dirs = [getAppPath(), @@ -86,26 +68,18 @@ def findFile(filename): return None - def launch_browser(url, caption=None, message=None): if not caption: caption = "Info" if not message: message = "Launch web browser?" - button = QtGui.QMessageBox.information( - None, - caption, - message, - QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel - ) - if button == QtGui.QMessageBox.Cancel: + button = QMessageBox.information(None, caption, message, QMessageBox.Ok | QMessageBox.Cancel) + if button == QMessageBox.Cancel: return False try: webbrowser.open(url) - except webbrowser.Error as e: + except webbrowser.Error, e: if debug: - print(e) - print("Couldn't open URL: {0}".format(url)) + print e + print "Couldn't open URL:", url return False return True - -#-----------------------------------------------------------------------------# diff --git a/py2exe-setup.py b/py2exe-setup.py index 1d78eb1..8f8c3af 100644 --- a/py2exe-setup.py +++ b/py2exe-setup.py @@ -1,27 +1,16 @@ #!/usr/bin/env python -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: - -#-----------------------------------------------------------------------------# -# Built-in modules - +# -*- coding: utf-8 -*- +from modules.version import VERSION +from distutils.core import setup +#from distutils.sysconfig import get_python_lib import os +import os.path import sys from glob import glob -from distutils.core import setup - -#-----------------------------------------------------------------------------# -# Installed modules - -import py2exe - -#-----------------------------------------------------------------------------# -# Kodos modules - -from modules.version import VERSION - -#-----------------------------------------------------------------------------# +try: + import py2exe +except: + pass args = sys.argv[1:] @@ -44,7 +33,7 @@ MODULES_DIR = os.path.join(libpath, "modules") TRANSLATIONS_DIR = os.path.join(libpath, "translations") -#-----------------------------------------------------------------------------# +######################################################################### setup(name="kodos", version=VERSION, @@ -73,4 +62,3 @@ """ ) -#-----------------------------------------------------------------------------# diff --git a/scripts/bapro2qtpro.py b/scripts/bapro2qtpro.py index dec91d7..0491450 100755 --- a/scripts/bapro2qtpro.py +++ b/scripts/bapro2qtpro.py @@ -1,16 +1,5 @@ -#!/usr/bin/env python -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: - -#-----------------------------------------------------------------------------# -# Built-in modules - -import os -import sys -import re - -#-----------------------------------------------------------------------------# +#!/bin/env python +import os, sys, re # regular expressions from Kodos (http://kodos.sourceforge.net) rx_folder = re.compile(r'''\ @@ -26,7 +15,6 @@ def __init__(self, infile, outfile): modules = self.getModules(infile) translations = self.getTranslations(outfile) self.saveQtFile(outfile, modules, translations) - return def getTranslations(self, outfile): @@ -99,18 +87,17 @@ def saveQtFile(self, outfile, modules, translations): fp.write("SOURCES = "); for module in modules: - fp.write("{0} ".format(module)) + fp.write("%s " % module) fp.write("\n") - fp.write("TRANSLATIONS = {0}\n".format(translations)) - return + fp.write("TRANSLATIONS = %s\n" % translations) -#-----------------------------------------------------------------------------# +################################################################################## def usage(): - print("Usage: {0} ba.pro qt.pro".format(sys.argv[0])) - return + print "Usage: ", sys.argv[0], " ba.pro qt.pro" + sys.exit(1) def convert(): try: @@ -118,19 +105,15 @@ def convert(): outfile = sys.argv[2] if infile == outfile: - print("ba.pro and qt.pro must refer to different filenames\n") + print "ba.pro and qt.pro must refer to different filenames\n" usage() - return 2 except: usage() - return 1 - Convert(infile, outfile) - return 0 + c = Convert(infile, outfile) -#-----------------------------------------------------------------------------# +################################################################################## if __name__ == '__main__': - sys.exit(convert()) + convert() -#-----------------------------------------------------------------------------# diff --git a/scripts/pyuicfix.py b/scripts/pyuicfix.py index 9326cd6..605bb61 100755 --- a/scripts/pyuicfix.py +++ b/scripts/pyuicfix.py @@ -1,21 +1,9 @@ -#!/usr/bin/env python -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: - -""" -this should be invoked by a pyuic wrapper -it looks for the arg after the -o cmd line flag -which is used as the source AND destination file. -""" - -#-----------------------------------------------------------------------------# -# Built-in modules - -import sys -import re - -#-----------------------------------------------------------------------------# +#!/bin/env python +# +# this should be invoked by a pyuic wrapper +# it looks for the arg after the -o cmd line flag +# which is used as the source AND destination file. +import sys, os, re filename = None args = sys.argv[1:] @@ -27,7 +15,7 @@ break if not filename: - print("Error: could not extract filename from: {0}".format(args)) + print "Error: could not extract filename from:", args sys.exit(0) fp = open(filename, "r") @@ -35,6 +23,7 @@ fp.close() + # regex from Kodos (of course!) rx = re.compile(r"""self\.clearWState\(Qt\.WState_Polished\)""") repl = """try: @@ -45,6 +34,7 @@ pycode = rx.sub(repl, pycode) + rx = re.compile(r"""\.setAccel\((?P.*)""") pos = 0 while 1: @@ -59,8 +49,10 @@ pycode[m.end():] + + + fp = open(filename, "w") fp.write(pycode) fp.close() -#-----------------------------------------------------------------------------# diff --git a/setup.py b/setup.py index dd83955..10d62ed 100644 --- a/setup.py +++ b/setup.py @@ -1,23 +1,13 @@ #!/usr/bin/env python -# -*- coding: utf-8; mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: 0 -*- -# vi: set fileencoding=utf-8 filetype=python expandtab tabstop=4 shiftwidth=4 softtabstop=4 cindent: -# :mode=python:indentSize=4:tabSize=4:noTabs=true: - -#-----------------------------------------------------------------------------# -# Built-in modules - +# -*- coding: utf-8 -*- +from modules.version import VERSION +from distutils.core import setup +from distutils.command.install import install as DistutilsInstall +#from distutils.sysconfig import get_python_lib import os +import os.path import sys from glob import glob -from distutils.core import setup -from distutils.command.install import install as DistutilsInstall - -#-----------------------------------------------------------------------------# -# Kodos modules - -from modules.version import VERSION - -#-----------------------------------------------------------------------------# args = sys.argv[1:] @@ -45,7 +35,7 @@ def run(self): os.system('make') DistutilsInstall.run(self) -#-----------------------------------------------------------------------------# +######################################################################### setup(name="kodos", version=VERSION, @@ -71,4 +61,3 @@ def run(self): cmdclass={'install':MyInstall}, ) -#-----------------------------------------------------------------------------# From 8619e4389e4fc0a9b91a6eb92c7641467dcd8bea Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Thu, 9 Aug 2012 20:16:38 +0200 Subject: [PATCH 02/37] Use the github page for the kodos project page url --- kodos | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kodos b/kodos index 8446047..5a433ae 100755 --- a/kodos +++ b/kodos @@ -983,7 +983,8 @@ class Kodos(KodosBA): def kodos_website(self): - self.launch_browser_wrapper("http://kodos.sourceforge.net") + self.launch_browser_wrapper('https://github.com/luksan/kodos', + message=self.tr('Launch web browser to go to the kodos project page?')) def check_for_update(self): From f76d70d2f3d4c879460b05933ceb699e4f9bfa06 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Thu, 9 Aug 2012 19:23:21 +0200 Subject: [PATCH 03/37] Remove the check_for_updates functionality --- kodos | 42 ------------------------------------------ modules/kodosBA.ui | 17 ----------------- 2 files changed, 59 deletions(-) diff --git a/kodos b/kodos index 5a433ae..f7797ed 100755 --- a/kodos +++ b/kodos @@ -987,48 +987,6 @@ class Kodos(KodosBA): message=self.tr('Launch web browser to go to the kodos project page?')) - def check_for_update(self): - url = "http://sourceforge.net/project/showfiles.php?group_id=43860" - try: - fp = urllib.urlopen(url) - except: - self.status_bar.set_message(self.tr("Failed to open url"), - 5, - TRUE) - return - - lines = fp.readlines() - html = string.join(lines) - - rawstr = r"""kodos-(?P.*?)\.\w{3,4}\<""" - match_obj = re.search(rawstr, html) - if match_obj: - latest_version = match_obj.group('version') - if latest_version == VERSION: - QMessageBox.information(None, - self.tr("No Update is Available"), - unicode(self.tr("You are currently using the latest version of Kodos")) + " (%s)" % VERSION) - else: - message = "%s\n\n%s: %s.\n%s: %s.\n\n%s\n" % \ - (unicode(self.tr("There is a newer version of Kodos available.")), - unicode(self.tr("You are using version:")), - VERSION, - unicode(self.tr("The latest version is:")), - latest_version, - unicode(self.tr("Press OK to launch browser"))) - - self.launch_browser_wrapper(url, - self.tr("Kodos Update Available"), - message) - else: - message = "%s.\n\n%s" % \ - (unicode(self.tr("Unable to get version info from Sourceforge")), - unicode(self.tr("Press OK to launch browser"))) - self.launch_browser_wrapper(url, - self.tr("Unknown version available"), - message) - - def launch_browser_wrapper(self, url, caption=None, message=None): if launch_browser(url, caption, message): self.status_bar.set_message(self.tr("Launching web browser"), diff --git a/modules/kodosBA.ui b/modules/kodosBA.ui index a600de2..14139b3 100644 --- a/modules/kodosBA.ui +++ b/modules/kodosBA.ui @@ -406,7 +406,6 @@ database. New in Python version 2.0. - @@ -1285,22 +1284,6 @@ database. New in Python version 2.0. - - helpCheckForUpdateAction - activated() - KodosBA - check_for_update() - - - -1 - -1 - - - 20 - 20 - - - replaceTextEdit textChanged() From 3bea2b878d295009888913cdfc292cd41449ddeb Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Thu, 9 Aug 2012 19:53:21 +0200 Subject: [PATCH 04/37] Remove the reportbug functionality and send the user to github instead --- kodos | 4 +- modules/reportBug.py | 104 --------------- modules/reportBugBA.ui | 290 ----------------------------------------- 3 files changed, 2 insertions(+), 396 deletions(-) delete mode 100644 modules/reportBug.py delete mode 100644 modules/reportBugBA.ui diff --git a/kodos b/kodos index f7797ed..49ead1b 100755 --- a/kodos +++ b/kodos @@ -33,7 +33,6 @@ import modules.help as help from modules.status_bar import * from modules.reference import * from modules.prefs import * -from modules.reportBug import reportBugWindow from modules.version import VERSION from modules.recent_files import RecentFiles from modules.urlDialog import URLDialog @@ -1005,7 +1004,8 @@ class Kodos(KodosBA): def report_bug(self): - self.bug_report_win = reportBugWindow(self) + self.launch_browser_wrapper('https://github.com/luksan/kodos/issues', + message=self.tr("Launch web browser to report a bug in kodos?")) ############################################################################## diff --git a/modules/reportBug.py b/modules/reportBug.py deleted file mode 100644 index e4351e4..0000000 --- a/modules/reportBug.py +++ /dev/null @@ -1,104 +0,0 @@ -# -*- coding: utf-8 -*- -# reportBug.py: -*- Python -*- DESCRIPTIVE TEXT. - -from reportBugBA import reportBugBA -from util import * -from PyQt4.QtGui import * -from PyQt4.QtCore import * -from PyQt4 import * -import sys -import string -import smtplib -from version import VERSION - -AUTHOR_ADDR = "phil_schwartz@users.sourceforge.net" - -class reportBug(reportBugBA): - def __init__(self, parent=None, name=None): - reportBugBA.__init__(self, parent) - self.parent = parent - self.kodos_main = parent.kodos_main - self.populate() - - - def populate(self): - self.OSEdit.setText(sys.platform) - pyvers = string.replace(sys.version, "\n", " - ") - self.pythonVersionEdit.setText(pyvers) - self.PyQtVersionEdit.setText(QT_VERSION_STR) - self.regexMultiLineEdit.setPlainText(self.kodos_main.regexMultiLineEdit.toPlainText()) - self.stringMultiLineEdit.setPlainText(self.kodos_main.stringMultiLineEdit.toPlainText()) - - - def cancel_slot(self): - self.parent.close() - - def submit_slot(self): - addr = str(self.emailAddressEdit.text()) - if not addr: - msg = self.tr( - "An email address is necessary so that the author " - "can contact you. Your email address will not " - "be used for any other purposes.") - - QMessageBox.information(None, - self.tr("You must supply a valid email address"), - msg) - return - - msg = "Subject: Kodos bug report\n\n" - msg += "Kodos Version: %s\n" % VERSION - msg += "Operating System: %s\n" % unicode(self.OSEdit.text()) - msg += "Python Version: %s\n" % unicode(self.pythonVersionEdit.text()) - msg += "PyQt Version: %s\n" % unicode(self.PyQtVersionEdit.text()) - msg += "\n" + "=" * 70 + "\n" - msg += "Regex:\n%s\n" % unicode(self.regexMultiLineEdit.text()) - msg += "=" * 70 + "\n" - msg += "String:\n%s\n" % unicode(self.stringMultiLineEdit.text()) - msg += "=" * 70 + "\n" - msg += "Comments:\n%s\n" % unicode(self.commentsMultiLineEdit.text()) - email_server = unicode(self.kodos_main.prefs.emailServerEdit.text()) or "localhost" - try: - server = smtplib.SMTP(email_server) - server.sendmail(addr, AUTHOR_ADDR, msg) - server.quit() - QMessageBox.information(None, - self.tr("Bug report sent"), - self.tr("Your bug report has been sent.")) - self.parent.close() - except Exception, e: - QMessageBox.information(None, - self.tr("An exception occurred sending bug report"), - str(e)) - - -class reportBugWindow(QMainWindow): - def __init__(self, kodos_main): - self.kodos_main = kodos_main - QMainWindow.__init__(self, kodos_main)#, Qt.Window | Qt.WA_DeleteOnClose) - - self.setGeometry(100, 50, 800, 600) - self.setWindowTitle(self.tr("Report a Bug")) - self.setWindowIcon(QIcon(QPixmap(":images/kodos_icon.png"))) - - self.bug_report = reportBug(self) - self.setCentralWidget(self.bug_report) - - - self.createMenu() - self.createToolBar() - - self.show() - - - def createMenu(self): - self.menubar = self.menuBar() - self.filemenu = self.menubar.addMenu(self.tr("&File")) - self.filemenu.addAction(self.tr("&Close"), self, SLOT("close()")) - - - def createToolBar(self): - toolbar = QToolBar() - self.addToolBar(toolbar) - self.logolabel = kodos_toolbar_logo(toolbar) - diff --git a/modules/reportBugBA.ui b/modules/reportBugBA.ui deleted file mode 100644 index 74b2eec..0000000 --- a/modules/reportBugBA.ui +++ /dev/null @@ -1,290 +0,0 @@ - - - reportBugBA - - - - 0 - 0 - 750 - 653 - - - - Form1 - - - - 11 - - - 6 - - - - - 6 - - - 0 - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 20 - 20 - - - - - - - - Submit Bug Report - - - - - - - Cancel - - - - - - - - - Kodos State Information - - - - 11 - - - 6 - - - - - 6 - - - 0 - - - - - Regular Expression: - - - false - - - - - - - Match String: - - - false - - - - - - - - - 6 - - - 0 - - - - - true - - - - - - - true - - - - - - - - - - - - System Information - - - - 11 - - - 6 - - - - - Operating System: - - - false - - - - - - - PyQt Version: - - - false - - - - - - - Python Version: - - - false - - - - - - - - - - - - - - - - - - - Comments - - - - 11 - - - 6 - - - - - 0 - - - 6 - - - - - Comments: - - - false - - - - - - - - - - - 0 - 0 - - - - Email address: - - - false - - - - - - - - - - - - - - - qPixmapFromMimeSource - - OSEdit - pythonVersionEdit - PyQtVersionEdit - emailAddressEdit - submitButton - cancelButton - - - - - submitButton - clicked() - reportBugBA - submit_slot() - - - 20 - 20 - - - 20 - 20 - - - - - cancelButton - clicked() - reportBugBA - cancel_slot() - - - 20 - 20 - - - 20 - 20 - - - - - From 954151af5d6f5c5ce2db093c414428b9d8643b14 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Mon, 13 Aug 2012 12:18:26 +0200 Subject: [PATCH 05/37] Remove the email server config item and the associated code --- modules/prefs.py | 3 --- modules/prefsBA.ui | 26 +++----------------------- 2 files changed, 3 insertions(+), 26 deletions(-) diff --git a/modules/prefs.py b/modules/prefs.py index 56ea409..3112d49 100644 --- a/modules/prefs.py +++ b/modules/prefs.py @@ -27,8 +27,6 @@ def load(self): self.parent.setfont(setting.toPyObject()) if preference == 'Match Font': self.parent.setMatchFont(setting.toPyObject()) - if preference == 'Email Server': - self.emailServerEdit.setText(setting.toPyObject()) if preference == 'Recent Files Count': self.recentFilesSpinBox.setValue(int(setting.toPyObject())) except Exception, e: @@ -39,7 +37,6 @@ def load(self): def save(self): self.settings.setValue('Font', self.parent.getfont()) self.settings.setValue('Match Font', self.parent.getMatchFont()) - self.settings.setValue('Email Server', self.emailServerEdit.text()) self.settings.setValue('Recent Files Count', self.recentFilesSpinBox.text()) self.settings.sync() diff --git a/modules/prefsBA.ui b/modules/prefsBA.ui index c5c8586..6b3b40a 100644 --- a/modules/prefsBA.ui +++ b/modules/prefsBA.ui @@ -68,26 +68,7 @@ - - - - - - - - 0 - 0 - - - - Email Server: - - - false - - - - + @@ -103,7 +84,7 @@ - + Qt::Horizontal @@ -119,7 +100,7 @@ - + @@ -228,7 +209,6 @@ fontButton - emailServerEdit recentFilesSpinBox buttonHelp buttonApply From c8bfce52e95f4daeba09b1ca25b1233a51232c02 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Mon, 13 Aug 2012 12:29:48 +0200 Subject: [PATCH 06/37] Fix the layout of the preferences window --- modules/prefsBA.ui | 73 ++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 45 deletions(-) diff --git a/modules/prefsBA.ui b/modules/prefsBA.ui index 6b3b40a..d2f2290 100644 --- a/modules/prefsBA.ui +++ b/modules/prefsBA.ui @@ -7,7 +7,7 @@ 0 0 540 - 268 + 145 @@ -22,7 +22,7 @@ 11 6 519 - 246 + 131 @@ -44,13 +44,6 @@ - - - - - - - @@ -61,14 +54,21 @@ - + - + + + + + + + + @@ -84,23 +84,7 @@ - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 380 - 20 - - - - - + @@ -116,24 +100,24 @@ + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 380 + 20 + + + + - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 40 - - - - @@ -209,7 +193,6 @@ fontButton - recentFilesSpinBox buttonHelp buttonApply buttonOk From 5f54559dd8250eaba624658c2cc6b735fe30bad3 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Mon, 13 Aug 2012 13:36:03 +0200 Subject: [PATCH 07/37] Remove the web browser and mail server paragraphs from the help --- help/prefs.html | 4 ---- 1 file changed, 4 deletions(-) diff --git a/help/prefs.html b/help/prefs.html index 06baaf2..793bfc3 100644 --- a/help/prefs.html +++ b/help/prefs.html @@ -77,12 +77,8 @@

Kodos - Help

Preferences

-Set your Web Browser path. You can use the ... button to use a file dialog to help locate your browser. The web browser is necessary to access external links within the Python Regex documentation.

- The Editor Font allows you to select a desirable font for use within the Kodos editor

-The Email Server is required for sending bug reports to the author. You can submit a bug report under the main Help menu

- You can control the number of Recent Files that are displayed at the bottom of the File menu. The default value is 5. To display more or less recent files, set this value accordingly. The recent file list is maintained independtly of this value such that applying a lower value and then a higher value will not purge entries. That is, if you have 10 files and then set this value to 3 and later set this value to 10, the 10 files will be immediately available for selection .

From 877d4469e5a6e87122ae6bda0110cb63ac56a896 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Mon, 13 Aug 2012 13:31:22 +0200 Subject: [PATCH 08/37] Split the kodos file into a small launcher and modules.main --- kodos | 1007 +---------------------------------------------- modules/main.py | 991 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 998 insertions(+), 1000 deletions(-) create mode 100644 modules/main.py diff --git a/kodos b/kodos index 49ead1b..b742888 100755 --- a/kodos +++ b/kodos @@ -4,1014 +4,21 @@ import sys import os -import string -import re -import cPickle -import types import getopt -import urllib -import signal try: - from PyQt4.QtGui import * - from PyQt4.QtCore import * + from PyQt4 import QtGui + from PyQt4 import QtCore except: sys.exit("""Could not locate the PyQt module. Please make sure that you have installed PyQt for the version of Python that you are running.""") ### make sure that this script can find kodos specific modules ### from distutils.sysconfig import get_python_lib - sys.path.append(os.path.join(get_python_lib(), "kodos")) -################################################################### - -from modules.kodosBA import * -from modules.util import * -from modules.about import * -import modules.help as help -from modules.status_bar import * -from modules.reference import * -from modules.prefs import * -from modules.version import VERSION -from modules.recent_files import RecentFiles -from modules.urlDialog import URLDialog -from modules.regexLibrary import RegexLibrary -from modules.newUserDialogBA import NewUserDialog -from modules.flags import reFlag, reFlagList - - -# match status -MATCH_NA = 0 -MATCH_OK = 1 -MATCH_FAIL = 2 -MATCH_PAUSED = 3 -MATCH_EXAMINED = 4 - -TRUE = 1 -FALSE = 0 - -TIMEOUT = 3 - -# regex to find special flags which must begin at beginning of line -# or after some spaces -EMBEDDED_FLAGS = r"^ *\(\?(?P[iLmsux]*)\)" - -RX_BACKREF = re.compile(r"""\\\d""") - -STATE_UNEDITED = 0 -STATE_EDITED = 1 - -GEO = "kodos_geometry" - -# colors for normal & examination mode -QCOLOR_WHITE = QColor(Qt.white) # normal -QCOLOR_YELLOW = QColor(255,255,127) # examine - -try: - signal.SIGALRM - HAS_ALARM = 1 -except: - HAS_ALARM = 0 - - -############################################################################## -# -# The Kodos class which defines the main functionality and user interaction -# -############################################################################## - -class Kodos(KodosBA): - def __init__(self, filename, debug): - KodosBA.__init__(self) - - self.debug = debug - self.regex = "" - self.matchstring = "" - self.replace = "" - self.is_paused = 0 - self.is_examined = 0 - self.filename = "" - self.match_num = 1 # matches are labeled 1..n - self.replace_num = 0 # replace all - self.url = None - self.group_tuples = None - self.editstate = STATE_UNEDITED - - self.ref_win = None - self.regexlibwin = None - - self.embedded_flags_obj = re.compile(EMBEDDED_FLAGS) - self.regex_embedded_flags_removed = "" - - self.createStatusBar() - - self.MSG_NA = self.tr("Enter a regular expression and a string to match against") - self.MSG_PAUSED = self.tr("Kodos regex processing is paused. Click the pause icon to unpause") - self.MSG_FAIL = self.tr("Pattern does not match") - - - self.statusPixmapsDict = { MATCH_NA: QPixmap(":images/yellow.png"), - MATCH_OK: QPixmap(":images/green.png"), - MATCH_FAIL: QPixmap(":images/red.png"), - MATCH_PAUSED: QPixmap(":images/pause.png"), - } - - - self.updateStatus(self.MSG_NA, MATCH_NA) - - self.reFlags = reFlagList([ - reFlag("re.IGNORECASE", "i", self.ignorecaseCheckBox), - reFlag("re.MULTILINE", "m", self.multilineCheckBox), - reFlag("re.DOTALL", "s", self.dotallCheckBox), - reFlag("re.VERBOSE", "x", self.verboseCheckBox), - reFlag("re.LOCALE", "L", self.localeCheckBox), - reFlag("re.UNICODE", "u", self.unicodeCheckBox), - ]) - self.reFlags.clearAll() - - restoreWindowSettings(self, GEO) - - self.show() - - self.prefs = Preferences(self, 1) - self.recent_files = RecentFiles(self, - self.prefs.recentFilesSpinBox.value(), - self.debug) - - if filename and self.openFile(filename): - qApp.processEvents() - - self.fileMenu.triggered.connect(self.fileMenuHandler) - - kodos_toolbar_logo(self.toolBar) - if self.replace: self.show_replace_widgets() - else: self.hide_replace_widgets() - - self.checkIfNewUser() - - - def checkIfNewUser(self): - s = QSettings() - if s.value('New User', "true").toPyObject() != "false": - self.newuserdialog = NewUserDialog() - self.newuserdialog.show() - s.setValue('New User', "false") - - - def createStatusBar(self): - self.status_bar = Status_Bar(self, FALSE, "") - - - def updateStatus(self, status_string, status_value, duration=0, replace=FALSE, tooltip=''): - pixmap = self.statusPixmapsDict.get(status_value) - - self.status_bar.set_message(status_string, duration, replace, tooltip, pixmap) - - - def fileMenuHandler(self, menuid): - if self.recent_files.isRecentFile(menuid): - fn = str(menuid.text()) - if self.openFile(fn): - self.recent_files.add(fn) - - def prefsSaved(self): - if self.debug: print "prefsSaved slot" - self.recent_files.setNumShown(self.prefs.recentFilesSpinBox.value()) - - - def kodos_edited_slot(self): - # invoked whenever the user has edited something - self.editstate = STATE_EDITED - - - def checkbox_slot(self): - self.process_regex() - - - def set_flags(self, flags): - # from the given integer value of flags, set the checkboxes - # this is used when loading a saved file - for f in self.reFlags: - f.checkBox.setChecked(flags & f.reFlag) - - - def get_flags_string(self): - flags_str = "" - - for f in self.reFlags: - if f.checkBox.isChecked(): - flags_str += "| " + f.flagName - - if flags_str: - flags_str = ", " + flags_str[1:] - return flags_str - - - def get_embedded_flags_string(self): - flags_str = flags = "" - - for f in self.reFlags: - if f.checkBox.isChecked(): - flags += f.shortFlag - - if flags: - flags_str = "(?" + flags + ")" - - return flags_str - - - def pause(self): - self.is_paused = not self.is_paused - if self.debug: print "is_paused:", self.is_paused - - if self.is_paused: - self.update_results(self.MSG_PAUSED, MATCH_PAUSED) - self.matchNumberSpinBox.setDisabled(1) - - else: - self.process_regex() - self.matchNumberSpinBox.setEnabled(1) - - - def examine(self): - self.is_examined = not self.is_examined - if self.debug: print "is_examined:", self.is_examined - - if self.is_examined: - color = QCOLOR_YELLOW - regex = self.regex - self.regex_saved = self.regex - length = len(regex) - self.regexMultiLineEdit.setReadOnly(1) - self.stringMultiLineEdit.setReadOnly(1) - self.replaceTextEdit.setReadOnly(1) - for i in range(length, 0, -1): - regex = regex[:i] - self.process_embedded_flags(self.regex) - try: - m = re.search(regex, self.matchstring, self.reFlags.allFlagsORed()) - if m: - if self.debug: print "examined regex:", regex - self.__refresh_regex_widget(color, regex) - return - except: - pass - - self.__refresh_regex_widget(color, "") - else: - regex = self.regex_saved - color = QCOLOR_WHITE - self.regexMultiLineEdit.setReadOnly(0) - self.stringMultiLineEdit.setReadOnly(0) - self.replaceTextEdit.setReadOnly(0) - self.__refresh_regex_widget(color, regex) - - - def __refresh_regex_widget(self, base_qcolor, regex): - pal = QPalette() - pal.setColor(pal.Base, base_qcolor) - self.regexMultiLineEdit.setPalette(pal) - - self.regexMultiLineEdit.blockSignals(1) - self.regexMultiLineEdit.clear() - self.regexMultiLineEdit.blockSignals(0) - self.regexMultiLineEdit.setPlainText(regex) - - - def match_num_slot(self, num): - self.match_num = num - self.process_regex() - - - def replace_num_slot(self, num): - self.replace_num = num - self.process_regex() - - - def regex_changed_slot(self): - self.regex = unicode(self.regexMultiLineEdit.toPlainText()) - self.process_regex() - - - def string_changed_slot(self): - self.matchstring = unicode(self.stringMultiLineEdit.toPlainText()) - self.process_regex() - - def helpContents(self, x = None): - pass #FIXME - def helpIndex(self, x = None): - pass #FIXME - - def hide_replace_widgets(self): - self.spacerLabel.hide() - self.replaceLabel.hide() - self.replaceNumberSpinBox.hide() - self.replaceTextBrowser.clear() - self.replaceTextBrowser.setDisabled(TRUE) - - def show_replace_widgets(self): - self.spacerLabel.show() - self.replaceLabel.show() - self.replaceNumberSpinBox.show() - self.replaceNumberSpinBox.setEnabled(TRUE) - self.replaceTextBrowser.setEnabled(TRUE) - - def replace_changed_slot(self): - self.replace = unicode(self.replaceTextEdit.toPlainText()) - self.process_regex() - if not self.replace: - self.hide_replace_widgets() - else: - self.show_replace_widgets() - - - def update_results(self, msg, val): - self.updateStatus(msg, val) - - - def populate_group_table(self, tuples): - rows = len(tuples) - # Remove old rows for groups that no longer exist - for i in range(rows, self.groupTable.rowCount()): - self.groupTable.removeRow(i) - - self.groupTable.setRowCount(rows) - row = 0 - for t in tuples: - self.groupTable.setItem(row, 0, QTableWidgetItem(t[1])) - self.groupTable.setItem(row, 1, QTableWidgetItem(t[2])) - row += 1 - - - def populate_code_textbrowser(self): - self.codeTextBrowser.clear() - - code = "import re\n\n" - code += "# common variables\n\n" - code += "rawstr = r\"\"\"" + self.regex_embedded_flags_removed + "\"\"\"\n" - code += "embedded_rawstr = r\"\"\"" + self.get_embedded_flags_string() + \ - self.regex_embedded_flags_removed + "\"\"\"\n" - code += 'matchstr = \"\"\"' + self.matchstring + '\"\"\"' - code += "\n\n" - code += "# method 1: using a compile object\n" - code += "compile_obj = re.compile(rawstr" - code += self.get_flags_string() - code += ")\n" - code += "match_obj = compile_obj.search(matchstr)\n\n" - - code += "# method 2: using search function (w/ external flags)\n" - code += "match_obj = re.search(rawstr, matchstr" - code += self.get_flags_string() - code += ")\n\n" - - code += "# method 3: using search function (w/ embedded flags)\n" - code += "match_obj = re.search(embedded_rawstr, matchstr)\n\n" - - - if self.group_tuples: - code += "# Retrieve group(s) from match_obj\n" - code += "all_groups = match_obj.groups()\n\n" - code += "# Retrieve group(s) by index\n" - i = 0 - named_grps = 0 - for grp in self.group_tuples: - i += 1 - code += "group_%d = match_obj.group(%d)\n" % (i, i) - if grp[1]: named_grps = 1 - - if named_grps: - code += "\n# Retrieve group(s) by name\n" - for grp in self.group_tuples: - if grp[1]: - code += "%s = match_obj.group('%s')\n" % (grp[1], grp[1]) - - code += "\n" - - if self.replace: - code += "# Replace string\n" - code += "newstr = compile_obj.subn('%s', %d)\n" % (self.replace, - self.replace_num) - - self.codeTextBrowser.setPlainText(code) - - - def colorize_strings(self, strings, widget, cursorOffset=0): - widget.clear() - - colors = (QBrush(QColor(Qt.black)), QBrush(QColor(Qt.blue)) ) - cur = widget.textCursor() - format = cur.charFormat() - - pos = cur.position() - i = 0 - for s in strings: - format.setForeground(colors[i%2]) - cur.insertText(s, format) - if i == cursorOffset: - pos = cur.position() - i += 1 - - cur.setPosition(pos) - widget.setTextCursor(cur) - widget.centerCursor() - - - def populate_match_textbrowser(self, startpos, endpos): - pre = post = match = "" - - match = self.matchstring[startpos:endpos] - - # prepend the beginning that didn't match - if startpos > 0: - pre = self.matchstring[0:startpos] - - # append the end that didn't match - if endpos < len(self.matchstring): - post = self.matchstring[endpos:] - - strings = [pre, match, post] - self.colorize_strings(strings, self.matchTextBrowser, 1) - - - def populate_replace_textbrowser(self, spans, nummatches, compile_obj): - self.replaceTextBrowser.clear() - if not spans: return - - num = self.replaceNumberSpinBox.value() - if num == 0: num = nummatches - text = self.matchstring - - replace_text = unicode(self.replaceTextEdit.toPlainText()) - if RX_BACKREF.search(replace_text): - # if the replace string contains a backref we just use the - # python regex methods for the substitution - replaced = compile_obj.subn(replace_text, text, num)[0] - self.replaceTextBrowser.setPlainText(replaced) - return - - numreplaced = idx = 0 - - strings = [] - - for span in spans: - if span[0] != 0: - s = text[idx:span[0]] - else: - s = "" - - idx = span[1] - numreplaced += 1 - - strings.append(s) - strings.append(self.replace) - - if numreplaced >= num: - strings.append(text[span[1]:]) - break - - self.colorize_strings(strings, self.replaceTextBrowser) - - - def populate_matchAll_textbrowser(self, spans): - self.matchAllTextBrowser.clear() - if not spans: return - - idx = 0 - text = self.matchstring - strings = [] - for span in spans: - if span[0] != 0: - s = text[idx:span[0]] - else: - s = "" - - idx = span[1] - strings.append(s) - strings.append(text[span[0]:span[1]]) - - if 0 <= idx <= len(text): - strings.append(text[span[1]:]) - - self.colorize_strings(strings, self.matchAllTextBrowser) - - - def clear_results(self): - # .clear() destroys the headers, and .clearContents() doesn't do - # anything at all, so remove the rows one by one - for i in range(self.groupTable.rowCount()): - self.groupTable.removeRow(i) - - self.codeTextBrowser.clear() - self.matchTextBrowser.clear() - self.matchNumberSpinBox.setEnabled(FALSE) - self.replaceNumberSpinBox.setEnabled(FALSE) - self.replaceTextBrowser.clear() - self.matchAllTextBrowser.clear() - - - def process_regex(self): - def timeout(signum, frame): - return - - if self.is_paused: - return - - self.process_embedded_flags(self.regex) - - if not self.regex or not self.matchstring: - self.update_results(self.MSG_NA, MATCH_NA) - self.clear_results() - return - - if HAS_ALARM: - signal.signal(signal.SIGALRM, timeout) - signal.alarm(TIMEOUT) - - try: - compile_obj = re.compile(self.regex, self.reFlags.allFlagsORed()) - allmatches = compile_obj.findall(self.matchstring) - - if allmatches and len(allmatches): - self.matchNumberSpinBox.setMaximum(len(allmatches)) - self.matchNumberSpinBox.setEnabled(TRUE) - self.replaceNumberSpinBox.setMaximum(len(allmatches)) - self.replaceNumberSpinBox.setEnabled(TRUE) - else: - self.matchNumberSpinBox.setEnabled(FALSE) - self.replaceNumberSpinBox.setEnabled(FALSE) - - match_obj = compile_obj.search(self.matchstring) - - except Exception, e: - self.update_results(unicode(e), MATCH_FAIL) - return - - if HAS_ALARM: - signal.alarm(0) - - if not match_obj: - self.update_results(self.MSG_FAIL, MATCH_FAIL) - - self.clear_results() - return - - # match_index is the list element for match_num. - # Therefor match_num is for ui display - # and match_index is for application logic. - match_index = self.match_num - 1 - - if match_index > 0: - for i in range(match_index): - match_obj = compile_obj.search(self.matchstring, - match_obj.end()) - - self.populate_match_textbrowser(match_obj.start(), match_obj.end()) - - self.group_tuples = [] - - if match_obj.groups(): - group_nums = {} - if compile_obj.groupindex: - keys = compile_obj.groupindex.keys() - for key in keys: - group_nums[compile_obj.groupindex[key]] = key - - if self.debug: - print "group_nums:", group_nums - print "grp index: ", compile_obj.groupindex - print "groups:", match_obj.groups() - print "span: ", match_obj.span() - - # create group_tuple in the form: (group #, group name, group matches) - g = allmatches[match_index] - if type(g) == types.TupleType: - for i in range(len(g)): - group_tuple = (i+1, group_nums.get(i+1, ""), g[i]) - self.group_tuples.append(group_tuple) - else: - self.group_tuples.append( (1, group_nums.get(1, ""), g) ) - - self.populate_group_table(self.group_tuples) - else: - # clear the group table - self.populate_group_table([]) - - str_pattern_matches = unicode(self.tr("Pattern matches")) - str_found = unicode(self.tr("found")) - str_match = unicode(self.tr("match")) - str_matches = unicode(self.tr("matches")) - - if len(allmatches) == 1: - status = "%s (%s 1 %s)" % (str_pattern_matches, - str_found, - str_match) - else: - status = "%s (%s %d %s)" % (str_pattern_matches, - str_found, - len(allmatches), - str_matches) - - self.update_results(status, MATCH_OK) - self.populate_code_textbrowser() - - spans = self.findAllSpans(compile_obj) - if self.replace: - self.populate_replace_textbrowser(spans, len(allmatches), compile_obj) - self.populate_matchAll_textbrowser(spans) - - - def findAllSpans(self, compile_obj): - spans = [] - - match_obj = compile_obj.search(self.matchstring) - - last_span = None - - while match_obj: - start = match_obj.start() - end = match_obj.end() - span = (start, end) - if last_span == span: break - - spans.append(span) - - last_span = span - match_obj = compile_obj.search(self.matchstring, end) - - return spans - - - def closeEvent(self, ev): - if not self.checkEditState(): - ev.ignore() - return - - saveWindowSettings(self, GEO) - - try: - self.regexlibwin.close() - except: - pass - - try: - self.ref_win.close() - except: - pass - ev.accept() - - - def fileNew(self): - if not self.checkEditState(): - return - self.filename = "" - - self.regexMultiLineEdit.setPlainText("") - self.stringMultiLineEdit.setPlainText("") - self.replaceTextEdit.setPlainText("") - self.set_flags(0) - self.editstate = STATE_UNEDITED - - - def importURL(self): - self.urldialog = URLDialog(self, self.url) - self.urldialog.urlImported.connect(self.urlImported) - - - def urlImported(self, html, url): - self.url = url - self.stringMultiLineEdit.setPlainText(html) - - - def importFile(self): - fn = QFileDialog.getOpenFileName(self, - self.tr("Import File"), - self.filename, - self.tr("All (*)")) - - if fn.isEmpty(): - self.updateStatus(self.tr("A file was not selected for import"), - -1, - 5, - TRUE) - return None - - filename = str(fn) - - try: - fp = open(filename, "r") - except: - msg = self.tr("Could not open file for reading: ") + filename - self.updateStatus(msg, -1, 5, TRUE) - return None - - data = fp.read() - fp.close() - self.stringMultiLineEdit.setPlainText(data) - - - def fileOpen(self): - filename = self.filename - if filename == None: - filename = "" - fn = QFileDialog.getOpenFileName(self, - self.tr("Open Kodos File"), - filename, - self.tr("Kodos file (*.kds);;All (*)")) - if not fn.isEmpty(): - filename = str(fn) - if self.openFile(filename): - self.recent_files.add(filename) - - - def openFile(self, filename): - if not self.checkEditState(): - return - - self.filename = None - - try: - fp = open(filename, "r") - except: - msg = self.tr("Could not open file for reading: ") + filename - self.updateStatus(msg, -1, 5, TRUE) - return None - - try: - u = cPickle.Unpickler(fp) - self.regex = u.load() - self.matchstring = u.load() - flags = u.load() - except Exception, e: #FIXME: don't catch everything - if self.debug: - print unicode(e) - msg = "%s %s" % (unicode(self.tr("Error reading from file:")), - filename) - self.updateStatus(msg, -1, 5, TRUE) - return 0 - - self.matchNumberSpinBox.setValue(1) - self.regexMultiLineEdit.setPlainText(self.regex) - self.stringMultiLineEdit.setPlainText(self.matchstring) - - self.set_flags(flags) - - try: - replace = u.load() - except: - # versions prior to 1.7 did not have replace functionality - # so kds files saved w/ these versions will throw exception - # here. - replace = "" - self.replaceTextEdit.setPlainText(replace) - - self.filename = filename - msg = "%s %s" % (filename, unicode(self.tr("loaded successfully"))) - self.updateStatus(msg, -1, 5, TRUE) - self.editstate = STATE_UNEDITED - return 1 - - - def fileSaveAs(self): - filename = self.filename - if filename == None: - filename = "" - filedialog = QFileDialog(self, - self.tr("Save Kodos File"), - filename, - "Kodos file (*.kds);;All (*)") - filedialog.setAcceptMode(QFileDialog.AcceptSave) - filedialog.setDefaultSuffix("kds") - ok = filedialog.exec_() - - if ok == QDialog.Rejected: - self.updateStatus(self.tr("No file selected to save"), -1, 5, TRUE) - return - - filename = os.path.normcase(unicode(filedialog.selectedFiles().first())) - - self.filename = filename - self.fileSave() - - - def fileSave(self): - if not self.filename: - self.fileSaveAs() - return - - try: - fp = open(self.filename, "w") - except: - msg = "%s: %s" % (unicode(self.tr("Could not open file for writing:")), - self.filename) - self.updateStatus(msg, -1, 5, TRUE) - return None - - self.editstate = STATE_UNEDITED - p = cPickle.Pickler(fp) - p.dump(self.regex) - p.dump(self.matchstring) - p.dump(self.reFlags.allFlagsORed()) - p.dump(self.replace) - - fp.close() - msg = "%s %s" % (unicode(self.filename), - unicode(self.tr("successfully saved"))) - self.updateStatus(msg, -1, 5, TRUE) - self.recent_files.add(self.filename) - - - def paste_symbol(self, symbol): - self.regexMultiLineEdit.insertPlainText(symbol) - - - def process_embedded_flags(self, regex): - # determine if the regex contains embedded regex flags. - # if it does, set the appropriate checkboxes on the UI to reflect the flags that are embedded - match = self.embedded_flags_obj.match(regex) - if not match: - embedded_flags = "" - self.regex_embedded_flags_removed = regex - else: - embedded_flags = match.group('flags') - self.regex_embedded_flags_removed = self.embedded_flags_obj.sub("", regex, 1) - - for f in self.reFlags: - if f.shortFlag in embedded_flags: - f.embed() - else: - f.deembed() - - - def checkEditState(self): - if self.editstate == STATE_EDITED: - message = self.tr("You have made changes. Would you like to save them before continuing?") - - prompt = QMessageBox.warning(None, - self.tr("Save changes?"), - message, - QMessageBox.Save | - QMessageBox.Cancel | - QMessageBox.Discard) - - if prompt == QMessageBox.Cancel: - return False - - if prompt == QMessageBox.Save: - self.fileSave() - if not self.filename: self.checkEditState() - - return True - - - def pasteFromRegexLib(self, d): - if not self.checkEditState(): - return - - self.filename = "" - - self.regexMultiLineEdit.setPlainText(d.get('regex', "")) - self.stringMultiLineEdit.setPlainText(d.get('text', "")) - self.replaceTextEdit.setPlainText(d.get('replace', "")) - - try: - # set the current page if applicable - self.resultTabWidget.setCurrentIndex(int(d['tab'])) - except KeyError: - pass - self.editstate = STATE_UNEDITED - - - def revert_file_slot(self): - if not self.filename: - self.updateStatus(self.tr("There is no filename to revert"), - -1, - 5, - TRUE) - return - - self.openFile(self.filename) - - - def getWidget(self): - widget = qApp.focusWidget() - if (widget == self.regexMultiLineEdit or - widget == self.stringMultiLineEdit or - widget == self.replaceTextEdit or - widget == self.codeTextBrowser): - return widget - else: - return None - - - def widgetMethod(self, methodstr, anywidget=0): - # execute the methodstr of widget only if widget - # is one of the editable widgets OR if the method - # may be applied to any widget. - widget = qApp.focusWidget() - if anywidget or ( - widget == self.regexMultiLineEdit or - widget == self.stringMultiLineEdit or - widget == self.replaceTextEdit or - widget == self.codeTextBrowser): - try: - eval("widget.%s" % methodstr) - except: - pass - - - def editUndo(self): - self.widgetMethod("undo()") - - def editRedo(self): - self.widgetMethod("redo()") - - def editCopy(self): - self.widgetMethod("copy()", 1) - - def editCut(self): - self.widgetMethod("cut()") - - def editPaste(self): - self.widgetMethod("paste()") - - - def preferences(self): - self.prefs.showPrefsDialog() - self.prefs.prefsSaved.connect(self.prefsSaved) - - def setfont(self, font): - self.regexMultiLineEdit.setFont(font) - self.stringMultiLineEdit.setFont(font) - self.replaceTextEdit.setFont(font) - - def setMatchFont(self, font): - self.groupTable.setFont(font) - self.matchTextBrowser.setFont(font) - self.matchAllTextBrowser.setFont(font) - self.replaceTextBrowser.setFont(font) - self.codeTextBrowser.setFont(font) - - - def getfont(self): - return self.regexMultiLineEdit.font() - - - def getMatchFont(self): - return self.groupTable.font() - - - def helpHelp(self): - self.helpWindow = help.Help(self, "kodos.html") - - - def helpPythonRegex(self): - self.helpWindow = help.Help(self, os.path.join("python", "module-re.html")) - - - def helpRegexLib(self): - f = os.path.join("help", "regex-lib.xml") - self.regexlibwin = RegexLibrary(f) - self.regexlibwin.pasteRegexLib.connect(self.pasteFromRegexLib) - self.regexlibwin.show() - - - def helpAbout(self): - self.aboutWindow = About() - self.aboutWindow.show() - - - def kodos_website(self): - self.launch_browser_wrapper('https://github.com/luksan/kodos', - message=self.tr('Launch web browser to go to the kodos project page?')) - - - def launch_browser_wrapper(self, url, caption=None, message=None): - if launch_browser(url, caption, message): - self.status_bar.set_message(self.tr("Launching web browser"), - 3, - TRUE) - else: - self.status_bar.set_message(self.tr("Cancelled web browser launch"), - 3, - TRUE) - - - def reference_guide(self): - self.ref_win = Reference(self) - self.ref_win.pasteSymbol.connect(self.paste_symbol) - self.ref_win.show() - - - def report_bug(self): - self.launch_browser_wrapper('https://github.com/luksan/kodos/issues', - message=self.tr("Launch web browser to report a bug in kodos?")) - - -############################################################################## -# -# -############################################################################## +from modules.main import Kodos +from modules.util import findFile def usage(): print "kodos.py [-f filename | --file=filename ] [ -d debug | --debug=debug ] [ -k kodos_dir ]" @@ -1056,20 +63,20 @@ def main(): os.environ['KODOS_DIR'] = kodos_dir - qApp = QApplication(sys.argv) + qApp = QtGui.QApplication(sys.argv) qApp.setOrganizationName("kodos") qApp.setApplicationName("kodos") qApp.setOrganizationDomain("kodos.sourceforge.net") if locale not in (None, 'en'): - localefile = "kodos_%s.qm" % (locale or QTextCodec.locale()) + localefile = "kodos_%s.qm" % (locale or QtCore.QTextCodec.locale()) localepath = findFile(os.path.join("translations", localefile)) if debug: print "locale changed to:", locale print localefile print localepath - translator = QTranslator(qApp) + translator = QtCore.QTranslator(qApp) translator.load(localepath) qApp.installTranslator(translator) diff --git a/modules/main.py b/modules/main.py new file mode 100644 index 0000000..e97f498 --- /dev/null +++ b/modules/main.py @@ -0,0 +1,991 @@ +# -*- coding: utf-8 -*- + +import re +import types +import signal +import string +import urllib +import cPickle + +from PyQt4.QtGui import * +from PyQt4.QtCore import * + +from kodosBA import * +from util import * +from about import * +from . import help +from status_bar import * +from reference import * +from prefs import * +from version import VERSION +from recent_files import RecentFiles +from urlDialog import URLDialog +from regexLibrary import RegexLibrary +from newUserDialogBA import NewUserDialog +from flags import reFlag, reFlagList + +# match status +MATCH_NA = 0 +MATCH_OK = 1 +MATCH_FAIL = 2 +MATCH_PAUSED = 3 +MATCH_EXAMINED = 4 + +TRUE = 1 +FALSE = 0 + +TIMEOUT = 3 + +# regex to find special flags which must begin at beginning of line +# or after some spaces +EMBEDDED_FLAGS = r"^ *\(\?(?P[iLmsux]*)\)" + +RX_BACKREF = re.compile(r"""\\\d""") + +STATE_UNEDITED = 0 +STATE_EDITED = 1 + +GEO = "kodos_geometry" + +# colors for normal & examination mode +QCOLOR_WHITE = QColor(Qt.white) # normal +QCOLOR_YELLOW = QColor(255,255,127) # examine + +try: + signal.SIGALRM + HAS_ALARM = 1 +except: + HAS_ALARM = 0 + + +############################################################################## +# +# The Kodos class which defines the main functionality and user interaction +# +############################################################################## + +class Kodos(KodosBA): + def __init__(self, filename, debug): + KodosBA.__init__(self) + + self.debug = debug + self.regex = "" + self.matchstring = "" + self.replace = "" + self.is_paused = 0 + self.is_examined = 0 + self.filename = "" + self.match_num = 1 # matches are labeled 1..n + self.replace_num = 0 # replace all + self.url = None + self.group_tuples = None + self.editstate = STATE_UNEDITED + + self.ref_win = None + self.regexlibwin = None + + self.embedded_flags_obj = re.compile(EMBEDDED_FLAGS) + self.regex_embedded_flags_removed = "" + + self.createStatusBar() + + self.MSG_NA = self.tr("Enter a regular expression and a string to match against") + self.MSG_PAUSED = self.tr("Kodos regex processing is paused. Click the pause icon to unpause") + self.MSG_FAIL = self.tr("Pattern does not match") + + + self.statusPixmapsDict = { MATCH_NA: QPixmap(":images/yellow.png"), + MATCH_OK: QPixmap(":images/green.png"), + MATCH_FAIL: QPixmap(":images/red.png"), + MATCH_PAUSED: QPixmap(":images/pause.png"), + } + + + self.updateStatus(self.MSG_NA, MATCH_NA) + + self.reFlags = reFlagList([ + reFlag("re.IGNORECASE", "i", self.ignorecaseCheckBox), + reFlag("re.MULTILINE", "m", self.multilineCheckBox), + reFlag("re.DOTALL", "s", self.dotallCheckBox), + reFlag("re.VERBOSE", "x", self.verboseCheckBox), + reFlag("re.LOCALE", "L", self.localeCheckBox), + reFlag("re.UNICODE", "u", self.unicodeCheckBox), + ]) + self.reFlags.clearAll() + + restoreWindowSettings(self, GEO) + + self.show() + + self.prefs = Preferences(self, 1) + self.recent_files = RecentFiles(self, + self.prefs.recentFilesSpinBox.value(), + self.debug) + + if filename and self.openFile(filename): + qApp.processEvents() + + self.fileMenu.triggered.connect(self.fileMenuHandler) + + kodos_toolbar_logo(self.toolBar) + if self.replace: self.show_replace_widgets() + else: self.hide_replace_widgets() + + self.checkIfNewUser() + + + def checkIfNewUser(self): + s = QSettings() + if s.value('New User', "true").toPyObject() != "false": + self.newuserdialog = NewUserDialog() + self.newuserdialog.show() + s.setValue('New User', "false") + + + def createStatusBar(self): + self.status_bar = Status_Bar(self, FALSE, "") + + + def updateStatus(self, status_string, status_value, duration=0, replace=FALSE, tooltip=''): + pixmap = self.statusPixmapsDict.get(status_value) + + self.status_bar.set_message(status_string, duration, replace, tooltip, pixmap) + + + def fileMenuHandler(self, menuid): + if self.recent_files.isRecentFile(menuid): + fn = str(menuid.text()) + if self.openFile(fn): + self.recent_files.add(fn) + + def prefsSaved(self): + if self.debug: print "prefsSaved slot" + self.recent_files.setNumShown(self.prefs.recentFilesSpinBox.value()) + + + def kodos_edited_slot(self): + # invoked whenever the user has edited something + self.editstate = STATE_EDITED + + + def checkbox_slot(self): + self.process_regex() + + + def set_flags(self, flags): + # from the given integer value of flags, set the checkboxes + # this is used when loading a saved file + for f in self.reFlags: + f.checkBox.setChecked(flags & f.reFlag) + + + def get_flags_string(self): + flags_str = "" + + for f in self.reFlags: + if f.checkBox.isChecked(): + flags_str += "| " + f.flagName + + if flags_str: + flags_str = ", " + flags_str[1:] + return flags_str + + + def get_embedded_flags_string(self): + flags_str = flags = "" + + for f in self.reFlags: + if f.checkBox.isChecked(): + flags += f.shortFlag + + if flags: + flags_str = "(?" + flags + ")" + + return flags_str + + + def pause(self): + self.is_paused = not self.is_paused + if self.debug: print "is_paused:", self.is_paused + + if self.is_paused: + self.update_results(self.MSG_PAUSED, MATCH_PAUSED) + self.matchNumberSpinBox.setDisabled(1) + + else: + self.process_regex() + self.matchNumberSpinBox.setEnabled(1) + + + def examine(self): + self.is_examined = not self.is_examined + if self.debug: print "is_examined:", self.is_examined + + if self.is_examined: + color = QCOLOR_YELLOW + regex = self.regex + self.regex_saved = self.regex + length = len(regex) + self.regexMultiLineEdit.setReadOnly(1) + self.stringMultiLineEdit.setReadOnly(1) + self.replaceTextEdit.setReadOnly(1) + for i in range(length, 0, -1): + regex = regex[:i] + self.process_embedded_flags(self.regex) + try: + m = re.search(regex, self.matchstring, self.reFlags.allFlagsORed()) + if m: + if self.debug: print "examined regex:", regex + self.__refresh_regex_widget(color, regex) + return + except: + pass + + self.__refresh_regex_widget(color, "") + else: + regex = self.regex_saved + color = QCOLOR_WHITE + self.regexMultiLineEdit.setReadOnly(0) + self.stringMultiLineEdit.setReadOnly(0) + self.replaceTextEdit.setReadOnly(0) + self.__refresh_regex_widget(color, regex) + + + def __refresh_regex_widget(self, base_qcolor, regex): + pal = QPalette() + pal.setColor(pal.Base, base_qcolor) + self.regexMultiLineEdit.setPalette(pal) + + self.regexMultiLineEdit.blockSignals(1) + self.regexMultiLineEdit.clear() + self.regexMultiLineEdit.blockSignals(0) + self.regexMultiLineEdit.setPlainText(regex) + + + def match_num_slot(self, num): + self.match_num = num + self.process_regex() + + + def replace_num_slot(self, num): + self.replace_num = num + self.process_regex() + + + def regex_changed_slot(self): + self.regex = unicode(self.regexMultiLineEdit.toPlainText()) + self.process_regex() + + + def string_changed_slot(self): + self.matchstring = unicode(self.stringMultiLineEdit.toPlainText()) + self.process_regex() + + def helpContents(self, x = None): + pass #FIXME + def helpIndex(self, x = None): + pass #FIXME + + def hide_replace_widgets(self): + self.spacerLabel.hide() + self.replaceLabel.hide() + self.replaceNumberSpinBox.hide() + self.replaceTextBrowser.clear() + self.replaceTextBrowser.setDisabled(TRUE) + + def show_replace_widgets(self): + self.spacerLabel.show() + self.replaceLabel.show() + self.replaceNumberSpinBox.show() + self.replaceNumberSpinBox.setEnabled(TRUE) + self.replaceTextBrowser.setEnabled(TRUE) + + def replace_changed_slot(self): + self.replace = unicode(self.replaceTextEdit.toPlainText()) + self.process_regex() + if not self.replace: + self.hide_replace_widgets() + else: + self.show_replace_widgets() + + + def update_results(self, msg, val): + self.updateStatus(msg, val) + + + def populate_group_table(self, tuples): + rows = len(tuples) + # Remove old rows for groups that no longer exist + for i in range(rows, self.groupTable.rowCount()): + self.groupTable.removeRow(i) + + self.groupTable.setRowCount(rows) + row = 0 + for t in tuples: + self.groupTable.setItem(row, 0, QTableWidgetItem(t[1])) + self.groupTable.setItem(row, 1, QTableWidgetItem(t[2])) + row += 1 + + + def populate_code_textbrowser(self): + self.codeTextBrowser.clear() + + code = "import re\n\n" + code += "# common variables\n\n" + code += "rawstr = r\"\"\"" + self.regex_embedded_flags_removed + "\"\"\"\n" + code += "embedded_rawstr = r\"\"\"" + self.get_embedded_flags_string() + \ + self.regex_embedded_flags_removed + "\"\"\"\n" + code += 'matchstr = \"\"\"' + self.matchstring + '\"\"\"' + code += "\n\n" + code += "# method 1: using a compile object\n" + code += "compile_obj = re.compile(rawstr" + code += self.get_flags_string() + code += ")\n" + code += "match_obj = compile_obj.search(matchstr)\n\n" + + code += "# method 2: using search function (w/ external flags)\n" + code += "match_obj = re.search(rawstr, matchstr" + code += self.get_flags_string() + code += ")\n\n" + + code += "# method 3: using search function (w/ embedded flags)\n" + code += "match_obj = re.search(embedded_rawstr, matchstr)\n\n" + + + if self.group_tuples: + code += "# Retrieve group(s) from match_obj\n" + code += "all_groups = match_obj.groups()\n\n" + code += "# Retrieve group(s) by index\n" + i = 0 + named_grps = 0 + for grp in self.group_tuples: + i += 1 + code += "group_%d = match_obj.group(%d)\n" % (i, i) + if grp[1]: named_grps = 1 + + if named_grps: + code += "\n# Retrieve group(s) by name\n" + for grp in self.group_tuples: + if grp[1]: + code += "%s = match_obj.group('%s')\n" % (grp[1], grp[1]) + + code += "\n" + + if self.replace: + code += "# Replace string\n" + code += "newstr = compile_obj.subn('%s', %d)\n" % (self.replace, + self.replace_num) + + self.codeTextBrowser.setPlainText(code) + + + def colorize_strings(self, strings, widget, cursorOffset=0): + widget.clear() + + colors = (QBrush(QColor(Qt.black)), QBrush(QColor(Qt.blue)) ) + cur = widget.textCursor() + format = cur.charFormat() + + pos = cur.position() + i = 0 + for s in strings: + format.setForeground(colors[i%2]) + cur.insertText(s, format) + if i == cursorOffset: + pos = cur.position() + i += 1 + + cur.setPosition(pos) + widget.setTextCursor(cur) + widget.centerCursor() + + + def populate_match_textbrowser(self, startpos, endpos): + pre = post = match = "" + + match = self.matchstring[startpos:endpos] + + # prepend the beginning that didn't match + if startpos > 0: + pre = self.matchstring[0:startpos] + + # append the end that didn't match + if endpos < len(self.matchstring): + post = self.matchstring[endpos:] + + strings = [pre, match, post] + self.colorize_strings(strings, self.matchTextBrowser, 1) + + + def populate_replace_textbrowser(self, spans, nummatches, compile_obj): + self.replaceTextBrowser.clear() + if not spans: return + + num = self.replaceNumberSpinBox.value() + if num == 0: num = nummatches + text = self.matchstring + + replace_text = unicode(self.replaceTextEdit.toPlainText()) + if RX_BACKREF.search(replace_text): + # if the replace string contains a backref we just use the + # python regex methods for the substitution + replaced = compile_obj.subn(replace_text, text, num)[0] + self.replaceTextBrowser.setPlainText(replaced) + return + + numreplaced = idx = 0 + + strings = [] + + for span in spans: + if span[0] != 0: + s = text[idx:span[0]] + else: + s = "" + + idx = span[1] + numreplaced += 1 + + strings.append(s) + strings.append(self.replace) + + if numreplaced >= num: + strings.append(text[span[1]:]) + break + + self.colorize_strings(strings, self.replaceTextBrowser) + + + def populate_matchAll_textbrowser(self, spans): + self.matchAllTextBrowser.clear() + if not spans: return + + idx = 0 + text = self.matchstring + strings = [] + for span in spans: + if span[0] != 0: + s = text[idx:span[0]] + else: + s = "" + + idx = span[1] + strings.append(s) + strings.append(text[span[0]:span[1]]) + + if 0 <= idx <= len(text): + strings.append(text[span[1]:]) + + self.colorize_strings(strings, self.matchAllTextBrowser) + + + def clear_results(self): + # .clear() destroys the headers, and .clearContents() doesn't do + # anything at all, so remove the rows one by one + for i in range(self.groupTable.rowCount()): + self.groupTable.removeRow(i) + + self.codeTextBrowser.clear() + self.matchTextBrowser.clear() + self.matchNumberSpinBox.setEnabled(FALSE) + self.replaceNumberSpinBox.setEnabled(FALSE) + self.replaceTextBrowser.clear() + self.matchAllTextBrowser.clear() + + + def process_regex(self): + def timeout(signum, frame): + return + + if self.is_paused: + return + + self.process_embedded_flags(self.regex) + + if not self.regex or not self.matchstring: + self.update_results(self.MSG_NA, MATCH_NA) + self.clear_results() + return + + if HAS_ALARM: + signal.signal(signal.SIGALRM, timeout) + signal.alarm(TIMEOUT) + + try: + compile_obj = re.compile(self.regex, self.reFlags.allFlagsORed()) + allmatches = compile_obj.findall(self.matchstring) + + if allmatches and len(allmatches): + self.matchNumberSpinBox.setMaximum(len(allmatches)) + self.matchNumberSpinBox.setEnabled(TRUE) + self.replaceNumberSpinBox.setMaximum(len(allmatches)) + self.replaceNumberSpinBox.setEnabled(TRUE) + else: + self.matchNumberSpinBox.setEnabled(FALSE) + self.replaceNumberSpinBox.setEnabled(FALSE) + + match_obj = compile_obj.search(self.matchstring) + + except Exception, e: + self.update_results(unicode(e), MATCH_FAIL) + return + + if HAS_ALARM: + signal.alarm(0) + + if not match_obj: + self.update_results(self.MSG_FAIL, MATCH_FAIL) + + self.clear_results() + return + + # match_index is the list element for match_num. + # Therefor match_num is for ui display + # and match_index is for application logic. + match_index = self.match_num - 1 + + if match_index > 0: + for i in range(match_index): + match_obj = compile_obj.search(self.matchstring, + match_obj.end()) + + self.populate_match_textbrowser(match_obj.start(), match_obj.end()) + + self.group_tuples = [] + + if match_obj.groups(): + group_nums = {} + if compile_obj.groupindex: + keys = compile_obj.groupindex.keys() + for key in keys: + group_nums[compile_obj.groupindex[key]] = key + + if self.debug: + print "group_nums:", group_nums + print "grp index: ", compile_obj.groupindex + print "groups:", match_obj.groups() + print "span: ", match_obj.span() + + # create group_tuple in the form: (group #, group name, group matches) + g = allmatches[match_index] + if type(g) == types.TupleType: + for i in range(len(g)): + group_tuple = (i+1, group_nums.get(i+1, ""), g[i]) + self.group_tuples.append(group_tuple) + else: + self.group_tuples.append( (1, group_nums.get(1, ""), g) ) + + self.populate_group_table(self.group_tuples) + else: + # clear the group table + self.populate_group_table([]) + + str_pattern_matches = unicode(self.tr("Pattern matches")) + str_found = unicode(self.tr("found")) + str_match = unicode(self.tr("match")) + str_matches = unicode(self.tr("matches")) + + if len(allmatches) == 1: + status = "%s (%s 1 %s)" % (str_pattern_matches, + str_found, + str_match) + else: + status = "%s (%s %d %s)" % (str_pattern_matches, + str_found, + len(allmatches), + str_matches) + + self.update_results(status, MATCH_OK) + self.populate_code_textbrowser() + + spans = self.findAllSpans(compile_obj) + if self.replace: + self.populate_replace_textbrowser(spans, len(allmatches), compile_obj) + self.populate_matchAll_textbrowser(spans) + + + def findAllSpans(self, compile_obj): + spans = [] + + match_obj = compile_obj.search(self.matchstring) + + last_span = None + + while match_obj: + start = match_obj.start() + end = match_obj.end() + span = (start, end) + if last_span == span: break + + spans.append(span) + + last_span = span + match_obj = compile_obj.search(self.matchstring, end) + + return spans + + + def closeEvent(self, ev): + if not self.checkEditState(): + ev.ignore() + return + + saveWindowSettings(self, GEO) + + try: + self.regexlibwin.close() + except: + pass + + try: + self.ref_win.close() + except: + pass + ev.accept() + + + def fileNew(self): + if not self.checkEditState(): + return + self.filename = "" + + self.regexMultiLineEdit.setPlainText("") + self.stringMultiLineEdit.setPlainText("") + self.replaceTextEdit.setPlainText("") + self.set_flags(0) + self.editstate = STATE_UNEDITED + + + def importURL(self): + self.urldialog = URLDialog(self, self.url) + self.urldialog.urlImported.connect(self.urlImported) + + + def urlImported(self, html, url): + self.url = url + self.stringMultiLineEdit.setPlainText(html) + + + def importFile(self): + fn = QFileDialog.getOpenFileName(self, + self.tr("Import File"), + self.filename, + self.tr("All (*)")) + + if fn.isEmpty(): + self.updateStatus(self.tr("A file was not selected for import"), + -1, + 5, + TRUE) + return None + + filename = str(fn) + + try: + fp = open(filename, "r") + except: + msg = self.tr("Could not open file for reading: ") + filename + self.updateStatus(msg, -1, 5, TRUE) + return None + + data = fp.read() + fp.close() + self.stringMultiLineEdit.setPlainText(data) + + + def fileOpen(self): + filename = self.filename + if filename == None: + filename = "" + fn = QFileDialog.getOpenFileName(self, + self.tr("Open Kodos File"), + filename, + self.tr("Kodos file (*.kds);;All (*)")) + if not fn.isEmpty(): + filename = str(fn) + if self.openFile(filename): + self.recent_files.add(filename) + + + def openFile(self, filename): + if not self.checkEditState(): + return + + self.filename = None + + try: + fp = open(filename, "r") + except: + msg = self.tr("Could not open file for reading: ") + filename + self.updateStatus(msg, -1, 5, TRUE) + return None + + try: + u = cPickle.Unpickler(fp) + self.regex = u.load() + self.matchstring = u.load() + flags = u.load() + except Exception, e: #FIXME: don't catch everything + if self.debug: + print unicode(e) + msg = "%s %s" % (unicode(self.tr("Error reading from file:")), + filename) + self.updateStatus(msg, -1, 5, TRUE) + return 0 + + self.matchNumberSpinBox.setValue(1) + self.regexMultiLineEdit.setPlainText(self.regex) + self.stringMultiLineEdit.setPlainText(self.matchstring) + + self.set_flags(flags) + + try: + replace = u.load() + except: + # versions prior to 1.7 did not have replace functionality + # so kds files saved w/ these versions will throw exception + # here. + replace = "" + self.replaceTextEdit.setPlainText(replace) + + self.filename = filename + msg = "%s %s" % (filename, unicode(self.tr("loaded successfully"))) + self.updateStatus(msg, -1, 5, TRUE) + self.editstate = STATE_UNEDITED + return 1 + + + def fileSaveAs(self): + filename = self.filename + if filename == None: + filename = "" + filedialog = QFileDialog(self, + self.tr("Save Kodos File"), + filename, + "Kodos file (*.kds);;All (*)") + filedialog.setAcceptMode(QFileDialog.AcceptSave) + filedialog.setDefaultSuffix("kds") + ok = filedialog.exec_() + + if ok == QDialog.Rejected: + self.updateStatus(self.tr("No file selected to save"), -1, 5, TRUE) + return + + filename = os.path.normcase(unicode(filedialog.selectedFiles().first())) + + self.filename = filename + self.fileSave() + + + def fileSave(self): + if not self.filename: + self.fileSaveAs() + return + + try: + fp = open(self.filename, "w") + except: + msg = "%s: %s" % (unicode(self.tr("Could not open file for writing:")), + self.filename) + self.updateStatus(msg, -1, 5, TRUE) + return None + + self.editstate = STATE_UNEDITED + p = cPickle.Pickler(fp) + p.dump(self.regex) + p.dump(self.matchstring) + p.dump(self.reFlags.allFlagsORed()) + p.dump(self.replace) + + fp.close() + msg = "%s %s" % (unicode(self.filename), + unicode(self.tr("successfully saved"))) + self.updateStatus(msg, -1, 5, TRUE) + self.recent_files.add(self.filename) + + + def paste_symbol(self, symbol): + self.regexMultiLineEdit.insertPlainText(symbol) + + + def process_embedded_flags(self, regex): + # determine if the regex contains embedded regex flags. + # if it does, set the appropriate checkboxes on the UI to reflect the flags that are embedded + match = self.embedded_flags_obj.match(regex) + if not match: + embedded_flags = "" + self.regex_embedded_flags_removed = regex + else: + embedded_flags = match.group('flags') + self.regex_embedded_flags_removed = self.embedded_flags_obj.sub("", regex, 1) + + for f in self.reFlags: + if f.shortFlag in embedded_flags: + f.embed() + else: + f.deembed() + + + def checkEditState(self): + if self.editstate == STATE_EDITED: + message = self.tr("You have made changes. Would you like to save them before continuing?") + + prompt = QMessageBox.warning(None, + self.tr("Save changes?"), + message, + QMessageBox.Save | + QMessageBox.Cancel | + QMessageBox.Discard) + + if prompt == QMessageBox.Cancel: + return False + + if prompt == QMessageBox.Save: + self.fileSave() + if not self.filename: self.checkEditState() + + return True + + + def pasteFromRegexLib(self, d): + if not self.checkEditState(): + return + + self.filename = "" + + self.regexMultiLineEdit.setPlainText(d.get('regex', "")) + self.stringMultiLineEdit.setPlainText(d.get('text', "")) + self.replaceTextEdit.setPlainText(d.get('replace', "")) + + try: + # set the current page if applicable + self.resultTabWidget.setCurrentIndex(int(d['tab'])) + except KeyError: + pass + self.editstate = STATE_UNEDITED + + + def revert_file_slot(self): + if not self.filename: + self.updateStatus(self.tr("There is no filename to revert"), + -1, + 5, + TRUE) + return + + self.openFile(self.filename) + + + def getWidget(self): + widget = qApp.focusWidget() + if (widget == self.regexMultiLineEdit or + widget == self.stringMultiLineEdit or + widget == self.replaceTextEdit or + widget == self.codeTextBrowser): + return widget + else: + return None + + + def widgetMethod(self, methodstr, anywidget=0): + # execute the methodstr of widget only if widget + # is one of the editable widgets OR if the method + # may be applied to any widget. + widget = qApp.focusWidget() + if anywidget or ( + widget == self.regexMultiLineEdit or + widget == self.stringMultiLineEdit or + widget == self.replaceTextEdit or + widget == self.codeTextBrowser): + try: + eval("widget.%s" % methodstr) + except: + pass + + + def editUndo(self): + self.widgetMethod("undo()") + + def editRedo(self): + self.widgetMethod("redo()") + + def editCopy(self): + self.widgetMethod("copy()", 1) + + def editCut(self): + self.widgetMethod("cut()") + + def editPaste(self): + self.widgetMethod("paste()") + + + def preferences(self): + self.prefs.showPrefsDialog() + self.prefs.prefsSaved.connect(self.prefsSaved) + + def setfont(self, font): + self.regexMultiLineEdit.setFont(font) + self.stringMultiLineEdit.setFont(font) + self.replaceTextEdit.setFont(font) + + def setMatchFont(self, font): + self.groupTable.setFont(font) + self.matchTextBrowser.setFont(font) + self.matchAllTextBrowser.setFont(font) + self.replaceTextBrowser.setFont(font) + self.codeTextBrowser.setFont(font) + + + def getfont(self): + return self.regexMultiLineEdit.font() + + + def getMatchFont(self): + return self.groupTable.font() + + + def helpHelp(self): + self.helpWindow = help.Help(self, "kodos.html") + + + def helpPythonRegex(self): + self.helpWindow = help.Help(self, os.path.join("python", "module-re.html")) + + + def helpRegexLib(self): + f = os.path.join("help", "regex-lib.xml") + self.regexlibwin = RegexLibrary(f) + self.regexlibwin.pasteRegexLib.connect(self.pasteFromRegexLib) + self.regexlibwin.show() + + + def helpAbout(self): + self.aboutWindow = About() + self.aboutWindow.show() + + + def kodos_website(self): + self.launch_browser_wrapper('https://github.com/luksan/kodos', + message=self.tr('Launch web browser to go to the kodos project page?')) + + + def launch_browser_wrapper(self, url, caption=None, message=None): + if launch_browser(url, caption, message): + self.status_bar.set_message(self.tr("Launching web browser"), + 3, + TRUE) + else: + self.status_bar.set_message(self.tr("Cancelled web browser launch"), + 3, + TRUE) + + + def reference_guide(self): + self.ref_win = Reference(self) + self.ref_win.pasteSymbol.connect(self.paste_symbol) + self.ref_win.show() + + + def report_bug(self): + self.launch_browser_wrapper('https://github.com/luksan/kodos/issues', + message=self.tr("Launch web browser to report a bug in kodos?")) From 519891cebe0637ac72b21f91b94d67cfe2673418 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Fri, 17 Aug 2012 16:04:59 +0200 Subject: [PATCH 09/37] Move kodos loader script to bin directory Also fix the util.getAppPath function that is used to find additional data files if kodos is run directly from the git checkout accordingly. --- kodos => bin/kodos | 0 modules/util.py | 2 +- setup.py | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename kodos => bin/kodos (100%) diff --git a/kodos b/bin/kodos similarity index 100% rename from kodos rename to bin/kodos diff --git a/modules/util.py b/modules/util.py index 2fca4f0..b024c7d 100644 --- a/modules/util.py +++ b/modules/util.py @@ -18,7 +18,7 @@ def getAppPath(): "Convenience function so that we can find the necessary images" - fullpath = os.path.abspath(sys.argv[0]) + fullpath = os.path.abspath(os.path.join(sys.argv[0], '..')) path = os.path.dirname(fullpath) return path diff --git a/setup.py b/setup.py index 10d62ed..0acc967 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ def run(self): author="Phil Schwartz", author_email="phil_schwartz@users.sourceforge.net", url="http://kodos.sourceforge.net", - scripts=['kodos'], + scripts=['bin/kodos'], ##package_dir={'': 'modules'}, packages=['modules', "."], data_files=[(HELP_DIR, glob(os.path.join("help", "*.*ml"))), From 0932b6691c7934762733df9a1186b90cc568055b Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Fri, 17 Aug 2012 16:11:33 +0200 Subject: [PATCH 10/37] Use subprocess.check_call instead of os.system The use of os.system should be replaced by the means of the subprocess module. This also makes sure that any non zero exit status of make is fatal. --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 0acc967..3ea400e 100644 --- a/setup.py +++ b/setup.py @@ -8,6 +8,7 @@ import os.path import sys from glob import glob +import subprocess args = sys.argv[1:] @@ -32,7 +33,7 @@ class MyInstall(DistutilsInstall): def run(self): - os.system('make') + subprocess.check_call(['make']) DistutilsInstall.run(self) ######################################################################### From 2f0d6c302f7d8b517b4a67ef7824a11feaff1afb Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Fri, 17 Aug 2012 17:00:15 +0200 Subject: [PATCH 11/37] Execute `make` in the build_py rather than in the install phase --- setup.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 3ea400e..928fc0a 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- from modules.version import VERSION from distutils.core import setup -from distutils.command.install import install as DistutilsInstall +from distutils.command.build_py import build_py as _build_py #from distutils.sysconfig import get_python_lib import os import os.path @@ -31,10 +31,10 @@ MODULES_DIR = os.path.join(libpath, "modules") TRANSLATIONS_DIR = os.path.join(libpath, "translations") -class MyInstall(DistutilsInstall): +class build_py(_build_py): def run(self): subprocess.check_call(['make']) - DistutilsInstall.run(self) + _build_py.run(self) ######################################################################### @@ -59,6 +59,6 @@ def run(self): long_description=""" Kodos is a visual regular expression editor and debugger. """, - cmdclass={'install':MyInstall}, + cmdclass={'build_py': build_py}, ) From bc30c45ec1decc2d01991b794869514af3bbc05c Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Fri, 17 Aug 2012 17:09:27 +0200 Subject: [PATCH 12/37] Remove commented out code and superfluous comments --- setup.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/setup.py b/setup.py index 928fc0a..7136033 100644 --- a/setup.py +++ b/setup.py @@ -3,9 +3,7 @@ from modules.version import VERSION from distutils.core import setup from distutils.command.build_py import build_py as _build_py -#from distutils.sysconfig import get_python_lib import os -import os.path import sys from glob import glob import subprocess @@ -16,8 +14,7 @@ # libpath = '.\\' libpath = r"lib\site-packages\kodos" else: - #libpath = "/usr/local/kodos" # 2.4.0 and prior - libpath = "/usr/share/kodos" # as of 2.4.1 + libpath = "/usr/share/kodos" for arg in args: if arg == "--formats=wininst": @@ -36,8 +33,6 @@ def run(self): subprocess.check_call(['make']) _build_py.run(self) -######################################################################### - setup(name="kodos", version=VERSION, description="Kodos is a visual regular expression editor", @@ -45,7 +40,6 @@ def run(self): author_email="phil_schwartz@users.sourceforge.net", url="http://kodos.sourceforge.net", scripts=['bin/kodos'], - ##package_dir={'': 'modules'}, packages=['modules', "."], data_files=[(HELP_DIR, glob(os.path.join("help", "*.*ml"))), (HELP_PY_DIR, glob(os.path.join("help", "python", "*.html"))), @@ -61,4 +55,3 @@ def run(self): """, cmdclass={'build_py': build_py}, ) - From 81147078184c0ff71379ad0719e83c66c2a41d4e Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Fri, 17 Aug 2012 17:58:35 +0200 Subject: [PATCH 13/37] Rename the `modules` directory to `kodos` --- MANIFEST.in | 4 +-- Makefile | 10 +++--- bin/kodos | 4 +-- kodos.pro | 50 +++++++++++++-------------- {modules => kodos}/Makefile | 0 {modules => kodos}/__init__.py | 0 {modules => kodos}/about.py | 0 {modules => kodos}/aboutBA.ui | 0 {modules => kodos}/debug.py | 0 {modules => kodos}/flags.py | 0 {modules => kodos}/help.py | 0 {modules => kodos}/helpBA.ui | 0 {modules => kodos}/kodosBA.ui | 0 {modules => kodos}/main.py | 0 {modules => kodos}/newUserDialogBA.ui | 0 {modules => kodos}/parseRegexLib.py | 0 {modules => kodos}/prefs.py | 0 {modules => kodos}/prefsBA.ui | 0 {modules => kodos}/recent_files.py | 0 {modules => kodos}/reference.py | 0 {modules => kodos}/referenceBA.ui | 0 {modules => kodos}/regexLibrary.py | 0 {modules => kodos}/regexLibraryBA.ui | 0 {modules => kodos}/status_bar.py | 0 {modules => kodos}/tooltip.py | 0 {modules => kodos}/urlDialog.py | 0 {modules => kodos}/urlDialogBA.ui | 0 {modules => kodos}/util.py | 0 {modules => kodos}/version.py | 0 setup.py | 7 ++-- 30 files changed, 37 insertions(+), 38 deletions(-) rename {modules => kodos}/Makefile (100%) rename {modules => kodos}/__init__.py (100%) rename {modules => kodos}/about.py (100%) rename {modules => kodos}/aboutBA.ui (100%) rename {modules => kodos}/debug.py (100%) rename {modules => kodos}/flags.py (100%) rename {modules => kodos}/help.py (100%) rename {modules => kodos}/helpBA.ui (100%) rename {modules => kodos}/kodosBA.ui (100%) rename {modules => kodos}/main.py (100%) rename {modules => kodos}/newUserDialogBA.ui (100%) rename {modules => kodos}/parseRegexLib.py (100%) rename {modules => kodos}/prefs.py (100%) rename {modules => kodos}/prefsBA.ui (100%) rename {modules => kodos}/recent_files.py (100%) rename {modules => kodos}/reference.py (100%) rename {modules => kodos}/referenceBA.ui (100%) rename {modules => kodos}/regexLibrary.py (100%) rename {modules => kodos}/regexLibraryBA.ui (100%) rename {modules => kodos}/status_bar.py (100%) rename {modules => kodos}/tooltip.py (100%) rename {modules => kodos}/urlDialog.py (100%) rename {modules => kodos}/urlDialogBA.ui (100%) rename {modules => kodos}/util.py (100%) rename {modules => kodos}/version.py (100%) diff --git a/MANIFEST.in b/MANIFEST.in index dfa0425..8372b26 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -8,8 +8,8 @@ include screenshots/*.png include MANIFEST.in include LICENSE.txt include README.txt -include modules/*.ui -include modules/*.py +include kodos/*.ui +include kodos/*.py include windows/build.bat include windows/installer.iss include CHANGELOG.txt diff --git a/Makefile b/Makefile index d03d8b0..2d3486e 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ -all: modules/kodos_rc.py - $(MAKE) -C modules +all: kodos/kodos_rc.py + $(MAKE) -C kodos pylupdate4 kodos.pro $(MAKE) -C translations clean: - $(RM) -fv modules/kodos_rc.py - $(MAKE) clean -C modules + $(RM) -fv kodos/kodos_rc.py + $(MAKE) clean -C kodos -modules/kodos_rc.py: kodos.qrc +kodos/kodos_rc.py: kodos.qrc pyrcc4 -o $@ $< diff --git a/bin/kodos b/bin/kodos index b742888..c6490f1 100755 --- a/bin/kodos +++ b/bin/kodos @@ -17,8 +17,8 @@ you have installed PyQt for the version of Python that you are running.""") from distutils.sysconfig import get_python_lib sys.path.append(os.path.join(get_python_lib(), "kodos")) -from modules.main import Kodos -from modules.util import findFile +from kodos.main import Kodos +from kodos.util import findFile def usage(): print "kodos.py [-f filename | --file=filename ] [ -d debug | --debug=debug ] [ -k kodos_dir ]" diff --git a/kodos.pro b/kodos.pro index 1e375b9..287437c 100644 --- a/kodos.pro +++ b/kodos.pro @@ -1,31 +1,31 @@ SOURCES = kodos - modules/about.py - modules/debug.py - modules/help.py - modules/__init__.py - modules/parseRegexLib.py - modules/prefs.py - modules/recent_files.py - modules/reference.py - modules/regexLibrary.py - modules/reportBug.py - modules/status_bar.py - modules/tooltip.py - modules/urlDialog.py - modules/util.py - modules/version.py + kodos/about.py + kodos/debug.py + kodos/help.py + kodos/__init__.py + kodos/parseRegexLib.py + kodos/prefs.py + kodos/recent_files.py + kodos/reference.py + kodos/regexLibrary.py + kodos/reportBug.py + kodos/status_bar.py + kodos/tooltip.py + kodos/urlDialog.py + kodos/util.py + kodos/version.py TRANSLATIONS = translations/kodos_en.ts \ translations/kodos_pl.ts \ translations/kodos_sv.ts -FORMS = modules/aboutBA.ui \ - modules/helpBA.ui \ - modules/kodosBA.ui \ - modules/newUserDialogBA.ui - modules/prefsBA.ui \ - modules/referenceBA.ui \ - modules/regexLibraryBA.ui \ - modules/reportBugBA.ui \ - modules/resultsBA.ui \ - modules/urlDialogBA.ui +FORMS = kodos/aboutBA.ui \ + kodos/helpBA.ui \ + kodos/kodosBA.ui \ + kodos/newUserDialogBA.ui + kodos/prefsBA.ui \ + kodos/referenceBA.ui \ + kodos/regexLibraryBA.ui \ + kodos/reportBugBA.ui \ + kodos/resultsBA.ui \ + kodos/urlDialogBA.ui diff --git a/modules/Makefile b/kodos/Makefile similarity index 100% rename from modules/Makefile rename to kodos/Makefile diff --git a/modules/__init__.py b/kodos/__init__.py similarity index 100% rename from modules/__init__.py rename to kodos/__init__.py diff --git a/modules/about.py b/kodos/about.py similarity index 100% rename from modules/about.py rename to kodos/about.py diff --git a/modules/aboutBA.ui b/kodos/aboutBA.ui similarity index 100% rename from modules/aboutBA.ui rename to kodos/aboutBA.ui diff --git a/modules/debug.py b/kodos/debug.py similarity index 100% rename from modules/debug.py rename to kodos/debug.py diff --git a/modules/flags.py b/kodos/flags.py similarity index 100% rename from modules/flags.py rename to kodos/flags.py diff --git a/modules/help.py b/kodos/help.py similarity index 100% rename from modules/help.py rename to kodos/help.py diff --git a/modules/helpBA.ui b/kodos/helpBA.ui similarity index 100% rename from modules/helpBA.ui rename to kodos/helpBA.ui diff --git a/modules/kodosBA.ui b/kodos/kodosBA.ui similarity index 100% rename from modules/kodosBA.ui rename to kodos/kodosBA.ui diff --git a/modules/main.py b/kodos/main.py similarity index 100% rename from modules/main.py rename to kodos/main.py diff --git a/modules/newUserDialogBA.ui b/kodos/newUserDialogBA.ui similarity index 100% rename from modules/newUserDialogBA.ui rename to kodos/newUserDialogBA.ui diff --git a/modules/parseRegexLib.py b/kodos/parseRegexLib.py similarity index 100% rename from modules/parseRegexLib.py rename to kodos/parseRegexLib.py diff --git a/modules/prefs.py b/kodos/prefs.py similarity index 100% rename from modules/prefs.py rename to kodos/prefs.py diff --git a/modules/prefsBA.ui b/kodos/prefsBA.ui similarity index 100% rename from modules/prefsBA.ui rename to kodos/prefsBA.ui diff --git a/modules/recent_files.py b/kodos/recent_files.py similarity index 100% rename from modules/recent_files.py rename to kodos/recent_files.py diff --git a/modules/reference.py b/kodos/reference.py similarity index 100% rename from modules/reference.py rename to kodos/reference.py diff --git a/modules/referenceBA.ui b/kodos/referenceBA.ui similarity index 100% rename from modules/referenceBA.ui rename to kodos/referenceBA.ui diff --git a/modules/regexLibrary.py b/kodos/regexLibrary.py similarity index 100% rename from modules/regexLibrary.py rename to kodos/regexLibrary.py diff --git a/modules/regexLibraryBA.ui b/kodos/regexLibraryBA.ui similarity index 100% rename from modules/regexLibraryBA.ui rename to kodos/regexLibraryBA.ui diff --git a/modules/status_bar.py b/kodos/status_bar.py similarity index 100% rename from modules/status_bar.py rename to kodos/status_bar.py diff --git a/modules/tooltip.py b/kodos/tooltip.py similarity index 100% rename from modules/tooltip.py rename to kodos/tooltip.py diff --git a/modules/urlDialog.py b/kodos/urlDialog.py similarity index 100% rename from modules/urlDialog.py rename to kodos/urlDialog.py diff --git a/modules/urlDialogBA.ui b/kodos/urlDialogBA.ui similarity index 100% rename from modules/urlDialogBA.ui rename to kodos/urlDialogBA.ui diff --git a/modules/util.py b/kodos/util.py similarity index 100% rename from modules/util.py rename to kodos/util.py diff --git a/modules/version.py b/kodos/version.py similarity index 100% rename from modules/version.py rename to kodos/version.py diff --git a/setup.py b/setup.py index 7136033..93b33b5 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from modules.version import VERSION +from kodos.version import VERSION from distutils.core import setup from distutils.command.build_py import build_py as _build_py import os @@ -40,16 +40,15 @@ def run(self): author_email="phil_schwartz@users.sourceforge.net", url="http://kodos.sourceforge.net", scripts=['bin/kodos'], - packages=['modules', "."], + packages=['kodos'], data_files=[(HELP_DIR, glob(os.path.join("help", "*.*ml"))), (HELP_PY_DIR, glob(os.path.join("help", "python", "*.html"))), (IMAGES_DIR, glob(os.path.join("images", "*.png"))), (SCREENSHOTS_DIR, glob(os.path.join("screenshots", "*.png"))), (TRANSLATIONS_DIR, glob(os.path.join("translations", "*"))), - (MODULES_DIR, glob("modules/*.ui")) + (MODULES_DIR, glob("kodos/*.ui")) ], license="GPL", - extra_path='kodos', long_description=""" Kodos is a visual regular expression editor and debugger. """, From 0492b534a7e79f2bc5d3c78ee55d8f7a4559377e Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Fri, 17 Aug 2012 17:59:31 +0200 Subject: [PATCH 14/37] Remove the now superfluous extension of sys.path --- bin/kodos | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bin/kodos b/bin/kodos index c6490f1..cbd1590 100755 --- a/bin/kodos +++ b/bin/kodos @@ -13,10 +13,6 @@ except: sys.exit("""Could not locate the PyQt module. Please make sure that you have installed PyQt for the version of Python that you are running.""") -### make sure that this script can find kodos specific modules ### -from distutils.sysconfig import get_python_lib -sys.path.append(os.path.join(get_python_lib(), "kodos")) - from kodos.main import Kodos from kodos.util import findFile From 69b5b45ca6e147b7296cf84bdb7e2d170de66afc Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sat, 18 Aug 2012 22:27:56 +0200 Subject: [PATCH 15/37] Do not install the .ui files The .ui files are not used at runtime, so there is no need to install them. --- setup.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup.py b/setup.py index 93b33b5..822db89 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,6 @@ HELP_PY_DIR = os.path.join(libpath, "help", "python") IMAGES_DIR = os.path.join(libpath, "images") SCREENSHOTS_DIR = os.path.join(libpath, "screenshots") -MODULES_DIR = os.path.join(libpath, "modules") TRANSLATIONS_DIR = os.path.join(libpath, "translations") class build_py(_build_py): @@ -46,7 +45,6 @@ def run(self): (IMAGES_DIR, glob(os.path.join("images", "*.png"))), (SCREENSHOTS_DIR, glob(os.path.join("screenshots", "*.png"))), (TRANSLATIONS_DIR, glob(os.path.join("translations", "*"))), - (MODULES_DIR, glob("kodos/*.ui")) ], license="GPL", long_description=""" From 098ec594a58b670408f8fc5fe102deecdae94211 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sat, 18 Aug 2012 23:50:40 +0200 Subject: [PATCH 16/37] Use optparse instead of getopt --- bin/kodos | 109 ++++++++++++++++++------------------------------------ 1 file changed, 37 insertions(+), 72 deletions(-) diff --git a/bin/kodos b/bin/kodos index cbd1590..6e98211 100755 --- a/bin/kodos +++ b/bin/kodos @@ -4,7 +4,7 @@ import sys import os -import getopt +import optparse try: from PyQt4 import QtGui @@ -16,74 +16,39 @@ you have installed PyQt for the version of Python that you are running.""") from kodos.main import Kodos from kodos.util import findFile -def usage(): - print "kodos.py [-f filename | --file=filename ] [ -d debug | --debug=debug ] [ -k kodos_dir ]" - print - print " -f filename | --filename=filename : Load filename on startup" - print " -d debug | --debug=debug : Set debug to this debug level" - print " -k kodos_dir : Path containing Kodos images & help subdirs" - print " -l locale | --locale=locale : 2-letter locale (eg. en)" - print - sys.exit(0) - -def main(): - filename = None - debug = 0 - kodos_dir = os.path.join(sys.prefix, "kodos") - locale = None - - args = sys.argv[1:] - try: - (opts, getopts) = getopt.getopt(args, 'd:f:k:l:?h', - ["file=", "debug=", - "help", "locale="]) - except: - print "\nInvalid command line option detected." - usage() - - for opt, arg in opts: - if opt in ('-h', '-?', '--help'): - usage() - if opt == '-k': - kodos_dir = arg - if opt in ('-d', '--debug'): - try: - debug = int(arg) - except: - print "debug value must be an integer" - usage() - if opt in ('-f', '--file'): - filename = arg - if opt in ('-l', '--locale'): - locale = arg - - os.environ['KODOS_DIR'] = kodos_dir - - qApp = QtGui.QApplication(sys.argv) - qApp.setOrganizationName("kodos") - qApp.setApplicationName("kodos") - qApp.setOrganizationDomain("kodos.sourceforge.net") - - if locale not in (None, 'en'): - localefile = "kodos_%s.qm" % (locale or QtCore.QTextCodec.locale()) - localepath = findFile(os.path.join("translations", localefile)) - if debug: - print "locale changed to:", locale - print localefile - print localepath - - translator = QtCore.QTranslator(qApp) - translator.load(localepath) - - qApp.installTranslator(translator) - - kodos = Kodos(filename, debug) - - kodos.show() - - sys.exit(qApp.exec_()) - - - -if __name__ == '__main__': - main() +parser = optparse.OptionParser() +parser.add_option('-f', '--filename', dest='filename', + help='Load filename on startup', metavar='FILE') +parser.add_option('-d', '--debug', dest='debug', type='int', + help='Set debug to LEVEL', metavar='LEVEL') +parser.add_option('-k', dest='kodos_dir', type='string', + default=os.path.join(sys.prefix, "kodos"), + help='Set path containing Kodos images & help subdirs', + metavar='DIR') +parser.add_option('-l', '--locale', dest='locale', type='string', + default='en', + help='2-letter locale', metavar='LEVEL') +options, args = parser.parse_args() + +os.environ['KODOS_DIR'] = options.kodos_dir + +qApp = QtGui.QApplication(sys.argv) +qApp.setOrganizationName("kodos") +qApp.setApplicationName("kodos") +qApp.setOrganizationDomain("kodos.sourceforge.net") + +if options.locale != 'en': + localefile = "kodos_%s.qm" % (options.locale or QtCore.QTextCodec.locale()) + localepath = findFile(os.path.join("translations", localefile)) + if debug: + print "locale changed to:", locale + print localefile + print localepath + + translator = QtCore.QTranslator(qApp) + translator.load(localepath) + qApp.installTranslator(translator) + +kodos = Kodos(options.filename, options.debug) +kodos.show() +sys.exit(qApp.exec_()) From 75c45e8ef44f59b5e09785aa2347b0fac4029a7e Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sun, 19 Aug 2012 08:08:42 +0200 Subject: [PATCH 17/37] Remove all debug related code from util.py The debug module is not used anywhere besides util.py and the variable `debug` from that module is initialized to `DEBUG_NONE` effectively disabling all debug related events in util.py anyway. --- kodos/util.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/kodos/util.py b/kodos/util.py index b024c7d..c8458a0 100644 --- a/kodos/util.py +++ b/kodos/util.py @@ -4,7 +4,6 @@ import os import os.path import sys -from debug import * import webbrowser from PyQt4.QtGui import * @@ -14,8 +13,6 @@ FALSE = 0 TRUE = 1 -global debug - def getAppPath(): "Convenience function so that we can find the necessary images" fullpath = os.path.abspath(os.path.join(sys.argv[0], '..')) @@ -28,9 +25,6 @@ def getPixmap(fileStr, fileType="PNG", dir="images"): to the binary location and residing in it's 'images' subdirectory""" image = getAppPath() + os.sep + dir + os.sep + fileStr - - if debug & DEBUG_PIXMAP: print "image:", image - pixmap = QPixmap(image, fileType) pixmap.setMask(pixmap.createHeuristicMask(1)) @@ -78,8 +72,6 @@ def launch_browser(url, caption=None, message=None): try: webbrowser.open(url) except webbrowser.Error, e: - if debug: - print e print "Couldn't open URL:", url return False return True From ceeba25d939a71fbeb56d74e85f22434c019a447 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sun, 19 Aug 2012 08:14:39 +0200 Subject: [PATCH 18/37] Remove the unused debug module --- kodos/debug.py | 34 ---------------------------------- 1 file changed, 34 deletions(-) delete mode 100755 kodos/debug.py diff --git a/kodos/debug.py b/kodos/debug.py deleted file mode 100755 index 32fd790..0000000 --- a/kodos/debug.py +++ /dev/null @@ -1,34 +0,0 @@ -# debug.py: -*- Python -*- DESCRIPTIVE TEXT. - -################################# DEBUGGING CONSTANTS ###################################### - -# debugging constants ... set debug to one of these -# if adding new debug levels make sure the new ones are -# a unique power of 2 (1, 2, 4, 8, 16...). Also, the new -# ones should be added to DEBUG_ALL -DEBUG_NONE = 0 -DEBUG_AUTO_COMPLETE = 1 -DEBUG_ANIMATE = 2 -DEBUG_CONNECT = 4 -DEBUG_SESSION = 8 -DEBUG_PIXMAP = 16 -DEBUG_HISTORY = 32 -DEBUG_SSTM = 64 -DEBUG_MISC = 128 -DEBUG_CMDLINE_ARGS = 256 -DEBUG_PRINT = 512 -DEBUG_PREFS = 1024 -DEBUG_PS_TPL = 2048 - -# convenience constant -DEBUG_ALL = ( - DEBUG_AUTO_COMPLETE | DEBUG_ANIMATE | - DEBUG_CONNECT | DEBUG_SESSION | - DEBUG_PIXMAP | DEBUG_HISTORY | - DEBUG_SSTM | DEBUG_MISC | DEBUG_CMDLINE_ARGS | - DEBUG_PRINT | DEBUG_PREFS | DEBUG_PS_TPL - ) - -# use a bitwise or (|) to use multiple debug levels -# debug = DEBUG_AUTO_COMPLETE | DEBUG_SESSION -debug = DEBUG_NONE From 0432bf3033492c1685ac52433b2eee2c31f67952 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sun, 19 Aug 2012 08:48:31 +0200 Subject: [PATCH 19/37] Use the logging framework instead of conditional prints --- bin/kodos | 20 +++++++++++++------- kodos/main.py | 28 +++++++++++++--------------- kodos/recent_files.py | 12 +++++++----- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/bin/kodos b/bin/kodos index 6e98211..12abc85 100755 --- a/bin/kodos +++ b/bin/kodos @@ -4,6 +4,7 @@ import sys import os +import logging import optparse try: @@ -19,8 +20,8 @@ from kodos.util import findFile parser = optparse.OptionParser() parser.add_option('-f', '--filename', dest='filename', help='Load filename on startup', metavar='FILE') -parser.add_option('-d', '--debug', dest='debug', type='int', - help='Set debug to LEVEL', metavar='LEVEL') +parser.add_option('-d', '--debug', dest='debug', action='store_true', + help='Set log level to debug') parser.add_option('-k', dest='kodos_dir', type='string', default=os.path.join(sys.prefix, "kodos"), help='Set path containing Kodos images & help subdirs', @@ -30,6 +31,12 @@ parser.add_option('-l', '--locale', dest='locale', type='string', help='2-letter locale', metavar='LEVEL') options, args = parser.parse_args() +if options.debug: + logging.basicConfig(level=logging.DEBUG) +else: + logging.basicConfig(level=logging.WARNING) +log = logging.getLogger('kodos') + os.environ['KODOS_DIR'] = options.kodos_dir qApp = QtGui.QApplication(sys.argv) @@ -40,15 +47,14 @@ qApp.setOrganizationDomain("kodos.sourceforge.net") if options.locale != 'en': localefile = "kodos_%s.qm" % (options.locale or QtCore.QTextCodec.locale()) localepath = findFile(os.path.join("translations", localefile)) - if debug: - print "locale changed to:", locale - print localefile - print localepath + log.debug('locale changed to: %s, file: %s, path: %s' % (locale, + localefile, + localepath)) translator = QtCore.QTranslator(qApp) translator.load(localepath) qApp.installTranslator(translator) -kodos = Kodos(options.filename, options.debug) +kodos = Kodos(options.filename) kodos.show() sys.exit(qApp.exec_()) diff --git a/kodos/main.py b/kodos/main.py index e97f498..0b210c4 100644 --- a/kodos/main.py +++ b/kodos/main.py @@ -6,6 +6,7 @@ import string import urllib import cPickle +import logging from PyQt4.QtGui import * from PyQt4.QtCore import * @@ -65,10 +66,10 @@ ############################################################################## class Kodos(KodosBA): - def __init__(self, filename, debug): + def __init__(self, filename): KodosBA.__init__(self) - self.debug = debug + self.log = logging.getLogger('kodos.main') self.regex = "" self.matchstring = "" self.replace = "" @@ -119,8 +120,7 @@ def __init__(self, filename, debug): self.prefs = Preferences(self, 1) self.recent_files = RecentFiles(self, - self.prefs.recentFilesSpinBox.value(), - self.debug) + self.prefs.recentFilesSpinBox.value()) if filename and self.openFile(filename): qApp.processEvents() @@ -159,7 +159,7 @@ def fileMenuHandler(self, menuid): self.recent_files.add(fn) def prefsSaved(self): - if self.debug: print "prefsSaved slot" + self.log.debug("prefsSaved slot") self.recent_files.setNumShown(self.prefs.recentFilesSpinBox.value()) @@ -206,7 +206,7 @@ def get_embedded_flags_string(self): def pause(self): self.is_paused = not self.is_paused - if self.debug: print "is_paused:", self.is_paused + self.log.debug("is_paused: %s" % self.is_paused) if self.is_paused: self.update_results(self.MSG_PAUSED, MATCH_PAUSED) @@ -219,7 +219,7 @@ def pause(self): def examine(self): self.is_examined = not self.is_examined - if self.debug: print "is_examined:", self.is_examined + self.log.debug("is_examined: %s" % self.is_examined) if self.is_examined: color = QCOLOR_YELLOW @@ -235,7 +235,7 @@ def examine(self): try: m = re.search(regex, self.matchstring, self.reFlags.allFlagsORed()) if m: - if self.debug: print "examined regex:", regex + self.log.debug("examined regex: %s" % regex) self.__refresh_regex_widget(color, regex) return except: @@ -560,11 +560,10 @@ def timeout(signum, frame): for key in keys: group_nums[compile_obj.groupindex[key]] = key - if self.debug: - print "group_nums:", group_nums - print "grp index: ", compile_obj.groupindex - print "groups:", match_obj.groups() - print "span: ", match_obj.span() + self.log.debug("group_nums: %s" % group_nums) + self.log.debug("grp index: %s" % compile_obj.groupindex) + self.log.debug("groups: %s" % (match_obj.groups(), )) + self.log.debug("span: %s" % (match_obj.span(), )) # create group_tuple in the form: (group #, group name, group matches) g = allmatches[match_index] @@ -726,8 +725,7 @@ def openFile(self, filename): self.matchstring = u.load() flags = u.load() except Exception, e: #FIXME: don't catch everything - if self.debug: - print unicode(e) + self.log.error('Error unpickling data from file: %s' % e) msg = "%s %s" % (unicode(self.tr("Error reading from file:")), filename) self.updateStatus(msg, -1, 5, TRUE) diff --git a/kodos/recent_files.py b/kodos/recent_files.py index 31b7dc8..d6e1fa7 100644 --- a/kodos/recent_files.py +++ b/kodos/recent_files.py @@ -1,15 +1,17 @@ # -*- coding: utf-8 -*- +import logging + from PyQt4.QtGui import QIcon, QPixmap from PyQt4.QtCore import QSettings MAX_SIZE = 50 # max number of files to retain class RecentFiles: - def __init__(self, parent, numShown=5, debug=None): + def __init__(self, parent, numShown=5): + self.log = logging.getLogger('kodos.recent_files') self.parent = parent self.numShown = int(numShown) - self.debug = debug self.__recent_files = [] self.__indecies = [] self.load() @@ -28,13 +30,13 @@ def load(self): break self.__recent_files.append(str(s)) except Exception, e: - print "Loading of recent file entry", i, "failed." - if self.debug: print e + self.log.error('Loading of recent file entry %i failed: %s' % + (i, e)) settings.remove("Filename") settings.endArray() - if self.debug: print "recent_files:", self.__recent_files + self.log.debug("recent_files: %s" % self.__recent_files) self.addToMenu() From c2b562ac2476baf972e36c8e2b7014e1fc2226a7 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sun, 19 Aug 2012 08:56:47 +0200 Subject: [PATCH 20/37] Use the logging framework instead of unconditional prints --- kodos/prefs.py | 6 +++++- kodos/util.py | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/kodos/prefs.py b/kodos/prefs.py index 3112d49..d99048c 100644 --- a/kodos/prefs.py +++ b/kodos/prefs.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- # prefs.py: -*- Python -*- DESCRIPTIVE TEXT. +import logging + from PyQt4.QtCore import pyqtSignal, QSettings from PyQt4.QtGui import QDialog, QFontDialog from prefsBA import PrefsBA @@ -11,6 +13,7 @@ class Preferences(PrefsBA): prefsSaved = pyqtSignal() def __init__(self, parent, autoload=0): + self.log = logging.getLogger('kodos.prefs') self.parent = parent PrefsBA.__init__(self, parent) @@ -30,7 +33,8 @@ def load(self): if preference == 'Recent Files Count': self.recentFilesSpinBox.setValue(int(setting.toPyObject())) except Exception, e: - print "Loading of configuration key", preference, "failed." + self.log.error('Loading of configuration key %s failed: %s' % + (preference, e)) self.settings.remove(preference) diff --git a/kodos/util.py b/kodos/util.py index c8458a0..fcc4b62 100644 --- a/kodos/util.py +++ b/kodos/util.py @@ -4,11 +4,14 @@ import os import os.path import sys +import logging import webbrowser from PyQt4.QtGui import * from PyQt4.QtCore import * +log = logging.getLogger('kodos.util') + # QT constants that should be defined FALSE = 0 TRUE = 1 @@ -72,6 +75,6 @@ def launch_browser(url, caption=None, message=None): try: webbrowser.open(url) except webbrowser.Error, e: - print "Couldn't open URL:", url + log.error("Couldn't open URL %r: %s" % (url, e)) return False return True From 1bf3cc67a226d2dfa82719920294bec4db3e6ffe Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sun, 19 Aug 2012 11:19:01 +0200 Subject: [PATCH 21/37] Hand the qApp object to the main `Kodos` class Formerly the code used the qApp imported from PyQt4.QtGui which also seems to work but it is not obviously clear why. It seems like the qApp there points to the right (the most recent created?) QApplication object. Hand a reference to our QApplication object to the `Kodos` class to make this explicit and more robust. --- bin/kodos | 2 +- kodos/main.py | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/bin/kodos b/bin/kodos index 12abc85..9ddbf20 100755 --- a/bin/kodos +++ b/bin/kodos @@ -55,6 +55,6 @@ if options.locale != 'en': translator.load(localepath) qApp.installTranslator(translator) -kodos = Kodos(options.filename) +kodos = Kodos(qApp, options.filename) kodos.show() sys.exit(qApp.exec_()) diff --git a/kodos/main.py b/kodos/main.py index 0b210c4..8c3d868 100644 --- a/kodos/main.py +++ b/kodos/main.py @@ -66,10 +66,11 @@ ############################################################################## class Kodos(KodosBA): - def __init__(self, filename): + def __init__(self, qApp, filename): KodosBA.__init__(self) self.log = logging.getLogger('kodos.main') + self.qApp = qApp self.regex = "" self.matchstring = "" self.replace = "" @@ -123,7 +124,7 @@ def __init__(self, filename): self.prefs.recentFilesSpinBox.value()) if filename and self.openFile(filename): - qApp.processEvents() + self.qApp.processEvents() self.fileMenu.triggered.connect(self.fileMenuHandler) @@ -875,7 +876,7 @@ def revert_file_slot(self): def getWidget(self): - widget = qApp.focusWidget() + widget = self.qApp.focusWidget() if (widget == self.regexMultiLineEdit or widget == self.stringMultiLineEdit or widget == self.replaceTextEdit or @@ -889,7 +890,7 @@ def widgetMethod(self, methodstr, anywidget=0): # execute the methodstr of widget only if widget # is one of the editable widgets OR if the method # may be applied to any widget. - widget = qApp.focusWidget() + widget = self.qApp.focusWidget() if anywidget or ( widget == self.regexMultiLineEdit or widget == self.stringMultiLineEdit or From b2efe70b31f2c9068b5a7aa2dbcc13f53f5ceea8 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sun, 19 Aug 2012 11:16:47 +0200 Subject: [PATCH 22/37] Use relative imports and avoid * imports --- kodos/main.py | 80 ++++++++++++++++++++++++------------------------ kodos/tooltip.py | 31 +++++++++---------- kodos/util.py | 23 +++++++------- 3 files changed, 66 insertions(+), 68 deletions(-) diff --git a/kodos/main.py b/kodos/main.py index 8c3d868..033b86d 100644 --- a/kodos/main.py +++ b/kodos/main.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- +import os import re import types import signal @@ -8,16 +9,15 @@ import cPickle import logging -from PyQt4.QtGui import * -from PyQt4.QtCore import * +from PyQt4 import Qt, QtCore -from kodosBA import * -from util import * -from about import * +from . import kodosBA +from . import util +from . import about from . import help -from status_bar import * -from reference import * -from prefs import * +from . import status_bar +from . import reference +from . import prefs from version import VERSION from recent_files import RecentFiles from urlDialog import URLDialog @@ -49,8 +49,8 @@ GEO = "kodos_geometry" # colors for normal & examination mode -QCOLOR_WHITE = QColor(Qt.white) # normal -QCOLOR_YELLOW = QColor(255,255,127) # examine +QCOLOR_WHITE = QtCore.Qt.white # normal +QCOLOR_YELLOW = Qt.QColor(255,255,127) # examine try: signal.SIGALRM @@ -65,9 +65,9 @@ # ############################################################################## -class Kodos(KodosBA): +class Kodos(kodosBA.KodosBA): def __init__(self, qApp, filename): - KodosBA.__init__(self) + kodosBA.KodosBA.__init__(self) self.log = logging.getLogger('kodos.main') self.qApp = qApp @@ -96,10 +96,10 @@ def __init__(self, qApp, filename): self.MSG_FAIL = self.tr("Pattern does not match") - self.statusPixmapsDict = { MATCH_NA: QPixmap(":images/yellow.png"), - MATCH_OK: QPixmap(":images/green.png"), - MATCH_FAIL: QPixmap(":images/red.png"), - MATCH_PAUSED: QPixmap(":images/pause.png"), + self.statusPixmapsDict = { MATCH_NA: Qt.QPixmap(":images/yellow.png"), + MATCH_OK: Qt.QPixmap(":images/green.png"), + MATCH_FAIL: Qt.QPixmap(":images/red.png"), + MATCH_PAUSED: Qt.QPixmap(":images/pause.png"), } @@ -115,11 +115,11 @@ def __init__(self, qApp, filename): ]) self.reFlags.clearAll() - restoreWindowSettings(self, GEO) + util.restoreWindowSettings(self, GEO) self.show() - self.prefs = Preferences(self, 1) + self.prefs = prefs.Preferences(self, 1) self.recent_files = RecentFiles(self, self.prefs.recentFilesSpinBox.value()) @@ -128,7 +128,7 @@ def __init__(self, qApp, filename): self.fileMenu.triggered.connect(self.fileMenuHandler) - kodos_toolbar_logo(self.toolBar) + util.kodos_toolbar_logo(self.toolBar) if self.replace: self.show_replace_widgets() else: self.hide_replace_widgets() @@ -136,7 +136,7 @@ def __init__(self, qApp, filename): def checkIfNewUser(self): - s = QSettings() + s = Qt.QSettings() if s.value('New User', "true").toPyObject() != "false": self.newuserdialog = NewUserDialog() self.newuserdialog.show() @@ -144,7 +144,7 @@ def checkIfNewUser(self): def createStatusBar(self): - self.status_bar = Status_Bar(self, FALSE, "") + self.status_bar = status_bar.Status_Bar(self, FALSE, "") def updateStatus(self, status_string, status_value, duration=0, replace=FALSE, tooltip=''): @@ -253,7 +253,7 @@ def examine(self): def __refresh_regex_widget(self, base_qcolor, regex): - pal = QPalette() + pal = Qt.QPalette() pal.setColor(pal.Base, base_qcolor) self.regexMultiLineEdit.setPalette(pal) @@ -323,8 +323,8 @@ def populate_group_table(self, tuples): self.groupTable.setRowCount(rows) row = 0 for t in tuples: - self.groupTable.setItem(row, 0, QTableWidgetItem(t[1])) - self.groupTable.setItem(row, 1, QTableWidgetItem(t[2])) + self.groupTable.setItem(row, 0, Qt.QTableWidgetItem(t[1])) + self.groupTable.setItem(row, 1, Qt.QTableWidgetItem(t[2])) row += 1 @@ -383,7 +383,7 @@ def populate_code_textbrowser(self): def colorize_strings(self, strings, widget, cursorOffset=0): widget.clear() - colors = (QBrush(QColor(Qt.black)), QBrush(QColor(Qt.blue)) ) + colors = (Qt.QBrush(Qt.QColor(QtCore.Qt.black)), Qt.QBrush(Qt.QColor(QtCore.Qt.blue)) ) cur = widget.textCursor() format = cur.charFormat() @@ -630,7 +630,7 @@ def closeEvent(self, ev): ev.ignore() return - saveWindowSettings(self, GEO) + util.saveWindowSettings(self, GEO) try: self.regexlibwin.close() @@ -667,7 +667,7 @@ def urlImported(self, html, url): def importFile(self): - fn = QFileDialog.getOpenFileName(self, + fn = Qt.QFileDialog.getOpenFileName(self, self.tr("Import File"), self.filename, self.tr("All (*)")) @@ -697,7 +697,7 @@ def fileOpen(self): filename = self.filename if filename == None: filename = "" - fn = QFileDialog.getOpenFileName(self, + fn = Qt.QFileDialog.getOpenFileName(self, self.tr("Open Kodos File"), filename, self.tr("Kodos file (*.kds);;All (*)")) @@ -758,15 +758,15 @@ def fileSaveAs(self): filename = self.filename if filename == None: filename = "" - filedialog = QFileDialog(self, + filedialog = Qt.QFileDialog(self, self.tr("Save Kodos File"), filename, "Kodos file (*.kds);;All (*)") - filedialog.setAcceptMode(QFileDialog.AcceptSave) + filedialog.setAcceptMode(Qt.QFileDialog.AcceptSave) filedialog.setDefaultSuffix("kds") ok = filedialog.exec_() - if ok == QDialog.Rejected: + if ok == Qt.QDialog.Rejected: self.updateStatus(self.tr("No file selected to save"), -1, 5, TRUE) return @@ -829,17 +829,17 @@ def checkEditState(self): if self.editstate == STATE_EDITED: message = self.tr("You have made changes. Would you like to save them before continuing?") - prompt = QMessageBox.warning(None, + prompt = Qt.QMessageBox.warning(None, self.tr("Save changes?"), message, - QMessageBox.Save | - QMessageBox.Cancel | - QMessageBox.Discard) + Qt.QMessageBox.Save | + Qt.QMessageBox.Cancel | + Qt.QMessageBox.Discard) - if prompt == QMessageBox.Cancel: + if prompt == Qt.QMessageBox.Cancel: return False - if prompt == QMessageBox.Save: + if prompt == Qt.QMessageBox.Save: self.fileSave() if not self.filename: self.checkEditState() @@ -959,7 +959,7 @@ def helpRegexLib(self): def helpAbout(self): - self.aboutWindow = About() + self.aboutWindow = about.About() self.aboutWindow.show() @@ -969,7 +969,7 @@ def kodos_website(self): def launch_browser_wrapper(self, url, caption=None, message=None): - if launch_browser(url, caption, message): + if util.launch_browser(url, caption, message): self.status_bar.set_message(self.tr("Launching web browser"), 3, TRUE) @@ -980,7 +980,7 @@ def launch_browser_wrapper(self, url, caption=None, message=None): def reference_guide(self): - self.ref_win = Reference(self) + self.ref_win = reference.Reference(self) self.ref_win.pasteSymbol.connect(self.paste_symbol) self.ref_win.show() diff --git a/kodos/tooltip.py b/kodos/tooltip.py index ae3dd8e..99e5872 100644 --- a/kodos/tooltip.py +++ b/kodos/tooltip.py @@ -1,29 +1,28 @@ # -*- coding: utf-8 -*- # tooltip.py: -*- Python -*- DESCRIPTIVE TEXT. -from PyQt4.QtGui import * -from PyQt4.QtCore import * -from util import * +from PyQt4 import Qt, QtCore +from util import FALSE -class Tooltip(QLabel): +class Tooltip(Qt.QLabel): def __init__(self, text, bgcolor="#ffd700",fgcolor="#000000",delay=1000): self.delay = delay - QLabel.__init__(self, None, Qt.WindowStaysOnTopHint - | Qt.FramelessWindowHint - | Qt.Tool) + Qt.QLabel.__init__(self, None, QtCore.Qt.WindowStaysOnTopHint + | QtCore.Qt.FramelessWindowHint + | QtCore.Qt.Tool) self.setMargin(1) self.setIndent(0) - self.setFrameStyle(QFrame.Plain | QFrame.Box) + self.setFrameStyle(Qt.QFrame.Plain | Qt.QFrame.Box) self.setLineWidth(1) self.setText(text) self.adjustSize() # set the pallete... - pal = QPalette() - pal.setColor(QPalette.Active, QPalette.Window, QColor(bgcolor)) - pal.setColor(QPalette.Active, QPalette.WindowText, QColor(fgcolor)) - pal.setColor(QPalette.Inactive, QPalette.Window, QColor(bgcolor)) - pal.setColor(QPalette.Inactive, QPalette.WindowText, QColor(fgcolor)) + pal = Qt.QPalette() + pal.setColor(Qt.QPalette.Active, Qt.QPalette.Window, Qt.QColor(bgcolor)) + pal.setColor(Qt.QPalette.Active, Qt.QPalette.WindowText, Qt.QColor(fgcolor)) + pal.setColor(Qt.QPalette.Inactive, Qt.QPalette.Window, Qt.QColor(bgcolor)) + pal.setColor(Qt.QPalette.Inactive, Qt.QPalette.WindowText, Qt.QColor(fgcolor)) self.setPalette(pal) self.enter_timer_id = None @@ -67,11 +66,11 @@ def timerEvent( self, ev ): def eventFilter(self, obj, ev): type = ev.type() - if type == QEvent.Enter: + if type == Qt.QEvent.Enter: self.killCustomTimers() self.enter_timer_id = self.startTimer(self.delay) self.event_widget = obj - elif type == QEvent.Leave: + elif type == Qt.QEvent.Leave: self.killCustomTimers() self.leave_timer_id = self.startTimer(self.delay) self.event_widget = None @@ -84,7 +83,7 @@ def tooltip_open(self): try: pos = self.event_widget.mapToGlobal( - QPoint(0, self.event_widget.height())) + Qt.QPoint(0, self.event_widget.height())) self.move(pos.x(), pos.y()) self.show() self.setFixedSize( self.sizeHint() ) diff --git a/kodos/util.py b/kodos/util.py index fcc4b62..43fc93e 100644 --- a/kodos/util.py +++ b/kodos/util.py @@ -7,8 +7,7 @@ import logging import webbrowser -from PyQt4.QtGui import * -from PyQt4.QtCore import * +from PyQt4 import Qt log = logging.getLogger('kodos.util') @@ -24,22 +23,22 @@ def getAppPath(): def getPixmap(fileStr, fileType="PNG", dir="images"): - """Return a QPixmap instance for the file fileStr relative + """Return a Qt.QPixmap instance for the file fileStr relative to the binary location and residing in it's 'images' subdirectory""" image = getAppPath() + os.sep + dir + os.sep + fileStr - pixmap = QPixmap(image, fileType) + pixmap = Qt.QPixmap(image, fileType) pixmap.setMask(pixmap.createHeuristicMask(1)) return pixmap def kodos_toolbar_logo(toolbar): # hack to move logo to right - blanklabel = QLabel() - blanklabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) + blanklabel = Qt.QLabel() + blanklabel.setSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Preferred) - logolabel = QLabel("kodos_logo") - logolabel.setPixmap(QPixmap(":/images/kodos_icon.png")) + logolabel = Qt.QLabel("kodos_logo") + logolabel.setPixmap(Qt.QPixmap(":/images/kodos_icon.png")) toolbar.addWidget(blanklabel) toolbar.addWidget(logolabel) @@ -47,11 +46,11 @@ def kodos_toolbar_logo(toolbar): return logolabel def saveWindowSettings(window, filename): - settings = QSettings() + settings = Qt.QSettings() settings.setValue(window.objectName(), window.saveGeometry()) def restoreWindowSettings(window, filename): - settings = QSettings() + settings = Qt.QSettings() window.restoreGeometry(settings.value(window.objectName()).toByteArray()) def findFile(filename): @@ -69,8 +68,8 @@ def launch_browser(url, caption=None, message=None): if not caption: caption = "Info" if not message: message = "Launch web browser?" - button = QMessageBox.information(None, caption, message, QMessageBox.Ok | QMessageBox.Cancel) - if button == QMessageBox.Cancel: + button = Qt.QMessageBox.information(None, caption, message, Qt.QMessageBox.Ok | Qt.QMessageBox.Cancel) + if button == Qt.QMessageBox.Cancel: return False try: webbrowser.open(url) From 4bc909af3d8fdda1eef426f4d3cd303b3e0f40a7 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sun, 19 Aug 2012 12:06:54 +0200 Subject: [PATCH 23/37] Remove unused imports --- kodos/main.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/kodos/main.py b/kodos/main.py index 033b86d..ae74511 100644 --- a/kodos/main.py +++ b/kodos/main.py @@ -4,8 +4,6 @@ import re import types import signal -import string -import urllib import cPickle import logging @@ -18,7 +16,6 @@ from . import status_bar from . import reference from . import prefs -from version import VERSION from recent_files import RecentFiles from urlDialog import URLDialog from regexLibrary import RegexLibrary From 5f2a208d37b8dcd866a8368be41b237039f93004 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sun, 19 Aug 2012 12:08:06 +0200 Subject: [PATCH 24/37] Remove RecentFiles.move(..) There is no QIconSet in Qt4. Simply remove the method RecentFiles.move since that this method is unused. --- kodos/recent_files.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/kodos/recent_files.py b/kodos/recent_files.py index d6e1fa7..cd6d55f 100644 --- a/kodos/recent_files.py +++ b/kodos/recent_files.py @@ -99,19 +99,3 @@ def setNumShown(self, numShown): def isRecentFile(self, menuid): return menuid in self.__indecies - - def move(self, filename, menuid): - # fix me.... - menu = self.parent.fileMenu - idx = menu.indexOf(self.__indecies[0]) - menu.removeItem(menuid) - menu.insertItem(QIconSet(QPixmap(":images/document-open-recent.png")), - filename, - -1, - idx) - try: - self.__recent_files.remove(filename) - except: - pass - self.__indecies.insert(0, filename) - From 38704c684c6e91300f656583cb90d555291036bb Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sun, 19 Aug 2012 12:11:21 +0200 Subject: [PATCH 25/37] Remove superfluous import of os.path --- kodos/util.py | 1 - 1 file changed, 1 deletion(-) diff --git a/kodos/util.py b/kodos/util.py index 43fc93e..1d90edb 100644 --- a/kodos/util.py +++ b/kodos/util.py @@ -2,7 +2,6 @@ # util.py: -*- Python -*- DESCRIPTIVE TEXT. import os -import os.path import sys import logging import webbrowser From e10a8b6967b0b0b4725505792de7c74c37a6e31e Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sun, 19 Aug 2012 12:26:44 +0200 Subject: [PATCH 26/37] Use package relative imports --- kodos/help.py | 6 +++--- kodos/main.py | 20 ++++++++++---------- kodos/parseRegexLib.py | 6 +++--- kodos/prefs.py | 8 ++++---- kodos/reference.py | 8 ++++---- kodos/regexLibrary.py | 12 ++++++------ kodos/status_bar.py | 6 +++--- kodos/tooltip.py | 2 +- kodos/urlDialog.py | 9 +++++---- 9 files changed, 39 insertions(+), 38 deletions(-) diff --git a/kodos/help.py b/kodos/help.py index b8b79c8..990478d 100755 --- a/kodos/help.py +++ b/kodos/help.py @@ -7,7 +7,7 @@ from PyQt4 import QtCore from . import util -from helpBA import HelpBA +from . import helpBA class textbrowser(QtGui.QTextBrowser): # reimplemented textbrowser that filters out external sources @@ -28,9 +28,9 @@ def setSource(self, src): -class Help(HelpBA): +class Help(helpBA.HelpBA): def __init__(self, parent, filename): - HelpBA.__init__(self, parent) + helpBA.HelpBA.__init__(self, parent) self.setGeometry(100, 50, 800, 600) diff --git a/kodos/main.py b/kodos/main.py index ae74511..4c240eb 100644 --- a/kodos/main.py +++ b/kodos/main.py @@ -16,11 +16,11 @@ from . import status_bar from . import reference from . import prefs -from recent_files import RecentFiles -from urlDialog import URLDialog -from regexLibrary import RegexLibrary -from newUserDialogBA import NewUserDialog -from flags import reFlag, reFlagList +from . import recent_files +from . import urlDialog +from . import regexLibrary +from . import newUserDialogBA +from .flags import reFlag, reFlagList # match status MATCH_NA = 0 @@ -117,8 +117,8 @@ def __init__(self, qApp, filename): self.show() self.prefs = prefs.Preferences(self, 1) - self.recent_files = RecentFiles(self, - self.prefs.recentFilesSpinBox.value()) + self.recent_files = recent_files.RecentFiles(self, + self.prefs.recentFilesSpinBox.value()) if filename and self.openFile(filename): self.qApp.processEvents() @@ -135,7 +135,7 @@ def __init__(self, qApp, filename): def checkIfNewUser(self): s = Qt.QSettings() if s.value('New User', "true").toPyObject() != "false": - self.newuserdialog = NewUserDialog() + self.newuserdialog = newUserDialogBA.NewUserDialog() self.newuserdialog.show() s.setValue('New User', "false") @@ -654,7 +654,7 @@ def fileNew(self): def importURL(self): - self.urldialog = URLDialog(self, self.url) + self.urldialog = urlDialog.URLDialog(self, self.url) self.urldialog.urlImported.connect(self.urlImported) @@ -950,7 +950,7 @@ def helpPythonRegex(self): def helpRegexLib(self): f = os.path.join("help", "regex-lib.xml") - self.regexlibwin = RegexLibrary(f) + self.regexlibwin = regexLibrary.RegexLibrary(f) self.regexlibwin.pasteRegexLib.connect(self.pasteFromRegexLib) self.regexlibwin.show() diff --git a/kodos/parseRegexLib.py b/kodos/parseRegexLib.py index d58c233..da81b9d 100644 --- a/kodos/parseRegexLib.py +++ b/kodos/parseRegexLib.py @@ -1,6 +1,6 @@ import re import os -from util import findFile +from . import util rx_entry = re.compile(r"(?P.*?)", re.DOTALL) @@ -25,7 +25,7 @@ class ParseRegexLib: def __init__(self, filename): if filename: - path = findFile(os.path.join("help", "regex-lib.xml")) + path = util.findFile(os.path.join("help", "regex-lib.xml")) data = open(path).read() self.data = data else: @@ -52,7 +52,7 @@ def parse(self, data=""): if __name__ == '__main__': - path = findFile(os.path.join("help", "regex-lib.xml")) + path = util.findFile(os.path.join("help", "regex-lib.xml")) x = ParseRegexLib(path) dicts = x.parse() diff --git a/kodos/prefs.py b/kodos/prefs.py index d99048c..e8e874d 100644 --- a/kodos/prefs.py +++ b/kodos/prefs.py @@ -5,17 +5,17 @@ from PyQt4.QtCore import pyqtSignal, QSettings from PyQt4.QtGui import QDialog, QFontDialog -from prefsBA import PrefsBA -import help +from . import prefsBA +from . import help -class Preferences(PrefsBA): +class Preferences(prefsBA.PrefsBA): prefsSaved = pyqtSignal() def __init__(self, parent, autoload=0): self.log = logging.getLogger('kodos.prefs') self.parent = parent - PrefsBA.__init__(self, parent) + prefsBA.PrefsBA.__init__(self, parent) self.settings = QSettings() diff --git a/kodos/reference.py b/kodos/reference.py index 85c2627..927ce41 100644 --- a/kodos/reference.py +++ b/kodos/reference.py @@ -2,17 +2,17 @@ # reference.py: -*- Python -*- DESCRIPTIVE TEXT. from PyQt4.QtCore import pyqtSignal -from referenceBA import ReferenceBA -from util import kodos_toolbar_logo, restoreWindowSettings, saveWindowSettings +from . import referenceBA +from .util import kodos_toolbar_logo, restoreWindowSettings, saveWindowSettings GEO = "regex-ref_geometry" -class Reference(ReferenceBA): +class Reference(referenceBA.ReferenceBA): pasteSymbol = pyqtSignal(str) def __init__(self, parent): - ReferenceBA.__init__(self, None) + referenceBA.ReferenceBA.__init__(self, None) self.parent = parent restoreWindowSettings(self, GEO) diff --git a/kodos/regexLibrary.py b/kodos/regexLibrary.py index 13af979..abce53b 100644 --- a/kodos/regexLibrary.py +++ b/kodos/regexLibrary.py @@ -1,17 +1,17 @@ # -*- coding: utf-8 -*- from PyQt4.QtCore import pyqtSignal -from regexLibraryBA import RegexLibraryBA -from parseRegexLib import ParseRegexLib -from util import restoreWindowSettings, saveWindowSettings, kodos_toolbar_logo +from . import regexLibraryBA +from . import parseRegexLib +from .util import restoreWindowSettings, saveWindowSettings, kodos_toolbar_logo GEO = "regex-lib_geometry" -class RegexLibrary(RegexLibraryBA): +class RegexLibrary(regexLibraryBA.RegexLibraryBA): pasteRegexLib = pyqtSignal(dict) def __init__(self, filename): - RegexLibraryBA.__init__(self, None) + regexLibraryBA.RegexLibraryBA.__init__(self, None) self.filename = filename self.selected = None @@ -28,7 +28,7 @@ def closeEvent(self, ev): def parseXML(self): - parser = ParseRegexLib(self.filename) + parser = parseRegexLib.ParseRegexLib(self.filename) self.xml_dicts = parser.parse() diff --git a/kodos/status_bar.py b/kodos/status_bar.py index e0ba25a..1e378e8 100644 --- a/kodos/status_bar.py +++ b/kodos/status_bar.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- # status_bar.py: -*- Python -*- DESCRIPTIVE TEXT. -from tooltip import Tooltip -from util import TRUE, FALSE +from . import tooltip +from .util import TRUE, FALSE from PyQt4.QtCore import QTimer from PyQt4.QtGui import QPixmap, QLabel, QProgressBar @@ -16,7 +16,7 @@ def __init__(self, parent, progress_bar=FALSE, message=''): self.__statusTimer.timeout.connect(self.reset_message) self.__statusLabel = QLabel("msg", self.statusBar) - self.tooltip = Tooltip('') + self.tooltip = tooltip.Tooltip('') self.tooltip.addWidget(self.__statusLabel) self.last_status_message = '' diff --git a/kodos/tooltip.py b/kodos/tooltip.py index 99e5872..35a6f46 100644 --- a/kodos/tooltip.py +++ b/kodos/tooltip.py @@ -2,7 +2,7 @@ # tooltip.py: -*- Python -*- DESCRIPTIVE TEXT. from PyQt4 import Qt, QtCore -from util import FALSE +from .util import FALSE class Tooltip(Qt.QLabel): def __init__(self, text, bgcolor="#ffd700",fgcolor="#000000",delay=1000): diff --git a/kodos/urlDialog.py b/kodos/urlDialog.py index 1900bf2..7ea64db 100644 --- a/kodos/urlDialog.py +++ b/kodos/urlDialog.py @@ -1,17 +1,18 @@ # -*- coding: utf-8 -*- + from PyQt4.QtCore import pyqtSignal from PyQt4.QtGui import QMessageBox -from urlDialogBA import URLDialogBA -import help +from . import urlDialogBA +from . import help import urllib -class URLDialog(URLDialogBA): +class URLDialog(urlDialogBA.URLDialogBA): urlImported = pyqtSignal(str, str) def __init__(self, parent, url=None): - URLDialogBA.__init__(self, parent) + urlDialogBA.URLDialogBA.__init__(self, parent) if url: self.URLTextEdit.setPlainText(url) From 1192ad6bfc12e982bd3098e2eda935006587dc95 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sun, 19 Aug 2012 12:33:39 +0200 Subject: [PATCH 27/37] Use True and False instead of TRUE and FALSE The PyQt4 bindings handle python booleans seamlessly. In fact, True and False are numeric values in python with the same values (isinstance(True, int) and True == 1). --- kodos/main.py | 47 +++++++++++++++++++++------------------------ kodos/status_bar.py | 7 +++---- kodos/tooltip.py | 3 +-- kodos/util.py | 4 ---- 4 files changed, 26 insertions(+), 35 deletions(-) diff --git a/kodos/main.py b/kodos/main.py index 4c240eb..180699c 100644 --- a/kodos/main.py +++ b/kodos/main.py @@ -29,9 +29,6 @@ MATCH_PAUSED = 3 MATCH_EXAMINED = 4 -TRUE = 1 -FALSE = 0 - TIMEOUT = 3 # regex to find special flags which must begin at beginning of line @@ -141,10 +138,10 @@ def checkIfNewUser(self): def createStatusBar(self): - self.status_bar = status_bar.Status_Bar(self, FALSE, "") + self.status_bar = status_bar.Status_Bar(self, False, "") - def updateStatus(self, status_string, status_value, duration=0, replace=FALSE, tooltip=''): + def updateStatus(self, status_string, status_value, duration=0, replace=False, tooltip=''): pixmap = self.statusPixmapsDict.get(status_value) self.status_bar.set_message(status_string, duration, replace, tooltip, pixmap) @@ -289,14 +286,14 @@ def hide_replace_widgets(self): self.replaceLabel.hide() self.replaceNumberSpinBox.hide() self.replaceTextBrowser.clear() - self.replaceTextBrowser.setDisabled(TRUE) + self.replaceTextBrowser.setDisabled(True) def show_replace_widgets(self): self.spacerLabel.show() self.replaceLabel.show() self.replaceNumberSpinBox.show() - self.replaceNumberSpinBox.setEnabled(TRUE) - self.replaceTextBrowser.setEnabled(TRUE) + self.replaceNumberSpinBox.setEnabled(True) + self.replaceTextBrowser.setEnabled(True) def replace_changed_slot(self): self.replace = unicode(self.replaceTextEdit.toPlainText()) @@ -485,8 +482,8 @@ def clear_results(self): self.codeTextBrowser.clear() self.matchTextBrowser.clear() - self.matchNumberSpinBox.setEnabled(FALSE) - self.replaceNumberSpinBox.setEnabled(FALSE) + self.matchNumberSpinBox.setEnabled(False) + self.replaceNumberSpinBox.setEnabled(False) self.replaceTextBrowser.clear() self.matchAllTextBrowser.clear() @@ -515,12 +512,12 @@ def timeout(signum, frame): if allmatches and len(allmatches): self.matchNumberSpinBox.setMaximum(len(allmatches)) - self.matchNumberSpinBox.setEnabled(TRUE) + self.matchNumberSpinBox.setEnabled(True) self.replaceNumberSpinBox.setMaximum(len(allmatches)) - self.replaceNumberSpinBox.setEnabled(TRUE) + self.replaceNumberSpinBox.setEnabled(True) else: - self.matchNumberSpinBox.setEnabled(FALSE) - self.replaceNumberSpinBox.setEnabled(FALSE) + self.matchNumberSpinBox.setEnabled(False) + self.replaceNumberSpinBox.setEnabled(False) match_obj = compile_obj.search(self.matchstring) @@ -673,7 +670,7 @@ def importFile(self): self.updateStatus(self.tr("A file was not selected for import"), -1, 5, - TRUE) + True) return None filename = str(fn) @@ -682,7 +679,7 @@ def importFile(self): fp = open(filename, "r") except: msg = self.tr("Could not open file for reading: ") + filename - self.updateStatus(msg, -1, 5, TRUE) + self.updateStatus(msg, -1, 5, True) return None data = fp.read() @@ -714,7 +711,7 @@ def openFile(self, filename): fp = open(filename, "r") except: msg = self.tr("Could not open file for reading: ") + filename - self.updateStatus(msg, -1, 5, TRUE) + self.updateStatus(msg, -1, 5, True) return None try: @@ -726,7 +723,7 @@ def openFile(self, filename): self.log.error('Error unpickling data from file: %s' % e) msg = "%s %s" % (unicode(self.tr("Error reading from file:")), filename) - self.updateStatus(msg, -1, 5, TRUE) + self.updateStatus(msg, -1, 5, True) return 0 self.matchNumberSpinBox.setValue(1) @@ -746,7 +743,7 @@ def openFile(self, filename): self.filename = filename msg = "%s %s" % (filename, unicode(self.tr("loaded successfully"))) - self.updateStatus(msg, -1, 5, TRUE) + self.updateStatus(msg, -1, 5, True) self.editstate = STATE_UNEDITED return 1 @@ -764,7 +761,7 @@ def fileSaveAs(self): ok = filedialog.exec_() if ok == Qt.QDialog.Rejected: - self.updateStatus(self.tr("No file selected to save"), -1, 5, TRUE) + self.updateStatus(self.tr("No file selected to save"), -1, 5, True) return filename = os.path.normcase(unicode(filedialog.selectedFiles().first())) @@ -783,7 +780,7 @@ def fileSave(self): except: msg = "%s: %s" % (unicode(self.tr("Could not open file for writing:")), self.filename) - self.updateStatus(msg, -1, 5, TRUE) + self.updateStatus(msg, -1, 5, True) return None self.editstate = STATE_UNEDITED @@ -796,7 +793,7 @@ def fileSave(self): fp.close() msg = "%s %s" % (unicode(self.filename), unicode(self.tr("successfully saved"))) - self.updateStatus(msg, -1, 5, TRUE) + self.updateStatus(msg, -1, 5, True) self.recent_files.add(self.filename) @@ -866,7 +863,7 @@ def revert_file_slot(self): self.updateStatus(self.tr("There is no filename to revert"), -1, 5, - TRUE) + True) return self.openFile(self.filename) @@ -969,11 +966,11 @@ def launch_browser_wrapper(self, url, caption=None, message=None): if util.launch_browser(url, caption, message): self.status_bar.set_message(self.tr("Launching web browser"), 3, - TRUE) + True) else: self.status_bar.set_message(self.tr("Cancelled web browser launch"), 3, - TRUE) + True) def reference_guide(self): diff --git a/kodos/status_bar.py b/kodos/status_bar.py index 1e378e8..b895b74 100644 --- a/kodos/status_bar.py +++ b/kodos/status_bar.py @@ -2,12 +2,11 @@ # status_bar.py: -*- Python -*- DESCRIPTIVE TEXT. from . import tooltip -from .util import TRUE, FALSE from PyQt4.QtCore import QTimer from PyQt4.QtGui import QPixmap, QLabel, QProgressBar class Status_Bar: - def __init__(self, parent, progress_bar=FALSE, message=''): + def __init__(self, parent, progress_bar=False, message=''): self.parent = parent self.statusBar = parent.statusBar() @@ -30,13 +29,13 @@ def __init__(self, parent, progress_bar=FALSE, message=''): self.statusBar.addWidget(self.__statusLabel) if progress_bar: self.progressBar = QProgressBar(self.statusBar) - self.statusBar.addWidget(self.progressBar, 1, TRUE) + self.statusBar.addWidget(self.progressBar, 1, True) if message: self.set_message(message) - def set_message(self, message='', duration=0, replace=FALSE, tooltip='', pixmap=''): + def set_message(self, message='', duration=0, replace=False, tooltip='', pixmap=''): """sets the status bar message label to message. if duration is > 0 than the message is displayed for duration seconds. diff --git a/kodos/tooltip.py b/kodos/tooltip.py index 35a6f46..539051f 100644 --- a/kodos/tooltip.py +++ b/kodos/tooltip.py @@ -2,7 +2,6 @@ # tooltip.py: -*- Python -*- DESCRIPTIVE TEXT. from PyQt4 import Qt, QtCore -from .util import FALSE class Tooltip(Qt.QLabel): def __init__(self, text, bgcolor="#ffd700",fgcolor="#000000",delay=1000): @@ -74,7 +73,7 @@ def eventFilter(self, obj, ev): self.killCustomTimers() self.leave_timer_id = self.startTimer(self.delay) self.event_widget = None - return FALSE ## Always return unhandled for this kind of filter!!! + return False ## Always return unhandled for this kind of filter!!! def tooltip_open(self): diff --git a/kodos/util.py b/kodos/util.py index 1d90edb..da53882 100644 --- a/kodos/util.py +++ b/kodos/util.py @@ -10,10 +10,6 @@ log = logging.getLogger('kodos.util') -# QT constants that should be defined -FALSE = 0 -TRUE = 1 - def getAppPath(): "Convenience function so that we can find the necessary images" fullpath = os.path.abspath(os.path.join(sys.argv[0], '..')) From 24e071105682c4fb436c764947333c59f4828417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= Date: Fri, 25 Dec 2020 02:19:00 +0000 Subject: [PATCH 28/37] Revert "Clean translations/*.ts" This reverts commit 49ef05184f614717d4d43d649277c224597937f9. --- .gitignore | 1 - setup.cfg | 6 +- translations/kodos_en.ts | 1338 +++++++++++++++++++++++++++++++++++++ translations/kodos_pl.ts | 1359 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 2700 insertions(+), 4 deletions(-) create mode 100644 translations/kodos_en.ts create mode 100644 translations/kodos_pl.ts diff --git a/.gitignore b/.gitignore index 86d2aff..0f414d8 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,3 @@ /modules/*BA.py /modules/kodos_rc.py /translations/*.qm -/translations/*.ts diff --git a/setup.cfg b/setup.cfg index 630e5fe..7447b44 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,10 +1,10 @@ [bdist_rpm] -build_requires=PyQt4 +build_requires=PyQt-3.8 vendor = Kodos - Sourceforge packager = Phil Schwartz distribution-name = Red Hat Linux -requires = python >= 2.4 -requires = PyQt >= 4.0 +requires = python >= 2.0 +requires = PyQt >= 3.0 build-requires = python-devel doc_files = README.txt LICENSE.txt diff --git a/translations/kodos_en.ts b/translations/kodos_en.ts new file mode 100644 index 0000000..ac79649 --- /dev/null +++ b/translations/kodos_en.ts @@ -0,0 +1,1338 @@ + + + AboutBA + + About Kodos + + + + &OK + + + + About... + + + + 0.8 + + + + Kodos + +Developed by: Phil Schwartz + +phil_schwartz@users.sourceforge.net + + + + Version: + + + + + Kodos + + Enter a regular expression and a string to match against + + + + Kodos regex processing is paused. Click the pause icon to unpause + + + + Pattern does not match + + + + Pattern matches + + + + found + + + + match + + + + matches + + + + &No, Just Exit Kodos + + + + A file was not selected for import + + + + Could not open file for reading: + + + + Open Kodos File + + + + loaded successfully + + + + Error reading from file: + + + + Save Kodos File + + + + No file selected to save + + + + The file + + + + already exists. + + + + Would you like to replace it? + + + + Replace file? + + + + &Replace + + + + &Cancel + + + + Could not open file for writing: + + + + successfully saved + + + + &No + + + + You have made changes + + + + Would you like to save them before continuing + + + + Save changes? + + + + &Yes, Save Changes + + + + There is no filename to revert + + + + Failed to open url + + + + No Update is Available + + + + You are currently using the latest version of Kodos + + + + There is a newer version of Kodos available. + + + + You are using version: + + + + The latest version is: + + + + Press OK to launch browser + + + + Kodos Update Available + + + + Unable to get version info from Sourceforge + + + + Unknown version available + + + + Launching web browser + + + + Cancelled web browser launch + + + + You have made changes. Would you like to save them before continuing + + + + + KodosBA + + Group # + + + + Group Name + + + + Match + + + + Kodos - The Python Regex Debugger + + + + Kodos + + + + Flags + + + + Ignore Case + + + + Perform case-insensitive matching; expressions like [A-Z] will match +lowercase letters, too. This is not affected by the current locale. + + + + Multi Line + + + + When specified, the pattern character "^" matches at the beginning of the +string and at the beginning of each line (immediately following each newline); +and the pattern character "$" matches at the end of the string and at the end +of each line (immediately preceding each newline). By default, "^" matches +only at the beginning of the string, and "$" only at the end of the string and +immediately before the newline (if any) at the end of the string. + + + + Dot All + + + + Make the "." special character match any character at all, including a +newline; without this flag, "." will match anything except a newline. + + + + Verbose + + + + This flag allows you to write regular expressions that look nicer. Whitespace +within the pattern is ignored, except when in a character class or preceded by +an unescaped backslash, and, when a line contains a "#" neither in a character +class or preceded by an unescaped backslash, all characters from the leftmost +such "#" through the end of the line are ignored. + + + + Locale + + + + Make \w, \W, \b, and \B dependent on the current locale. + + + + Unicode + + + + "Make \w, \W, \b, and \B dependent on the Unicode character properties +database. New in Python version 2.0. + + + + Regular Expression Pattern + + + + Group + + + + Match All + + + + Replace + + + + Sample Code + + + + Search String + + + + Replace String + + + + Match Number + + + + Replace Number + + + + New + + + + &New + + + + Ctrl+N + + + + Open + + + + &Open... + + + + Ctrl+O + + + + Save + + + + &Save + + + + Ctrl+S + + + + Save As + + + + Save &As... + + + + Exit + + + + E&xit + + + + Undo + + + + &Undo + + + + Ctrl+Z + + + + Redo + + + + &Redo + + + + Ctrl+Y + + + + Cut + + + + &Cut + + + + Ctrl+X + + + + Copy + + + + C&opy + + + + Ctrl+C + + + + Paste + + + + &Paste + + + + Ctrl+V + + + + Examine Regex for Match + + + + E&xamine Regex + + + + Contents + + + + &Contents... + + + + Index + + + + &Index... + + + + About + + + + &About + + + + Action + + + + Pause Processing + + + + Ctrl+P + + + + Preferences + + + + Help + + + + Ctrl+/ + + + + Python Regex Help + + + + &Python Regex Help + + + + Regex Reference Guide + + + + &Regex Reference Guide + + + + Ctrl+R + + + + Visit Kodos Website + + + + &Visit Kodos Website + + + + Check for Kodos Update + + + + &Check for Kodos Update + + + + Report a Bug + + + + Report a &Bug + + + + Import File + + + + Import &File + + + + Import URL + + + + Import &URL + + + + Regex Library + + + + Regex &Library + + + + Open the Regex Library + + + + Ctrl+L + + + + Revert Kodos File + + + + &Revert Kodos File + + + + Tools + + + + &File + + + + &Edit + + + + &Help + + + + + NewUserDialog + + Kodos new user information + + + + <h3>Welcome to Kodos.</h3> +<p></p> +It appears that this is your first time using +Kodos - The Python Regular Expression Debugger. +<p></p> +In order to help you familiarize yourself with Kodos, you may wish to explore +the Regex Library. Additionally, Kodos contains a Python Regex Reference Guide. +You can access these tools by clicking on the appropriate toolbar icon. + + + + <b>Regex Reference Guide</b> + + + + <b>Regex Library</b> + + + + &OK + + + + Alt+O + + + + + PrefsBA + + Preferences + + + + ... + + + + Recent Files: + + + + Web Browser: + + + + Email Server: + + + + Editor Font: + + + + &Help + + + + &Apply + + + + &OK + + + + &Cancel + + + + + ReferenceBA + + Symbol + + + + Definition + + + + Kodos - Regex Reference Guide + + + + . + + + + Matches any character + + + + * + + + + Matches 0 or more repetition of preceeding RE + + + + + + + + + Matches 1 or more repetition of preceeding RE + + + + ? + + + + Matches 0 or 1 repetition of preceeding RE + + + + ^ + + + + Matches start of string + + + + $ + + + + Matches the end of the string + + + + \A + + + + Matches only at the start of the string + + + + \B + + + + Matches the empty string, but only when it is not at the beginning or end of a word + + + + \b + + + + Matches the empty string, but only at the beginning or end of a word + + + + \d + + + + Matches any decimal digit + + + + \D + + + + Matches any non-digit character + + + + \z + + + + Matches only at the end of the string + + + + \W + + + + Matches any non-word + + + + \w + + + + Matches any word + + + + \S + + + + Matches any non-whitespace character + + + + \s + + + + Matches any whitespace character + + + + \\ + + + + Matches a literal backslash + + + + ?? + + + + Non-greedy ? + + + + *? + + + + Non-greedy * + + + + +? + + + + Non-greedy + + + + + () + + + + Capturing Parenthesis + + + + (?:) + + + + Non-capturing Parenthesis + + + + [] + + + + Character class + + + + {m,n} + + + + match from m to n repetitions of the preceding RE, attempting to match as many repetitions as possible. + + + + {m,n}? + + + + match from m to n repetitions of the preceding RE, attempting to match as few repetitions as possible. + + + + (?P<name>...) + + + + Similar to regular parentheses, but the substring matched by the group is accessible via the symbolic group name name. + + + + (?P=name) + + + + Matches whatever text was matched by the earlier group named name. + + + + \number + + + + Matches the contents of the group of the same number. Groups are numbered starting from 1. + + + + (?<=...) + + + + Matches if the current position in the string is preceded by a match for ... that ends at the current position. This is called a positive lookbehind assertion. + + + + (?<!...) + + + + Matches if the current position in the string is not preceded by a match for .... This is called a negative lookbehind assertion. + + + + (?=...) + + + + Matches if ... matches next, but doesn't consume any of the string. This is called a lookahead assertion. + + + + (?!...) + + + + Matches if ... doesn't match next. This is a negative lookahead assertion + + + + (?#...) + + + + A comment; the contents of the parentheses are simply ignored. + + + + New + + + + &New + + + + Ctrl+N + + + + Open + + + + &Open... + + + + Ctrl+O + + + + Save + + + + &Save + + + + Ctrl+S + + + + Save As + + + + Save &As... + + + + Print + + + + &Print... + + + + Ctrl+P + + + + Exit + + + + E&xit + + + + Undo + + + + &Undo + + + + Ctrl+Z + + + + Redo + + + + &Redo + + + + Ctrl+Y + + + + Cut + + + + &Cut + + + + Ctrl+X + + + + Copy + + + + C&opy + + + + Ctrl+C + + + + Paste + + + + &Paste + + + + Paste selection into Kodos + + + + Ctrl+V + + + + Find + + + + &Find... + + + + Ctrl+F + + + + Contents + + + + &Contents... + + + + Index + + + + &Index... + + + + About + + + + &About + + + + Help + + + + &Help + + + + Python Regex Help + + + + &Python Regex Help + + + + Tools + + + + &File + + + + &Edit + + + + + RegexLibraryBA + + Kodos - Regex Library + + + + Description + + + + Regex + + + + Contributed By: + + + + Notes + + + + Paste + + + + &Paste Example Into Kodos + + + + Paste This Example Into Kodos + + + + Ctrl+V + + + + Help + + + + &Help + + + + Ctrl+/ + + + + Exit + + + + &Exit + + + + Tools + + + + &File + + + + &Edit + + + + + URLDialogBA + + Import URL + + + + &Help + + + + F1 + + + + &OK + + + + &Cancel + + + + Enter URL to import + + + + http://kodos.sourceforge.net + + + + + reportBug + + An email address is necessary so that the author can contact you. Your email address will not be used for any other purposes. + + + + You must supply a valid email address + + + + Bug report sent + + + + Your bug report has been sent. + + + + An exception occurred sending bug report + + + + + reportBugBA + + Form1 + + + + Submit Bug Report + + + + Cancel + + + + Kodos State Information + + + + Regular Expression: + + + + Match String: + + + + System Information + + + + Operating System: + + + + PyQt Version: + + + + Python Version: + + + + Comments + + + + Comments: + + + + Email address: + + + + + reportBugWindow + + Report a Bug + + + + &Close + + + + &File + + + + diff --git a/translations/kodos_pl.ts b/translations/kodos_pl.ts new file mode 100644 index 0000000..43c31c2 --- /dev/null +++ b/translations/kodos_pl.ts @@ -0,0 +1,1359 @@ + + + AboutBA + + About Kodos + O programie Kodos + + + &OK + &OK + + + About... + O programie... + + + 0.8 + 0.8 + + + Kodos + +Developed by: Phil Schwartz + +phil_schwartz@users.sourceforge.net + Kodos + +Autor: Phil Schwartz + +phil_schwartz@users.sourceforge.net + + + Version: + Wersja: + + + + Kodos + + Enter a regular expression and a string to match against + Wpisz wyrażenie regularne i tekst do sprawdzenia + + + Kodos regex processing is paused. Click the pause icon to unpause + Przetwarzanie wyrażenia regularnego wstrzymane. Kliknij ponownie pauzę by wznowić. + + + Pattern does not match + Brak dopasowania + + + Pattern matches + Wzorzec pasuje + + + found + znaleziono + + + match + dopasowanie + + + matches + pasuje + + + &No, Just Exit Kodos + &Nie, zakończ program + + + A file was not selected for import + Nie wybrano pliku do importu + + + Could not open file for reading: + Pliku nie udało się otworzyć: + + + Open Kodos File + Otwórz plik Kodos + + + loaded successfully + załadowany + + + Error reading from file: + Błąd podczas odczytu pliku: + + + Save Kodos File + Zapisz plik Kodos + + + No file selected to save + Nie wybrano pliku do zapisu + + + The file + Plik + + + already exists. + już istnieje. + + + Would you like to replace it? + Zastąpić? + + + Replace file? + Czy zastąpić plik? + + + &Replace + Za&mień + + + &Cancel + &Anuluj + + + Could not open file for writing: + Nie można zapisać pliku: + + + successfully saved + zapisano + + + &No + &Nie + + + You have made changes + Zmieniono + + + Would you like to save them before continuing + Czy zapisać zmiany + + + Save changes? + Czy zapisać zmiany? + + + &Yes, Save Changes + Tak, zapi&sz + + + There is no filename to revert + Brak wcześniejszej nazwy pliku + + + Failed to open url + Nie udało się otworzyć URL + + + No Update is Available + Nie ma uaktualnień + + + You are currently using the latest version of Kodos + Używasz najnowszej wersji Kodos + + + There is a newer version of Kodos available. + Dostępna jest nowsza wersja Kodos. + + + You are using version: + Używasz wersji: + + + The latest version is: + Najnowsza wersja: + + + Press OK to launch browser + Naciśnij OK by uruchomić przeglądarkę + + + Kodos Update Available + Dostępne jest uaktualnienie Kodos + + + Unable to get version info from Sourceforge + Nie udało się pobrać wersji z SourceForge + + + Unknown version available + Dostępna wersja jest nieznana + + + Launching web browser + Uruchamianie przeglądarki + + + Cancelled web browser launch + Anulowano uruchomienie przeglądarki + + + You have made changes. Would you like to save them before continuing + Czy zachować wprowadzone zmiany + + + + KodosBA + + Group # + Grupa # + + + Group Name + Nazwa grupy + + + Match + Dopasowanie + + + Kodos - The Python Regex Debugger + Kodos - debugger wyrażeń regularnych dla Pythona + + + Kodos + Kodos + + + Flags + Flagi + + + Ignore Case + re.IGNORECASE + + + Perform case-insensitive matching; expressions like [A-Z] will match +lowercase letters, too. This is not affected by the current locale. + Wyszukiwanie bez rozróżniania wielkości liter; wyrażenia jak [A-Z] będą pasować +również do małych liter.Ustawienia regionalne nie mają wpływu na tę flagę. + + + Multi Line + re.MULTILINE + + + When specified, the pattern character "^" matches at the beginning of the +string and at the beginning of each line (immediately following each newline); +and the pattern character "$" matches at the end of the string and at the end +of each line (immediately preceding each newline). By default, "^" matches +only at the beginning of the string, and "$" only at the end of the string and +immediately before the newline (if any) at the end of the string. + Z tym ustawieniam, znak "^" dopasowuje początek tekstu i początek każdej +linii (po znaku nowego wiersza); z kolei znak "$" dopasowuje koniec tekstu i koniec +każdej linii (przed znakiem nowego wiersza). Domyślnie "^" dopasowuje tylko +początek tekstu, a "$" tylko koniec tekstu lub koniec wiersza, gdy tekst kończy się +znakiem nowego wiersza. + + + Dot All + re.DOTALL + + + Make the "." special character match any character at all, including a +newline; without this flag, "." will match anything except a newline. + Powoduje, że znak "." dopasowuje dowolny znak, włączając w to znak +nowego wiersza. Domyślnie znak "." nie dopasowuje znaku nowego wiersza. + + + Verbose + re.VERBOSE + + + This flag allows you to write regular expressions that look nicer. Whitespace +within the pattern is ignored, except when in a character class or preceded by +an unescaped backslash, and, when a line contains a "#" neither in a character +class or preceded by an unescaped backslash, all characters from the leftmost +such "#" through the end of the line are ignored. + Z tym ustawieniem wyrażenia regularne są bardziej czytelne. Białe znaki we wzorcu +są ignorowane wszędzie, poza klasami znaków i poza miejscami zabezpieczonymi +odwrócomym ukośnikiem. Gdy we wzorcu wystąpi znak "#" poza deklaracją klasy znaków +lub niezabezpieczony, wtedy wszystkie występujące po nim znaki są ignorowane. + + + Locale + re.LOCALE + + + Make \w, \W, \b, and \B dependent on the current locale. + Wzorce \w, \W, \b i \B zachowują się zgodnie z bieżącymi ustawieniami międzynarodowymi. + + + Unicode + re.UNICODE + + + "Make \w, \W, \b, and \B dependent on the Unicode character properties +database. New in Python version 2.0. + Wzorce \w, \W, \b i \B zachowują się zgodnie z właśiwościami znaków Unicode. +Nowość w Pythonie 2.0. + + + Regular Expression Pattern + Wyrażenie regularne + + + Group + Grupa + + + Match All + Wszystkie dopasowania + + + Replace + Zamiana + + + Sample Code + Przykładowy kod + + + Search String + Przeszukiwany tekst + + + Replace String + Zamieniany tekst + + + Match Number + Numer dopasowania + + + Replace Number + Numer zamiany + + + New + Nowy + + + &New + &Nowy + + + Ctrl+N + Ctrl+N + + + Open + Otwórz + + + &Open... + &Otwórz... + + + Ctrl+O + Ctrl+O + + + Save + Zapisz + + + &Save + Zapi&sz + + + Ctrl+S + Ctrl+S + + + Save As + Zapisza jako + + + Save &As... + Zapisz j&ako... + + + Exit + Koniec + + + E&xit + &Koniec + + + Undo + Cofnij + + + &Undo + &Cofnij + + + Ctrl+Z + Ctrl+Z + + + Redo + Ponów + + + &Redo + &Ponów + + + Ctrl+Y + Ctrl+Y + + + Cut + Wytnij + + + &Cut + W&ytnij + + + Ctrl+X + Ctrl+X + + + Copy + Kopiuj + + + C&opy + K&opiuj + + + Ctrl+C + Ctrl+C + + + Paste + Wklej + + + &Paste + &Wklej + + + Ctrl+V + Ctrl+V + + + Examine Regex for Match + Sprawdź wyrażenie regularne + + + E&xamine Regex + Sp&rawdź wyrażenie regularne + + + Contents + Zawartość + + + &Contents... + &Zawartość... + + + Index + Indeks + + + &Index... + &Indeks... + + + About + O programie + + + &About + &O programie + + + Action + Akcja + + + Pause Processing + Wstrzymaj + + + Ctrl+P + Ctrl+P + + + Preferences + Ustawienia + + + Help + Pomoc + + + Ctrl+/ + Ctrl+/ + + + Python Regex Help + Pomoc dla RE w Pythonie + + + &Python Regex Help + &Pomoc dla RE w Pythonie + + + Regex Reference Guide + Przewodnik po wyrażeniach regularnych + + + &Regex Reference Guide + P&rzewodnik po wyrażeniach regularnych + + + Ctrl+R + Ctrl+R + + + Visit Kodos Website + Odwiedź stronę domową Kodos + + + &Visit Kodos Website + Od&wiedź stronę Kodos + + + Check for Kodos Update + Sprawdź uaktualnienie Kodos + + + &Check for Kodos Update + &Sprawdź uaktualnienie Kodos + + + Report a Bug + Zgłoś błąd + + + Report a &Bug + Zgłoś &błąd + + + Import File + Importuj plik + + + Import &File + Importuj &plik + + + Import URL + Importuj URL + + + Import &URL + Importuj &URL + + + Regex Library + Biblioteka wyrażeń regularnych + + + Regex &Library + Bib&lioteka wyrażeń regularnych + + + Open the Regex Library + Otwórz bibliotekę wyrażeń regularnych + + + Ctrl+L + Ctrl+L + + + Revert Kodos File + Przywróć plik + + + &Revert Kodos File + P&rzywróć plik + + + Tools + Narzędzia + + + &File + &Plik + + + &Edit + &Edycja + + + &Help + P&omoc + + + + NewUserDialog + + Kodos new user information + Informacje o nowym uzytkowniku Kodos + + + <h3>Welcome to Kodos.</h3> +<p></p> +It appears that this is your first time using +Kodos - The Python Regular Expression Debugger. +<p></p> +In order to help you familiarize yourself with Kodos, you may wish to explore +the Regex Library. Additionally, Kodos contains a Python Regex Reference Guide. +You can access these tools by clicking on the appropriate toolbar icon. + <h3>Witaj w programie Kodos.</h3> +<p><p> +Wygląda na to, że po raz pierwszy uruchamiasz Kodos - +debugger wyrażeń regularnych Pythona. +<p></p> +Aby zapoznać się z programem Kodos, powinieneś przejrzeć bibliotekę wyrażeń +regularnych. Dodatkowo Kodos posiada przewodnik po wyrażeniach regularnych. +Aby uzyskać dostęp do tych narzędzi, kliknij odpowiednią ikonę na pasku narzędzi. + + + <b>Regex Reference Guide</b> + <b>Przewodnik po wyrażeniach regularnych</p> + + + <b>Regex Library</b> + <b>Biblioteka wyrażeń regularnych</b> + + + &OK + &OK + + + Alt+O + Alt+O + + + + PrefsBA + + Preferences + Ustawienia + + + ... + ... + + + Recent Files: + Ostatnio otwarte pliki: + + + Web Browser: + Przeglądarka WWW: + + + Email Server: + Serwer poczty: + + + Editor Font: + Czcionka edytora: + + + &Help + &Pomoc + + + &Apply + Za&twierdź + + + &OK + &OK + + + &Cancel + &Anuluj + + + + ReferenceBA + + Symbol + Symbol + + + Definition + Definicja + + + Kodos - Regex Reference Guide + Przewodnik po wyrażeniach regularnych + + + . + . + + + Matches any character + Dopasowuje dowolny znak + + + * + * + + + Matches 0 or more repetition of preceeding RE + Dopasowuje 0 lub więceń wystąpień poprzedzającego RE + + + + + + + + + Matches 1 or more repetition of preceeding RE + Dopasowuje 1 lub więceń wystąpień poprzedzającego RE + + + ? + ? + + + Matches 0 or 1 repetition of preceeding RE + Dopasowuje 0 lub 1 wystąpienie poprzedzającego RE + + + ^ + ^ + + + Matches start of string + Dopasowuje początek tekstu + + + $ + $ + + + Matches the end of the string + Dopasowuje koniec tekstu + + + \A + \A + + + Matches only at the start of the string + Dopasowuje wyłącznie na początku tekstu + + + \B + \B + + + Matches the empty string, but only when it is not at the beginning or end of a word + Dopasowuje pusty ciąg, ale tylko wtedy, gdy nie jest na początku lub na końcu słowa + + + \b + \b + + + Matches the empty string, but only at the beginning or end of a word + Dopasowuje pusty ciąg, ale tylko wtedy, gdy jest na początku lub na końcu słowa + + + \d + \d + + + Matches any decimal digit + Dopasowuje dowolną liczbę dziesiętną + + + \D + \D + + + Matches any non-digit character + Dopasowuje dowolny znak, nie będący liczbą + + + \z + \z + + + Matches only at the end of the string + Dopasowuje wyłącznie na końcu tekstu + + + \W + \W + + + Matches any non-word + Dopasowuje dowolny ciąg, nie będący słowem + + + \w + \w + + + Matches any word + Dopasowuje dowolne słowo + + + \S + \S + + + Matches any non-whitespace character + Dopasowuje dowolny znak poza białymi znakami + + + \s + \s + + + Matches any whitespace character + Dopasowuje dowolny biały znak + + + \\ + \\ + + + Matches a literal backslash + Dopasowuje odwrócony ukośnik + + + ?? + ?? + + + Non-greedy ? + + + + *? + + + + Non-greedy * + + + + +? + + + + Non-greedy + + + + + () + + + + Capturing Parenthesis + + + + (?:) + + + + Non-capturing Parenthesis + + + + [] + [] + + + Character class + Klasa znaków + + + {m,n} + {m,n} + + + match from m to n repetitions of the preceding RE, attempting to match as many repetitions as possible. + + + + {m,n}? + + + + match from m to n repetitions of the preceding RE, attempting to match as few repetitions as possible. + + + + (?P<name>...) + + + + Similar to regular parentheses, but the substring matched by the group is accessible via the symbolic group name name. + + + + (?P=name) + + + + Matches whatever text was matched by the earlier group named name. + + + + \number + \liczba + + + Matches the contents of the group of the same number. Groups are numbered starting from 1. + Dopasowuje zawartość grupy o wskazanym numerze. Grupy są numerowane od 1. + + + (?<=...) + + + + Matches if the current position in the string is preceded by a match for ... that ends at the current position. This is called a positive lookbehind assertion. + + + + (?<!...) + + + + Matches if the current position in the string is not preceded by a match for .... This is called a negative lookbehind assertion. + + + + (?=...) + + + + Matches if ... matches next, but doesn't consume any of the string. This is called a lookahead assertion. + + + + (?!...) + + + + Matches if ... doesn't match next. This is a negative lookahead assertion + + + + (?#...) + (?#...) + + + A comment; the contents of the parentheses are simply ignored. + Komentarz, zawartość w nawiasach jest ignorowana. + + + New + Nowy + + + &New + &Nowy + + + Ctrl+N + Ctrl+N + + + Open + Otwórz + + + &Open... + &Otwórz... + + + Ctrl+O + Ctrl+O + + + Save + Zapisz + + + &Save + Zapi&sz + + + Ctrl+S + Ctrl+S + + + Save As + Zapisz jako + + + Save &As... + Zapisz j&ako... + + + Print + Drukuj + + + &Print... + &Drukuj... + + + Ctrl+P + Ctrl+P + + + Exit + Koniec + + + E&xit + &Koniec + + + Undo + Cofnij + + + &Undo + &Cofnij + + + Ctrl+Z + Ztrl+Z + + + Redo + Ponów + + + &Redo + &Ponów + + + Ctrl+Y + Ctrl+Y + + + Cut + Wytnij + + + &Cut + &Wytnij + + + Ctrl+X + Ctrl+X + + + Copy + Kopiuj + + + C&opy + K&opiuj + + + Ctrl+C + Ctrl+C + + + Paste + Wklej + + + &Paste + W&klej + + + Paste selection into Kodos + Wklej wybór do Kodos + + + Ctrl+V + Ctrl+V + + + Find + Znajdź + + + &Find... + &Znajdź... + + + Ctrl+F + Ctrl+F + + + Contents + Zawartość + + + &Contents... + &Zawartość... + + + Index + Indeks + + + &Index... + &Indeks... + + + About + O programie + + + &About + &O programie + + + Help + Pomoc + + + &Help + P&omoc + + + Python Regex Help + Pomoc do wyrażeń regularnych w Pythonie + + + &Python Regex Help + &Pomoc do RE Pythona + + + Tools + Narzędzia + + + &File + &Plik + + + &Edit + &Edycja + + + + RegexLibraryBA + + Kodos - Regex Library + Kodos - Biblioteka wyrażeń regularnych + + + Description + Opis + + + Regex + Wyrażenie regularne + + + Contributed By: + Autor: + + + Notes + Uwagi + + + Paste + Wklej + + + &Paste Example Into Kodos + &Wklej przykład do Kodos + + + Paste This Example Into Kodos + Wklej ten przykład do Kodos + + + Ctrl+V + Ctrl+V + + + Help + Pomoc + + + &Help + &Pomoc + + + Ctrl+/ + Ctrl+/ + + + Exit + Zamknij + + + &Exit + Z&amknij + + + Tools + Narzędzia + + + &File + &Plik + + + &Edit + &Edycja + + + + URLDialogBA + + Import URL + Importuj URL + + + &Help + &Pomoc + + + F1 + F1 + + + &OK + &OK + + + &Cancel + &Anuluj + + + Enter URL to import + Wpisz URL do zaimportowania + + + http://kodos.sourceforge.net + http://kodos.sourceforge.net + + + + reportBug + + An email address is necessary so that the author can contact you. Your email address will not be used for any other purposes. + Adres poczty elektroniczne jest konieczny, by autor programu mógł się z Tobą skontaktować. Podany adres nie zostanie użyty w żadnym innym celu. + + + You must supply a valid email address + Musisz podać działający adres poczty elektronicznej + + + Bug report sent + Zgłoszenie błedu zostało wysłane + + + Your bug report has been sent. + Twoje zgłoszenie błędu zostało wysłane. + + + An exception occurred sending bug report + Podczas wysyłania wystąpił błąd + + + + reportBugBA + + Form1 + Form1 + + + Submit Bug Report + Wyślij zgłoszenie błędu + + + Cancel + Anuluj + + + Kodos State Information + Informacja o stanie Kodos + + + Regular Expression: + Wyrażenie regularne: + + + Match String: + Przeszukiwany tekst: + + + System Information + Informacja o systemie + + + Operating System: + System operacyjny: + + + PyQt Version: + Wersja PyQt: + + + Python Version: + Wersja Pythona: + + + Comments + Uwagi + + + Comments: + Uwagi: + + + Email address: + Adres email: + + + + reportBugWindow + + Report a Bug + Zgłoś błąd + + + &Close + &Zamknij + + + &File + &Plik + + + From 5801e306d2b4189ede68606d02ff025146188f0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= Date: Fri, 25 Dec 2020 02:19:55 +0000 Subject: [PATCH 29/37] bdist_rpm has been removed from Distutils !? --- setup.cfg | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 setup.cfg diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 7447b44..0000000 --- a/setup.cfg +++ /dev/null @@ -1,10 +0,0 @@ -[bdist_rpm] -build_requires=PyQt-3.8 -vendor = Kodos - Sourceforge -packager = Phil Schwartz -distribution-name = Red Hat Linux -requires = python >= 2.0 -requires = PyQt >= 3.0 -build-requires = python-devel -doc_files = README.txt LICENSE.txt - From cf30768bcc2f76fef52071306549aafbbeed55a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= Date: Fri, 25 Dec 2020 02:15:04 +0000 Subject: [PATCH 30/37] Remove removed ui files resultsBA.ui and reportBugBA Bugfix kodos.pro, completes commmit 937a5e6 --- kodos.pro | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/kodos.pro b/kodos.pro index 287437c..2607647 100644 --- a/kodos.pro +++ b/kodos.pro @@ -16,16 +16,13 @@ SOURCES = kodos kodos/version.py TRANSLATIONS = translations/kodos_en.ts \ - translations/kodos_pl.ts \ - translations/kodos_sv.ts + translations/kodos_pl.ts FORMS = kodos/aboutBA.ui \ kodos/helpBA.ui \ kodos/kodosBA.ui \ - kodos/newUserDialogBA.ui + kodos/newUserDialogBA.ui \ kodos/prefsBA.ui \ kodos/referenceBA.ui \ kodos/regexLibraryBA.ui \ - kodos/reportBugBA.ui \ - kodos/resultsBA.ui \ kodos/urlDialogBA.ui From c297cdae0349db33d96e26d98a081ef40c1f948b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= Date: Fri, 25 Dec 2020 02:56:33 +0000 Subject: [PATCH 31/37] Fix NameError: global name 'URLDialogBA' is not defined File "/usr/lib/python2.7/site-packages/kodos/urlDialog.py", line 39, in ok_slot URLDialogBA.accept(self) --- kodos/urlDialog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kodos/urlDialog.py b/kodos/urlDialog.py index 7ea64db..32946b2 100644 --- a/kodos/urlDialog.py +++ b/kodos/urlDialog.py @@ -36,4 +36,4 @@ def ok_slot(self): self.urlImported.emit(html, url) - URLDialogBA.accept(self) + urlDialogBA.URLDialogBA.accept(self) From e83b231f66384fbf3574aac2ab6186651d09832d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= Date: Fri, 25 Dec 2020 04:38:48 +0000 Subject: [PATCH 32/37] update PKG-INFO and .gitignore --- .gitignore | 6 ++++-- PKG-INFO | 8 +++----- kodos/version.py | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 0f414d8..7f4809e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,13 @@ *.pyc *.pyo *~ +*.rej +*.orig /.pc/ /build/ /debian/ /dist/ /MANIFEST -/modules/*BA.py -/modules/kodos_rc.py +*BA.py +kodos_rc.py /translations/*.qm diff --git a/PKG-INFO b/PKG-INFO index c235842..43a6b28 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,12 +1,10 @@ Metadata-Version: 1.0 Name: kodos -Version: 2.4.9 +Version: 2.5.1 Summary: Kodos is a visual regular expression editor -Home-page: http://kodos.sourceforge.net +Home-page: https://github.com/sergiomb2/kodos Author: Phil Schwartz Author-email: phil_schwartz@users.sourceforge.net License: GPL -Description: - Kodos is a visual regular expression editor and debugger. - +Description: Kodos is a visual regular expression editor and debugger. Platform: UNKNOWN diff --git a/kodos/version.py b/kodos/version.py index c2b2315..f8ac5a9 100644 --- a/kodos/version.py +++ b/kodos/version.py @@ -1 +1 @@ -VERSION="2.4.9" +VERSION="2.5.1" From 0d5f75692b5b8f7413171861692cc16360d07534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= Date: Sat, 26 Dec 2020 07:12:38 +0000 Subject: [PATCH 33/37] Migrate to Python3 --- kodos/main.py | 67 ++++++++++++++++++++---------------------- kodos/parseRegexLib.py | 4 +-- kodos/prefs.py | 2 +- kodos/recent_files.py | 4 +-- kodos/status_bar.py | 2 +- kodos/urlDialog.py | 13 ++++---- kodos/util.py | 4 +-- 7 files changed, 46 insertions(+), 50 deletions(-) diff --git a/kodos/main.py b/kodos/main.py index 180699c..d1756ba 100644 --- a/kodos/main.py +++ b/kodos/main.py @@ -4,7 +4,7 @@ import re import types import signal -import cPickle +import pickle import logging from PyQt4 import Qt, QtCore @@ -131,7 +131,7 @@ def __init__(self, qApp, filename): def checkIfNewUser(self): s = Qt.QSettings() - if s.value('New User', "true").toPyObject() != "false": + if s.value('New User', "true") != "false": self.newuserdialog = newUserDialogBA.NewUserDialog() self.newuserdialog.show() s.setValue('New User', "false") @@ -149,9 +149,9 @@ def updateStatus(self, status_string, status_value, duration=0, replace=False, t def fileMenuHandler(self, menuid): if self.recent_files.isRecentFile(menuid): - fn = str(menuid.text()) - if self.openFile(fn): - self.recent_files.add(fn) + filename = menuid.text() + if self.openFile(filename): + self.recent_files.add(filename) def prefsSaved(self): self.log.debug("prefsSaved slot") @@ -268,12 +268,12 @@ def replace_num_slot(self, num): def regex_changed_slot(self): - self.regex = unicode(self.regexMultiLineEdit.toPlainText()) + self.regex = self.regexMultiLineEdit.toPlainText() self.process_regex() def string_changed_slot(self): - self.matchstring = unicode(self.stringMultiLineEdit.toPlainText()) + self.matchstring = self.stringMultiLineEdit.toPlainText() self.process_regex() def helpContents(self, x = None): @@ -296,7 +296,7 @@ def show_replace_widgets(self): self.replaceTextBrowser.setEnabled(True) def replace_changed_slot(self): - self.replace = unicode(self.replaceTextEdit.toPlainText()) + self.replace = self.replaceTextEdit.toPlainText() self.process_regex() if not self.replace: self.hide_replace_widgets() @@ -420,7 +420,7 @@ def populate_replace_textbrowser(self, spans, nummatches, compile_obj): if num == 0: num = nummatches text = self.matchstring - replace_text = unicode(self.replaceTextEdit.toPlainText()) + replace_text = self.replaceTextEdit.toPlainText() if RX_BACKREF.search(replace_text): # if the replace string contains a backref we just use the # python regex methods for the substitution @@ -521,8 +521,8 @@ def timeout(signum, frame): match_obj = compile_obj.search(self.matchstring) - except Exception, e: - self.update_results(unicode(e), MATCH_FAIL) + except Exception as e: + self.update_results(str(e), MATCH_FAIL) return if HAS_ALARM: @@ -551,7 +551,7 @@ def timeout(signum, frame): if match_obj.groups(): group_nums = {} if compile_obj.groupindex: - keys = compile_obj.groupindex.keys() + keys = list(compile_obj.groupindex.keys()) for key in keys: group_nums[compile_obj.groupindex[key]] = key @@ -562,7 +562,7 @@ def timeout(signum, frame): # create group_tuple in the form: (group #, group name, group matches) g = allmatches[match_index] - if type(g) == types.TupleType: + if type(g) == tuple: for i in range(len(g)): group_tuple = (i+1, group_nums.get(i+1, ""), g[i]) self.group_tuples.append(group_tuple) @@ -574,10 +574,10 @@ def timeout(signum, frame): # clear the group table self.populate_group_table([]) - str_pattern_matches = unicode(self.tr("Pattern matches")) - str_found = unicode(self.tr("found")) - str_match = unicode(self.tr("match")) - str_matches = unicode(self.tr("matches")) + str_pattern_matches = self.tr("Pattern matches") + str_found = self.tr("found") + str_match = self.tr("match") + str_matches = self.tr("matches") if len(allmatches) == 1: status = "%s (%s 1 %s)" % (str_pattern_matches, @@ -661,20 +661,18 @@ def urlImported(self, html, url): def importFile(self): - fn = Qt.QFileDialog.getOpenFileName(self, + filename = Qt.QFileDialog.getOpenFileName(self, self.tr("Import File"), self.filename, self.tr("All (*)")) - if fn.isEmpty(): + if filename == "" : self.updateStatus(self.tr("A file was not selected for import"), -1, 5, True) return None - filename = str(fn) - try: fp = open(filename, "r") except: @@ -691,12 +689,11 @@ def fileOpen(self): filename = self.filename if filename == None: filename = "" - fn = Qt.QFileDialog.getOpenFileName(self, + filename = Qt.QFileDialog.getOpenFileName(self, self.tr("Open Kodos File"), filename, self.tr("Kodos file (*.kds);;All (*)")) - if not fn.isEmpty(): - filename = str(fn) + if filename != "": if self.openFile(filename): self.recent_files.add(filename) @@ -708,20 +705,20 @@ def openFile(self, filename): self.filename = None try: - fp = open(filename, "r") + fp = open(filename, "rb") except: msg = self.tr("Could not open file for reading: ") + filename self.updateStatus(msg, -1, 5, True) return None try: - u = cPickle.Unpickler(fp) + u = pickle.Unpickler(fp) self.regex = u.load() self.matchstring = u.load() flags = u.load() - except Exception, e: #FIXME: don't catch everything + except Exception as e: #FIXME: don't catch everything self.log.error('Error unpickling data from file: %s' % e) - msg = "%s %s" % (unicode(self.tr("Error reading from file:")), + msg = "%s %s" % (str(self.tr("Error reading from file:")), filename) self.updateStatus(msg, -1, 5, True) return 0 @@ -742,7 +739,7 @@ def openFile(self, filename): self.replaceTextEdit.setPlainText(replace) self.filename = filename - msg = "%s %s" % (filename, unicode(self.tr("loaded successfully"))) + msg = "%s %s" % (filename, str(self.tr("loaded successfully"))) self.updateStatus(msg, -1, 5, True) self.editstate = STATE_UNEDITED return 1 @@ -764,7 +761,7 @@ def fileSaveAs(self): self.updateStatus(self.tr("No file selected to save"), -1, 5, True) return - filename = os.path.normcase(unicode(filedialog.selectedFiles().first())) + filename = os.path.normcase(str(filedialog.selectedFiles()[0])) self.filename = filename self.fileSave() @@ -776,23 +773,23 @@ def fileSave(self): return try: - fp = open(self.filename, "w") + fp = open(self.filename, "wb") except: - msg = "%s: %s" % (unicode(self.tr("Could not open file for writing:")), + msg = "%s: %s" % (str(self.tr("Could not open file for writing:")), self.filename) self.updateStatus(msg, -1, 5, True) return None self.editstate = STATE_UNEDITED - p = cPickle.Pickler(fp) + p = pickle.Pickler(fp) p.dump(self.regex) p.dump(self.matchstring) p.dump(self.reFlags.allFlagsORed()) p.dump(self.replace) fp.close() - msg = "%s %s" % (unicode(self.filename), - unicode(self.tr("successfully saved"))) + msg = "%s %s" % (str(self.filename), + str(self.tr("successfully saved"))) self.updateStatus(msg, -1, 5, True) self.recent_files.add(self.filename) diff --git a/kodos/parseRegexLib.py b/kodos/parseRegexLib.py index da81b9d..83af6ab 100644 --- a/kodos/parseRegexLib.py +++ b/kodos/parseRegexLib.py @@ -36,7 +36,7 @@ def parse(self, data=""): dicts = [] allmatches = rx_entry.findall(data) - rx_keys = RX_DICT.keys() + rx_keys = list(RX_DICT.keys()) for match in allmatches: d = {} for key in rx_keys: @@ -56,6 +56,6 @@ def parse(self, data=""): x = ParseRegexLib(path) dicts = x.parse() - print dicts + print(dicts) diff --git a/kodos/prefs.py b/kodos/prefs.py index e8e874d..60a481c 100644 --- a/kodos/prefs.py +++ b/kodos/prefs.py @@ -32,7 +32,7 @@ def load(self): self.parent.setMatchFont(setting.toPyObject()) if preference == 'Recent Files Count': self.recentFilesSpinBox.setValue(int(setting.toPyObject())) - except Exception, e: + except Exception as e: self.log.error('Loading of configuration key %s failed: %s' % (preference, e)) self.settings.remove(preference) diff --git a/kodos/recent_files.py b/kodos/recent_files.py index cd6d55f..42a136d 100644 --- a/kodos/recent_files.py +++ b/kodos/recent_files.py @@ -25,11 +25,11 @@ def load(self): i += 1 settings.setArrayIndex(i) try: - s = settings.value("Filename").toPyObject() + s = settings.value("Filename") if s == None: break self.__recent_files.append(str(s)) - except Exception, e: + except Exception as e: self.log.error('Loading of recent file entry %i failed: %s' % (i, e)) settings.remove("Filename") diff --git a/kodos/status_bar.py b/kodos/status_bar.py index b895b74..d1abeaa 100644 --- a/kodos/status_bar.py +++ b/kodos/status_bar.py @@ -45,7 +45,7 @@ def set_message(self, message='', duration=0, replace=False, tooltip='', pixmap= """ self.__statusTimer.stop() - self.last_status_message = unicode(self.__statusLabel.text()) + self.last_status_message = str(self.__statusLabel.text()) self.replace_status_message = replace self.__statusLabel.setText(message) diff --git a/kodos/urlDialog.py b/kodos/urlDialog.py index 32946b2..1a2969d 100644 --- a/kodos/urlDialog.py +++ b/kodos/urlDialog.py @@ -4,7 +4,7 @@ from PyQt4.QtGui import QMessageBox from . import urlDialogBA from . import help -import urllib +import urllib.request class URLDialog(urlDialogBA.URLDialogBA): @@ -22,18 +22,17 @@ def help_slot(self): self.helpWindow = help.Help(self, "importURL.html") def ok_slot(self): - url = str(self.URLTextEdit.toPlainText()) + url = self.URLTextEdit.toPlainText() try: - fp = urllib.urlopen(url) - lines = fp.readlines() - except Exception, e: + fp = urllib.request.urlopen(url) + charset = fp.info().get_content_charset() or "utf-8" + html = fp.read().decode(charset) + except Exception as e: QMessageBox.information(None, "Failed to open URL", "Could not open the specified URL. Please check to ensure that you have entered the correct URL.\n\n%s" % str(e)) return - html = ''.join(lines) - self.urlImported.emit(html, url) urlDialogBA.URLDialogBA.accept(self) diff --git a/kodos/util.py b/kodos/util.py index da53882..957d3bd 100644 --- a/kodos/util.py +++ b/kodos/util.py @@ -46,7 +46,7 @@ def saveWindowSettings(window, filename): def restoreWindowSettings(window, filename): settings = Qt.QSettings() - window.restoreGeometry(settings.value(window.objectName()).toByteArray()) + #window.restoreGeometry(settings.value(window.objectName()).toByteArray()) def findFile(filename): dirs = [getAppPath(), @@ -68,7 +68,7 @@ def launch_browser(url, caption=None, message=None): return False try: webbrowser.open(url) - except webbrowser.Error, e: + except webbrowser.Error as e: log.error("Couldn't open URL %r: %s" % (url, e)) return False return True From 988596b9c76413a30f26564faef9df989b646c88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= Date: Sat, 26 Dec 2020 07:11:26 +0000 Subject: [PATCH 34/37] Update PKG-INFO, CHANGELOG.txt and version.py --- CHANGELOG.txt | 8 ++++++++ PKG-INFO | 2 +- kodos/version.py | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index faf4839..e5ecb14 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,13 @@ Kodos ChangeLog +2.5.2 +===== + *) First Python3 version , still using PyQt4, python3-PyQt4 is now required + +2.5.1 +===== + *) Migrated to PyQt4 completed using teythoon repo + 2.4.9 ===== *) Fixed help window (corrects problem related to tooltip api changes) diff --git a/PKG-INFO b/PKG-INFO index 43a6b28..f6a2b42 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: kodos -Version: 2.5.1 +Version: 2.5.2 Summary: Kodos is a visual regular expression editor Home-page: https://github.com/sergiomb2/kodos Author: Phil Schwartz diff --git a/kodos/version.py b/kodos/version.py index f8ac5a9..da47dcb 100644 --- a/kodos/version.py +++ b/kodos/version.py @@ -1 +1 @@ -VERSION="2.5.1" +VERSION="2.5.2" From 3ab9f526a9e4091975a1deb24f3f49ad16a4ab01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= Date: Sat, 26 Dec 2020 07:58:53 +0000 Subject: [PATCH 35/37] Add kodos.spec to packaging directory and minor fixes --- kodos.desktop | 2 +- packaging/CMakeLists.txt | 2 +- packaging/kodos.desktop | 9 --- packaging/kodos.spec | 119 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 11 deletions(-) delete mode 100644 packaging/kodos.desktop create mode 100644 packaging/kodos.spec diff --git a/kodos.desktop b/kodos.desktop index 0a067fb..a135f39 100644 --- a/kodos.desktop +++ b/kodos.desktop @@ -1,7 +1,7 @@ [Desktop Entry] Encoding=UTF-8 Name=Kodos -GenericName=Visual RegEx Editor +GenericName=The Python Regular Expression Debugger Comment=Kodos is a Visual regular expression editor Exec=kodos Icon=kodos_icon.png diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt index b2a870d..87c540c 100644 --- a/packaging/CMakeLists.txt +++ b/packaging/CMakeLists.txt @@ -23,7 +23,7 @@ endif() set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Johannes Maier ") install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../dist/kodos DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/kodos.desktop DESTINATION /usr/share/applications) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../kodos.desktop DESTINATION /usr/share/applications) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../images/kodos_icon.png DESTINATION /usr/share/pixmaps) diff --git a/packaging/kodos.desktop b/packaging/kodos.desktop deleted file mode 100644 index e2ea4be..0000000 --- a/packaging/kodos.desktop +++ /dev/null @@ -1,9 +0,0 @@ -[Desktop Entry] -Name=kodos -Comment[en]=The regex debugger -Exec=kodos -Icon=/usr/share/pixmaps/kodos_icon.png -Terminal=false -Type=Application -Categories=Application;Science;Engineering;Math; -StartupNotify=false \ No newline at end of file diff --git a/packaging/kodos.spec b/packaging/kodos.spec new file mode 100644 index 0000000..70e0b02 --- /dev/null +++ b/packaging/kodos.spec @@ -0,0 +1,119 @@ +Name: kodos +Version: 2.5.2 +Release: 1%{?dist} +Summary: Visual regular expression editor + +Group: Development/Tools +# No version specified. +License: GPL+ +URL: http://kodos.sourceforge.net/ +Source0: https://github.com/sergiomb2/kodos/archive/v%{version}/%{name}-%{version}.tar.gz + +BuildArch: noarch +BuildRequires: python3-devel +BuildRequires: desktop-file-utils +BuildRequires: python3-PyQt4-devel + +Requires: python3-PyQt4 + + +%description +Kodos is a visual regular expression editor and debugger written in Python. + + +%prep +%setup -q + + +%build +%py3_build + + +%install +%py3_install + +rm -f %{buildroot}%{python3_sitelib}/kodos/py2exe* +mkdir -p -m 0755 %{buildroot}%{_datadir}/pixmaps +install -m 0644 images/kodos_icon.png %{buildroot}%{_datadir}/pixmaps/ +desktop-file-install --dir %{buildroot}%{_datadir}/applications \ + kodos.desktop + + +%files +%doc CHANGELOG.txt +%license LICENSE.txt +%{_bindir}/* +%{_datadir}/kodos +%{python3_sitelib}/* +%{_datadir}/applications/* +%{_datadir}/pixmaps/* + + +%changelog +* Fri Dec 25 2020 Sérgio Basto - 2.5.2-1 +- Update to 2.5.2 (pyhton3 version) + +* Fri Dec 25 2020 Sérgio Basto - 2.5.1-1 +- Update to 2.5.1 (teythoon branch) + +* Sun Jun 24 2018 Sérgio Basto - 2.5.0-1 +- Unofficial Kodos 2.5.0 but with pyqt4 + +* Tue Jul 19 2016 Fedora Release Engineering - 2.4.9-19 +- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages + +* Thu Feb 04 2016 Fedora Release Engineering - 2.4.9-18 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jun 17 2015 Fedora Release Engineering - 2.4.9-17 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Sun Jun 08 2014 Fedora Release Engineering - 2.4.9-16 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Sat Aug 03 2013 Fedora Release Engineering - 2.4.9-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Wed Mar 6 2013 Toshio Kuratomi - 2.4.9-14 +- Remove vendor prefix from desktop files in F19+ https://fedorahosted.org/fesco/ticket/1077 + +* Thu Feb 14 2013 Fedora Release Engineering - 2.4.9-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Thu Jul 19 2012 Fedora Release Engineering - 2.4.9-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Fri Jan 13 2012 Fedora Release Engineering - 2.4.9-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Mon Feb 07 2011 Fedora Release Engineering - 2.4.9-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Wed Jul 21 2010 David Malcolm - 2.4.9-9 +- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild + +* Fri Jul 24 2009 Fedora Release Engineering - 2.4.9-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Wed Feb 25 2009 Fedora Release Engineering - 2.4.9-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Sat Nov 29 2008 Ignacio Vazquez-Abrams - 2.4.9-6 +- Rebuild for Python 2.6 + +* Tue Aug 5 2008 Tom "spot" Callaway - 2.4.9-5 +- fix license tag + +* Sat Jun 16 2007 Konstantin Ryabitsev - 2.4.9-4 +- Remove leftover useless Requires. + +* Sun Jun 10 2007 Konstantin Ryabitsev - 2.4.9-3 +- Don't add X-Fedora to desktop-file-install +- Don't run update-desktop-database, since there's no MimeType to worry about + +* Sun Mar 11 2007 Konstantin Ryabitsev - 2.4.9-2 +- BR desktop-file-utils +- Set permissions correctly to appease rpmlint + +* Mon Jan 29 2007 Konstantin Ryabitsev - 2.4.9-1 +- Initial packaging for Extras. From 7c8357812437d737094cc6a469630c3cef8bf8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= Date: Sat, 26 Dec 2020 16:15:37 +0000 Subject: [PATCH 36/37] Remove kodos/__init__.py and fix file mode of help.py --- kodos/__init__.py | 2 -- kodos/help.py | 0 2 files changed, 2 deletions(-) delete mode 100644 kodos/__init__.py mode change 100755 => 100644 kodos/help.py diff --git a/kodos/__init__.py b/kodos/__init__.py deleted file mode 100644 index 4e8bb24..0000000 --- a/kodos/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# __init__.py: -*- Python -*- DESCRIPTIVE TEXT. -__all__ = [] diff --git a/kodos/help.py b/kodos/help.py old mode 100755 new mode 100644 From 7f10e7b0d1b3170591e3e8ad24e60d62dae5da85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20M=2E=20Basto?= Date: Sat, 26 Dec 2020 17:50:09 +0000 Subject: [PATCH 37/37] Fix Makefiles Add -py3 to pyrcc4 Add --from-imports to pyuic4 Comment sed replace on translations/Makefile --- Makefile | 2 +- kodos/Makefile | 2 +- translations/Makefile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 2d3486e..a6f9d90 100644 --- a/Makefile +++ b/Makefile @@ -8,4 +8,4 @@ clean: $(MAKE) clean -C kodos kodos/kodos_rc.py: kodos.qrc - pyrcc4 -o $@ $< + pyrcc4 -py3 -o $@ $< diff --git a/kodos/Makefile b/kodos/Makefile index f7b1fe7..d285670 100644 --- a/kodos/Makefile +++ b/kodos/Makefile @@ -7,4 +7,4 @@ clean: $(RM) -vf *.pyc %.py: %.ui - pyuic4 -w -o $*.py $< + pyuic4 --from-imports -w -o $*.py $< diff --git a/translations/Makefile b/translations/Makefile index 837efcf..e13ab4d 100644 --- a/translations/Makefile +++ b/translations/Makefile @@ -1,4 +1,4 @@ TSFILES := $(wildcard *.ts) all: $(TSFILES) - sed -i -e 's#\(filename="\)#\1../#g' $^ + #sed -i -e 's#\(filename="\)#\1../#g' $^