PrEditor 2.1.0__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.
Files changed (179) hide show
  1. preditor/__init__.py +315 -0
  2. preditor/__main__.py +13 -0
  3. preditor/about_module.py +165 -0
  4. preditor/cli.py +192 -0
  5. preditor/config.py +318 -0
  6. preditor/constants.py +13 -0
  7. preditor/contexts.py +210 -0
  8. preditor/cores/__init__.py +0 -0
  9. preditor/cores/core.py +20 -0
  10. preditor/dccs/.hab.json +10 -0
  11. preditor/dccs/maya/PrEditor_maya.mod +1 -0
  12. preditor/dccs/maya/README.md +22 -0
  13. preditor/dccs/maya/plug-ins/PrEditor_maya.py +141 -0
  14. preditor/dccs/studiomax/PackageContents.xml +32 -0
  15. preditor/dccs/studiomax/PrEditor-PrEditor_Show.mcr +8 -0
  16. preditor/dccs/studiomax/README.md +17 -0
  17. preditor/dccs/studiomax/preditor.ms +16 -0
  18. preditor/dccs/studiomax/preditor_menu.mnx +7 -0
  19. preditor/debug.py +149 -0
  20. preditor/delayable_engine/__init__.py +302 -0
  21. preditor/delayable_engine/delayables.py +85 -0
  22. preditor/enum.py +728 -0
  23. preditor/excepthooks.py +165 -0
  24. preditor/gui/__init__.py +56 -0
  25. preditor/gui/app.py +163 -0
  26. preditor/gui/codehighlighter.py +289 -0
  27. preditor/gui/completer.py +237 -0
  28. preditor/gui/console.py +605 -0
  29. preditor/gui/console_base.py +911 -0
  30. preditor/gui/dialog.py +181 -0
  31. preditor/gui/drag_tab_bar.py +625 -0
  32. preditor/gui/editor_chooser.py +57 -0
  33. preditor/gui/errordialog.py +69 -0
  34. preditor/gui/find_files.py +137 -0
  35. preditor/gui/fuzzy_search/__init__.py +0 -0
  36. preditor/gui/fuzzy_search/fuzzy_search.py +97 -0
  37. preditor/gui/group_tab_widget/__init__.py +0 -0
  38. preditor/gui/group_tab_widget/group_tab_widget.py +528 -0
  39. preditor/gui/group_tab_widget/grouped_tab_menu.py +35 -0
  40. preditor/gui/group_tab_widget/grouped_tab_models.py +107 -0
  41. preditor/gui/group_tab_widget/grouped_tab_widget.py +223 -0
  42. preditor/gui/group_tab_widget/one_tab_widget.py +96 -0
  43. preditor/gui/level_buttons.py +358 -0
  44. preditor/gui/logger_window_handler.py +77 -0
  45. preditor/gui/logger_window_plugin.py +35 -0
  46. preditor/gui/loggerwindow.py +2405 -0
  47. preditor/gui/newtabwidget.py +69 -0
  48. preditor/gui/output_console.py +11 -0
  49. preditor/gui/qtdesigner/__init__.py +21 -0
  50. preditor/gui/qtdesigner/_log_plugin.py +29 -0
  51. preditor/gui/qtdesigner/console_base_plugin.py +48 -0
  52. preditor/gui/qtdesigner/console_predit_plugin.py +48 -0
  53. preditor/gui/set_text_editor_path_dialog.py +61 -0
  54. preditor/gui/status_label.py +99 -0
  55. preditor/gui/suggest_path_quotes_dialog.py +50 -0
  56. preditor/gui/ui/editor_chooser.ui +93 -0
  57. preditor/gui/ui/errordialog.ui +74 -0
  58. preditor/gui/ui/find_files.ui +140 -0
  59. preditor/gui/ui/loggerwindow.ui +1909 -0
  60. preditor/gui/ui/set_text_editor_path_dialog.ui +189 -0
  61. preditor/gui/ui/suggest_path_quotes_dialog.ui +225 -0
  62. preditor/gui/window.py +161 -0
  63. preditor/gui/workbox_mixin.py +1139 -0
  64. preditor/gui/workbox_text_edit.py +136 -0
  65. preditor/gui/workboxwidget.py +315 -0
  66. preditor/logging_config.py +55 -0
  67. preditor/osystem.py +401 -0
  68. preditor/plugins.py +118 -0
  69. preditor/prefs.py +381 -0
  70. preditor/resource/environment_variables.html +26 -0
  71. preditor/resource/error_mail.html +85 -0
  72. preditor/resource/error_mail_inline.html +41 -0
  73. preditor/resource/img/README.md +17 -0
  74. preditor/resource/img/arrow_forward.png +0 -0
  75. preditor/resource/img/check-bold.png +0 -0
  76. preditor/resource/img/chevron-down.png +0 -0
  77. preditor/resource/img/chevron-up.png +0 -0
  78. preditor/resource/img/close-thick.png +0 -0
  79. preditor/resource/img/comment-edit.png +0 -0
  80. preditor/resource/img/content-copy.png +0 -0
  81. preditor/resource/img/content-cut.png +0 -0
  82. preditor/resource/img/content-duplicate.png +0 -0
  83. preditor/resource/img/content-paste.png +0 -0
  84. preditor/resource/img/content-save.png +0 -0
  85. preditor/resource/img/debug_disabled.png +0 -0
  86. preditor/resource/img/eye-check.png +0 -0
  87. preditor/resource/img/file-plus.png +0 -0
  88. preditor/resource/img/file-remove.png +0 -0
  89. preditor/resource/img/format-align-left.png +0 -0
  90. preditor/resource/img/format-letter-case-lower.png +0 -0
  91. preditor/resource/img/format-letter-case-upper.png +0 -0
  92. preditor/resource/img/format-letter-case.svg +1 -0
  93. preditor/resource/img/information.png +0 -0
  94. preditor/resource/img/logging_critical.png +0 -0
  95. preditor/resource/img/logging_custom.png +0 -0
  96. preditor/resource/img/logging_debug.png +0 -0
  97. preditor/resource/img/logging_error.png +0 -0
  98. preditor/resource/img/logging_info.png +0 -0
  99. preditor/resource/img/logging_not_set.png +0 -0
  100. preditor/resource/img/logging_warning.png +0 -0
  101. preditor/resource/img/marker.png +0 -0
  102. preditor/resource/img/play.png +0 -0
  103. preditor/resource/img/playlist-play.png +0 -0
  104. preditor/resource/img/plus-minus-variant.png +0 -0
  105. preditor/resource/img/preditor.ico +0 -0
  106. preditor/resource/img/preditor.png +0 -0
  107. preditor/resource/img/preditor.psd +0 -0
  108. preditor/resource/img/preditor.svg +44 -0
  109. preditor/resource/img/regex.svg +1 -0
  110. preditor/resource/img/restart.svg +1 -0
  111. preditor/resource/img/skip-forward-outline.png +0 -0
  112. preditor/resource/img/skip-next-outline.png +0 -0
  113. preditor/resource/img/skip-next.png +0 -0
  114. preditor/resource/img/skip-previous.png +0 -0
  115. preditor/resource/img/subdirectory-arrow-right.png +0 -0
  116. preditor/resource/img/text-search-variant.png +0 -0
  117. preditor/resource/img/warning-big.png +0 -0
  118. preditor/resource/lang/python.json +30 -0
  119. preditor/resource/pref_updates/pref_updates.json +17 -0
  120. preditor/resource/settings.ini +25 -0
  121. preditor/resource/stylesheet/Bright.css +76 -0
  122. preditor/resource/stylesheet/Dark.css +210 -0
  123. preditor/scintilla/__init__.py +40 -0
  124. preditor/scintilla/delayables/__init__.py +11 -0
  125. preditor/scintilla/delayables/smart_highlight.py +97 -0
  126. preditor/scintilla/delayables/spell_check.py +174 -0
  127. preditor/scintilla/documenteditor.py +1924 -0
  128. preditor/scintilla/finddialog.py +68 -0
  129. preditor/scintilla/lang/__init__.py +80 -0
  130. preditor/scintilla/lang/config/bash.ini +15 -0
  131. preditor/scintilla/lang/config/batch.ini +14 -0
  132. preditor/scintilla/lang/config/cpp.ini +19 -0
  133. preditor/scintilla/lang/config/css.ini +19 -0
  134. preditor/scintilla/lang/config/eyeonscript.ini +17 -0
  135. preditor/scintilla/lang/config/html.ini +21 -0
  136. preditor/scintilla/lang/config/javascript.ini +24 -0
  137. preditor/scintilla/lang/config/lua.ini +16 -0
  138. preditor/scintilla/lang/config/maxscript.ini +20 -0
  139. preditor/scintilla/lang/config/mel.ini +18 -0
  140. preditor/scintilla/lang/config/mu.ini +22 -0
  141. preditor/scintilla/lang/config/nsi.ini +19 -0
  142. preditor/scintilla/lang/config/perl.ini +19 -0
  143. preditor/scintilla/lang/config/puppet.ini +19 -0
  144. preditor/scintilla/lang/config/python.ini +28 -0
  145. preditor/scintilla/lang/config/ruby.ini +19 -0
  146. preditor/scintilla/lang/config/sql.ini +7 -0
  147. preditor/scintilla/lang/config/xml.ini +21 -0
  148. preditor/scintilla/lang/config/yaml.ini +18 -0
  149. preditor/scintilla/lang/language.py +240 -0
  150. preditor/scintilla/lexers/__init__.py +0 -0
  151. preditor/scintilla/lexers/cpplexer.py +22 -0
  152. preditor/scintilla/lexers/javascriptlexer.py +27 -0
  153. preditor/scintilla/lexers/maxscriptlexer.py +235 -0
  154. preditor/scintilla/lexers/mellexer.py +369 -0
  155. preditor/scintilla/lexers/mulexer.py +33 -0
  156. preditor/scintilla/lexers/pythonlexer.py +42 -0
  157. preditor/scintilla/ui/finddialog.ui +160 -0
  158. preditor/settings.py +71 -0
  159. preditor/stream/__init__.py +72 -0
  160. preditor/stream/console_handler.py +169 -0
  161. preditor/stream/director.py +144 -0
  162. preditor/stream/manager.py +97 -0
  163. preditor/streamhandler_helper.py +46 -0
  164. preditor/utils/__init__.py +191 -0
  165. preditor/utils/call_stack.py +86 -0
  166. preditor/utils/cute.py +106 -0
  167. preditor/utils/stylesheets.py +54 -0
  168. preditor/utils/text_search.py +338 -0
  169. preditor/version.py +34 -0
  170. preditor/weakref.py +363 -0
  171. preditor-2.1.0.dist-info/METADATA +308 -0
  172. preditor-2.1.0.dist-info/RECORD +179 -0
  173. preditor-2.1.0.dist-info/WHEEL +5 -0
  174. preditor-2.1.0.dist-info/entry_points.txt +19 -0
  175. preditor-2.1.0.dist-info/licenses/LICENSE +165 -0
  176. preditor-2.1.0.dist-info/top_level.txt +3 -0
  177. tests/encodings/test_ecoding.py +33 -0
  178. tests/find_files/test_find_files.py +74 -0
  179. tests/ide/test_delayable_engine.py +171 -0
preditor/prefs.py ADDED
@@ -0,0 +1,381 @@
1
+ """
2
+ Module for handling user interface preferences
3
+
4
+ """
5
+ from __future__ import absolute_import
6
+
7
+ import datetime
8
+ import json
9
+ import os
10
+ import re
11
+ import shutil
12
+ import sys
13
+ from pathlib import Path
14
+
15
+ import six
16
+
17
+ from . import resourcePath, utils
18
+
19
+ # cache of all the preferences
20
+ _cache = {}
21
+
22
+ DATETIME_FORMAT = "%Y-%m-%d-%H-%M-%S-%f"
23
+ DATETIME_PATTERN = re.compile(r"\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}-\d{6}")
24
+
25
+
26
+ class VersionTypes:
27
+ """Nice names for the workbox version types."""
28
+
29
+ First = 0
30
+ Previous = 1
31
+ Next = 2
32
+ TwoBeforeLast = 3
33
+ Last = 4
34
+
35
+
36
+ def backup():
37
+ """Saves a copy of the current preferences to a zip archive."""
38
+ import glob
39
+ import shutil
40
+
41
+ archive_base = "preditor_backup_"
42
+ # Save all prefs not just the current core_name.
43
+ prefs = prefs_path()
44
+ # Note: Using parent dir of prefs so we can use shutil.make_archive without
45
+ # backing up the previous backups.
46
+ parent_dir = os.path.join(os.path.dirname(prefs), "_backups")
47
+
48
+ # Get the next backup version number to use.
49
+ filenames = glob.glob(os.path.join(parent_dir, "{}*.zip".format(archive_base)))
50
+ version = 1
51
+ if filenames:
52
+ # Add one to the largest version that exists on disk.
53
+ version = int(os.path.splitext(max(filenames))[0].split(archive_base)[-1])
54
+ version += 1
55
+
56
+ # Build the file path to save the archive to.
57
+ archive_base = os.path.join(parent_dir, archive_base + "{:04}".format(version))
58
+
59
+ # Save the preferences to the given archive name.
60
+ zip_path = shutil.make_archive(archive_base, "zip", prefs)
61
+
62
+ return zip_path
63
+
64
+
65
+ def browse(core_name):
66
+ from . import osystem
67
+
68
+ path = prefs_path(core_name)
69
+ osystem.explore(path)
70
+
71
+
72
+ def existing():
73
+ """Returns a list of PrEditor preference path names that exist on disk."""
74
+ root = prefs_path()
75
+ return sorted(next(os.walk(root))[1], key=lambda i: i.lower())
76
+
77
+
78
+ def get_full_path(core_name, workbox_id, backup_file=None):
79
+ """Get the full path for the given workbox_id in the given core. If
80
+ backup_file is provided, use that.
81
+
82
+ Args:
83
+ core_name (str): The current core_name
84
+ workbox_id (str): The current workbox_id
85
+ backup_file (str, optional): The backup_file (ie with time stamped path)
86
+
87
+ Returns:
88
+ full_path (str): The constructed full path
89
+ """
90
+ workbox_dir = get_prefs_dir(core_name)
91
+ workbox_dir = get_prefs_dir(core_name=core_name)
92
+ if backup_file:
93
+ full_path = Path(workbox_dir) / backup_file
94
+ else:
95
+ full_path = Path(workbox_dir) / workbox_id / workbox_id
96
+ full_path = str(full_path.with_suffix(".py"))
97
+ return full_path
98
+
99
+
100
+ def get_relative_path(core_name, path):
101
+ """Get the file path relative to the current core's prefs path. If path is
102
+ not relative to working_dir, return the original path
103
+
104
+ Args:
105
+ core_name (str): The current core_name
106
+ path (str): The full path
107
+
108
+ Returns:
109
+ rel_path (rel_path): The determined relative path.
110
+ """
111
+ workbox_dir = get_prefs_dir(core_name)
112
+ workbox_dir = get_prefs_dir(core_name=core_name)
113
+ try:
114
+ rel_path = str(Path(path).relative_to(workbox_dir))
115
+ except ValueError:
116
+ rel_path = path
117
+ return rel_path
118
+
119
+
120
+ def prefs_path(filename=None, core_name=None):
121
+ """The path PrEditor's preferences are saved as a json file.
122
+
123
+ The enviroment variable `PREDITOR_PREF_PATH` is used if set, otherwise
124
+ it is saved in one of the user folders.
125
+ """
126
+ if "PREDITOR_PREF_PATH" in os.environ:
127
+ ret = os.environ["PREDITOR_PREF_PATH"]
128
+ else:
129
+ if sys.platform == "win32":
130
+ ret = "%appdata%/blur/preditor"
131
+ else:
132
+ ret = "$HOME/.blur/preditor"
133
+ ret = os.path.normpath(os.path.expandvars(os.path.expanduser(ret)))
134
+ if core_name:
135
+ ret = os.path.join(ret, core_name)
136
+ if filename:
137
+ ret = os.path.join(ret, filename)
138
+ return ret
139
+
140
+
141
+ def get_prefs_dir(sub_dir='workboxes', core_name=None, create=False):
142
+ """Get the prefs path including the given sub directory, and optionally
143
+ create the file on disk.
144
+
145
+ Args:
146
+ sub_dir (str, optional): The needed sub directory, defaults to 'workboxes'
147
+ core_name (str, optional): The current core_name
148
+ create (bool, optional): Whether to create directories on disk
149
+
150
+ Returns:
151
+ prefs_dir (str): The determined path
152
+ """
153
+ prefs_dir = prefs_path(sub_dir, core_name=core_name)
154
+ if create:
155
+ Path(prefs_dir).mkdir(parents=True, exist_ok=True)
156
+ return prefs_dir
157
+
158
+
159
+ def create_stamped_path(core_name, filepath, sub_dir='workboxes', time_str=None):
160
+ """For the given filepath, generate a filepath which includes a time stamp,
161
+ which is either based on the current time, or passed explicitly (ie to
162
+ re-order backups when prefs are saved in another instance of PrEditor in the
163
+ same core.
164
+
165
+ Args:
166
+ core_name (str): The current core_name
167
+ filepath (str): The filepath we need to create a time-stamped path for
168
+ sub_dir (str, optional): The needed sub directory, defaults to 'workboxes'
169
+ time_str (None, optional): A specific time-stamp to use, otherwise generate
170
+ a new one from current time.
171
+
172
+ Returns:
173
+ path (str): The created stamped path
174
+ """
175
+ path = Path(get_prefs_dir(sub_dir=sub_dir, core_name=core_name, create=True))
176
+ filepath = Path(filepath)
177
+ stem = filepath.stem
178
+ name = filepath.name
179
+ suffix = filepath.suffix or ".py"
180
+
181
+ if sub_dir == "workboxes":
182
+ path = path / stem
183
+
184
+ if not time_str:
185
+ now = datetime.datetime.now()
186
+ time_str = now.strftime(DATETIME_FORMAT)
187
+ name = "{}-{}".format(stem, time_str)
188
+
189
+ path = path / name
190
+ path = path.with_suffix(suffix)
191
+
192
+ path.parent.mkdir(exist_ok=True)
193
+
194
+ path = six.text_type(path)
195
+ return path
196
+
197
+
198
+ def get_file_group(core_name, workbox_id):
199
+ """Get the backup files for the given workbox_id, for the given core_name
200
+
201
+ Args:
202
+ core_name (str): The current core_name
203
+ workbox_id (str): The current workbox_id
204
+
205
+ Returns:
206
+ files (list): The list of files found for the given workbox_id
207
+ """
208
+ directory = Path(get_prefs_dir(core_name=core_name, sub_dir='workboxes'))
209
+ workbox_dir = directory / workbox_id
210
+ workbox_dir.mkdir(exist_ok=True)
211
+ files = sorted(list(workbox_dir.iterdir()))
212
+ return files
213
+
214
+
215
+ def get_backup_file_index_and_count(core_name, workbox_id, backup_file, files=None):
216
+ """For the given core_name and workbox_id, find the (zero-based)index
217
+ backup_file is within that workbox's backup files, plus the total count of
218
+ backup files.
219
+
220
+ Args:
221
+ core_name (str): The current core_name
222
+ workbox_id (str): The current workbox_id
223
+ backup_file (None, optional): The currently loaded backup file.
224
+ files (None, optional): If we already found the files on disk, pass them
225
+ in here
226
+ Returns:
227
+ idx, count (int, int): The zero-based index of backup_file, and file count
228
+ """
229
+ idx = None
230
+ files = files or get_file_group(core_name, workbox_id)
231
+ count = len(files)
232
+ if not files:
233
+ return None, None
234
+
235
+ backup_file = Path(backup_file) if backup_file else None
236
+ if not backup_file:
237
+ return None, None
238
+
239
+ backup_file = get_full_path(core_name, workbox_id, backup_file)
240
+ backup_file = Path(backup_file)
241
+
242
+ if backup_file in files:
243
+ idx = files.index(backup_file)
244
+ return idx, count
245
+
246
+
247
+ def get_backup_version_info(core_name, workbox_id, versionType, backup_file=None):
248
+ """For the given core_name and workbox_id, find the filename based on versionType,
249
+ potentially relative to backup_file . Include the (one-based) index filename is
250
+ within that workbox's backup files, plus the total count of backup files.
251
+
252
+ Args:
253
+ core_name (str): The current core_name
254
+ workbox_id (str): The current workbox_id
255
+ versionType (VersionType): The VersionType (ie First, Previous, Next, Last)
256
+ backup_file (None, optional): The currently loaded backup file.
257
+
258
+ Returns:
259
+ filepath, display_idx, count (str, int, int): The found filepath, it's
260
+ (one-based) index within backup files, but count of backup files.
261
+ """
262
+ files = get_file_group(core_name, workbox_id)
263
+ if not files:
264
+ return ("", "", 0)
265
+ count = len(files)
266
+
267
+ idx = len(files) - 1
268
+ if versionType == VersionTypes.First:
269
+ idx = 0
270
+ elif versionType == VersionTypes.Last:
271
+ idx = len(files) - 1
272
+ else:
273
+ idx, count = get_backup_file_index_and_count(
274
+ core_name, workbox_id, backup_file, files=files
275
+ )
276
+ if idx is not None:
277
+ if versionType == VersionTypes.TwoBeforeLast:
278
+ idx -= 2
279
+ idx = max(idx, 0)
280
+ elif versionType == VersionTypes.Previous:
281
+ idx -= 1
282
+ idx = max(idx, 0)
283
+ elif versionType == VersionTypes.Next:
284
+ idx += 1
285
+ idx = min(idx, count - 1)
286
+
287
+ filepath = six.text_type(files[idx])
288
+ display_idx = idx + 1
289
+ return filepath, display_idx, count
290
+
291
+
292
+ def get_prefs_updates():
293
+ """Get any defined updates to prefs args / values
294
+
295
+ Returns:
296
+ updates (dict): The dict of defined updates
297
+ """
298
+ updates = {}
299
+ path = resourcePath(r"pref_updates\pref_updates.json")
300
+ try:
301
+ updates = utils.Json(path).load()
302
+ except (FileNotFoundError, json.decoder.JSONDecodeError):
303
+ pass
304
+ return updates
305
+
306
+
307
+ def update_pref_args(core_name, pref_dict, old_name, update_data):
308
+ """Update an individual pref name and/or value.
309
+
310
+ Args:
311
+ core_name (str): The current core_name
312
+ pref_dict (dict): The pref to update
313
+ old_name (str): Original pref name, which may be updated
314
+ update_data (str): Dict to define ways to update the values, which
315
+ currently only supports str.replace.
316
+ """
317
+ workbox_dir = Path(get_prefs_dir(core_name=core_name, create=True))
318
+
319
+ if old_name == "tempfile":
320
+ orig_pref = pref_dict.get(old_name)
321
+ else:
322
+ orig_pref = pref_dict.pop(old_name)
323
+ pref = orig_pref[:] if isinstance(orig_pref, list) else orig_pref
324
+
325
+ if isinstance(pref, six.text_type):
326
+ replacements = update_data.get("replace", [])
327
+ for replacement in replacements:
328
+ pref = pref.replace(*replacement)
329
+
330
+ existing_backup_file = pref_dict.get("backup_file", None)
331
+ if not existing_backup_file and old_name == "tempfile":
332
+ newfilepath = create_stamped_path(core_name, pref)
333
+ orig_filepath = workbox_dir / orig_pref
334
+ if orig_filepath.is_file():
335
+ orig_filepath = six.text_type(orig_filepath)
336
+
337
+ if not Path(newfilepath).is_file():
338
+ shutil.copy(orig_filepath, newfilepath)
339
+ newfilepath = six.text_type(Path(newfilepath).relative_to(workbox_dir))
340
+
341
+ pref_dict.update({"backup_file": newfilepath})
342
+
343
+ pref_name = old_name
344
+ if isinstance(update_data, dict):
345
+ pref_name = update_data.get("new_name", old_name)
346
+
347
+ pref_dict.update({pref_name: pref})
348
+
349
+
350
+ def update_prefs_args(core_name, prefs_dict, prefs_updates):
351
+ """Update all the PrEditor prefs, as defined in prefs_updates
352
+
353
+ Args:
354
+ core_name (str): The current core_name
355
+ prefs_dict (dict): The PrEditor prefs to update
356
+ prefs_updates (dict): The update definition dict
357
+
358
+ Returns:
359
+ prefs_dict (dict): The updated dict
360
+ """
361
+
362
+ # Check if we have already updated to this prefs_update version
363
+ update_version = prefs_updates.get("prefs_version", 1.0)
364
+
365
+ for old_name, data in prefs_updates.items():
366
+ if old_name not in prefs_dict:
367
+ continue
368
+
369
+ if old_name == "workbox_prefs":
370
+ for sub_old_name, sub_data in prefs_updates["workbox_prefs"].items():
371
+ for group_dict in prefs_dict["workbox_prefs"]["groups"]:
372
+ for tab_dict in group_dict["tabs"]:
373
+ if sub_old_name not in tab_dict:
374
+ continue
375
+ update_pref_args(core_name, tab_dict, sub_old_name, sub_data)
376
+ else:
377
+ update_pref_args(core_name, prefs_dict, old_name, data)
378
+
379
+ prefs_dict["prefs_version"] = update_version
380
+
381
+ return prefs_dict
@@ -0,0 +1,26 @@
1
+ <html>
2
+ <head/>
3
+ <body>
4
+ <h1>blurdev</h1>
5
+ <hr>
6
+ <h2>blurdev Site variables:</h2>
7
+ <p><span style=" font-style:italic;">These variables should be defined at a user or system level to configure blurdev.</span></p>
8
+ <p><span style=" font-weight:bold;">BDEV_DESIGNERPLUG_*:</span> Used to add a collection of designer plugins to QDesigner. Should be set to "XMLPATH,MODULE_DIR". XMLPATH is the full path to a xml file listing plugins to load. MODULE_DIR is a path that needs added to sys.path so the modules in XMLPATH are importable. You can use environment variables in these strings, they will be expanded. This is used by QDesigner, nothing else.</p>
9
+ <p><span style=" font-weight:bold;">BDEV_OFFLINE:</span> If set to 1, this indicates that blurdev is not running on the "Blur" network. This causes the [* Offline] section of blurdev/resource/settings.ini to override the [Default] and [*] sections. When blurdev is imported it adds all env vars defined in settings.ini for the current operating system and Default if they are not already defined in os.environ.</p>
10
+ <p><span style=" font-weight:bold;">BDEV_PATH_PREFS:</span> This environment variable points to where per-computer user prefs are stored.</p>
11
+ <p><span style=" font-weight:bold;">BDEV_PATH_PREFS_SHARED:</span> This environment variable points to where shared user prefs are stored. This is often on the network and includes the os's logged in username in the path. If BDEV_OFFLINE is set to 1 this may point to the BDEV_PATH_PREFS location.</p>
12
+ <p></p>
13
+ <h2>blurdev Temp variables:</h2>
14
+ <p><span style=" font-style:italic;">These variables should not be defined all the time.</span></p>
15
+ <p><span style=" font-weight:bold;">BDEV_DISABLE_AUTORUN:</span> Set to "true" to disable the autorun.bat script used at blur. If this is not set when Maya shuts down, maya takes minutes to close. Maya uses several subprocess calls when closing and for some reason the doskey calls in the script take much longer than normal.</p>
16
+ <p><span style=" font-weight:bold;">BDEV_STYLESHEET:</span> Used to override the stylesheet when initalizing blurdev.</p>
17
+ <p><span style=" font-weight:bold;">BDEV_TOOL_ENVIRONMENT:</span> Forces blurdev to initialize with this treegrunt environment name. When saving prefs, this environment name change will not be saved. This is mostly used to ensure that launching a subprocess or farm job happens on the same treegrunt environment.</p>
18
+ <p></p>
19
+ <h1>trax</h1>
20
+ <hr>
21
+ <p><span style=" font-weight:bold;">TRAX_SPOOL_DIRECTORY_OVERRIDE:</span> If defined, all messages will be stored the directory of this variable. Each message filename will have a "[mapping.mount()]_" prefix added giving you a hint to which server it would have ended up on. Defining this variable effectively disables all spool messages, and gives you a way to see what each spool message would look like. If your code depends on trax.api.spool.waitForCompletion, it will never complete.</p>
22
+ <h1>Notes</h1>
23
+ <hr>
24
+ <p>Any variable names containing a * are wildcards. This allows you to add as many instances of that environment variable type as needed.</p>
25
+ </body>
26
+ </html>
@@ -0,0 +1,85 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <style>
5
+ body {
6
+ font-family: Verdana, sans-serif;
7
+ font-size: 12px;
8
+ color: #484848;
9
+ background: white;
10
+ }
11
+ p {
12
+ margin: 0;
13
+ padding: 0;
14
+ }
15
+ h1, h2, h3 {
16
+ font-family: "Trebuchet MS", Verdana, sans-serif;
17
+ margin: 0 0 10px 0;
18
+ padding: 0;
19
+ }
20
+ h1 {
21
+ font-size: 16px;
22
+ }
23
+ h2 {
24
+ font-size: 15px;
25
+ }
26
+ h3 {
27
+ font-size: 14px;
28
+ }
29
+ ul {
30
+ margin: 0 0 10px 10px;
31
+ padding: 0;
32
+ list-style: none;
33
+ }
34
+ li {
35
+ margin: 0;
36
+ padding: 0;
37
+ }
38
+ .information, .traceback, .error_report, .footer {
39
+ margin: 0;
40
+ padding: 0;
41
+ }
42
+ .footer {
43
+ border-top: solid black 1px;
44
+ padding: 10px 0 0 0;
45
+ }
46
+ </style>
47
+ </head>
48
+ <body>
49
+ <h1>{{ subject }}</h1>
50
+ <div class="information">
51
+ <h2>Debug Information</h2>
52
+
53
+ {% for label, section_dict in info_dict.items() %}
54
+ <h3>{{ label }}</h3>
55
+ <ul>
56
+ {% for key, value in section_dict.items() %}
57
+ <li><span style="font-weight:bold">{{ key }}:</span> {{ value }}</li>
58
+ {% endfor %}
59
+ </ul>
60
+ {% endfor %}
61
+
62
+ </div>
63
+ <div class="traceback">
64
+ <h2>Trackback</h2>
65
+ {{ highlight_code(traceback) }}
66
+ </div>
67
+
68
+ {% if error_report %}
69
+ <div class="error_report">
70
+ <h2>Error Reports</h2>
71
+
72
+ {% for title, report in error_report %}
73
+ <h3>{{ title }}</h3>
74
+ {{ highlight_code(report) }}
75
+ {% endfor %}
76
+ </div>
77
+ {% endif %}
78
+
79
+ <div class="footer">
80
+ <p class="send_time">{{ send_time }}</p>
81
+ <p>You received this notification because you have either subscribed to it, or are involved in it.</p>
82
+ <p>To change your notification preferences, go into trax and change your options settings.</p>
83
+ </div>
84
+ </body>
85
+ </html>
@@ -0,0 +1,41 @@
1
+ <!-- AUTOGENERATED FROM 'error_mail.html' (see: https://inliner.cm/) -->
2
+ <!DOCTYPE html>
3
+ <html lang="en">
4
+ <body style="font-family:Verdana, sans-serif;font-size:12px;color:#484848;background-color:white;background-image:none;background-repeat:repeat;background-position:top left;background-attachment:scroll;" >
5
+ <h1 style="font-family:'Trebuchet MS', Verdana, sans-serif;margin-top:0;margin-bottom:10px;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-size:16px;" >{{ subject }}</h1>
6
+ <div class="information" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
7
+ <h2 style="font-family:'Trebuchet MS', Verdana, sans-serif;margin-top:0;margin-bottom:10px;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-size:15px;" >Debug Information</h2>
8
+
9
+ {% for label, section_dict in info_dict.items() %}
10
+ <h3 style="font-family:'Trebuchet MS', Verdana, sans-serif;margin-top:0;margin-bottom:10px;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-size:14px;" >{{ label }}</h3>
11
+ <ul style="margin-top:0;margin-bottom:10px;margin-right:0;margin-left:10px;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;list-style-type:none;list-style-position:outside;list-style-image:none;" >
12
+ {% for key, value in section_dict.items() %}
13
+ <li style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" ><span style="font-weight:bold;" >{{ key }}:</span> {{ value }}</li>
14
+ {% endfor %}
15
+ </ul>
16
+ {% endfor %}
17
+
18
+ </div>
19
+ <div class="traceback" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
20
+ <h2 style="font-family:'Trebuchet MS', Verdana, sans-serif;margin-top:0;margin-bottom:10px;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-size:15px;" >Trackback</h2>
21
+ {{ highlight_code(traceback) }}
22
+ </div>
23
+
24
+ {% if error_report %}
25
+ <div class="error_report" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
26
+ <h2 style="font-family:'Trebuchet MS', Verdana, sans-serif;margin-top:0;margin-bottom:10px;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-size:15px;" >Error Reports</h2>
27
+
28
+ {% for title, report in error_report %}
29
+ <h3 style="font-family:'Trebuchet MS', Verdana, sans-serif;margin-top:0;margin-bottom:10px;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-size:14px;" >{{ title }}</h3>
30
+ {{ highlight_code(report) }}
31
+ {% endfor %}
32
+ </div>
33
+ {% endif %}
34
+
35
+ <div class="footer" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;border-top-width:1px;border-top-style:solid;border-top-color:black;padding-top:10px;padding-bottom:0;padding-right:0;padding-left:0;" >
36
+ <p class="send_time" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >{{ send_time }}</p>
37
+ <p style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >You received this notification because you have either subscribed to it, or are involved in it.</p>
38
+ <p style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >To change your notification preferences, go into trax and change your options settings.</p>
39
+ </div>
40
+ </body>
41
+ </html>
@@ -0,0 +1,17 @@
1
+ # Preditor icon build from these source images
2
+
3
+ * Predator Icon: https://icon-icons.com/icon/predator/54149
4
+ * Pencil Icon: https://icon-icons.com/icon/pencil/73779
5
+ Converted to multi-resolution icon using: https://convertico.com/svg-to-ico/
6
+
7
+ Most other icons downloaded from https://materialdesignicons.com/.
8
+
9
+ Svg icons are preferred as they are plain text files that play nicely with git.
10
+ Please make sure to update the sources table when adding or updating images.
11
+
12
+ # Sources for resources
13
+
14
+ | File | Source | Notes | Author |
15
+ |---|---|---|---|
16
+ | ![](preditor/resource/img/format-letter-case.svg) [format-letter-case.svg](preditor/resource/img/format-letter-case.svg) | https://pictogrammers.com/library/mdi/icon/format-letter-case/ | | [Austin Andrews](https://pictogrammers.com/contributor/Templarian/) |
17
+ | ![](preditor/resource/img/regex.svg) [regex.svg](preditor/resource/img/regex.svg) | https://pictogrammers.com/library/mdi/icon/regex/ | | [Doug C. Hardester](https://pictogrammers.com/contributor/r3volution11/) |
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.06,18C20,17.83 19.91,17.54 19.86,17.11C19.19,17.81 18.38,18.16 17.45,18.16C16.62,18.16 15.93,17.92 15.4,17.45C14.87,17 14.6,16.39 14.6,15.66C14.6,14.78 14.93,14.1 15.6,13.61C16.27,13.12 17.21,12.88 18.43,12.88H19.83V12.24C19.83,11.75 19.68,11.36 19.38,11.07C19.08,10.78 18.63,10.64 18.05,10.64C17.53,10.64 17.1,10.76 16.75,11C16.4,11.25 16.23,11.54 16.23,11.89H14.77C14.77,11.46 14.92,11.05 15.22,10.65C15.5,10.25 15.93,9.94 16.44,9.71C16.95,9.5 17.5,9.36 18.13,9.36C19.11,9.36 19.87,9.6 20.42,10.09C20.97,10.58 21.26,11.25 21.28,12.11V16C21.28,16.8 21.38,17.42 21.58,17.88V18H20.06M17.66,16.88C18.11,16.88 18.54,16.77 18.95,16.56C19.35,16.35 19.65,16.07 19.83,15.73V14.16H18.7C16.93,14.16 16.04,14.63 16.04,15.57C16.04,16 16.19,16.3 16.5,16.53C16.8,16.76 17.18,16.88 17.66,16.88M5.46,13.71H9.53L7.5,8.29L5.46,13.71M6.64,6H8.36L13.07,18H11.14L10.17,15.43H4.82L3.86,18H1.93L6.64,6Z" /></svg>
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file