def _populate_app_fields(self):
        with WindowServiceProxy(59000) as w:
            self.video_mode_map = w.get_video_mode_map()
            if self.video_mode_map:
                self._video_available = True
            else:
                self._video_available = False
            self.video_mode_keys = sorted(self.video_mode_map.keys())
            if self._video_available:
                self.device_key, self.devices = w.get_video_source_configs()

        field_list = [
            Integer.named('overlay_opacity').using(default=50, optional=True),
            Directory.named('device_directory').using(default='', optional=True),
            String.named('transform_matrix').using(default='', optional=True,
                                                properties={'show_in_gui':
                                                            False}), ]

        if self._video_available:
            video_mode_enum = Enum.named('video_mode').valued(
                *self.video_mode_keys).using(default=self.video_mode_keys[0],
                                             optional=True)
            video_enabled_boolean = Boolean.named('video_enabled').using(
                default=False, optional=True, properties={'show_in_gui': True})
            recording_enabled_boolean = Boolean.named('recording_enabled').using(
                default=False, optional=True, properties={'show_in_gui': False})
            field_list.append(video_mode_enum)
            field_list.append(video_enabled_boolean)
            field_list.append(recording_enabled_boolean)
        return Form.of(*field_list)
Esempio n. 2
0
class DmfDeviceController(SingletonPlugin, AppDataController):
    implements(IPlugin)

    AppFields = Form.of(Directory.named('device_directory')
                        .using(default='', optional=True))

    def __init__(self):
        self.name = "microdrop.gui.dmf_device_controller"
        self.previous_device_dir = None
        self._modified = False

    @property
    def modified(self):
        return self._modified

    @modified.setter
    def modified(self, value):
        self._modified = value
        if getattr(self, 'menu_rename_dmf_device', None):
            self.menu_rename_dmf_device.set_sensitive(not value)
            self.menu_save_dmf_device.set_sensitive(value)

    @gtk_threadsafe
    def on_app_options_changed(self, plugin_name):
        try:
            if plugin_name == self.name:
                values = self.get_app_values()
                if 'device_directory' in values:
                    self.apply_device_dir(values['device_directory'])
        except (Exception,):
            _L().info(''.join(traceback.format_exc()))
            raise

    def apply_device_dir(self, device_directory):
        app = get_app()

        # if the device directory is empty or None, set a default
        if not device_directory:
            device_directory = (ph.path(app.config.data['data_dir'])
                                .joinpath('devices'))
            self.set_app_values({'device_directory': device_directory})

        if self.previous_device_dir and (device_directory ==
                                         self.previous_device_dir):
            # If the data directory hasn't changed, we do nothing
            return False

        device_directory = ph.path(device_directory)
        if self.previous_device_dir:
            device_directory.makedirs_p()
            if device_directory.listdir():
                result = yesno('Merge?', '''\
Target directory [%s] is not empty.  Merge contents with
current devices [%s] (overwriting common paths in the target
directory)?''' % (device_directory, self.previous_device_dir))
                if not result == gtk.RESPONSE_YES:
                    return False

            original_directory = ph.path(self.previous_device_dir)
            for d in original_directory.dirs():
                copytree(d, device_directory.joinpath(d.name))
            for f in original_directory.files():
                f.copyfile(device_directory.joinpath(f.name))
            original_directory.rmtree()
        elif not device_directory.isdir():
            # if the device directory doesn't exist, copy the skeleton dir
            if device_directory.parent:
                device_directory.parent.makedirs_p()
            base_path().joinpath('devices').copytree(device_directory)
        self.previous_device_dir = device_directory
        return True

    def on_plugin_enable(self):
        '''
        .. versionchanged:: 2.11.2
            Use :func:`gtk_threadsafe` decorator to wrap GTK code blocks,
            ensuring the code runs in the main GTK thread.
        '''
        app = get_app()

        app.dmf_device_controller = self
        defaults = self.get_default_app_options()
        data = app.get_data(self.name)
        for k, v in defaults.items():
            if k not in data:
                data[k] = v
        app.set_data(self.name, data)
        emit_signal('on_app_options_changed', [self.name])

        self.menu_detect_connections = \
            app.builder.get_object('menu_detect_connections')
        self.menu_import_dmf_device = \
            app.builder.get_object('menu_import_dmf_device')
        self.menu_load_dmf_device = \
            app.builder.get_object('menu_load_dmf_device')
        self.menu_rename_dmf_device = \
            app.builder.get_object('menu_rename_dmf_device')
        self.menu_save_dmf_device = \
            app.builder.get_object('menu_save_dmf_device')
        self.menu_save_dmf_device_as = \
            app.builder.get_object('menu_save_dmf_device_as')

        app.signals["on_menu_detect_connections_activate"] = \
            self.on_detect_connections
        app.signals["on_menu_import_dmf_device_activate"] = \
            self.on_import_dmf_device
        app.signals["on_menu_load_dmf_device_activate"] = \
            self.on_load_dmf_device
        app.signals["on_menu_rename_dmf_device_activate"] = \
            self.on_rename_dmf_device
        app.signals["on_menu_save_dmf_device_activate"] = \
            self.on_save_dmf_device
        app.signals["on_menu_save_dmf_device_as_activate"] = \
            self.on_save_dmf_device_as

        @gtk_threadsafe
        def _init_ui():
            # disable menu items until a device is loaded
            self.menu_detect_connections.set_sensitive(False)
            self.menu_rename_dmf_device.set_sensitive(False)
            self.menu_save_dmf_device.set_sensitive(False)
            self.menu_save_dmf_device_as.set_sensitive(False)

        _init_ui()

    def on_protocol_pause(self):
        pass

    def on_app_exit(self):
        self.save_check()

    def load_device(self, file_path, **kwargs):
        '''
        Load device file.

        Parameters
        ----------
        file_path : str
            A MicroDrop device `.svg` file or a (deprecated) MicroDrop 1.0
            device.
        '''
        logger = _L()  # use logger with method context
        app = get_app()
        self.modified = False
        device = app.dmf_device
        file_path = ph.path(file_path)

        if not file_path.isfile():
            old_version_file_path = (file_path.parent
                                     .joinpath(OLD_DEVICE_FILENAME))
            if old_version_file_path:
                # SVG device file does not exist, but old-style (i.e., v0.3.0)
                # device file found.
                try:
                    # Try to import old-style device to new SVG format.
                    self.import_device(old_version_file_path)
                    logger.warning('Auto-converted old-style device to new SVG'
                                   ' device format.  Open in Inkscape to '
                                   'verify scale and adjacent electrode '
                                   'connections.')
                except Exception, e:
                    logger.error('Error importing device. %s', e,
                                 exc_info=True)
                return
            else:
                logger.error('Error opening device.  Please ensure file '
                             'exists and is readable.', exc_info=True)
                return

        # SVG device file exists.  Load the device.
        try:
            logger.info('[DmfDeviceController].load_device: %s' % file_path)
            if app.get_device_directory().realpath() == (file_path.realpath()
                                                         .parent.parent):
                # Selected device file is in MicroDrop devices directory.
                new_device = False
            else:
                # Selected device file is not in MicroDrop devices directory.

                # Copy file to devices directory under subdirectory with same
                # name as file.
                new_device_directory = (app.get_device_directory().realpath()
                                        .joinpath(file_path.namebase)
                                        .noconflict())
                new_device_directory.makedirs_p()
                new_file_path = new_device_directory.joinpath('device.svg')
                file_path.copy(new_file_path)
                file_path = new_file_path
                new_device = True

            # Load device from SVG file.
            device = DmfDevice.load(file_path, name=file_path.parent.name,
                                    **kwargs)
            if new_device:
                # Inform user that device was copied from original location
                # into MicroDrop devices directory.
                pgh.ui.dialogs.info('Device imported successfully',
                                    long='New device copied into MicroDrop '
                                    'devices directory:\n{}'.format(file_path),
                                    parent=app.main_window_controller.view)
                logger.info('[DmfDeviceController].load_device: Copied new '
                            'device to: %s', file_path)
            emit_signal("on_dmf_device_swapped", [app.dmf_device, device])
        except Exception:
            logger.error('Error loading device.', exc_info=True)
 def AppFields(self):
     return Form.of(
         Directory.named('notebook_directory').using(default='', optional=True),
     )
 def AppFields(self):
     return Form.of(
         Directory.named('notebook_directory').using(default='',
                                                     optional=True), )