class RequestHandler(QObject): """Handle introspection request. """ introspection_complete = Signal() def __init__(self, code_info, plugins): super(RequestHandler, self).__init__() self.info = code_info self.timer = QTimer() self.timer.singleShot(LEAD_TIME_SEC * 1000, self._handle_timeout) self.waiting = True self.pending = {} self.result = None self.plugins = plugins self._start_time = time.time() self._threads = {} for plugin in plugins: self._make_async_call(plugin, code_info) def _handle_timeout(self): debug_print('got timeout: %s' % self.plugins) if self.pending: for plugin in self.plugins: if plugin.name in self.pending: self._finalize(plugin.name, self.pending[plugin.name]) return self.waiting = False def _handle_incoming(self, name): # coerce to a str in case it is a QString name = str(name) self._threads[name].wait() if self.result: return result = self._threads[name].result if name == self.plugins[0].name or not self.waiting: if result: self._finalize(name, result) else: debug_print('No valid responses acquired') self.introspection_complete.emit() else: self.pending[name] = result def _make_async_call(self, plugin, info): """Trigger an introspection job in a thread""" self._threads[str(plugin.name)] = thread = IntrospectionThread( plugin, info) thread.request_handled.connect(self._handle_incoming) thread.start() def _finalize(self, name, result): self.result = result self.waiting = False self.pending = None delta = time.time() - self._start_time debug_print('%s request from %s finished: "%s" in %.1f sec' % (self.info.name, name, str(result)[:100], delta)) self.introspection_complete.emit()
class RequestHandler(QObject): """Handle introspection request. """ introspection_complete = Signal() def __init__(self, code_info, plugins): super(RequestHandler, self).__init__() self.info = code_info self.timer = QTimer() self.timer.singleShot(LEAD_TIME_SEC * 1000, self._handle_timeout) self.waiting = True self.pending = {} self.result = None self.plugins = plugins self._start_time = time.time() self._threads = {} for plugin in plugins: self._make_async_call(plugin, code_info) def _handle_timeout(self): debug_print('got timeout: %s' % self.plugins) if self.pending: for plugin in self.plugins: if plugin.name in self.pending: self._finalize(plugin.name, self.pending[plugin.name]) return self.waiting = False def _handle_incoming(self, name): # coerce to a str in case it is a QString name = str(name) self._threads[name].wait() if self.result: return result = self._threads[name].result if name == self.plugins[0].name or not self.waiting: if result: self._finalize(name, result) else: debug_print('No valid responses acquired') self.introspection_complete.emit() else: self.pending[name] = result def _make_async_call(self, plugin, info): """Trigger an introspection job in a thread""" self._threads[str(plugin.name)] = thread = IntrospectionThread(plugin, info) thread.request_handled.connect(self._handle_incoming) thread.start() def _finalize(self, name, result): self.result = result self.waiting = False self.pending = None delta = time.time() - self._start_time debug_print('%s request from %s finished: "%s" in %.1f sec' % (self.info.name, name, str(result)[:100], delta)) self.introspection_complete.emit()
def focusOutEvent(self, event): """Handle focus out event restoring the last valid selected path.""" # Calling asynchronously the 'add_current_text' to avoid crash # https://groups.google.com/group/spyderlib/browse_thread/thread/2257abf530e210bd lineedit = self.lineEdit() QTimer.singleShot(50, lambda: lineedit.setText(self.selected_text)) hide_status = getattr(self.lineEdit(), 'hide_status_icon', None) if hide_status: hide_status() QComboBox.focusOutEvent(self, event)
def follow_directories_loaded(self, fname): """Follow directories loaded during startup""" if self._to_be_loaded is None: return path = osp.normpath(to_text_string(fname)) if path in self._to_be_loaded: self._to_be_loaded.remove(path) if self._to_be_loaded is not None and len(self._to_be_loaded) == 0 and not is_pyqt46: self.fsmodel.directoryLoaded.disconnect(self.follow_directories_loaded) if self._scrollbar_positions is not None: # The tree view need some time to render branches: QTimer.singleShot(50, self.restore_scrollbar_positions)
def follow_directories_loaded(self, fname): """Follow directories loaded during startup""" if self._to_be_loaded is None: return path = osp.normpath(to_text_string(fname)) if path in self._to_be_loaded: self._to_be_loaded.remove(path) if self._to_be_loaded is not None and len(self._to_be_loaded) == 0: self.disconnect(self.fsmodel, SIGNAL('directoryLoaded(QString)'), self.follow_directories_loaded) if self._scrollbar_positions is not None: # The tree view need some time to render branches: QTimer.singleShot(50, self.restore_scrollbar_positions)
def follow_directories_loaded(self, fname): """Follow directories loaded during startup""" if self._to_be_loaded is None: return path = osp.normpath(unicode(fname)) if path in self._to_be_loaded: self._to_be_loaded.pop(self._to_be_loaded.index(path)) if self._to_be_loaded is not None and len(self._to_be_loaded) == 0: self.disconnect(self.fsmodel, SIGNAL('directoryLoaded(QString)'), self.follow_directories_loaded) if self._scrollbar_positions is not None: # The tree view need some time to render branches: QTimer.singleShot(50, self.restore_scrollbar_positions)
def event(self, event): """Qt Override. Filter tab keys and process double tab keys. """ if (event.type() == QEvent.KeyPress) and (event.key() == Qt.Key_Tab): self.sig_tab_pressed.emit(True) self.numpress += 1 if self.numpress == 1: self.presstimer = QTimer.singleShot(400, self.handle_keypress) return True return QComboBox.event(self, event)
def focusOutEvent(self, event): """Handle focus out event""" # Calling asynchronously the 'add_current_text' to avoid crash # https://groups.google.com/group/spyderlib/browse_thread/thread/2257abf530e210bd QTimer.singleShot(50, self.add_current_text_if_valid) QComboBox.focusOutEvent(self, event)
class PluginManager(QObject): introspection_complete = Signal(object) def __init__(self, executable): super(PluginManager, self).__init__() plugins = OrderedDict() for name in PLUGINS: try: plugin = PluginClient(name, executable) plugin.run() except Exception as e: debug_print('Introspection Plugin Failed: %s' % name) debug_print(str(e)) continue debug_print('Introspection Plugin Loaded: %s' % name) plugins[name] = plugin plugin.received.connect(self.handle_response) self.plugins = plugins self.timer = QTimer() self.desired = [] self.ids = dict() self.info = None self.request = None self.pending = None self.pending_request = None self.waiting = False def send_request(self, info): """Handle an incoming request from the user.""" if self.waiting: if info.serialize() != self.info.serialize(): self.pending_request = info else: debug_print('skipping duplicate request') return debug_print('%s request' % info.name) desired = None self.info = info editor = info.editor if (info.name == 'completion' and 'jedi' not in self.plugins and info.line.lstrip().startswith(('import ', 'from '))): desired = 'fallback' if ((not editor.is_python_like()) or sourcecode.is_keyword(info.obj) or (editor.in_comment_or_string() and info.name != 'info')): desired = 'fallback' plugins = self.plugins.values() if desired: plugins = [self.plugins[desired]] self.desired = [desired] elif (info.name == 'definition' and not info.editor.is_python() or info.name == 'info'): self.desired = list(self.plugins.keys()) else: # Use all but the fallback plugins = list(self.plugins.values())[:-1] self.desired = list(self.plugins.keys())[:-1] self._start_time = time.time() self.waiting = True method = 'get_%s' % info.name value = info.serialize() self.ids = dict() for plugin in plugins: request_id = plugin.request(method, value) self.ids[request_id] = plugin.name self.timer.stop() self.timer.singleShot(LEAD_TIME_SEC * 1000, self._handle_timeout) def validate(self): for plugin in self.plugins.values(): plugin.request('validate') def handle_response(self, response): name = self.ids.get(response['request_id'], None) if not name: return if response.get('error', None): debug_print('Response error:', response['error']) return if name == self.desired[0] or not self.waiting: if response.get('result', None): self._finalize(response) else: self.pending = response def close(self): [plugin.close() for plugin in self.plugins] def _finalize(self, response): self.waiting = False self.pending = None if self.info: delta = time.time() - self._start_time debug_print('%s request from %s finished: "%s" in %.1f sec' % (self.info.name, response['name'], str(response['result'])[:100], delta)) response['info'] = self.info self.introspection_complete.emit(response) self.info = None if self.pending_request: info = self.pending_request self.pending_request = None self.send_request(info) def _handle_timeout(self): self.waiting = False if self.pending: self._finalize(self.pending) else: debug_print('No valid responses acquired')
class PluginManager(QObject): introspection_complete = Signal(object) def __init__(self, executable): super(PluginManager, self).__init__() plugins = OrderedDict() for name in PLUGINS: try: plugin = PluginClient(name, executable) except Exception as e: debug_print('Introspection Plugin Failed: %s' % name) debug_print(str(e)) continue debug_print('Introspection Plugin Loaded: %s' % name) plugins[name] = plugin plugin.request_handled.connect(self.handle_response) self.plugins = plugins self.timer = QTimer() self.desired = [] self.info = None self.request = None self.pending = None self.pending_request = None self.waiting = False def send_request(self, info): """Handle an incoming request from the user.""" if self.waiting: if info.serialize() != self.info.serialize(): self.pending_request = info else: debug_print('skipping duplicate request') return debug_print('%s request' % info.name) desired = None self.info = info editor = info.editor if (info.name == 'completion' and 'jedi' not in self.plugins and info.line.lstrip().startswith(('import ', 'from '))): desired = 'fallback' if ((not editor.is_python_like()) or sourcecode.is_keyword(info.obj) or (editor.in_comment_or_string() and info.name != 'info')): desired = 'fallback' plugins = self.plugins.values() if desired: plugins = [self.plugins[desired]] self.desired = [desired] elif (info.name == 'definition' and not info.editor.is_python() or info.name == 'info'): self.desired = list(self.plugins.keys()) else: # Use all but the fallback plugins = list(self.plugins.values())[:-1] self.desired = list(self.plugins.keys())[:-1] self._start_time = time.time() self.waiting = True request = dict(method='get_%s' % info.name, args=[info.serialize()], request_id=id(info)) for plugin in plugins: plugin.send(request) debug_print('sending %s' % (plugin.plugin_name)) self.timer.stop() self.timer.singleShot(LEAD_TIME_SEC * 1000, self._handle_timeout) self.request = request def validate(self): message = dict(method='validate') for plugin in self.plugins.values(): plugin.send(message) def handle_response(self, response): if (self.request is None): return if (response.get('request_id', None) != id(self.info)): return name = response['plugin_name'] response['info'] = self.info if response.get('error', None): debug_print('Response error:', response['error']) return if name == self.desired[0] or not self.waiting: if response.get('result', None): self._finalize(response) else: self.pending = response def close(self): [plugin.close() for plugin in self.plugins] def _finalize(self, response): self.waiting = False self.pending = None delta = time.time() - self._start_time debug_print(str(response.keys())) debug_print('%s request from %s finished: "%s" in %.1f sec' % (self.info.name, response['plugin_name'], str(response['result'])[:100], delta)) self.introspection_complete.emit(response) self.info = None if self.pending_request: info = self.pending_request self.pending_request = None self.send_request(info) def _handle_timeout(self): self.waiting = False if self.pending: self._finalize(self.pending) else: debug_print('No valid responses acquired', self.request['method'])
def refresh_plugin(self): """Refresh widget""" if self._starting_up: self._starting_up = False QTimer.singleShot(5000, self.refresh_plugin) self.set_object_text(None, force_refresh=False)