def create_settings(): # Special settings #----------------------------------------------------------------------------- # These settings require special handling in the code, hence their separation # from the other settings. special_settings = pgsettinggroup.SettingGroup('special', [ { 'type': pgsetting.SettingTypes.enumerated, 'name': 'run_mode', 'default_value': 'non_interactive', 'items': [('interactive', "RUN-INTERACTIVE", gimpenums.RUN_INTERACTIVE), ('non_interactive', "RUN-NONINTERACTIVE", gimpenums.RUN_NONINTERACTIVE), ('run_with_last_vals', "RUN-WITH-LAST-VALS", gimpenums.RUN_WITH_LAST_VALS)], 'display_name': _("The run mode") }, { 'type': pgsetting.SettingTypes.image, 'name': 'image', 'default_value': None, 'display_name': _("Image") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'first_plugin_run', 'default_value': True, 'pdb_type': pgsetting.SettingPdbTypes.none }, ]) # Main settings #----------------------------------------------------------------------------- main_settings = pgsettinggroup.SettingGroup('main', [ { 'type': pgsetting.SettingTypes.file_extension, 'name': 'file_extension', 'default_value': "png", 'display_name': "File extension", 'error_messages': { 'default_needed': _( "You need to specify default file extension for layers with invalid or no extension.") } }, { 'type': pgsetting.SettingTypes.string, 'name': 'output_directory', 'default_value': gimp.user_directory(1), # "Documents" directory 'display_name': _("Output directory") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'layer_groups_as_folders', 'default_value': False, 'display_name': _("Treat layer groups as folders") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'ignore_invisible', 'default_value': False, 'display_name': _("Ignore invisible layers") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'autocrop', 'default_value': False, 'display_name': _("Autocrop layers") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'use_image_size', 'default_value': False, 'display_name': _("Use image size") }, { 'type': pgsetting.SettingTypes.enumerated, 'name': 'file_extension_mode', 'default_value': 'no_special_handling', 'items': [('no_special_handling', _("No special handling")), ('only_matching_file_extension', _("Export only layers matching file extension")), ('use_as_file_extensions', _("Use as file extensions"))], 'display_name': _("File extensions in layer names") }, { 'type': pgsetting.SettingTypes.enumerated, 'name': 'strip_mode', 'default_value': 'always', 'items': [('always', _("Always strip file extension")), ('identical', _("Strip identical file extension")), ('never', _("Never strip file extension"))], 'display_name': _("File extension stripping") }, { 'type': pgsetting.SettingTypes.enumerated, 'name': 'tagged_layers_mode', 'default_value': 'normal', 'items': [('normal', _("Treat as normal layers")), ('special', _("Treat specially")), ('ignore', _("Ignore")), ('ignore_other', _("Ignore other layers"))], 'display_name': _("[Tagged] layers") }, { 'type': pgsetting.SettingTypes.enumerated, 'name': 'crop_mode', 'default_value': 'crop_to_layer', 'items': [('crop_to_layer', _("Crop to layer")), ('crop_to_background', _("Crop to background")), ('crop_to_foreground', _("Crop to foreground"))], 'display_name': _("Crop mode") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'merge_layer_groups', 'default_value': False, 'display_name': _("Merge layer groups") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'empty_folders', 'default_value': False, 'display_name': _("Create folders for empty layer groups") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'ignore_layer_modes', 'default_value': False, 'display_name': _("Ignore layer modes") }, { 'type': pgsetting.SettingTypes.enumerated, 'name': 'overwrite_mode', 'default_value': 'rename_new', 'items': [('replace', _("_Replace"), overwrite.OverwriteModes.REPLACE), ('skip', _("_Skip"), overwrite.OverwriteModes.SKIP), ('rename_new', _("Rename _new file"), overwrite.OverwriteModes.RENAME_NEW), ('rename_existing', _("Rename _existing file"), overwrite.OverwriteModes.RENAME_EXISTING), ('cancel', _("_Cancel"), overwrite.OverwriteModes.CANCEL)], 'display_name': _("Overwrite mode (non-interactive run mode only)") }, ]) #----------------------------------------------------------------------------- def on_layer_groups_as_folders_changed(layer_groups_as_folders, empty_folders, merge_layer_groups): if not layer_groups_as_folders.value: empty_folders.set_value(False) empty_folders.gui.set_enabled(False) merge_layer_groups.gui.set_enabled(True) else: empty_folders.gui.set_enabled(True) merge_layer_groups.gui.set_enabled(False) merge_layer_groups.set_value(False) def on_file_extension_mode_changed(file_extension_mode, file_extension, strip_mode): if file_extension_mode.is_item('no_special_handling'): strip_mode.set_value(strip_mode.default_value) strip_mode.gui.set_enabled(True) file_extension.error_messages[pgpath.FileValidatorErrorStatuses.IS_EMPTY] = "" elif file_extension_mode.is_item('only_matching_file_extension'): strip_mode.set_item('never') strip_mode.gui.set_enabled(False) file_extension.error_messages[pgpath.FileValidatorErrorStatuses.IS_EMPTY] = "" elif file_extension_mode.is_item('use_as_file_extensions'): strip_mode.set_item('never') strip_mode.gui.set_enabled(False) file_extension.error_messages[pgpath.FileValidatorErrorStatuses.IS_EMPTY] = ( file_extension.error_messages['default_needed']) def on_merge_layer_groups_changed(merge_layer_groups, layer_groups_as_folders): if merge_layer_groups.value: layer_groups_as_folders.set_value(False) layer_groups_as_folders.gui.set_enabled(False) else: layer_groups_as_folders.gui.set_enabled(True) def on_autocrop_changed(autocrop, tagged_layers_mode, crop_mode): if autocrop.value and tagged_layers_mode.is_item('special'): crop_mode.gui.set_enabled(True) else: crop_mode.set_item('crop_to_layer') crop_mode.gui.set_enabled(False) def on_tagged_layers_mode_changed(tagged_layers_mode, autocrop, crop_mode): on_autocrop_changed(autocrop, tagged_layers_mode, crop_mode) #----------------------------------------------------------------------------- main_settings['layer_groups_as_folders'].connect_value_changed_event( on_layer_groups_as_folders_changed, main_settings['empty_folders'], main_settings['merge_layer_groups'] ) main_settings['file_extension_mode'].connect_value_changed_event( on_file_extension_mode_changed, main_settings['file_extension'], main_settings['strip_mode'] ) main_settings['merge_layer_groups'].connect_value_changed_event( on_merge_layer_groups_changed, main_settings['layer_groups_as_folders'] ) main_settings['autocrop'].connect_value_changed_event( on_autocrop_changed, main_settings['tagged_layers_mode'], main_settings['crop_mode'] ) main_settings['tagged_layers_mode'].connect_value_changed_event( on_tagged_layers_mode_changed, main_settings['autocrop'], main_settings['crop_mode'] ) #----------------------------------------------------------------------------- main_settings.set_ignore_tags({ 'output_directory': ['reset'], }) #----------------------------------------------------------------------------- settings = pgsettinggroup.SettingGroup('all_settings', [special_settings, main_settings]) return settings
def create_settings(): settings = pg.setting.create_groups({ "name": "all_settings", "groups": [ { # These settings require special handling in the code, hence their separation # from the other settings. "name": "special", "tags": ["ignore_reset", "ignore_load", "ignore_save"], "setting_attributes": { "gui_type": None }, }, { "name": "main", "setting_attributes": { "setting_sources": [pg.config.SESSION_SOURCE, pg.config.PERSISTENT_SOURCE] }, } ] }) settings["special"].add([ { "type": pg.SettingTypes.enumerated, "name": "run_mode", "default_value": "non_interactive", "items": [("interactive", "RUN-INTERACTIVE", gimpenums.RUN_INTERACTIVE), ("non_interactive", "RUN-NONINTERACTIVE", gimpenums.RUN_NONINTERACTIVE), ("run_with_last_vals", "RUN-WITH-LAST-VALS", gimpenums.RUN_WITH_LAST_VALS)], "display_name": _("The run mode"), }, { "type": pg.SettingTypes.image, "name": "image", "default_value": None, "display_name": _("Image"), }, { "type": pg.SettingTypes.boolean, "name": "first_plugin_run", "default_value": True, "pdb_type": None, "setting_sources": [pg.config.SESSION_SOURCE], }, ]) settings["main"].add([ { "type": pg.SettingTypes.file_extension, "name": "file_extension", "default_value": "png", "display_name": "File extension", }, { "type": pg.SettingTypes.string, "name": "output_directory", "default_value": gimp.user_directory(1), # `Documents` directory "display_name": _("Output directory"), "gui_type": None, "tags": ["ignore_reset"], }, { "type": pg.SettingTypes.string, "name": "layer_filename_pattern", "default_value": "[layer name]", "display_name": _("Layer filename pattern"), "description": _("Layer filename pattern (empty string = layer name)"), "gui_type": None, }, { "type": pg.SettingTypes.generic, "name": "selected_layers", # key: image ID; value: set of selected layer IDs "default_value": collections.defaultdict(set), "display_name": _("Selected layers"), "pdb_type": None, "setting_sources": [pg.config.SESSION_SOURCE], }, { "type": pg.SettingTypes.generic, "name": "selected_layers_persistent", # key: image file path; value: set of selected layer names "default_value": collections.defaultdict(set), "display_name": _("Selected layers"), "pdb_type": None, "setting_sources": [pg.config.PERSISTENT_SOURCE], }, { "type": pg.SettingTypes.enumerated, "name": "overwrite_mode", "default_value": "rename_new", "items": [("replace", _("_Replace"), pg.overwrite.OverwriteModes.REPLACE), ("skip", _("_Skip"), pg.overwrite.OverwriteModes.SKIP), ("rename_new", _("Rename _new file"), pg.overwrite.OverwriteModes.RENAME_NEW), ("rename_existing", _("Rename _existing file"), pg.overwrite.OverwriteModes.RENAME_EXISTING)], "display_name": _("Overwrite mode (non-interactive run mode only)"), }, { "type": pg.SettingTypes.generic, "name": "available_tags", "default_value": operations.BUILTIN_TAGS, "pdb_type": None, "gui_type": None, }, { "type": pg.SettingTypes.generic, "name": "plugin_version", "default_value": pg.config.PLUGIN_VERSION, "pdb_type": None, "gui_type": None, }, ]) settings.add(settings_gui.create_gui_settings()) settings["main"].add([ operations.create( name="procedures", initial_operations=[ builtin_procedures.BUILTIN_PROCEDURES["use_layer_size"] ]), ]) settings["main"].add([ operations.create( name="constraints", initial_operations=[ builtin_constraints.BUILTIN_CONSTRAINTS["include_layers"], builtin_constraints.BUILTIN_CONSTRAINTS["only_visible_layers"] ]), ]) settings["main/procedures"].connect_event("after-add-operation", _on_after_add_procedure, settings["main/file_extension"]) settings["main/constraints"].connect_event( "after-add-operation", _on_after_add_constraint, settings["main/selected_layers"], settings["special/image"]) return settings
def _create_settings(self): self._add(pgsetting.FileExtensionSetting('file_extension', "")) self['file_extension'].display_name = _("File extension") self['file_extension'].description = _( "Type in file extension (with or without the leading period). " "To export in RAW format, type \"data\"." ) self._add(pgsetting.DirectorySetting('output_directory', gimp.user_directory(1))) # "Documents" directory self['output_directory'].display_name = _("Output directory") self._add(pgsetting.BoolSetting('layer_groups_as_folders', False)) self['layer_groups_as_folders'].display_name = _("Treat layer groups as folders") self['layer_groups_as_folders'].description = _( "If enabled, layers will be exported to subfolders corresponding to the layer groups.\n" "If disabled, all layers will be exported to the output folder on the same level." ) self._add(pgsetting.BoolSetting('ignore_invisible', False)) self['ignore_invisible'].display_name = _("Ignore invisible layers") self['ignore_invisible'].description = _( "If enabled, invisible layers will not be exported. Visible layers within " "invisible layer groups will also not be exported." ) self._add(pgsetting.BoolSetting('autocrop', False)) self['autocrop'].display_name = _("Autocrop layers") self['autocrop'].description = _( "If enabled, layers will be autocropped before being exported." ) self._add(pgsetting.BoolSetting('use_image_size', False)) self['use_image_size'].display_name = _("Use image size") self['use_image_size'].description = _( "If enabled, layers will be resized (but not scaled) to the image size. This is " "useful if you want to keep the size of the image canvas and the layer position " "within the image. If layers are partially outside the image canvas, " "they will be cut off." ) self._add( pgsetting.EnumSetting( 'file_ext_mode', 'no_special_handling', [('no_special_handling', _("No special handling")), ('only_matching_file_extension', _("Export only layers matching file extension")), ('use_as_file_extensions', _("Use as file extensions"))] ) ) self['file_ext_mode'].display_name = _("File extensions in layer names") self._add( pgsetting.EnumSetting( 'strip_mode', 'identical', [('always', _("Always strip file extension")), ('identical', _("Strip identical file extension")), ('never', _("Never strip file extension"))] ) ) self['strip_mode'].display_name = _("File extension stripping") self['strip_mode'].description = _( "Determines when to strip file extensions from layer names (including the period)." ) self._add( pgsetting.EnumSetting( 'square_bracketed_mode', 'normal', [('normal', _("Treat as normal layers")), ('background', _("Treat as background layers")), ('ignore', _("Ignore")), ('ignore_other', _("Ignore other layers"))] ) ) self['square_bracketed_mode'].display_name = _("Layer names in [square brackets]") self._add(pgsetting.BoolSetting('crop_to_background', False)) self['crop_to_background'].display_name = _("Crop to background") self['crop_to_background'].description = _( "If enabled, layers will be cropped to the combined size of the " "background layers instead of their own size." ) self._add(pgsetting.BoolSetting('merge_layer_groups', False)) self['merge_layer_groups'].display_name = _("Merge layer groups") self['merge_layer_groups'].description = _( "If enabled, each top-level layer group is merged into one layer. The name " "of each merged layer is the name of the corresponding top-level layer group." ) self._add(pgsetting.BoolSetting('empty_folders', False)) self['empty_folders'].display_name = _("Create folders for empty layer groups") self['empty_folders'].description = _( "If enabled, subfolders for empty layer groups will be created." ) self._add(pgsetting.BoolSetting('ignore_layer_modes', False)) self['ignore_layer_modes'].display_name = _("Ignore layer modes") self['ignore_layer_modes'].description = _( "If enabled, the layer mode for each layer will be set to Normal. This is " "useful for layers with opacity less than 100% and a layer mode different " "than Normal or Dissolve, which would normally be completely invisible " "if a file format supporting alpha channel is used (such as PNG)." ) self._add( pgsetting.EnumSetting( 'overwrite_mode', 'rename_new', [('replace', _("Replace"), exportlayers.OverwriteHandler.REPLACE), ('skip', _("Skip"), exportlayers.OverwriteHandler.SKIP), ('rename_new', _("Rename new file"), exportlayers.OverwriteHandler.RENAME_NEW), ('rename_existing', _("Rename existing file"), exportlayers.OverwriteHandler.RENAME_EXISTING), ('cancel', _("Cancel"), exportlayers.OverwriteHandler.CANCEL)] ) ) self['overwrite_mode'].display_name = _("Overwrite mode (non-interactive run mode only)") self['overwrite_mode'].description = _( "Indicates how to handle conflicting files. Skipped layers " "will not be regarded as exported." ) #--------------------------------------------------------------------------- self['file_ext_mode'].description = _( 'If "{0}" is selected, "{1}" must still be ' 'specified (for layers with invalid or no file extension).' ).format(self['file_ext_mode'].options_display_names['use_as_file_extensions'], self['file_extension'].display_name) self['square_bracketed_mode'].description = _( '"{0}": these layers will be used as a background for all other layers ' 'and will not be exported separately.\n' '"{1}": these layers will not be exported (and will not be treated as ' 'background layers).\n' '"{2}": all other layers will not be exported.' ).format(self['square_bracketed_mode'].options_display_names['background'], self['square_bracketed_mode'].options_display_names['ignore'], self['square_bracketed_mode'].options_display_names['ignore_other']) self['file_extension'].error_messages['default_needed'] = _( "You need to specify default file extension for layers with invalid or no extension." ) #--------------------------------------------------------------------------- def streamline_layer_groups_as_folders(layer_groups_as_folders, empty_folders, merge_layer_groups): if not layer_groups_as_folders.value: empty_folders.value = False empty_folders.ui_enabled = False merge_layer_groups.ui_enabled = True else: empty_folders.ui_enabled = True merge_layer_groups.ui_enabled = False merge_layer_groups.value = False def streamline_file_ext_mode(file_ext_mode, file_extension, strip_mode): if file_ext_mode.value == file_ext_mode.options['no_special_handling']: strip_mode.ui_enabled = True file_extension.error_messages[pgpath.FileExtensionValidator.IS_EMPTY] = "" elif file_ext_mode.value == file_ext_mode.options['only_matching_file_extension']: strip_mode.value = strip_mode.options['never'] strip_mode.ui_enabled = False file_extension.error_messages[pgpath.FileExtensionValidator.IS_EMPTY] = "" elif file_ext_mode.value == file_ext_mode.options['use_as_file_extensions']: strip_mode.value = strip_mode.options['never'] strip_mode.ui_enabled = False file_extension.error_messages[pgpath.FileExtensionValidator.IS_EMPTY] = ( file_extension.error_messages['default_needed'] ) def streamline_merge_layer_groups(merge_layer_groups, layer_groups_as_folders): if merge_layer_groups.value: layer_groups_as_folders.value = False layer_groups_as_folders.ui_enabled = False else: layer_groups_as_folders.ui_enabled = True def streamline_autocrop(autocrop, square_bracketed_mode, crop_to_background): if autocrop.value and square_bracketed_mode.value == square_bracketed_mode.options['background']: crop_to_background.ui_enabled = True else: crop_to_background.value = False crop_to_background.ui_enabled = False def streamline_square_bracketed_mode(square_bracketed_mode, autocrop, crop_to_background): if autocrop.value and square_bracketed_mode.value == square_bracketed_mode.options['background']: crop_to_background.ui_enabled = True else: crop_to_background.value = False crop_to_background.ui_enabled = False #--------------------------------------------------------------------------- self['layer_groups_as_folders'].set_streamline_func( streamline_layer_groups_as_folders, self['empty_folders'], self['merge_layer_groups'] ) self['file_ext_mode'].set_streamline_func( streamline_file_ext_mode, self['file_extension'], self['strip_mode'] ) self['merge_layer_groups'].set_streamline_func( streamline_merge_layer_groups, self['layer_groups_as_folders'] ) self['autocrop'].set_streamline_func( streamline_autocrop, self['square_bracketed_mode'], self['crop_to_background'] ) self['square_bracketed_mode'].set_streamline_func( streamline_square_bracketed_mode, self['autocrop'], self['crop_to_background'] )
def create_settings(): #----------------------------------------------------------------------------- # Special settings #----------------------------------------------------------------------------- # These settings require special handling in the code, hence their separation # from the other settings. special_settings = pgsettinggroup.SettingGroup('special', [ { 'type': pgsetting.SettingTypes.enumerated, 'name': 'run_mode', 'default_value': 'non_interactive', 'items': [('interactive', "RUN-INTERACTIVE", gimpenums.RUN_INTERACTIVE), ('non_interactive', "RUN-NONINTERACTIVE", gimpenums.RUN_NONINTERACTIVE), ('run_with_last_vals', "RUN-WITH-LAST-VALS", gimpenums.RUN_WITH_LAST_VALS)], 'display_name': _("The run mode") }, { 'type': pgsetting.SettingTypes.image, 'name': 'image', 'default_value': None, 'display_name': _("Image") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'first_plugin_run', 'default_value': True, 'pdb_type': pgsetting.SettingPdbTypes.none }, ]) #----------------------------------------------------------------------------- # Main settings #----------------------------------------------------------------------------- main_settings = pgsettinggroup.SettingGroup( 'main', [ { 'type': pgsetting.SettingTypes.file_extension, 'name': 'file_extension', 'default_value': "png", 'display_name': "File extension", 'error_messages': { 'default_needed': _("You need to specify default file extension for layers with invalid or no extension." ) } }, { 'type': pgsetting.SettingTypes.directory, 'name': 'output_directory', 'default_value': gimp.user_directory(1), # "Documents" directory 'display_name': _("Output directory"), 'error_messages': { pgpath.DirectoryPathValidator.IS_EMPTY: _("Output directory is not specified.") } }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'layer_groups_as_folders', 'default_value': False, 'display_name': _("Treat layer groups as folders") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'ignore_invisible', 'default_value': False, 'display_name': _("Ignore invisible layers") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'autocrop', 'default_value': False, 'display_name': _("Autocrop layers") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'use_image_size', 'default_value': False, 'display_name': _("Use image size") }, { 'type': pgsetting.SettingTypes.enumerated, 'name': 'file_ext_mode', 'default_value': 'no_special_handling', 'items': [('no_special_handling', _("No special handling")), ('only_matching_file_extension', _("Export only layers matching file extension")), ('use_as_file_extensions', _("Use as file extensions"))], 'display_name': _("File extensions in layer names") }, { 'type': pgsetting.SettingTypes.enumerated, 'name': 'strip_mode', 'default_value': 'always', 'items': [('always', _("Always strip file extension")), ('identical', _("Strip identical file extension")), ('never', _("Never strip file extension"))], 'display_name': _("File extension stripping") }, { 'type': pgsetting.SettingTypes.enumerated, 'name': 'square_bracketed_mode', 'default_value': 'normal', 'items': [('normal', _("Treat as normal layers")), ('background', _("Treat as background layers")), ('ignore', _("Ignore")), ('ignore_other', _("Ignore other layers"))], 'display_name': _("Layer names in [square brackets]") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'crop_to_background', 'default_value': False, 'display_name': _("Crop to background") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'merge_layer_groups', 'default_value': False, 'display_name': _("Merge layer groups") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'empty_folders', 'default_value': False, 'display_name': _("Create folders for empty layer groups") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'ignore_layer_modes', 'default_value': False, 'display_name': _("Ignore layer modes") }, { 'type': pgsetting.SettingTypes.enumerated, 'name': 'overwrite_mode', 'default_value': 'rename_new', 'items': [('replace', _("_Replace"), exportlayers.OverwriteHandler.REPLACE), ('skip', _("_Skip"), exportlayers.OverwriteHandler.SKIP), ('rename_new', _("Rename _new file"), exportlayers.OverwriteHandler.RENAME_NEW), ('rename_existing', _("Rename _existing file"), exportlayers.OverwriteHandler.RENAME_EXISTING), ('cancel', _("_Cancel"), exportlayers.OverwriteHandler.CANCEL) ], 'display_name': _("Overwrite mode (non-interactive run mode only)") }, ]) #----------------------------------------------------------------------------- def on_layer_groups_as_folders_changed(layer_groups_as_folders, empty_folders, merge_layer_groups): if not layer_groups_as_folders.value: empty_folders.set_value(False) empty_folders.gui.set_enabled(False) merge_layer_groups.gui.set_enabled(True) else: empty_folders.gui.set_enabled(True) merge_layer_groups.gui.set_enabled(False) merge_layer_groups.set_value(False) def on_file_ext_mode_changed(file_ext_mode, file_extension, strip_mode): if file_ext_mode.value == file_ext_mode.items['no_special_handling']: strip_mode.set_value(strip_mode.default_value) strip_mode.gui.set_enabled(True) file_extension.error_messages[ pgpath.FileExtensionValidator.IS_EMPTY] = "" elif file_ext_mode.value == file_ext_mode.items[ 'only_matching_file_extension']: strip_mode.set_value(strip_mode.items['never']) strip_mode.gui.set_enabled(False) file_extension.error_messages[ pgpath.FileExtensionValidator.IS_EMPTY] = "" elif file_ext_mode.value == file_ext_mode.items[ 'use_as_file_extensions']: strip_mode.set_value(strip_mode.items['never']) strip_mode.gui.set_enabled(False) file_extension.error_messages[ pgpath.FileExtensionValidator.IS_EMPTY] = ( file_extension.error_messages['default_needed']) def on_merge_layer_groups_changed(merge_layer_groups, layer_groups_as_folders): if merge_layer_groups.value: layer_groups_as_folders.set_value(False) layer_groups_as_folders.gui.set_enabled(False) else: layer_groups_as_folders.gui.set_enabled(True) def on_autocrop_changed(autocrop, square_bracketed_mode, crop_to_background): if autocrop.value and square_bracketed_mode.value == square_bracketed_mode.items[ 'background']: crop_to_background.gui.set_enabled(True) else: crop_to_background.set_value(False) crop_to_background.gui.set_enabled(False) def on_square_bracketed_mode_changed(square_bracketed_mode, autocrop, crop_to_background): on_autocrop_changed(autocrop, square_bracketed_mode, crop_to_background) #----------------------------------------------------------------------------- main_settings['layer_groups_as_folders'].connect_value_changed_event( on_layer_groups_as_folders_changed, [main_settings['empty_folders'], main_settings['merge_layer_groups']]) main_settings['file_ext_mode'].connect_value_changed_event( on_file_ext_mode_changed, [main_settings['file_extension'], main_settings['strip_mode']]) main_settings['merge_layer_groups'].connect_value_changed_event( on_merge_layer_groups_changed, [main_settings['layer_groups_as_folders']]) main_settings['autocrop'].connect_value_changed_event( on_autocrop_changed, [ main_settings['square_bracketed_mode'], main_settings['crop_to_background'] ]) main_settings['square_bracketed_mode'].connect_value_changed_event( on_square_bracketed_mode_changed, [main_settings['autocrop'], main_settings['crop_to_background']]) #----------------------------------------------------------------------------- main_settings.set_ignore_tags({ 'output_directory': ['reset'], }) #----------------------------------------------------------------------------- settings = pgsettinggroup.SettingGroup('all_settings', [special_settings, main_settings]) return settings
def create_settings(): settings = pg.setting.create_groups({ "name": "all_settings", "groups": [ { # These settings require special handling in the code, hence their separation # from the other settings. "name": "special", "tags": ["ignore_reset", "ignore_load", "ignore_save"], "setting_attributes": {"gui_type": None}, }, { "name": "main", "setting_attributes": { "setting_sources": [pg.config.SESSION_SOURCE, pg.config.PERSISTENT_SOURCE]}, } ] }) settings["special"].add([ { "type": pg.SettingTypes.enumerated, "name": "run_mode", "default_value": "non_interactive", "items": [ ("interactive", "RUN-INTERACTIVE", gimpenums.RUN_INTERACTIVE), ("non_interactive", "RUN-NONINTERACTIVE", gimpenums.RUN_NONINTERACTIVE), ("run_with_last_vals", "RUN-WITH-LAST-VALS", gimpenums.RUN_WITH_LAST_VALS)], "display_name": _("The run mode"), }, { "type": pg.SettingTypes.image, "name": "image", "default_value": None, "display_name": _("Image"), }, { "type": pg.SettingTypes.boolean, "name": "first_plugin_run", "default_value": True, "pdb_type": None, "setting_sources": [pg.config.SESSION_SOURCE], }, ]) settings["main"].add([ { "type": pg.SettingTypes.file_extension, "name": "file_extension", "default_value": "png", "display_name": "File extension", }, { "type": pg.SettingTypes.string, "name": "output_directory", "default_value": gimp.user_directory(1), # `Documents` directory "display_name": _("Output directory"), "gui_type": None, "tags": ["ignore_reset"], }, { "type": pg.SettingTypes.string, "name": "layer_filename_pattern", "default_value": "[layer name]", "display_name": _("Layer filename pattern"), "description": _("Layer filename pattern (empty string = layer name)"), "gui_type": None, }, { "type": pg.SettingTypes.generic, "name": "selected_layers", # key: image ID; value: set of selected layer IDs "default_value": collections.defaultdict(set), "display_name": _("Selected layers"), "pdb_type": None, "setting_sources": [pg.config.SESSION_SOURCE], }, { "type": pg.SettingTypes.generic, "name": "selected_layers_persistent", # key: image file path; value: set of selected layer names "default_value": collections.defaultdict(set), "display_name": _("Selected layers"), "pdb_type": None, "setting_sources": [pg.config.PERSISTENT_SOURCE], }, { "type": pg.SettingTypes.enumerated, "name": "overwrite_mode", "default_value": "rename_new", "items": [ ("replace", _("_Replace"), pg.overwrite.OverwriteModes.REPLACE), ("skip", _("_Skip"), pg.overwrite.OverwriteModes.SKIP), ("rename_new", _("Rename _new file"), pg.overwrite.OverwriteModes.RENAME_NEW), ("rename_existing", _("Rename _existing file"), pg.overwrite.OverwriteModes.RENAME_EXISTING)], "display_name": _("Overwrite mode (non-interactive run mode only)"), }, { "type": pg.SettingTypes.generic, "name": "available_tags", "default_value": operations.BUILTIN_TAGS, "pdb_type": None, "gui_type": None, }, { "type": pg.SettingTypes.generic, "name": "plugin_version", "default_value": pg.config.PLUGIN_VERSION, "pdb_type": None, "gui_type": None, }, ]) settings.add(settings_gui.create_gui_settings()) settings["main"].add([operations.create( name="procedures", initial_operations=[builtin_procedures.BUILTIN_PROCEDURES["use_layer_size"]]), ]) settings["main"].add([operations.create( name="constraints", initial_operations=[ builtin_constraints.BUILTIN_CONSTRAINTS["include_layers"], builtin_constraints.BUILTIN_CONSTRAINTS["only_visible_layers"]]), ]) settings["main/procedures"].connect_event( "after-add-operation", _on_after_add_procedure, settings["main/file_extension"]) settings["main/constraints"].connect_event( "after-add-operation", _on_after_add_constraint, settings["main/selected_layers"], settings["special/image"]) return settings
def create_settings(): # Special settings #----------------------------------------------------------------------------- # These settings require special handling in the code, hence their separation # from the other settings. special_settings = pgsettinggroup.SettingGroup('special', [ { 'type': pgsetting.SettingTypes.enumerated, 'name': 'run_mode', 'default_value': 'non_interactive', 'items': [('interactive', "RUN-INTERACTIVE", gimpenums.RUN_INTERACTIVE), ('non_interactive', "RUN-NONINTERACTIVE", gimpenums.RUN_NONINTERACTIVE), ('run_with_last_vals', "RUN-WITH-LAST-VALS", gimpenums.RUN_WITH_LAST_VALS)], 'display_name': _("The run mode") }, { 'type': pgsetting.SettingTypes.image, 'name': 'image', 'default_value': None, 'display_name': _("Image") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'first_plugin_run', 'default_value': True, 'pdb_type': None, 'setting_sources': [pygimplib.config.SOURCE_SESSION] }, ]) # Main settings #----------------------------------------------------------------------------- main_settings = pgsettinggroup.SettingGroup('main', [ { 'type': pgsetting.SettingTypes.file_extension, 'name': 'file_extension', 'default_value': "png", 'display_name': "File extension" }, { 'type': pgsetting.SettingTypes.string, 'name': 'output_directory', 'default_value': gimp.user_directory(1), # "Documents" directory 'display_name': _("Output directory"), 'gui_type': None }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'layer_groups_as_folders', 'default_value': False, 'display_name': _("Treat layer groups as folders") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'only_visible_layers', 'default_value': False, 'display_name': _("Only visible layers") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'use_image_size', 'default_value': False, 'display_name': _("Use image size") }, { 'type': pgsetting.SettingTypes.string, 'name': 'layer_filename_pattern', 'default_value': "[layer name]", 'display_name': _("Layer filename pattern"), 'description': _("Layer filename pattern (empty string = layer name)"), 'gui_type': None }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'process_tagged_layers', 'default_value': False, 'display_name': _("Process tagged layers") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'export_only_selected_layers', 'default_value': False, 'display_name': _("Export only selected layers"), 'pdb_type': None }, { 'type': pgsetting.SettingTypes.generic, 'name': 'selected_layers', # key: image ID; value: set of selected layer IDs 'default_value': collections.defaultdict(set), 'display_name': _("Selected layers"), 'pdb_type': None, 'setting_sources': [pygimplib.config.SOURCE_SESSION] }, { 'type': pgsetting.SettingTypes.generic, 'name': 'selected_layers_persistent', # key: image filename; value: set of selected layer names 'default_value': collections.defaultdict(set), 'display_name': _("Selected layers"), 'pdb_type': None, 'setting_sources': [pygimplib.config.SOURCE_PERSISTENT] }, { 'type': pgsetting.SettingTypes.enumerated, 'name': 'overwrite_mode', 'default_value': 'rename_new', 'items': [('replace', _("_Replace"), overwrite.OverwriteModes.REPLACE), ('skip', _("_Skip"), overwrite.OverwriteModes.SKIP), ('rename_new', _("Rename _new file"), overwrite.OverwriteModes.RENAME_NEW), ('rename_existing', _("Rename _existing file"), overwrite.OverwriteModes.RENAME_EXISTING), ('cancel', _("_Cancel"), overwrite.OverwriteModes.CANCEL)], 'display_name': _("Overwrite mode (non-interactive run mode only)") }, ], setting_sources=[pygimplib.config.SOURCE_SESSION, pygimplib.config.SOURCE_PERSISTENT]) # Additional settings - operations and filters #----------------------------------------------------------------------------- more_operations_settings = pgsettinggroup.SettingGroup('more_operations', [ { 'type': pgsetting.SettingTypes.boolean, 'name': 'merge_layer_groups', 'default_value': False, 'display_name': _("Merge layer groups") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'inherit_transparency_from_groups', 'default_value': False, 'display_name': _("Inherit transparency from layer groups"), }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'create_folders_for_empty_groups', 'default_value': False, 'display_name': _("Create folders for empty layer groups") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'ignore_layer_modes', 'default_value': False, 'display_name': _("Ignore layer modes") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'autocrop', 'default_value': False, 'display_name': _("Autocrop") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'autocrop_to_background', 'default_value': False, 'display_name': _("Autocrop to background") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'autocrop_to_foreground', 'default_value': False, 'display_name': _("Autocrop to foreground") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'use_file_extensions_in_layer_names', 'default_value': False, 'display_name': _("Use file extensions in layer names") }, ], pdb_type=None, setting_sources=[pygimplib.config.SOURCE_SESSION, pygimplib.config.SOURCE_PERSISTENT]) more_filters_settings = pgsettinggroup.SettingGroup('more_filters', [ { 'type': pgsetting.SettingTypes.boolean, 'name': 'only_layers_matching_file_extension', 'default_value': False, 'display_name': _("Only layers matching file extension") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'only_non_tagged_layers', 'default_value': False, 'display_name': _("Only non-tagged layers") }, { 'type': pgsetting.SettingTypes.boolean, 'name': 'only_tagged_layers', 'default_value': False, 'display_name': _("Only tagged layers") }, ], pdb_type=None, setting_sources=[pygimplib.config.SOURCE_SESSION, pygimplib.config.SOURCE_PERSISTENT]) main_settings.add([more_operations_settings, more_filters_settings]) #----------------------------------------------------------------------------- def on_layer_groups_as_folders_changed(layer_groups_as_folders, create_folders_for_empty_groups, merge_layer_groups): if not layer_groups_as_folders.value: create_folders_for_empty_groups.set_value(False) create_folders_for_empty_groups.gui.set_enabled(False) merge_layer_groups.gui.set_enabled(True) else: create_folders_for_empty_groups.gui.set_enabled(True) merge_layer_groups.gui.set_enabled(False) merge_layer_groups.set_value(False) def on_use_file_extensions_in_layer_names_changed(use_file_extensions_in_layer_names, file_extension): if not use_file_extensions_in_layer_names.value: file_extension.error_messages[pgpath.FileValidatorErrorStatuses.IS_EMPTY] = "" else: file_extension.error_messages[pgpath.FileValidatorErrorStatuses.IS_EMPTY] = _( "You need to specify default file extension for layers with invalid or no extension.") def on_merge_layer_groups_changed(merge_layer_groups, layer_groups_as_folders): if merge_layer_groups.value: layer_groups_as_folders.set_value(False) layer_groups_as_folders.gui.set_enabled(False) else: layer_groups_as_folders.gui.set_enabled(True) #----------------------------------------------------------------------------- main_settings['layer_groups_as_folders'].connect_event('value-changed', on_layer_groups_as_folders_changed, main_settings['more_operations/create_folders_for_empty_groups'], main_settings['more_operations/merge_layer_groups']) main_settings['more_operations/use_file_extensions_in_layer_names'].connect_event('value-changed', on_use_file_extensions_in_layer_names_changed, main_settings['file_extension']) main_settings['more_operations/merge_layer_groups'].connect_event('value-changed', on_merge_layer_groups_changed, main_settings['layer_groups_as_folders']) #----------------------------------------------------------------------------- settings = pgsettinggroup.SettingGroup('all_settings', [special_settings, main_settings]) settings.set_ignore_tags({ 'special': ['reset', 'load', 'save'], 'main/output_directory': ['reset'] }) #----------------------------------------------------------------------------- return settings
def create_settings(): # Special settings #----------------------------------------------------------------------------- # These settings require special handling in the code, hence their separation # from the other settings. special_settings = pgsettinggroup.SettingGroup(name="special") special_settings.add([ { "type": pgsetting.SettingTypes.enumerated, "name": "run_mode", "default_value": "non_interactive", "items": [("interactive", "RUN-INTERACTIVE", gimpenums.RUN_INTERACTIVE), ("non_interactive", "RUN-NONINTERACTIVE", gimpenums.RUN_NONINTERACTIVE), ("run_with_last_vals", "RUN-WITH-LAST-VALS", gimpenums.RUN_WITH_LAST_VALS)], "display_name": _("The run mode") }, { "type": pgsetting.SettingTypes.image, "name": "image", "default_value": None, "display_name": _("Image") }, { "type": pgsetting.SettingTypes.boolean, "name": "first_plugin_run", "default_value": True, "pdb_type": None, "setting_sources": [pygimplib.config.SOURCE_SESSION] }, ]) # Main settings #----------------------------------------------------------------------------- main_settings = pgsettinggroup.SettingGroup( name="main", setting_attributes={ "setting_sources": [ pygimplib.config.SOURCE_SESSION, pygimplib.config.SOURCE_PERSISTENT ] }) main_settings.add([ { "type": pgsetting.SettingTypes.file_extension, "name": "file_extension", "default_value": "png", "display_name": "File extension" }, { "type": pgsetting.SettingTypes.string, "name": "output_directory", "default_value": gimp.user_directory(1), # `Documents` directory "display_name": _("Output directory"), "gui_type": None }, { "type": pgsetting.SettingTypes.boolean, "name": "layer_groups_as_folders", "default_value": False, "display_name": _("Treat layer groups as folders") }, { "type": pgsetting.SettingTypes.boolean, "name": "use_image_size", "default_value": False, "display_name": _("Use image size") }, { "type": pgsetting.SettingTypes.boolean, "name": "only_visible_layers", "default_value": False, "display_name": _("Only visible layers") }, { "type": pgsetting.SettingTypes.string, "name": "layer_filename_pattern", "default_value": "[layer name]", "display_name": _("Layer filename pattern"), "description": _("Layer filename pattern (empty string = layer name)"), "gui_type": None }, { "type": pgsetting.SettingTypes.generic, "name": "selected_layers", # key: image ID; value: set of selected layer IDs "default_value": collections.defaultdict(set), "display_name": _("Selected layers"), "pdb_type": None, "setting_sources": [pygimplib.config.SOURCE_SESSION] }, { "type": pgsetting.SettingTypes.generic, "name": "selected_layers_persistent", # key: image file path; value: set of selected layer names "default_value": collections.defaultdict(set), "display_name": _("Selected layers"), "pdb_type": None, "setting_sources": [pygimplib.config.SOURCE_PERSISTENT] }, { "type": pgsetting.SettingTypes.enumerated, "name": "overwrite_mode", "default_value": "rename_new", "items": [("replace", _("_Replace"), pgoverwrite.OverwriteModes.REPLACE), ("skip", _("_Skip"), pgoverwrite.OverwriteModes.SKIP), ("rename_new", _("Rename _new file"), pgoverwrite.OverwriteModes.RENAME_NEW), ("rename_existing", _("Rename _existing file"), pgoverwrite.OverwriteModes.RENAME_EXISTING)], "display_name": _("Overwrite mode (non-interactive run mode only)") }, ]) # Additional settings - operations and constraints #----------------------------------------------------------------------------- operations_settings = pgsettinggroup.SettingGroup( name="operations", setting_attributes={ "pdb_type": None, "setting_sources": [ pygimplib.config.SOURCE_SESSION, pygimplib.config.SOURCE_PERSISTENT ] }) operations_settings.add([ { "type": pgsetting.SettingTypes.boolean, "name": "insert_background_layers", "default_value": False, "display_name": _("Insert background layers") }, { "type": pgsetting.SettingTypes.boolean, "name": "insert_foreground_layers", "default_value": False, "display_name": _("Insert foreground layers") }, { "type": pgsetting.SettingTypes.boolean, "name": "inherit_transparency_from_layer_groups", "default_value": False, "display_name": _("Inherit transparency from layer groups"), }, { "type": pgsetting.SettingTypes.boolean, "name": "ignore_layer_modes", "default_value": False, "display_name": _("Ignore layer modes") }, { "type": pgsetting.SettingTypes.boolean, "name": "autocrop", "default_value": False, "display_name": _("Autocrop") }, { "type": pgsetting.SettingTypes.boolean, "name": "autocrop_background", "default_value": False, "display_name": _("Autocrop background") }, { "type": pgsetting.SettingTypes.boolean, "name": "autocrop_foreground", "default_value": False, "display_name": _("Autocrop foreground") }, { "type": pgsetting.SettingTypes.boolean, "name": "use_file_extensions_in_layer_names", "default_value": False, "display_name": _("Use file extensions in layer names") }, ]) constraints_settings = pgsettinggroup.SettingGroup( name="constraints", setting_attributes={ "pdb_type": None, "setting_sources": [ pygimplib.config.SOURCE_SESSION, pygimplib.config.SOURCE_PERSISTENT ] }) include_constraints_settings = pgsettinggroup.SettingGroup( name="include", display_name=_("Include"), setting_attributes={ "pdb_type": None, "setting_sources": [ pygimplib.config.SOURCE_SESSION, pygimplib.config.SOURCE_PERSISTENT ] }) include_constraints_settings.add([{ "type": pgsetting.SettingTypes.boolean, "name": "include_layers", "default_value": True, "display_name": _("Include layers") }, { "type": pgsetting.SettingTypes.boolean, "name": "include_layer_groups", "default_value": False, "display_name": _("Include layer groups") }, { "type": pgsetting.SettingTypes.boolean, "name": "include_empty_layer_groups", "default_value": False, "display_name": _("Include empty layer groups") }]) constraints_settings.add([ include_constraints_settings, { "type": pgsetting.SettingTypes.boolean, "name": "only_layers_without_tags", "default_value": False, "display_name": _("Only layers without tags") }, { "type": pgsetting.SettingTypes.boolean, "name": "only_layers_with_tags", "default_value": False, "display_name": _("Only layers with tags") }, { "type": pgsetting.SettingTypes.boolean, "name": "only_layers_matching_file_extension", "default_value": False, "display_name": _("Only layers matching file extension") }, { "type": pgsetting.SettingTypes.boolean, "name": "only_toplevel_layers", "default_value": False, "display_name": _("Only top-level layers") }, { "type": pgsetting.SettingTypes.boolean, "name": "only_selected_layers", "default_value": False, "display_name": _("Only layers selected in preview") } ]) main_settings.add([operations_settings, constraints_settings]) #----------------------------------------------------------------------------- def on_use_file_extensions_in_layer_names_changed( use_file_extensions_in_layer_names, file_extension): if not use_file_extensions_in_layer_names.value: file_extension.error_messages[ pgpath.FileValidatorErrorStatuses.IS_EMPTY] = "" else: file_extension.error_messages[ pgpath.FileValidatorErrorStatuses.IS_EMPTY] = _( "You need to specify default file extension for layers with invalid " "or no extension.") main_settings[ "operations/use_file_extensions_in_layer_names"].connect_event( "value-changed", on_use_file_extensions_in_layer_names_changed, main_settings["file_extension"]) #----------------------------------------------------------------------------- settings = pgsettinggroup.SettingGroup(name="all_settings") settings.add([special_settings, main_settings]) settings["special"].tags.update( ["ignore_reset", "ignore_load", "ignore_save"]) settings["main/output_directory"].tags.add("ignore_reset") #----------------------------------------------------------------------------- return settings
def _create_settings(self): self._add(pgsetting.FileExtensionSetting('file_extension', "png")) self['file_extension'].display_name = _("File extension") self['file_extension'].description = _( "Type in file extension (with or without the leading period). " "To export in RAW format, type \"data\"." ) self._add(pgsetting.DirectorySetting('output_directory', gimp.user_directory(1))) # "Documents" directory self['output_directory'].display_name = _("Output directory") self._add(pgsetting.BoolSetting('layer_groups_as_folders', False)) self['layer_groups_as_folders'].display_name = _("Treat layer groups as folders") self['layer_groups_as_folders'].description = _( "If enabled, layers will be exported to subfolders corresponding to the layer groups.\n" "If disabled, all layers will be exported to the output folder on the same level." ) self._add(pgsetting.BoolSetting('ignore_invisible', False)) self['ignore_invisible'].display_name = _("Ignore invisible layers") self['ignore_invisible'].description = _( "If enabled, invisible layers will not be exported. Visible layers within " "invisible layer groups will also not be exported." ) self._add(pgsetting.BoolSetting('autocrop', False)) self['autocrop'].display_name = _("Autocrop layers") self['autocrop'].description = _( "If enabled, layers will be autocropped before being exported." ) self._add(pgsetting.BoolSetting('use_image_size', False)) self['use_image_size'].display_name = _("Use image size") self['use_image_size'].description = _( "If enabled, layers will be resized (but not scaled) to the image size. This is " "useful if you want to keep the size of the image canvas and the layer position " "within the image. If layers are partially outside the image canvas, " "they will be cut off." ) self._add( pgsetting.EnumSetting( 'file_ext_mode', 'no_special_handling', [('no_special_handling', _("No special handling")), ('only_matching_file_extension', _("Export only layers matching file extension")), ('use_as_file_extensions', _("Use as file extensions"))] ) ) self['file_ext_mode'].display_name = _("File extensions in layer names") self._add( pgsetting.EnumSetting( 'strip_mode', 'identical', [('always', _("Always strip file extension")), ('identical', _("Strip identical file extension")), ('never', _("Never strip file extension"))] ) ) self['strip_mode'].display_name = _("File extension stripping") self['strip_mode'].description = _( "Determines when to strip file extensions from layer names (including the period)." ) self._add( pgsetting.EnumSetting( 'square_bracketed_mode', 'normal', [('normal', _("Treat as normal layers")), ('background', _("Treat as background layers")), ('ignore', _("Ignore")), ('ignore_other', _("Ignore other layers"))] ) ) self['square_bracketed_mode'].display_name = _("Layer names in [square brackets]") self._add(pgsetting.BoolSetting('crop_to_background', False)) self['crop_to_background'].display_name = _("Crop to background") self['crop_to_background'].description = _( "If enabled, layers will be cropped to the combined size of the " "background layers instead of their own size." ) self._add(pgsetting.BoolSetting('merge_layer_groups', False)) self['merge_layer_groups'].display_name = _("Merge layer groups") self['merge_layer_groups'].description = _( "If enabled, each top-level layer group is merged into one layer. The name " "of each merged layer is the name of the corresponding top-level layer group." ) self._add(pgsetting.BoolSetting('empty_folders', False)) self['empty_folders'].display_name = _("Create folders for empty layer groups") self['empty_folders'].description = _( "If enabled, subfolders for empty layer groups will be created." ) self._add(pgsetting.BoolSetting('ignore_layer_modes', False)) self['ignore_layer_modes'].display_name = _("Ignore layer modes") self['ignore_layer_modes'].description = _( "If enabled, the layer mode for each layer will be set to Normal. This is " "useful for layers with opacity less than 100% and a layer mode different " "than Normal or Dissolve, which would normally be completely invisible " "if a file format supporting alpha channel is used (such as PNG)." ) self._add( pgsetting.EnumSetting( 'overwrite_mode', 'rename_new', [('replace', _("Replace"), exportlayers.OverwriteHandler.REPLACE), ('skip', _("Skip"), exportlayers.OverwriteHandler.SKIP), ('rename_new', _("Rename new file"), exportlayers.OverwriteHandler.RENAME_NEW), ('rename_existing', _("Rename existing file"), exportlayers.OverwriteHandler.RENAME_EXISTING), ('cancel', _("Cancel"), exportlayers.OverwriteHandler.CANCEL)] ) ) self['overwrite_mode'].display_name = _("Overwrite mode (non-interactive run mode only)") self['overwrite_mode'].description = _( "Indicates how to handle conflicting files. Skipped layers " "will not be regarded as exported." ) #--------------------------------------------------------------------------- self['file_ext_mode'].description = _( 'If "{0}" is selected, "{1}" must still be ' 'specified (for layers with invalid or no file extension).' ).format(self['file_ext_mode'].options_display_names['use_as_file_extensions'], self['file_extension'].display_name) self['square_bracketed_mode'].description = _( '"{0}": these layers will be used as a background for all other layers ' 'and will not be exported separately.\n' '"{1}": these layers will not be exported (and will not be treated as ' 'background layers).\n' '"{2}": all other layers will not be exported.' ).format(self['square_bracketed_mode'].options_display_names['background'], self['square_bracketed_mode'].options_display_names['ignore'], self['square_bracketed_mode'].options_display_names['ignore_other']) self['file_extension'].error_messages['default_needed'] = _( "You need to specify default file extension for layers with invalid or no extension." ) #--------------------------------------------------------------------------- def streamline_layer_groups_as_folders(layer_groups_as_folders, empty_folders, merge_layer_groups): if not layer_groups_as_folders.value: empty_folders.value = False empty_folders.ui_enabled = False merge_layer_groups.ui_enabled = True else: empty_folders.ui_enabled = True merge_layer_groups.ui_enabled = False merge_layer_groups.value = False def streamline_file_ext_mode(file_ext_mode, file_extension, strip_mode): if file_ext_mode.value == file_ext_mode.options['no_special_handling']: strip_mode.ui_enabled = True file_extension.error_messages[pgpath.FileExtensionValidator.IS_EMPTY] = "" elif file_ext_mode.value == file_ext_mode.options['only_matching_file_extension']: strip_mode.value = strip_mode.options['never'] strip_mode.ui_enabled = False file_extension.error_messages[pgpath.FileExtensionValidator.IS_EMPTY] = "" elif file_ext_mode.value == file_ext_mode.options['use_as_file_extensions']: strip_mode.value = strip_mode.options['never'] strip_mode.ui_enabled = False file_extension.error_messages[pgpath.FileExtensionValidator.IS_EMPTY] = ( file_extension.error_messages['default_needed'] ) def streamline_merge_layer_groups(merge_layer_groups, layer_groups_as_folders): if merge_layer_groups.value: layer_groups_as_folders.value = False layer_groups_as_folders.ui_enabled = False else: layer_groups_as_folders.ui_enabled = True def streamline_autocrop(autocrop, square_bracketed_mode, crop_to_background): if autocrop.value and square_bracketed_mode.value == square_bracketed_mode.options['background']: crop_to_background.ui_enabled = True else: crop_to_background.value = False crop_to_background.ui_enabled = False def streamline_square_bracketed_mode(square_bracketed_mode, autocrop, crop_to_background): if autocrop.value and square_bracketed_mode.value == square_bracketed_mode.options['background']: crop_to_background.ui_enabled = True else: crop_to_background.value = False crop_to_background.ui_enabled = False #--------------------------------------------------------------------------- self['layer_groups_as_folders'].set_streamline_func( streamline_layer_groups_as_folders, self['empty_folders'], self['merge_layer_groups'] ) self['file_ext_mode'].set_streamline_func( streamline_file_ext_mode, self['file_extension'], self['strip_mode'] ) self['merge_layer_groups'].set_streamline_func( streamline_merge_layer_groups, self['layer_groups_as_folders'] ) self['autocrop'].set_streamline_func( streamline_autocrop, self['square_bracketed_mode'], self['crop_to_background'] ) self['square_bracketed_mode'].set_streamline_func( streamline_square_bracketed_mode, self['autocrop'], self['crop_to_background'] )
class ExportLayersPlugin(gimpplugin.plugin): PLUG_IN_EXPORT_LAYERS_PARAMS = [ (gimpenums.PDB_INT32, "run_mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }"), (gimpenums.PDB_IMAGE, "image", "Image to export layers from"), (gimpenums.PDB_STRING, "file_format", "File format"), (gimpenums.PDB_STRING, "output_directory", "Output directory"), (gimpenums.PDB_INT32, "layer_groups_as_directories", "Treat layer groups as directories"), (gimpenums.PDB_INT32, "ignore_invisible", "Ignore invisible layers"), (gimpenums.PDB_INT32, "is_autocrop", "Autocrop layers"), (gimpenums.PDB_INT32, "use_image_size", "Use image size instead of layer size"), (gimpenums.PDB_INT32, "overwrite_mode", ("Overwrite mode (non-interactive only)" "{ 1 = Skip, 2 = Overwrite, 3 = Rename new files, 4 = Rename existing files}" )), ] PLUG_IN_EXPORT_LAYERS_TO_PARAMS = [ (gimpenums.PDB_INT32, "run_mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }"), (gimpenums.PDB_IMAGE, "image", "Image to export layers from"), ] PARAMS_DEFAULT_VALUES = { 'file_format': "", 'output_directory': gimp.user_directory(4), # Pictures directory 'overwrite_mode': OverwriteMode.OVERWRITE, 'layer_groups_as_directories': False, 'ignore_invisible': False, 'is_autocrop': False, 'use_image_size': False, } PLUG_IN_RETS = [ # (gimpenums.PDB_INT32ARRAY, "exported_layers", "Layer IDs of exported layers"), ] def query(self): gimp.install_procedure( "plug_in_export_layers", "Export layers as separate images in specified file format to specified directory.", "Layer names are used as filenames for the exported images.", "khalim19", "khalim19", "2013", "<Image>/File/Export/E_xport Layers...", "*", gimpenums.PLUGIN, self.PLUG_IN_EXPORT_LAYERS_PARAMS, self.PLUG_IN_RETS) gimp.install_procedure( "plug_in_export_layers_to", "Run Export Layers with last values specified.", ("This plug-in runs plug-in-export-layers non-interactively, using last values specified in that plug-in. " "If plug-in-export-layers was not run for the first time, plug-in-export-layers will be run interactively, " "otherwise this plug-in will take effect. " "Refer to plug-in-export-layers for more information."), "khalim19", "khalim19", "2013", "<Image>/File/Export/Export Layers _to", "*", gimpenums.PLUGIN, self.PLUG_IN_EXPORT_LAYERS_TO_PARAMS, self.PLUG_IN_RETS) def plug_in_export_layers(self, run_mode, image, file_format=None, output_directory=None, layer_groups_as_directories=False, ignore_invisible=False, is_autocrop=False, use_image_size=False, overwrite_mode=OverwriteMode.OVERWRITE): if run_mode == gimpenums.RUN_INTERACTIVE: gui = ExportLayersGui(image) gtk.main() exported_layers = retrieve_setting('exported_layers', ()) elif run_mode == gimpenums.RUN_WITH_LAST_VALS: first_run = retrieve_setting('first_run', True) if first_run: raise ExportLayersError( "No last values specified. Use RUN_INTERACTIVE or RUN_NONINTERACTIVE run mode" ) exported_layers = export_layers( run_mode, image, retrieve_setting('file_format', self.PARAMS_DEFAULT_VALUES['file_format']), retrieve_setting( 'output_directory', self.PARAMS_DEFAULT_VALUES['output_directory']), NoninteractiveOverwrite( retrieve_setting( 'overwrite_mode', self.PARAMS_DEFAULT_VALUES['overwrite_mode'])), retrieve_setting( 'layer_groups_as_directories', self.PARAMS_DEFAULT_VALUES['layer_groups_as_directories']), retrieve_setting( 'ignore_invisible', self.PARAMS_DEFAULT_VALUES['ignore_invisible']), retrieve_setting('is_autocrop', self.PARAMS_DEFAULT_VALUES['is_autocrop']), retrieve_setting('use_image_size', self.PARAMS_DEFAULT_VALUES['use_image_size']), ) else: # gimpenums.RUN_NONINTERACTIVE if output_directory is None: output_directory = self.PARAMS_DEFAULT_VALUES[ 'output_directory'] if file_format is None: file_format = self.PARAMS_DEFAULT_VALUES['file_format'] if overwrite_mode not in OverwriteMode.OVERWRITE_MODES: overwrite_mode = self.PARAMS_DEFAULT_VALUES['overwrite_mode'] exported_layers = export_layers( run_mode, image, file_format, output_directory, NoninteractiveOverwrite(overwrite_mode), layer_groups_as_directories, ignore_invisible, is_autocrop, use_image_size) store_settings(first_run=False) # Sadly, upon returning the value, "Execution Error" is thrown, # and I coudn't find a way to resolve it. # return tuple([layer.ID for layer in exported_layers]) def plug_in_export_layers_to(self, run_mode, image): first_run = retrieve_setting('first_run', True) if not first_run: exported_layers = self.plug_in_export_layers( gimpenums.RUN_WITH_LAST_VALS, image) else: exported_layers = self.plug_in_export_layers( gimpenums.RUN_INTERACTIVE, image)
class ExportLayersPlugin(gimpplugin.plugin): PLUG_IN_EXPORT_LAYERS_PARAMS = [ (gimpenums.PDB_INT32, "run_mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }"), (gimpenums.PDB_IMAGE, "image", "Image to export layers from"), (gimpenums.PDB_STRING, "file_format", "File format"), (gimpenums.PDB_STRING, "output_directory", "Output directory"), (gimpenums.PDB_INT32, "overwrite_mode", ("Overwrite mode (non-interactive only)" "{ 1 = Skip, 2 = Overwrite, 3 = Rename new files, 4 = Rename existing files}" )), ] PARAMS_DEFAULT_VALUES = { 'file_format': "png", 'output_directory': gimp.user_directory(4), # Pictures directory 'overwrite_mode': OverwriteMode.OVERWRITE, } PLUG_IN_RETS = [] def query(self): gimp.install_procedure( "plug_in_export_layers", "Export layers as separate images in specified file format to specified directory.", "Layer names are used as filenames for the exported images.", "khalim19", "khalim19", "2014", "<Image>/File/Export/E_xport Layers (HTI)...", "*", gimpenums.PLUGIN, self.PLUG_IN_EXPORT_LAYERS_PARAMS, self.PLUG_IN_RETS) def plug_in_export_layers(self, run_mode, image, file_format=None, output_directory=None, overwrite_mode=OverwriteMode.OVERWRITE): if run_mode == gimpenums.RUN_INTERACTIVE: gui = ExportLayersGui(image) gtk.main() elif run_mode == gimpenums.RUN_WITH_LAST_VALS: first_run = retrieve_setting('first_run', True) if first_run: raise ExportLayersError( "No last values specified. Use RUN_INTERACTIVE or RUN_NONINTERACTIVE run mode" ) export_layers( run_mode, image, retrieve_setting('file_format', self.PARAMS_DEFAULT_VALUES['file_format']), retrieve_setting( 'output_directory', self.PARAMS_DEFAULT_VALUES['output_directory']), NoninteractiveOverwrite( retrieve_setting( 'overwrite_mode', self.PARAMS_DEFAULT_VALUES['overwrite_mode']))) else: # gimpenums.RUN_NONINTERACTIVE if output_directory is None: output_directory = self.PARAMS_DEFAULT_VALUES[ 'output_directory'] if file_format is None: file_format = self.PARAMS_DEFAULT_VALUES['file_format'] if overwrite_mode not in OverwriteMode.OVERWRITE_MODES: overwrite_mode = self.PARAMS_DEFAULT_VALUES['overwrite_mode'] export_layers(run_mode, image, file_format, output_directory, NoninteractiveOverwrite(overwrite_mode)) store_settings(first_run=False)
from gimp import pdb from export_layers import builtin_procedures from export_layers import builtin_constraints from export_layers import operations from export_layers import settings_plugin from export_layers.gui import main as gui_main PLUGINS_DIRPATH = os.path.dirname(os.path.dirname(pg.utils.get_current_module_filepath())) TEST_IMAGES_DIRPATH = os.path.join(pg.config.PLUGIN_SUBDIRPATH, "tests", "test_images") TEST_IMAGES_FILEPATH = os.path.join( TEST_IMAGES_DIRPATH, "test_export_layers_contents.xcf") if gimp.user_directory(4): OUTPUT_DIRPATH = os.path.join(gimp.user_directory(4), "Loading Screens", "Components") else: OUTPUT_DIRPATH = os.path.join(gimp.directory, "Loading Screens", "Components") SCREENSHOTS_DIRPATH = os.path.join(PLUGINS_DIRPATH, "docs", "images") SCREENSHOT_DIALOG_BASIC_USAGE_FILENAME = "screenshot_dialog_basic_usage.png" SCREENSHOT_DIALOG_CUSTOMIZING_EXPORT_FILENAME = "screenshot_dialog_customizing_export.png" def take_screenshots(gui, dialog, settings): pg.path.make_dirs(OUTPUT_DIRPATH) settings["gui_session/current_directory"].set_value(OUTPUT_DIRPATH) settings["gui/show_more_settings"].set_value(False)