PrEditor 0.2.0__py2.py3-none-any.whl → 0.4.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of PrEditor might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PrEditor
3
- Version: 0.2.0
3
+ Version: 0.4.0
4
4
  Summary: A python REPL and Editor and console based on Qt.
5
5
  Home-page: https://github.com/blurstudio/PrEditor.git
6
6
  Author: Blur Studio
@@ -11,7 +11,7 @@ preditor/plugins.py,sha256=W3DfdDEE5DtEXOXioEyIe4tuIVV1V-RLcV8LoZJWpWU,1916
11
11
  preditor/prefs.py,sha256=BPtSsdv2yuiRpIaqEml9fxlVYKHNfqQ77hp5YIQRDBg,2172
12
12
  preditor/settings.py,sha256=DV9_DbJorEnhdIvW15E7h7PswlQUsy0UlA8bXUYN0og,2206
13
13
  preditor/streamhandler_helper.py,sha256=kiU6T9WqJ3JKTTKCa7IUU8brwK7zO5UUpEzLhEfKe44,1788
14
- preditor/version.py,sha256=g0RU_Fiae76hPEUjU6lGnapa9IZoqGcB4oFcTnsoMbM,142
14
+ preditor/version.py,sha256=LXsVgL30inwYURXgt8agwHpCAGkWqXpMAmFq8N7WB4Q,142
15
15
  preditor/weakref.py,sha256=b--KomFAHcMWr3DEAIN2j3XxRhjDWKw0WABXyn1nxDg,12177
16
16
  preditor/cores/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  preditor/cores/core.py,sha256=ZXB4bts05DMQtc-dtkk81chIWNqYXImMuWCYuUHwLdA,2389
@@ -28,13 +28,14 @@ preditor/gui/dialog.py,sha256=Vw8Wflb2P3TngO8b-2suWP6JKHBVHdbGgYiRDKzYRlQ,7488
28
28
  preditor/gui/drag_tab_bar.py,sha256=5J-BSKQzS6_WuYxxGqmnUJr6AriTAvwfVK7Q3p7knrM,7933
29
29
  preditor/gui/editor_chooser.py,sha256=v82SPuxPgai3XiRWi9ypT0aRkbV6_IrbfBoAljM9pRY,1986
30
30
  preditor/gui/errordialog.py,sha256=FZzSykNtqgTZ-CKEsLFXfcw_k8zwx7g_aMaHbpnq2xI,3110
31
- preditor/gui/find_files.py,sha256=eG935f9Xbh7F1M8IK7PKko84a37shoaoplQitPMv_-c,4116
31
+ preditor/gui/find_files.py,sha256=vh19jY571Z4E9IWSL4VyYcNJWYXzwxBHzBOzxWjI9QM,4223
32
32
  preditor/gui/level_buttons.py,sha256=yPFIWKc0bgKLrP2XHyBqNuvvTnXZqGdtN_p27jSb1Og,11925
33
33
  preditor/gui/logger_window_handler.py,sha256=VTNhaoFUnConE3NHj9KaDZlVoifix8xCbCuN5Ozjz0M,1482
34
- preditor/gui/loggerwindow.py,sha256=_f7T6e04pFHF1MZQYE77JvAHUQnJ28TS7CPGizNS2yo,47589
34
+ preditor/gui/loggerwindow.py,sha256=hSVNH36CL_zrHStNqfjN-uiXnMUYlWXt6an8meVfifE,47760
35
35
  preditor/gui/newtabwidget.py,sha256=5aCWn9xAl5h1oZACqVuEsOAbzKTS2RegrLI41gROC8A,1971
36
36
  preditor/gui/redmine_login_dialog.py,sha256=cMPBuecSZD5yjycNkMwHa1AbdwgGoyHvX8anIvWjEFo,1893
37
37
  preditor/gui/set_text_editor_path_dialog.py,sha256=6mbHAXEVQhaWyg0N67f54aZpd5fp6puGWzeM0tPepiU,2251
38
+ preditor/gui/status_label.py,sha256=UUSw2HSi5u8PA6W0pIeiaBN_LzrsJwb_AZAaGXQXBY8,2397
38
39
  preditor/gui/window.py,sha256=bZAEKQDM6V4aew1nlSTPyq_tG-_IoSvyXHcZxrdFMaE,6924
39
40
  preditor/gui/workbox_mixin.py,sha256=4tUiOWRFc0tEOAAo9BDD3idlkfO6t4VCuL4tklYNnTY,12543
40
41
  preditor/gui/workbox_text_edit.py,sha256=fJY7eo1bpMyzLri5DfdVb2vad9znJjBvzLkY34T8gb4,3678
@@ -140,15 +141,15 @@ preditor/scintilla/lexers/mulexer.py,sha256=Y2FVp6ZJ9CgLIuIvItOzXMMRemuToID66dpB
140
141
  preditor/scintilla/lexers/pythonlexer.py,sha256=WgL74RQGvGgsdAL-l2ioOMybqRw7M0GG-SxmzXsW4xw,1682
141
142
  preditor/scintilla/ui/finddialog.ui,sha256=CEXouVKqVCDOfMBciK-89OmsGe2Kr6XdMbSPiffp0PA,4048
142
143
  preditor/stream/__init__.py,sha256=SxILA3U3W8aNfVBd_oJ4-WXkA214cl1zGLSCelFx5QU,2682
143
- preditor/stream/director.py,sha256=ymay-JYrw96MwLiR7DoFJ9af3BhTODJSoEPNnkivOuE,1915
144
+ preditor/stream/director.py,sha256=Gklbl6jwTmB0BtyR6MZxRytdlufaz5MoiW9Le9WFTmo,2733
144
145
  preditor/stream/manager.py,sha256=NP4lf6hd5L_Ui-9Ws66gVEk6ZL8YqF7BxOzUsdrh3v0,2811
145
146
  preditor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
146
147
  preditor/utils/cute.py,sha256=LfF8gXMAkkQAdo4mm6J9aVkDLwWZbE6prQ0moDbtCys,1045
147
148
  preditor/utils/stylesheets.py,sha256=EVWZNq3WnaRiyUPoYMKQo_dLEwbRyKu26b03I1JDA-s,1622
148
149
  preditor/utils/text_search.py,sha256=21kuSDTpLIPUcriB81WP1kWfzuDBuP13ZtHUtypP5jE,14218
149
- PrEditor-0.2.0.dist-info/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
150
- PrEditor-0.2.0.dist-info/METADATA,sha256=3XtyKNBXmKiZ5nbUBpSZgT_RzSmyMollevrf_fp6GxU,9277
151
- PrEditor-0.2.0.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
152
- PrEditor-0.2.0.dist-info/entry_points.txt,sha256=mpe0HFD_oIEBNPTJNyUEbmMV6Ivrp4EuYyZ34C5d_PU,519
153
- PrEditor-0.2.0.dist-info/top_level.txt,sha256=iX1_mrUOky_BQr2oG0l_MbEUYF6idyjiWSzu9z3irIw,9
154
- PrEditor-0.2.0.dist-info/RECORD,,
150
+ PrEditor-0.4.0.dist-info/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
151
+ PrEditor-0.4.0.dist-info/METADATA,sha256=uWRRXD5RnLauKw3NobDW8znh1VsatdJXz5PAa0M9itQ,9277
152
+ PrEditor-0.4.0.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
153
+ PrEditor-0.4.0.dist-info/entry_points.txt,sha256=mpe0HFD_oIEBNPTJNyUEbmMV6Ivrp4EuYyZ34C5d_PU,519
154
+ PrEditor-0.4.0.dist-info/top_level.txt,sha256=iX1_mrUOky_BQr2oG0l_MbEUYF6idyjiWSzu9z3irIw,9
155
+ PrEditor-0.4.0.dist-info/RECORD,,
@@ -1,7 +1,7 @@
1
1
  from __future__ import absolute_import, print_function
2
2
 
3
3
  from Qt.QtCore import Qt
4
- from Qt.QtGui import QIcon
4
+ from Qt.QtGui import QIcon, QKeySequence
5
5
  from Qt.QtWidgets import QApplication, QShortcut, QWidget
6
6
 
7
7
  from .. import resourcePath
@@ -30,17 +30,22 @@ class FindFiles(QWidget):
30
30
 
31
31
  # Create shortcuts
32
32
  self.uiCloseSCT = QShortcut(
33
- Qt.Key_Escape, self, context=Qt.WidgetWithChildrenShortcut
33
+ QKeySequence(Qt.Key_Escape), self, context=Qt.WidgetWithChildrenShortcut
34
34
  )
35
+
35
36
  self.uiCloseSCT.activated.connect(self.hide)
36
37
 
37
38
  self.uiCaseSensitiveSCT = QShortcut(
38
- Qt.AltModifier | Qt.Key_C, self, context=Qt.WidgetWithChildrenShortcut
39
+ QKeySequence(Qt.AltModifier | Qt.Key_C),
40
+ self,
41
+ context=Qt.WidgetWithChildrenShortcut,
39
42
  )
40
43
  self.uiCaseSensitiveSCT.activated.connect(self.uiCaseSensitiveBTN.toggle)
41
44
 
42
45
  self.uiRegexSCT = QShortcut(
43
- Qt.AltModifier | Qt.Key_R, self, context=Qt.WidgetWithChildrenShortcut
46
+ QKeySequence(Qt.AltModifier | Qt.Key_R),
47
+ self,
48
+ context=Qt.WidgetWithChildrenShortcut,
44
49
  )
45
50
  self.uiRegexSCT.activated.connect(self.uiRegexBTN.toggle)
46
51
 
@@ -18,7 +18,6 @@ from Qt.QtGui import QCursor, QFont, QFontDatabase, QIcon, QTextCursor
18
18
  from Qt.QtWidgets import (
19
19
  QApplication,
20
20
  QInputDialog,
21
- QLabel,
22
21
  QMessageBox,
23
22
  QTextBrowser,
24
23
  QToolTip,
@@ -44,6 +43,7 @@ from ..utils import stylesheets
44
43
  from .completer import CompleterMode
45
44
  from .level_buttons import LoggingLevelButton
46
45
  from .set_text_editor_path_dialog import SetTextEditorPathDialog
46
+ from .status_label import StatusLabel
47
47
 
48
48
 
49
49
  class WorkboxPages:
@@ -84,7 +84,7 @@ class LoggerWindow(Window):
84
84
  self.uiConsoleTXT.uiClearToLastPromptACT.setShortcut('')
85
85
 
86
86
  # create the status reporting label
87
- self.uiStatusLBL = QLabel(self)
87
+ self.uiStatusLBL = StatusLabel(self)
88
88
  self.uiMenuBar.setCornerWidget(self.uiStatusLBL)
89
89
 
90
90
  # create the workbox tabs
@@ -654,7 +654,8 @@ class LoggerWindow(Window):
654
654
 
655
655
  def reportExecutionTime(self, seconds):
656
656
  """Update status text with seconds passed in."""
657
- self.setStatusText('Exec: {:0.04f} Seconds'.format(seconds))
657
+ self.uiStatusLBL.showSeconds(seconds)
658
+ self.uiMenuBar.adjustSize()
658
659
 
659
660
  def recordPrefs(self, manual=False):
660
661
  if not manual and not self.uiAutoSaveSettingssACT.isChecked():
@@ -681,6 +682,7 @@ class LoggerWindow(Window):
681
682
  'uiAutoPromptACT': self.uiAutoPromptACT.isChecked(),
682
683
  'uiLinesInNewWorkboxACT': self.uiLinesInNewWorkboxACT.isChecked(),
683
684
  'uiErrorHyperlinksACT': self.uiErrorHyperlinksACT.isChecked(),
685
+ 'uiStatusLbl_limit': self.uiStatusLBL.limit(),
684
686
  'textEditorPath': self.textEditorPath,
685
687
  'textEditorCmdTempl': self.textEditorCmdTempl,
686
688
  'currentStyleSheet': self._stylesheet,
@@ -796,6 +798,7 @@ class LoggerWindow(Window):
796
798
  pref.get('uiLinesInNewWorkboxACT', False)
797
799
  )
798
800
  self.uiErrorHyperlinksACT.setChecked(pref.get('uiErrorHyperlinksACT', True))
801
+ self.uiStatusLBL.setLimit(pref.get('uiStatusLbl_limit', 5))
799
802
 
800
803
  # Find Files settings
801
804
  self.uiFindInWorkboxesWGT.uiRegexBTN.setChecked(
@@ -876,7 +879,7 @@ class LoggerWindow(Window):
876
879
 
877
880
  def clearStatusText(self):
878
881
  """Clear any displayed status text"""
879
- self.uiStatusLBL.setText('')
882
+ self.uiStatusLBL.clear()
880
883
  self.uiMenuBar.adjustSize()
881
884
 
882
885
  def autoHideStatusText(self):
@@ -0,0 +1,79 @@
1
+ from __future__ import absolute_import
2
+
3
+ from collections import deque
4
+
5
+ from Qt.QtCore import QPoint, QTimer
6
+ from Qt.QtWidgets import QInputDialog, QLabel, QMenu
7
+
8
+
9
+ class StatusLabel(QLabel):
10
+ """A label that shows text and an average of code execution times in popup menu."""
11
+
12
+ def __init__(self, *args, limit=5, **kwargs):
13
+ self.render_as_href = False
14
+ super(StatusLabel, self).__init__(*args, **kwargs)
15
+ self.times = deque(maxlen=limit)
16
+
17
+ def clear(self):
18
+ self.setText("")
19
+
20
+ def clearTimes(self):
21
+ """"""
22
+ self.times.clear()
23
+
24
+ def chooseLimit(self):
25
+ limit, success = QInputDialog.getInt(
26
+ self,
27
+ "Choose Avg length",
28
+ "Choose how many execution time history to keep.",
29
+ value=self.limit(),
30
+ min=1,
31
+ max=100,
32
+ )
33
+ if limit:
34
+ self.setLimit(limit)
35
+
36
+ def mouseReleaseEvent(self, event):
37
+ QTimer.singleShot(0, self.showMenu)
38
+ super(StatusLabel, self).mouseReleaseEvent(event)
39
+
40
+ def secondsText(self, seconds):
41
+ """Generates text to show seconds of exec time."""
42
+ return 'Exec: {:0.04f} Seconds'.format(seconds)
43
+
44
+ def limit(self):
45
+ return self.times.maxlen
46
+
47
+ def setLimit(self, limit):
48
+ self.times = deque(self.times, maxlen=limit)
49
+
50
+ def setText(self, text):
51
+ if self.render_as_href:
52
+ text = '<a href="showMenu">{}</a>'.format(text)
53
+ super(StatusLabel, self).setText(text)
54
+
55
+ def showSeconds(self, seconds):
56
+ self.times.append(seconds)
57
+ self.setText(self.secondsText(seconds))
58
+
59
+ def showMenu(self):
60
+ menu = QMenu(self)
61
+ if self.times:
62
+ # Show the time it took to run the last X code calls
63
+ for seconds in self.times:
64
+ menu.addAction(self.secondsText(seconds))
65
+
66
+ menu.addSeparator()
67
+ avg = sum(self.times) / len(self.times)
68
+ menu.addAction("Average: {:0.04f}s".format(avg))
69
+ act = menu.addAction("Clear")
70
+ act.triggered.connect(self.clearTimes)
71
+
72
+ menu.addSeparator()
73
+ act = menu.addAction("Set limit...")
74
+ act.triggered.connect(self.chooseLimit)
75
+
76
+ # Position the menu at the bottom of the widget
77
+ height = self.geometry().height()
78
+ pos = self.mapToGlobal(QPoint(0, height))
79
+ menu.popup(pos)
@@ -28,17 +28,34 @@ class Director(io.TextIOBase):
28
28
  self.manager = manager
29
29
  self.state = state
30
30
 
31
+ # Keep track of whether we wrapped a std stream
32
+ # that way we don't .close() any streams that we don't control
33
+ self.std_stream_wrapped = False
34
+
31
35
  if old_stream is False:
32
36
  old_stream = None
33
37
  elif old_stream is None:
34
38
  if state == STDOUT:
35
- old_stream = sys.stdout
39
+ # On Windows if we're in pythonw.exe, then sys.stdout is named "nul"
40
+ # And it uses cp1252 encoding (which breaks with unicode)
41
+ # So if we find this nul TextIOWrapper, it's safe to just skip it
42
+ if getattr(sys.stdout, 'name', '') != 'nul':
43
+ self.std_stream_wrapped = True
44
+ old_stream = sys.stdout
36
45
  elif state == STDERR:
37
- old_stream = sys.stderr
46
+ if getattr(sys.stderr, 'name', '') != 'nul':
47
+ self.std_stream_wrapped = True
48
+ old_stream = sys.stderr
49
+
38
50
  self.old_stream = old_stream
39
51
 
40
52
  def close(self):
41
- if self.old_stream:
53
+ if (
54
+ self.old_stream
55
+ and not self.std_stream_wrapped
56
+ and self.old_stream is not sys.__stdout__
57
+ and self.old_stream is not sys.__stderr__
58
+ ):
42
59
  self.old_stream.close()
43
60
 
44
61
  super(Director, self).close()
preditor/version.py CHANGED
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
  # file generated by setuptools_scm
3
3
  # don't change, don't track in version control
4
- version = '0.2.0'
5
- version_tuple = (0, 2, 0)
4
+ version = '0.4.0'
5
+ version_tuple = (0, 4, 0)