1 | """ |
||
2 | Orange Canvas Configuration |
||
3 | |||
4 | """ |
||
5 | |||
6 | import os |
||
7 | import sys |
||
8 | import logging |
||
9 | import pickle as pickle |
||
10 | import itertools |
||
11 | |||
12 | import pkg_resources |
||
13 | |||
14 | from PyQt4.QtGui import ( |
||
0 ignored issues
–
show
|
|||
15 | QPainter, QFont, QFontMetrics, QColor, QPixmap, QIcon |
||
16 | ) |
||
17 | |||
18 | from PyQt4.QtCore import Qt, QCoreApplication, QPoint, QRect |
||
0 ignored issues
–
show
The import
PyQt4.QtCore could not be resolved.
This can be caused by one of the following: 1. Missing DependenciesThis error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands. # .scrutinizer.yml
before_commands:
- sudo pip install abc # Python2
- sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use
the command for the correct version.
2. Missing __init__.py filesThis error could also result from missing ![]() |
|||
19 | |||
20 | from .utils.settings import Settings, config_slot |
||
21 | |||
22 | # Import QSettings from qtcompat module (compatibility with PyQt < 4.8.3 |
||
23 | from .utils.qtcompat import QSettings |
||
24 | |||
25 | log = logging.getLogger(__name__) |
||
26 | |||
27 | |||
28 | def init(): |
||
0 ignored issues
–
show
|
|||
29 | """ |
||
30 | Initialize the QCoreApplication.organizationDomain, applicationName, |
||
31 | applicationVersion and the default settings format. Will only run once. |
||
32 | |||
33 | .. note:: This should not be run before QApplication has been initialized. |
||
34 | Otherwise it can break Qt's plugin search paths. |
||
35 | |||
36 | """ |
||
37 | dist = pkg_resources.get_distribution("Orange") |
||
38 | version = dist.version |
||
39 | # Use only major.minor |
||
40 | version = ".".join(version.split(".", 2)[:2]) |
||
41 | |||
42 | QCoreApplication.setOrganizationDomain("biolab.si") |
||
43 | QCoreApplication.setApplicationName("Orange Canvas") |
||
44 | QCoreApplication.setApplicationVersion(version) |
||
45 | QSettings.setDefaultFormat(QSettings.IniFormat) |
||
46 | |||
47 | # Make it a null op. |
||
48 | global init |
||
0 ignored issues
–
show
|
|||
49 | init = lambda: None |
||
50 | |||
51 | rc = {} |
||
52 | |||
53 | |||
54 | spec = \ |
||
55 | [("startup/show-splash-screen", bool, True, |
||
56 | "Show splash screen at startup"), |
||
57 | |||
58 | ("startup/show-welcome-screen", bool, True, |
||
59 | "Show Welcome screen at startup"), |
||
60 | |||
61 | ("stylesheet", str, "orange", |
||
62 | "QSS stylesheet to use"), |
||
63 | |||
64 | ("schemeinfo/show-at-new-scheme", bool, True, |
||
65 | "Show Workflow Properties when creating a new Workflow"), |
||
66 | |||
67 | ("mainwindow/scheme-margins-enabled", bool, False, |
||
68 | "Show margins around the workflow view"), |
||
69 | |||
70 | ("mainwindow/show-scheme-shadow", bool, True, |
||
71 | "Show shadow around the workflow view"), |
||
72 | |||
73 | ("mainwindow/toolbox-dock-exclusive", bool, True, |
||
74 | "Should the toolbox show only one expanded category at the time"), |
||
75 | |||
76 | ("mainwindow/toolbox-dock-floatable", bool, False, |
||
77 | "Is the canvas toolbox floatable (detachable from the main window)"), |
||
78 | |||
79 | ("mainwindow/toolbox-dock-movable", bool, True, |
||
80 | "Is the canvas toolbox movable (between left and right edge)"), |
||
81 | |||
82 | ("mainwindow/toolbox-dock-use-popover-menu", bool, True, |
||
83 | "Use a popover menu to select a widget when clicking on a category " |
||
84 | "button"), |
||
85 | |||
86 | ("mainwindow/number-of-recent-schemes", int, 15, |
||
87 | "Number of recent workflows to keep in history"), |
||
88 | |||
89 | ("schemeedit/show-channel-names", bool, True, |
||
90 | "Show channel names"), |
||
91 | |||
92 | ("schemeedit/show-link-state", bool, True, |
||
93 | "Show link state hints."), |
||
94 | |||
95 | ("schemeedit/enable-node-animations", bool, True, |
||
96 | "Enable node animations."), |
||
97 | |||
98 | ("schemeedit/freeze-on-load", bool, False, |
||
99 | "Freeze signal propagation when loading a workflow."), |
||
100 | |||
101 | ("quickmenu/trigger-on-double-click", bool, True, |
||
102 | "Show quick menu on double click."), |
||
103 | |||
104 | ("quickmenu/trigger-on-right-click", bool, True, |
||
105 | "Show quick menu on right click."), |
||
106 | |||
107 | ("quickmenu/trigger-on-space-key", bool, True, |
||
108 | "Show quick menu on space key press."), |
||
109 | |||
110 | ("quickmenu/trigger-on-any-key", bool, False, |
||
111 | "Show quick menu on double click."), |
||
112 | |||
113 | ("logging/level", int, 1, "Logging level"), |
||
114 | |||
115 | ("logging/show-on-error", bool, True, "Show log window on error"), |
||
116 | |||
117 | ("logging/dockable", bool, True, "Allow log window to be docked"), |
||
118 | |||
119 | ("output/redirect-stderr", bool, True, |
||
120 | "Redirect and display standard error output"), |
||
121 | |||
122 | ("output/redirect-stdout", bool, True, |
||
123 | "Redirect and display standard output"), |
||
124 | |||
125 | ("output/stay-on-top", bool, True, ""), |
||
126 | |||
127 | ("output/show-on-error", bool, True, "Show output window on error"), |
||
128 | |||
129 | ("output/dockable", bool, True, "Allow output window to be docked"), |
||
130 | |||
131 | ("help/stay-on-top", bool, True, ""), |
||
132 | |||
133 | ("help/dockable", bool, True, "Allow help window to be docked"), |
||
134 | |||
135 | ("help/open-in-external-browser", bool, False, |
||
136 | "Open help in an external browser") |
||
137 | ] |
||
138 | |||
139 | spec = [config_slot(*t) for t in spec] |
||
140 | |||
141 | |||
142 | def settings(): |
||
143 | init() |
||
144 | store = QSettings() |
||
145 | settings = Settings(defaults=spec, store=store) |
||
0 ignored issues
–
show
settings is re-defining a name which is already available in the outer-scope (previously defined on line 142 ).
It is generally a bad practice to shadow variables from the outer-scope. In most cases, this is done unintentionally and might lead to unexpected behavior: param = 5
class Foo:
def __init__(self, param): # "param" would be flagged here
self.param = param
![]() |
|||
146 | return settings |
||
147 | |||
148 | |||
149 | def data_dir(): |
||
150 | """Return the application data directory. If the directory path |
||
151 | does not yet exists then create it. |
||
152 | |||
153 | """ |
||
154 | from Orange.misc import environ |
||
155 | path = os.path.join(environ.data_dir(), "canvas") |
||
156 | |||
157 | if not os.path.isdir(path): |
||
158 | os.makedirs(path, exist_ok=True) |
||
159 | return path |
||
160 | |||
161 | |||
162 | def cache_dir(): |
||
163 | """Return the application cache directory. If the directory path |
||
164 | does not yet exists then create it. |
||
165 | |||
166 | """ |
||
167 | from Orange.misc import environ |
||
168 | path = os.path.join(environ.cache_dir(), "canvas") |
||
169 | |||
170 | if not os.path.isdir(path): |
||
171 | os.makedirs(path, exist_ok=True) |
||
172 | return path |
||
173 | |||
174 | |||
175 | def log_dir(): |
||
176 | """ |
||
177 | Return the application log directory. |
||
178 | """ |
||
179 | init() |
||
180 | if sys.platform == "darwin": |
||
181 | name = str(QCoreApplication.applicationName()) |
||
182 | logdir = os.path.join(os.path.expanduser("~/Library/Logs"), name) |
||
183 | else: |
||
184 | logdir = data_dir() |
||
185 | |||
186 | if not os.path.exists(logdir): |
||
187 | os.makedirs(logdir) |
||
188 | return logdir |
||
189 | |||
190 | |||
191 | def widget_settings_dir(): |
||
192 | """ |
||
193 | Return the widget settings directory. |
||
194 | """ |
||
195 | from Orange.misc import environ |
||
196 | return environ.widget_settings_dir() |
||
197 | |||
198 | |||
199 | def open_config(): |
||
200 | global rc |
||
0 ignored issues
–
show
|
|||
201 | app_dir = data_dir() |
||
202 | filename = os.path.join(app_dir, "canvas-rc.pck") |
||
203 | if os.path.exists(filename): |
||
204 | with open(os.path.join(app_dir, "canvas-rc.pck"), "rb") as f: |
||
205 | rc.update(pickle.load(f)) |
||
206 | |||
207 | |||
208 | def save_config(): |
||
209 | app_dir = data_dir() |
||
210 | with open(os.path.join(app_dir, "canvas-rc.pck"), "wb") as f: |
||
211 | pickle.dump(rc, f) |
||
212 | |||
213 | |||
214 | def recent_schemes(): |
||
215 | """Return a list of recently accessed schemes. |
||
216 | """ |
||
217 | app_dir = data_dir() |
||
218 | recent_filename = os.path.join(app_dir, "recent.pck") |
||
219 | recent = [] |
||
220 | if os.path.isdir(app_dir) and os.path.isfile(recent_filename): |
||
221 | with open(recent_filename, "rb") as f: |
||
222 | recent = pickle.load(f) |
||
223 | |||
224 | # Filter out files not found on the file system |
||
225 | recent = [(title, path) for title, path in recent \ |
||
226 | if os.path.exists(path)] |
||
227 | return recent |
||
228 | |||
229 | |||
230 | def save_recent_scheme_list(scheme_list): |
||
231 | """Save the list of recently accessed schemes |
||
232 | """ |
||
233 | app_dir = data_dir() |
||
234 | recent_filename = os.path.join(app_dir, "recent.pck") |
||
235 | |||
236 | if os.path.isdir(app_dir): |
||
237 | with open(recent_filename, "wb") as f: |
||
238 | pickle.dump(scheme_list, f) |
||
239 | |||
240 | |||
241 | WIDGETS_ENTRY = "orange.widgets" |
||
242 | |||
243 | |||
244 | # This could also be achieved by declaring the entry point in |
||
245 | # Orange's setup.py, but that would not guaranty this entry point |
||
246 | # is the first in a list. |
||
247 | |||
248 | def default_entry_point(): |
||
249 | """ |
||
250 | Return a default orange.widgets entry point for loading |
||
251 | default Orange Widgets. |
||
252 | |||
253 | """ |
||
254 | dist = pkg_resources.get_distribution("Orange") |
||
255 | ep = pkg_resources.EntryPoint("Orange Widgets", "Orange.widgets", |
||
256 | dist=dist) |
||
257 | return ep |
||
258 | |||
259 | |||
260 | def widgets_entry_points(): |
||
261 | """ |
||
262 | Return an `EntryPoint` iterator for all 'orange.widget' entry |
||
263 | points plus the default Orange Widgets. |
||
264 | |||
265 | """ |
||
266 | ep_iter = pkg_resources.iter_entry_points(WIDGETS_ENTRY) |
||
267 | chain = [[default_entry_point()], |
||
268 | ep_iter |
||
269 | ] |
||
270 | return itertools.chain(*chain) |
||
271 | |||
272 | #: Parameters for searching add-on packages in PyPi using xmlrpc api. |
||
273 | ADDON_PYPI_SEARCH_SPEC = {"keywords": "orange3 add-on"} |
||
274 | #: Entry points by which add-ons register with pkg_resources. |
||
275 | ADDON_ENTRY = "orange3.addon" |
||
276 | |||
277 | |||
278 | def splash_screen(): |
||
0 ignored issues
–
show
|
|||
279 | """ |
||
280 | """ |
||
281 | pm = QPixmap( |
||
282 | pkg_resources.resource_filename( |
||
283 | __name__, "icons/orange-splash-screen.png") |
||
284 | ) |
||
285 | |||
286 | version = QCoreApplication.applicationVersion() |
||
287 | size = 21 if len(version) < 5 else 16 |
||
288 | font = QFont("Helvetica") |
||
289 | font.setPixelSize(size) |
||
290 | font.setBold(True) |
||
291 | font.setItalic(True) |
||
292 | font.setLetterSpacing(QFont.AbsoluteSpacing, 2) |
||
293 | metrics = QFontMetrics(font) |
||
294 | br = metrics.boundingRect(version).adjusted(-5, 0, 5, 0) |
||
295 | br.moveCenter(QPoint(436, 224)) |
||
296 | |||
297 | p = QPainter(pm) |
||
298 | p.setRenderHint(QPainter.Antialiasing) |
||
299 | p.setRenderHint(QPainter.TextAntialiasing) |
||
300 | p.setFont(font) |
||
301 | p.setPen(QColor("#231F20")) |
||
302 | p.drawText(br, Qt.AlignCenter, version) |
||
303 | p.end() |
||
304 | return pm, QRect(88, 193, 200, 20) |
||
305 | |||
306 | |||
307 | def application_icon(): |
||
308 | """ |
||
309 | Return the main application icon. |
||
310 | """ |
||
311 | path = pkg_resources.resource_filename( |
||
312 | __name__, "icons/orange-canvas.svg" |
||
313 | ) |
||
314 | return QIcon(path) |
||
315 | |||
316 |
This can be caused by one of the following:
1. Missing Dependencies
This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.
2. Missing __init__.py files
This error could also result from missing
__init__.py
files in your module folders. Make sure that you place one file in each sub-folder.