PrEditor 0.3.0__py2.py3-none-any.whl → 0.5.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.
- {PrEditor-0.3.0.dist-info → PrEditor-0.5.0.dist-info}/METADATA +17 -17
- {PrEditor-0.3.0.dist-info → PrEditor-0.5.0.dist-info}/RECORD +23 -20
- {PrEditor-0.3.0.dist-info → PrEditor-0.5.0.dist-info}/WHEEL +1 -1
- preditor/gui/console.py +103 -6
- preditor/gui/editor_chooser.py +1 -1
- preditor/gui/find_files.py +9 -4
- preditor/gui/group_tab_widget/__init__.py +1 -1
- preditor/gui/group_tab_widget/grouped_tab_widget.py +3 -0
- preditor/gui/loggerwindow.py +158 -72
- preditor/gui/set_text_editor_path_dialog.py +4 -4
- preditor/gui/status_label.py +90 -0
- preditor/gui/suggest_path_quotes_dialog.py +50 -0
- preditor/gui/ui/loggerwindow.ui +82 -34
- preditor/gui/ui/set_text_editor_path_dialog.ui +48 -8
- preditor/gui/ui/suggest_path_quotes_dialog.ui +225 -0
- preditor/gui/workbox_mixin.py +50 -18
- preditor/gui/workbox_text_edit.py +24 -4
- preditor/gui/workboxwidget.py +24 -2
- preditor/scintilla/documenteditor.py +3 -3
- preditor/version.py +2 -2
- {PrEditor-0.3.0.dist-info → PrEditor-0.5.0.dist-info}/LICENSE +0 -0
- {PrEditor-0.3.0.dist-info → PrEditor-0.5.0.dist-info}/entry_points.txt +0 -0
- {PrEditor-0.3.0.dist-info → PrEditor-0.5.0.dist-info}/top_level.txt +0 -0
preditor/gui/loggerwindow.py
CHANGED
|
@@ -14,11 +14,11 @@ import __main__
|
|
|
14
14
|
import six
|
|
15
15
|
from Qt import QtCompat, QtCore, QtWidgets
|
|
16
16
|
from Qt.QtCore import QByteArray, Qt, QTimer, Signal, Slot
|
|
17
|
-
from Qt.QtGui import QCursor, QFont,
|
|
17
|
+
from Qt.QtGui import QCursor, QFont, QIcon, QTextCursor
|
|
18
18
|
from Qt.QtWidgets import (
|
|
19
19
|
QApplication,
|
|
20
|
+
QFontDialog,
|
|
20
21
|
QInputDialog,
|
|
21
|
-
QLabel,
|
|
22
22
|
QMessageBox,
|
|
23
23
|
QTextBrowser,
|
|
24
24
|
QToolTip,
|
|
@@ -44,6 +44,7 @@ from ..utils import stylesheets
|
|
|
44
44
|
from .completer import CompleterMode
|
|
45
45
|
from .level_buttons import LoggingLevelButton
|
|
46
46
|
from .set_text_editor_path_dialog import SetTextEditorPathDialog
|
|
47
|
+
from .status_label import StatusLabel
|
|
47
48
|
|
|
48
49
|
|
|
49
50
|
class WorkboxPages:
|
|
@@ -75,6 +76,7 @@ class LoggerWindow(Window):
|
|
|
75
76
|
loadUi(__file__, self)
|
|
76
77
|
|
|
77
78
|
self.uiConsoleTXT.flash_window = self
|
|
79
|
+
self.uiConsoleTXT.clearExecutionTime = self.clearExecutionTime
|
|
78
80
|
self.uiConsoleTXT.reportExecutionTime = self.reportExecutionTime
|
|
79
81
|
self.uiClearToLastPromptACT.triggered.connect(
|
|
80
82
|
self.uiConsoleTXT.clearToLastPrompt
|
|
@@ -84,7 +86,7 @@ class LoggerWindow(Window):
|
|
|
84
86
|
self.uiConsoleTXT.uiClearToLastPromptACT.setShortcut('')
|
|
85
87
|
|
|
86
88
|
# create the status reporting label
|
|
87
|
-
self.uiStatusLBL =
|
|
89
|
+
self.uiStatusLBL = StatusLabel(self)
|
|
88
90
|
self.uiMenuBar.setCornerWidget(self.uiStatusLBL)
|
|
89
91
|
|
|
90
92
|
# create the workbox tabs
|
|
@@ -119,12 +121,38 @@ class LoggerWindow(Window):
|
|
|
119
121
|
self.uiCloseLoggerACT.triggered.connect(self.closeLogger)
|
|
120
122
|
|
|
121
123
|
self.uiRunAllACT.triggered.connect(self.execAll)
|
|
122
|
-
|
|
124
|
+
# Even though the RunSelected actions (with shortcuts) are connected
|
|
125
|
+
# here, this only affects if the action is chosen from the menu. The
|
|
126
|
+
# shortcuts are always intercepted by the workbox document editor. To
|
|
127
|
+
# handle this, the workbox.keyPressEvent method will perceive the
|
|
128
|
+
# shortcut press, and call .execSelected, which will then ultimately call
|
|
129
|
+
# workbox.__exec_selected__
|
|
130
|
+
self.uiRunSelectedACT.triggered.connect(
|
|
131
|
+
partial(self.execSelected, truncate=True)
|
|
132
|
+
)
|
|
133
|
+
self.uiRunSelectedDontTruncateACT.triggered.connect(
|
|
134
|
+
partial(self.execSelected, truncate=False)
|
|
135
|
+
)
|
|
123
136
|
|
|
124
|
-
self.
|
|
137
|
+
self.uiConsoleAutoCompleteEnabledACT.toggled.connect(
|
|
138
|
+
partial(self.setAutoCompleteEnabled, console=True)
|
|
139
|
+
)
|
|
140
|
+
self.uiWorkboxAutoCompleteEnabledACT.toggled.connect(
|
|
141
|
+
partial(self.setAutoCompleteEnabled, console=False)
|
|
142
|
+
)
|
|
125
143
|
|
|
126
144
|
self.uiAutoCompleteCaseSensitiveACT.toggled.connect(self.setCaseSensitive)
|
|
127
145
|
|
|
146
|
+
self.uiSelectMonospaceFontACT.triggered.connect(
|
|
147
|
+
partial(self.selectFont, monospace=True)
|
|
148
|
+
)
|
|
149
|
+
self.uiSelectProportionalFontACT.triggered.connect(
|
|
150
|
+
partial(self.selectFont, proportional=True)
|
|
151
|
+
)
|
|
152
|
+
self.uiSelectAllFontACT.triggered.connect(
|
|
153
|
+
partial(self.selectFont, monospace=True, proportional=True)
|
|
154
|
+
)
|
|
155
|
+
|
|
128
156
|
# Setup ability to cycle completer mode, and create action for each mode
|
|
129
157
|
self.completerModeCycle = itertools.cycle(CompleterMode)
|
|
130
158
|
# create CompleterMode submenu
|
|
@@ -234,27 +262,9 @@ class LoggerWindow(Window):
|
|
|
234
262
|
# Make action shortcuts available anywhere in the Logger
|
|
235
263
|
self.addAction(self.uiClearLogACT)
|
|
236
264
|
|
|
265
|
+
self.dont_ask_again = []
|
|
237
266
|
self.restorePrefs()
|
|
238
267
|
|
|
239
|
-
# add font menu list
|
|
240
|
-
curFamily = self.console().font().family()
|
|
241
|
-
fontDB = QFontDatabase()
|
|
242
|
-
fontFamilies = fontDB.families(QFontDatabase.Latin)
|
|
243
|
-
monospaceFonts = [fam for fam in fontFamilies if fontDB.isFixedPitch(fam)]
|
|
244
|
-
|
|
245
|
-
self.uiMonospaceFontMENU.clear()
|
|
246
|
-
self.uiProportionalFontMENU.clear()
|
|
247
|
-
|
|
248
|
-
for family in fontFamilies:
|
|
249
|
-
if family in monospaceFonts:
|
|
250
|
-
action = self.uiMonospaceFontMENU.addAction(family)
|
|
251
|
-
else:
|
|
252
|
-
action = self.uiProportionalFontMENU.addAction(family)
|
|
253
|
-
action.setObjectName(u'ui{}FontACT'.format(family))
|
|
254
|
-
action.setCheckable(True)
|
|
255
|
-
action.setChecked(family == curFamily)
|
|
256
|
-
action.triggered.connect(partial(self.selectFont, action))
|
|
257
|
-
|
|
258
268
|
# add stylesheet menu options.
|
|
259
269
|
for style_name in stylesheets.stylesheets():
|
|
260
270
|
action = self.uiStyleMENU.addAction(style_name)
|
|
@@ -276,6 +286,9 @@ class LoggerWindow(Window):
|
|
|
276
286
|
)
|
|
277
287
|
)
|
|
278
288
|
|
|
289
|
+
self.setWorkboxFontBasedOnConsole()
|
|
290
|
+
self.setEditorChooserFontBasedOnConsole()
|
|
291
|
+
|
|
279
292
|
self.setup_run_workbox()
|
|
280
293
|
|
|
281
294
|
if not standalone:
|
|
@@ -429,7 +442,7 @@ class LoggerWindow(Window):
|
|
|
429
442
|
if not workbox.hasFocus():
|
|
430
443
|
return
|
|
431
444
|
|
|
432
|
-
text = workbox.__selected_text__()
|
|
445
|
+
text, _line = workbox.__selected_text__(selectText=True)
|
|
433
446
|
if not text:
|
|
434
447
|
line, index = workbox.__cursor_position__()
|
|
435
448
|
text = workbox.__text__(line)
|
|
@@ -513,15 +526,7 @@ class LoggerWindow(Window):
|
|
|
513
526
|
newSize = font.pointSize() + delta
|
|
514
527
|
newSize = max(min(newSize, maxSize), minSize)
|
|
515
528
|
|
|
516
|
-
|
|
517
|
-
self.console().setConsoleFont(font)
|
|
518
|
-
|
|
519
|
-
for workbox in self.uiWorkboxTAB.all_widgets():
|
|
520
|
-
marginsFont = workbox.__margins_font__()
|
|
521
|
-
marginsFont.setPointSize(newSize)
|
|
522
|
-
workbox.__set_margins_font__(marginsFont)
|
|
523
|
-
|
|
524
|
-
workbox.__set_font__(font)
|
|
529
|
+
self.setFontSize(newSize)
|
|
525
530
|
else:
|
|
526
531
|
Window.wheelEvent(self, event)
|
|
527
532
|
|
|
@@ -539,41 +544,76 @@ class LoggerWindow(Window):
|
|
|
539
544
|
menu = action.parentWidget()
|
|
540
545
|
QToolTip.showText(QCursor.pos(), text, menu)
|
|
541
546
|
|
|
542
|
-
def
|
|
543
|
-
"""
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
action = None
|
|
548
|
-
for act in actions:
|
|
549
|
-
if act.isChecked():
|
|
550
|
-
action = act
|
|
551
|
-
break
|
|
552
|
-
|
|
553
|
-
return action
|
|
554
|
-
|
|
555
|
-
def selectFont(self, action):
|
|
556
|
-
"""Set console and workbox font to current font
|
|
547
|
+
def selectFont(self, monospace=False, proportional=False):
|
|
548
|
+
"""Present a QFontChooser dialog, offering, monospace, proportional, or all
|
|
549
|
+
fonts, based on user choice. If a font is chosen, set it on the console and
|
|
550
|
+
workboxes.
|
|
557
551
|
|
|
558
552
|
Args:
|
|
559
553
|
action (QAction): menu action associated with chosen font
|
|
560
554
|
"""
|
|
555
|
+
origFont = self.console().font()
|
|
556
|
+
curFontFamily = origFont.family()
|
|
557
|
+
|
|
558
|
+
if monospace and proportional:
|
|
559
|
+
options = QFontDialog.MonospacedFonts | QFontDialog.ProportionalFonts
|
|
560
|
+
kind = "monospace or proportional "
|
|
561
|
+
elif monospace:
|
|
562
|
+
options = QFontDialog.MonospacedFonts
|
|
563
|
+
kind = "monospace "
|
|
564
|
+
elif proportional:
|
|
565
|
+
options = QFontDialog.ProportionalFonts
|
|
566
|
+
kind = "proportional "
|
|
567
|
+
|
|
568
|
+
# Present a QFontDialog for user to choose a font
|
|
569
|
+
title = "Pick a {} font. Current font is: {}".format(kind, curFontFamily)
|
|
570
|
+
newFont, okClicked = QFontDialog.getFont(origFont, self, title, options=options)
|
|
571
|
+
|
|
572
|
+
if okClicked:
|
|
573
|
+
self.console().setConsoleFont(newFont)
|
|
574
|
+
self.setWorkboxFontBasedOnConsole()
|
|
575
|
+
self.setEditorChooserFontBasedOnConsole()
|
|
576
|
+
|
|
577
|
+
def setFontSize(self, newSize):
|
|
578
|
+
"""Update the font size in the console and current workbox.
|
|
561
579
|
|
|
562
|
-
|
|
563
|
-
|
|
580
|
+
Args:
|
|
581
|
+
newSize (int): The new size to set the font
|
|
582
|
+
"""
|
|
583
|
+
font = self.console().font()
|
|
584
|
+
font.setPointSize(newSize)
|
|
585
|
+
self.console().setConsoleFont(font)
|
|
564
586
|
|
|
565
|
-
|
|
566
|
-
|
|
587
|
+
self.setWorkboxFontBasedOnConsole()
|
|
588
|
+
self.setEditorChooserFontBasedOnConsole()
|
|
567
589
|
|
|
568
|
-
|
|
590
|
+
def setWorkboxFontBasedOnConsole(self):
|
|
591
|
+
"""If the current workbox's font is different to the console's font, set it to
|
|
592
|
+
match.
|
|
593
|
+
"""
|
|
569
594
|
font = self.console().font()
|
|
570
|
-
font.setFamily(family)
|
|
571
|
-
self.console().setConsoleFont(font)
|
|
572
595
|
|
|
573
|
-
|
|
596
|
+
workboxGroup = self.uiWorkboxTAB.currentWidget()
|
|
597
|
+
if workboxGroup is None:
|
|
598
|
+
return
|
|
599
|
+
|
|
600
|
+
workbox = workboxGroup.currentWidget()
|
|
601
|
+
if workbox is None:
|
|
602
|
+
return
|
|
603
|
+
|
|
604
|
+
if workbox.__font__() != font:
|
|
574
605
|
workbox.__set_margins_font__(font)
|
|
575
606
|
workbox.__set_font__(font)
|
|
576
607
|
|
|
608
|
+
def setEditorChooserFontBasedOnConsole(self):
|
|
609
|
+
"""Set the EditorChooser font to match console. This helps with legibility when
|
|
610
|
+
using EditorChooser.
|
|
611
|
+
"""
|
|
612
|
+
font = self.console().font()
|
|
613
|
+
for child in self.uiEditorChooserWGT.children():
|
|
614
|
+
if hasattr(child, "font"):
|
|
615
|
+
child.setFont(font)
|
|
616
|
+
|
|
577
617
|
@classmethod
|
|
578
618
|
def _genPrefName(cls, baseName, index):
|
|
579
619
|
if index:
|
|
@@ -635,11 +675,21 @@ class LoggerWindow(Window):
|
|
|
635
675
|
prompt = console.prompt()
|
|
636
676
|
console.startPrompt(prompt)
|
|
637
677
|
|
|
638
|
-
def execSelected(self):
|
|
639
|
-
"""Clears the console before executing selected workbox code
|
|
678
|
+
def execSelected(self, truncate=True):
|
|
679
|
+
"""Clears the console before executing selected workbox code.
|
|
680
|
+
|
|
681
|
+
NOTE! This method is not called when the uiRunSelectedACT is triggered,
|
|
682
|
+
because the workbox will always intercept it. So instead, the workbox's
|
|
683
|
+
keyPressEvent will notice the shortcut and call this method.
|
|
684
|
+
"""
|
|
685
|
+
|
|
640
686
|
if self.uiClearBeforeRunningACT.isChecked():
|
|
641
687
|
self.clearLog()
|
|
642
|
-
|
|
688
|
+
|
|
689
|
+
self.current_workbox().__exec_selected__(truncate=truncate)
|
|
690
|
+
|
|
691
|
+
if self.uiAutoPromptACT.isChecked():
|
|
692
|
+
self.console().startInputLine()
|
|
643
693
|
|
|
644
694
|
def keyPressEvent(self, event):
|
|
645
695
|
# Fix 'Maya : Qt tools lose focus' https://redmine.blur.com/issues/34430
|
|
@@ -652,9 +702,15 @@ class LoggerWindow(Window):
|
|
|
652
702
|
if self.uiClearLogOnRefreshACT.isChecked():
|
|
653
703
|
self.clearLog()
|
|
654
704
|
|
|
705
|
+
def clearExecutionTime(self):
|
|
706
|
+
"""Update status text with hyphens to indicate execution has begun."""
|
|
707
|
+
self.setStatusText('Exec: -.- Seconds')
|
|
708
|
+
QApplication.instance().processEvents()
|
|
709
|
+
|
|
655
710
|
def reportExecutionTime(self, seconds):
|
|
656
711
|
"""Update status text with seconds passed in."""
|
|
657
|
-
self.
|
|
712
|
+
self.uiStatusLBL.showSeconds(seconds)
|
|
713
|
+
self.uiMenuBar.adjustSize()
|
|
658
714
|
|
|
659
715
|
def recordPrefs(self, manual=False):
|
|
660
716
|
if not manual and not self.uiAutoSaveSettingssACT.isChecked():
|
|
@@ -670,17 +726,22 @@ class LoggerWindow(Window):
|
|
|
670
726
|
'SplitterSize': self.uiSplitterSPLIT.sizes(),
|
|
671
727
|
'tabIndent': self.uiIndentationsTabsACT.isChecked(),
|
|
672
728
|
'copyIndentsAsSpaces': self.uiCopyTabsToSpacesACT.isChecked(),
|
|
673
|
-
'hintingEnabled': self.
|
|
729
|
+
'hintingEnabled': self.uiConsoleAutoCompleteEnabledACT.isChecked(),
|
|
730
|
+
'workboxHintingEnabled': (
|
|
731
|
+
self.uiWorkboxAutoCompleteEnabledACT.isChecked()
|
|
732
|
+
),
|
|
674
733
|
'spellCheckEnabled': self.uiSpellCheckEnabledACT.isChecked(),
|
|
675
734
|
'wordWrap': self.uiWordWrapACT.isChecked(),
|
|
676
735
|
'clearBeforeRunning': self.uiClearBeforeRunningACT.isChecked(),
|
|
677
736
|
'clearBeforeEnvRefresh': self.uiClearLogOnRefreshACT.isChecked(),
|
|
737
|
+
'uiSelectTextACT': self.uiSelectTextACT.isChecked(),
|
|
678
738
|
'toolbarStates': six.text_type(self.saveState().toHex(), 'utf-8'),
|
|
679
739
|
'consoleFont': self.console().font().toString(),
|
|
680
740
|
'uiAutoSaveSettingssACT': self.uiAutoSaveSettingssACT.isChecked(),
|
|
681
741
|
'uiAutoPromptACT': self.uiAutoPromptACT.isChecked(),
|
|
682
742
|
'uiLinesInNewWorkboxACT': self.uiLinesInNewWorkboxACT.isChecked(),
|
|
683
743
|
'uiErrorHyperlinksACT': self.uiErrorHyperlinksACT.isChecked(),
|
|
744
|
+
'uiStatusLbl_limit': self.uiStatusLBL.limit(),
|
|
684
745
|
'textEditorPath': self.textEditorPath,
|
|
685
746
|
'textEditorCmdTempl': self.textEditorCmdTempl,
|
|
686
747
|
'currentStyleSheet': self._stylesheet,
|
|
@@ -691,6 +752,10 @@ class LoggerWindow(Window):
|
|
|
691
752
|
),
|
|
692
753
|
'find_files_context': self.uiFindInWorkboxesWGT.uiContextSPN.value(),
|
|
693
754
|
'find_files_text': self.uiFindInWorkboxesWGT.uiFindTXT.text(),
|
|
755
|
+
'uiHighlightExactCompletionACT': (
|
|
756
|
+
self.uiHighlightExactCompletionACT.isChecked()
|
|
757
|
+
),
|
|
758
|
+
'dont_ask_again': self.dont_ask_again,
|
|
694
759
|
}
|
|
695
760
|
)
|
|
696
761
|
|
|
@@ -725,6 +790,15 @@ class LoggerWindow(Window):
|
|
|
725
790
|
with open(filename, 'w') as fp:
|
|
726
791
|
json.dump(pref, fp, indent=4)
|
|
727
792
|
|
|
793
|
+
def maybeDisplayDialog(self, dialog):
|
|
794
|
+
"""If user hasn't previously opted to not show this particular dialog again,
|
|
795
|
+
show it.
|
|
796
|
+
"""
|
|
797
|
+
if dialog.objectName() in self.dont_ask_again:
|
|
798
|
+
return
|
|
799
|
+
|
|
800
|
+
dialog.exec_()
|
|
801
|
+
|
|
728
802
|
def restartLogger(self):
|
|
729
803
|
"""Closes this PrEditor instance and starts a new process with the same
|
|
730
804
|
cli arguments.
|
|
@@ -774,21 +848,20 @@ class LoggerWindow(Window):
|
|
|
774
848
|
self.setWindowState(Qt.WindowStates(pref.get('windowState', 0)))
|
|
775
849
|
self.uiIndentationsTabsACT.setChecked(pref.get('tabIndent', True))
|
|
776
850
|
self.uiCopyTabsToSpacesACT.setChecked(pref.get('copyIndentsAsSpaces', False))
|
|
777
|
-
self.uiAutoCompleteEnabledACT.setChecked(pref.get('hintingEnabled', True))
|
|
778
851
|
|
|
779
852
|
# completer settings
|
|
780
853
|
self.setCaseSensitive(pref.get('caseSensitive', True))
|
|
781
854
|
completerMode = CompleterMode(pref.get('completerMode', 0))
|
|
782
855
|
self.cycleToCompleterMode(completerMode)
|
|
783
856
|
self.setCompleterMode(completerMode)
|
|
857
|
+
self.uiHighlightExactCompletionACT.setChecked(
|
|
858
|
+
pref.get('uiHighlightExactCompletionACT', False)
|
|
859
|
+
)
|
|
784
860
|
|
|
785
861
|
self.setSpellCheckEnabled(self.uiSpellCheckEnabledACT.isChecked())
|
|
786
862
|
self.uiSpellCheckEnabledACT.setChecked(pref.get('spellCheckEnabled', False))
|
|
787
863
|
self.uiSpellCheckEnabledACT.setDisabled(False)
|
|
788
864
|
|
|
789
|
-
self.uiConsoleTXT.completer().setEnabled(
|
|
790
|
-
self.uiAutoCompleteEnabledACT.isChecked()
|
|
791
|
-
)
|
|
792
865
|
self.uiAutoSaveSettingssACT.setChecked(pref.get('uiAutoSaveSettingssACT', True))
|
|
793
866
|
|
|
794
867
|
self.uiAutoPromptACT.setChecked(pref.get('uiAutoPromptACT', False))
|
|
@@ -796,6 +869,7 @@ class LoggerWindow(Window):
|
|
|
796
869
|
pref.get('uiLinesInNewWorkboxACT', False)
|
|
797
870
|
)
|
|
798
871
|
self.uiErrorHyperlinksACT.setChecked(pref.get('uiErrorHyperlinksACT', True))
|
|
872
|
+
self.uiStatusLBL.setLimit(pref.get('uiStatusLbl_limit', 5))
|
|
799
873
|
|
|
800
874
|
# Find Files settings
|
|
801
875
|
self.uiFindInWorkboxesWGT.uiRegexBTN.setChecked(
|
|
@@ -811,7 +885,7 @@ class LoggerWindow(Window):
|
|
|
811
885
|
|
|
812
886
|
# External text editor filepath and command template
|
|
813
887
|
defaultExePath = r"C:\Program Files\Sublime Text 3\sublime_text.exe"
|
|
814
|
-
defaultCmd = r"{exePath} {modulePath}:{lineNum}
|
|
888
|
+
defaultCmd = r'"{exePath}" "{modulePath}":{lineNum}'
|
|
815
889
|
self.textEditorPath = pref.get('textEditorPath', defaultExePath)
|
|
816
890
|
self.textEditorCmdTempl = pref.get('textEditorCmdTempl', defaultCmd)
|
|
817
891
|
|
|
@@ -820,6 +894,7 @@ class LoggerWindow(Window):
|
|
|
820
894
|
self.uiClearBeforeRunningACT.setChecked(pref.get('clearBeforeRunning', False))
|
|
821
895
|
self.uiClearLogOnRefreshACT.setChecked(pref.get('clearBeforeEnvRefresh', False))
|
|
822
896
|
self.setClearBeforeRunning(self.uiClearBeforeRunningACT.isChecked())
|
|
897
|
+
self.uiSelectTextACT.setChecked(pref.get('uiSelectTextACT', True))
|
|
823
898
|
|
|
824
899
|
self._stylesheet = pref.get('currentStyleSheet', 'Bright')
|
|
825
900
|
if self._stylesheet == 'Custom':
|
|
@@ -830,6 +905,13 @@ class LoggerWindow(Window):
|
|
|
830
905
|
|
|
831
906
|
self.uiWorkboxTAB.restore_prefs(pref.get('workbox_prefs', {}))
|
|
832
907
|
|
|
908
|
+
hintingEnabled = pref.get('hintingEnabled', True)
|
|
909
|
+
self.uiConsoleAutoCompleteEnabledACT.setChecked(hintingEnabled)
|
|
910
|
+
self.setAutoCompleteEnabled(hintingEnabled, console=True)
|
|
911
|
+
workboxHintingEnabled = pref.get('workboxHintingEnabled', True)
|
|
912
|
+
self.uiWorkboxAutoCompleteEnabledACT.setChecked(workboxHintingEnabled)
|
|
913
|
+
self.setAutoCompleteEnabled(workboxHintingEnabled, console=False)
|
|
914
|
+
|
|
833
915
|
# Ensure the correct workbox stack page is shown
|
|
834
916
|
self.update_workbox_stack()
|
|
835
917
|
|
|
@@ -839,6 +921,8 @@ class LoggerWindow(Window):
|
|
|
839
921
|
if font.fromString(_font):
|
|
840
922
|
self.console().setConsoleFont(font)
|
|
841
923
|
|
|
924
|
+
self.dont_ask_again = pref.get('dont_ask_again', [])
|
|
925
|
+
|
|
842
926
|
def restoreToolbars(self, pref=None):
|
|
843
927
|
if pref is None:
|
|
844
928
|
pref = self.load_prefs()
|
|
@@ -848,10 +932,12 @@ class LoggerWindow(Window):
|
|
|
848
932
|
state = QByteArray.fromHex(bytes(state, 'utf-8'))
|
|
849
933
|
self.restoreState(state)
|
|
850
934
|
|
|
851
|
-
def setAutoCompleteEnabled(self, state):
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
935
|
+
def setAutoCompleteEnabled(self, state, console=True):
|
|
936
|
+
if console:
|
|
937
|
+
self.uiConsoleTXT.completer().setEnabled(state)
|
|
938
|
+
else:
|
|
939
|
+
for workbox, _, _, _, _ in self.uiWorkboxTAB.all_widgets():
|
|
940
|
+
workbox.__set_auto_complete_enabled__(state)
|
|
855
941
|
|
|
856
942
|
def setSpellCheckEnabled(self, state):
|
|
857
943
|
try:
|
|
@@ -876,7 +962,7 @@ class LoggerWindow(Window):
|
|
|
876
962
|
|
|
877
963
|
def clearStatusText(self):
|
|
878
964
|
"""Clear any displayed status text"""
|
|
879
|
-
self.uiStatusLBL.
|
|
965
|
+
self.uiStatusLBL.clear()
|
|
880
966
|
self.uiMenuBar.adjustSize()
|
|
881
967
|
|
|
882
968
|
def autoHideStatusText(self):
|
|
@@ -17,7 +17,7 @@ class SetTextEditorPathDialog(QDialog):
|
|
|
17
17
|
super(SetTextEditorPathDialog, self).__init__(parent)
|
|
18
18
|
loadUi(__file__, self)
|
|
19
19
|
|
|
20
|
-
#
|
|
20
|
+
# Retrieve existing data from LoggerWindow
|
|
21
21
|
path = self.parent().textEditorPath
|
|
22
22
|
cmdTempl = self.parent().textEditorCmdTempl
|
|
23
23
|
|
|
@@ -29,9 +29,9 @@ class SetTextEditorPathDialog(QDialog):
|
|
|
29
29
|
|
|
30
30
|
toolTip = (
|
|
31
31
|
"Examples:\n"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
'SublimeText: "{exePath}" "{modulePath}":{lineNum}\n'
|
|
33
|
+
'notepad++: "{exePath}" "{modulePath}" -n{lineNum}\n'
|
|
34
|
+
'vim: "{exePath}" + {lineNum} "{modulePath}'
|
|
35
35
|
)
|
|
36
36
|
self.uiTextEditorCommandPatternLE.setToolTip(toolTip)
|
|
37
37
|
|
|
@@ -0,0 +1,90 @@
|
|
|
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[0]))
|
|
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
|
+
times = []
|
|
64
|
+
for seconds in self.times:
|
|
65
|
+
secs, cmd = seconds
|
|
66
|
+
times.append(secs)
|
|
67
|
+
|
|
68
|
+
# Add a simplified copy of the command that was run
|
|
69
|
+
cmd = cmd.strip()
|
|
70
|
+
cmds = cmd.split("\n")
|
|
71
|
+
if len(cmds) > 1 or len(cmds[0]) > 50:
|
|
72
|
+
cmd = "{} ...".format(cmds[0][:50])
|
|
73
|
+
# Escape &'s so they dont' get turned into a shortcut'
|
|
74
|
+
cmd = cmd.replace("&", "&&")
|
|
75
|
+
menu.addAction("{}: {}".format(self.secondsText(secs), cmd))
|
|
76
|
+
|
|
77
|
+
menu.addSeparator()
|
|
78
|
+
avg = sum(times) / len(times)
|
|
79
|
+
menu.addAction("Average: {:0.04f}s".format(avg))
|
|
80
|
+
act = menu.addAction("Clear")
|
|
81
|
+
act.triggered.connect(self.clearTimes)
|
|
82
|
+
|
|
83
|
+
menu.addSeparator()
|
|
84
|
+
act = menu.addAction("Set limit...")
|
|
85
|
+
act.triggered.connect(self.chooseLimit)
|
|
86
|
+
|
|
87
|
+
# Position the menu at the bottom of the widget
|
|
88
|
+
height = self.geometry().height()
|
|
89
|
+
pos = self.mapToGlobal(QPoint(0, height))
|
|
90
|
+
menu.popup(pos)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from __future__ import absolute_import
|
|
2
|
+
|
|
3
|
+
from Qt.QtWidgets import QDialog
|
|
4
|
+
|
|
5
|
+
from . import loadUi
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SuggestPathQuotesDialog(QDialog):
|
|
9
|
+
"""A dialog to suggest to enclose paths in double-quotes in the cmdTempl which is
|
|
10
|
+
used to launch an external text editor.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, parent, oldCmdTempl, newCmdTempl):
|
|
14
|
+
super(SuggestPathQuotesDialog, self).__init__(parent)
|
|
15
|
+
loadUi(__file__, self)
|
|
16
|
+
|
|
17
|
+
self.parentWindow = self.parent().window()
|
|
18
|
+
|
|
19
|
+
self.uiTextEditorOldCommandPatternLE.setText(oldCmdTempl)
|
|
20
|
+
self.uiTextEditorNewCommandPatternLE.setText(newCmdTempl)
|
|
21
|
+
|
|
22
|
+
toolTip = (
|
|
23
|
+
"Examples:\n"
|
|
24
|
+
'SublimeText: "{exePath}" "{modulePath}":{lineNum}\n'
|
|
25
|
+
'notepad++: "{exePath}" "{modulePath}" -n{lineNum}\n'
|
|
26
|
+
'vim: "{exePath}" + {lineNum} "{modulePath}'
|
|
27
|
+
)
|
|
28
|
+
self.uiTextEditorNewCommandPatternLE.setToolTip(toolTip)
|
|
29
|
+
|
|
30
|
+
def accept(self):
|
|
31
|
+
"""Set the parentWindow's textEditorCmdTempl property from the dialog, and
|
|
32
|
+
optionally add dialog to parent's dont_ask_again list, and accept.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
cmdTempl = self.uiTextEditorNewCommandPatternLE.text()
|
|
36
|
+
self.parentWindow.textEditorCmdTempl = cmdTempl
|
|
37
|
+
|
|
38
|
+
if self.uiDontAskAgainCHK.isChecked():
|
|
39
|
+
if hasattr(self.parentWindow, "dont_ask_again"):
|
|
40
|
+
self.parentWindow.dont_ask_again.append(self.objectName())
|
|
41
|
+
|
|
42
|
+
super(SuggestPathQuotesDialog, self).accept()
|
|
43
|
+
|
|
44
|
+
def reject(self):
|
|
45
|
+
"""Optionally add dialog to parentWindow's dont_ask_again list, and reject"""
|
|
46
|
+
if self.uiDontAskAgainCHK.isChecked():
|
|
47
|
+
if hasattr(self.parentWindow, "dont_ask_again"):
|
|
48
|
+
self.parentWindow.dont_ask_again.append(self.objectName())
|
|
49
|
+
|
|
50
|
+
super(SuggestPathQuotesDialog, self).reject()
|