Skip to content

Commit

Permalink
Add Unicode support
Browse files Browse the repository at this point in the history
Also, cleanup here and there.
  • Loading branch information
khalim19 committed Jul 15, 2014
1 parent 8b40f4c commit 8ec3139
Show file tree
Hide file tree
Showing 13 changed files with 164 additions and 57 deletions.
10 changes: 7 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
2.1 (Upcoming)
------------------------

* Added support for Unicode characters. This means you can now use any character
in layer names and the output directory, except for most of the special characters.
* Renamed "File format" to "File extension" since that's what the user actually
specifies. Because of this, if you use "Save settings", you'll need to re-save them.
* Renamed a bunch of options so that they contain "extension" instead of "format".
specifies. Also, Renamed a bunch of options so that they contain "extension"
instead of "format". Because of this, if you use "Save settings", you'll need to
re-save them.
* Removed "Remove squared brackets" setting as it served little purpose.
[square brackets] will now always be removed from the layer names.
[square brackets] will now always be removed from layer names.
* Added "Ignore Layer Mode" setting, which sets the layer mode to Normal for each layer.
* Fixed a bug that caused the file format dialog to not appear if the user chose
Skip in the overwrite dialog for the first file (or the first and subsequent files).
* When "No special handling" is selected, file extension strip mode now defaults to
"Strip identical file extension".
* More special characters are now removed from layer names.
* Removed unnecessary files from the package.
* More code refactoring and cleanup.

Expand Down
10 changes: 7 additions & 3 deletions export_layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@

from __future__ import absolute_import
from __future__ import print_function
#from __future__ import unicode_literals
from __future__ import unicode_literals
from __future__ import division

str = unicode

#===============================================================================

import gimp
Expand Down Expand Up @@ -69,7 +71,7 @@ def __init__(self):
self.export_layers_to_settings = [
self.special_settings['run_mode'],
self.special_settings['image'],
]
]

self.export_layers_return_values = []
self.export_layers_to_return_values = []
Expand Down Expand Up @@ -128,6 +130,8 @@ def plug_in_export_layers_to(self, run_mode, image):
def _run_noninteractive(self, image, args):
# Start with the third parameter - run_mode and image are already set.
for setting, arg in zip(self.export_layers_settings[2:], args[2:]):
if isinstance(arg, bytes):
arg = arg.decode()
setting.value = arg

self._run_plugin_noninteractive(gimpenums.RUN_NONINTERACTIVE, image)
Expand Down Expand Up @@ -174,7 +178,7 @@ def _create_plugin_params(self, settings):
return [self._create_plugin_param(setting) for setting in settings]

def _create_plugin_param(self, setting):
return (setting.gimp_pdb_type, setting.name, setting.short_description)
return (setting.gimp_pdb_type, setting.name.encode(), setting.short_description.encode())

#===============================================================================

Expand Down
4 changes: 3 additions & 1 deletion export_layers/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@

from __future__ import absolute_import
from __future__ import print_function
#from __future__ import unicode_literals
from __future__ import unicode_literals
from __future__ import division

str = unicode

#===============================================================================

import os
Expand Down
48 changes: 25 additions & 23 deletions export_layers/exportlayers.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@

from __future__ import absolute_import
from __future__ import print_function
#from __future__ import unicode_literals
from __future__ import unicode_literals
from __future__ import division

str = unicode

#===============================================================================

import os
Expand Down Expand Up @@ -242,8 +244,7 @@ def _init_attributes(self):

def _process_export_layers_args(self):
"""
Process and validate arguments (user input) passed when calling
the `export_layers()` method.
Process the main settings and layer names.
Set layer filters according to the main settings.
"""
Expand Down Expand Up @@ -281,8 +282,9 @@ def _process_export_layers_args(self):
# brackets. After the validation, the square brackets will be removed,
# thus getting mixed with the other layers that don't have them.
# The solution is to cache the layers that match the current filters.
# Temporarily remove the 'layer_types' subfilter so that 'empty_directories'
# does not end up with zero empty layer groups if the image has some.
# Also, temporarily remove the 'layer_types' subfilter so that
# 'empty_directories' does not end up with zero empty layer groups if
# the image has some.
with self._layer_data.filter.remove_subfilter_temp('layer_types'):
self._layer_data.cache_layers()

Expand All @@ -293,8 +295,8 @@ def _process_export_layers_args(self):
if self._layer_data.filter.has_rule(LayerFilters.is_not_enclosed_in_square_brackets):
self._layer_data.filter.remove_rule(LayerFilters.is_not_enclosed_in_square_brackets)

# Validate every layer. It makes a lot of things easier and doesn't affect
# the end result.
# Validate all layers and groups. It makes a lot of things easier and
# doesn't affect the end result.
self._layer_data.is_filtered = False
for layerdata_elem in self._layer_data:
layerdata_elem.validate_name()
Expand Down Expand Up @@ -375,11 +377,12 @@ def _do_export_layers(self):
self._export(layerdata_elem, self._image_copy, layer_copy)

self.progress_updater.update_tasks(1)
pdb.gimp_image_remove_layer(self._image_copy, layer_copy)
if not self._is_current_layer_skipped:
# Append the original layer, not the copy, since the copy was destroyed.
# Append the original layer, not the copy, since the copy is going to be
# destroyed.
self._exported_layers.append(layer)
self._layer_file_extension_properties[self._file_extension].processed_count += 1
pdb.gimp_image_remove_layer(self._image_copy, layer_copy)

def _setup(self):
# Save context just in case. No need for undo groups or undo freeze here.
Expand Down Expand Up @@ -422,7 +425,6 @@ def _uniquify_layer_names(self):
self.main_settings['file_ext_mode'].options['only_matching_file_extension']))

if self.main_settings['empty_directories'].value:
# If layer_groups_as_directories is True, even non-empty layer groups must be uniquified.
with self._layer_data.filter['layer_types'].remove_rule_temp(LayerFilters.is_layer):
self._layer_data.uniquify_layer_names(include_layer_path, place_before_file_extension)
else:
Expand All @@ -431,38 +433,37 @@ def _uniquify_layer_names(self):
def _remove_copy_suffix(self, layer, layer_copy):
if layer_copy.name.endswith(self._COPY_SUFFIX) and not layer.name.endswith(self._COPY_SUFFIX):
layer_copy.name = layer_copy.name.rstrip(self._COPY_SUFFIX)

return layer_copy

def _crop_and_merge(self, layer_copy):
def _crop_and_merge(self, layer):
if not self.main_settings['use_image_size'].value:
pdb.gimp_image_resize_to_layers(self._image_copy)
if self.main_settings['crop_to_background'].value:
if self._background_layerdata:
layer_copy = pdb.gimp_image_merge_visible_layers(self._image_copy, gimpenums.CLIP_TO_IMAGE)
layer = pdb.gimp_image_merge_visible_layers(self._image_copy, gimpenums.CLIP_TO_IMAGE)
if self.main_settings['autocrop'].value:
pdb.plug_in_autocrop(self._image_copy, layer_copy)
pdb.plug_in_autocrop(self._image_copy, layer)
else:
if self.main_settings['autocrop'].value:
pdb.plug_in_autocrop(self._image_copy, layer_copy)
pdb.plug_in_autocrop(self._image_copy, layer)
if self._background_layerdata:
layer_copy = pdb.gimp_image_merge_visible_layers(self._image_copy, gimpenums.CLIP_TO_IMAGE)
layer = pdb.gimp_image_merge_visible_layers(self._image_copy, gimpenums.CLIP_TO_IMAGE)
else:
if self.main_settings['crop_to_background'].value and self._background_layer_merged is not None:
if self.main_settings['autocrop'].value:
self._image_copy.active_layer = self._background_layer_merged
pdb.plug_in_autocrop_layer(self._image_copy, self._background_layer_merged)
self._image_copy.active_layer = layer_copy
self._image_copy.active_layer = layer
else:
if self.main_settings['autocrop'].value:
pdb.plug_in_autocrop_layer(self._image_copy, layer_copy)
pdb.plug_in_autocrop_layer(self._image_copy, layer)

if self._background_layerdata:
layer_copy = pdb.gimp_image_merge_visible_layers(self._image_copy, gimpenums.CLIP_TO_IMAGE)
layer = pdb.gimp_image_merge_visible_layers(self._image_copy, gimpenums.CLIP_TO_IMAGE)

pdb.gimp_layer_resize_to_image_size(layer_copy)
pdb.gimp_layer_resize_to_image_size(layer)

return layer_copy
return layer

def _set_file_extension(self, layerdata_elem):
if (self.main_settings['file_ext_mode'].value ==
Expand Down Expand Up @@ -510,11 +511,12 @@ def _export(self, layerdata_elem, image, layer):
self.progress_updater.update_text("Saving '" + output_filename + "'")

if not self._is_current_layer_skipped:
libfiles.make_dirs(os.path.dirname(output_filename))
self._export_layer(self._file_export_func, image, layer, output_filename)

def _export_layer(self, file_export_function, image, layer, output_filename):
run_mode = self._get_run_mode()
libfiles.make_dirs(os.path.dirname(output_filename))

self._export_layer_once(file_export_function, run_mode,
image, layer, output_filename)

Expand All @@ -528,7 +530,7 @@ def _export_layer_once(self, file_export_function, run_mode,
self._current_layer_export_status = self._NOT_EXPORTED_YET

try:
file_export_function(image, layer, output_filename, os.path.basename(output_filename),
file_export_function(image, layer, output_filename.encode(), os.path.basename(output_filename).encode(),
run_mode=run_mode)
except RuntimeError as e:
# HACK: Since RuntimeError could indicate anything, including pdb.gimp_file_save
Expand Down
25 changes: 15 additions & 10 deletions export_layers/gui_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@

from __future__ import absolute_import
from __future__ import print_function
#from __future__ import unicode_literals
from __future__ import unicode_literals
from __future__ import division

str = unicode

#===============================================================================

import traceback
Expand Down Expand Up @@ -211,18 +213,22 @@ def _init_gui(self):

self.advanced_settings_file_ext_mode_label = gtk.Label(self.main_settings['file_ext_mode'].display_name + ":")
self.advanced_settings_file_ext_mode_label.set_alignment(0, 0.5)
self.advanced_settings_file_ext_mode = gimpui.IntComboBox(
tuple(self.main_settings['file_ext_mode'].get_option_display_names_and_values()))
self.advanced_settings_strip_mode = gimpui.IntComboBox(
tuple(self.main_settings['strip_mode'].get_option_display_names_and_values()))
self.advanced_settings_file_ext_mode = gui.IntComboBox(
self.main_settings['file_ext_mode'].get_option_display_names_and_values()
)
self.advanced_settings_strip_mode = gui.IntComboBox(
self.main_settings['strip_mode'].get_option_display_names_and_values()
)

self.advanced_settings_square_bracketed_mode_label = gtk.Label(
self.main_settings['square_bracketed_mode'].display_name + ":")
self.advanced_settings_square_bracketed_mode_label.set_alignment(0, 0.5)
self.advanced_settings_square_bracketed_mode = gimpui.IntComboBox(
tuple(self.main_settings['square_bracketed_mode'].get_option_display_names_and_values()))
self.advanced_settings_square_bracketed_mode = gui.IntComboBox(
self.main_settings['square_bracketed_mode'].get_option_display_names_and_values()
)
self.advanced_settings_crop_to_background = gtk.CheckButton(
self.main_settings['crop_to_background'].display_name)
self.main_settings['crop_to_background'].display_name
)

self.advanced_settings_merge_layer_groups = gtk.CheckButton(self.main_settings['merge_layer_groups'].display_name)
self.advanced_settings_empty_directories = gtk.CheckButton(self.main_settings['empty_directories'].display_name)
Expand Down Expand Up @@ -342,7 +348,7 @@ def create_setting_presenters(self):
self.main_settings['output_directory'],
self.directory_chooser,
image=self.image,
default_directory=None))
default_directory=None)) # in GTK, None = recently used directory

self.setting_presenters.add(
gui.GtkCheckButtonPresenter(
Expand Down Expand Up @@ -515,7 +521,6 @@ def refresh_ui(self):
return True

def display_message_label(self, text, message_type=ERROR):

if text is None or not text:
self.label_message.set_text("")
else:
Expand Down
2 changes: 1 addition & 1 deletion export_layers/pylibgimpplugin
4 changes: 3 additions & 1 deletion export_layers/runtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,11 @@

from __future__ import absolute_import
from __future__ import print_function
#from __future__ import unicode_literals
from __future__ import unicode_literals
from __future__ import division

str = unicode

#===============================================================================

import os
Expand Down
6 changes: 3 additions & 3 deletions export_layers/settings_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@

from __future__ import absolute_import
from __future__ import print_function
#from __future__ import unicode_literals
from __future__ import unicode_literals
from __future__ import division

str = unicode

#===============================================================================

import gimp
Expand Down Expand Up @@ -82,8 +84,6 @@ def _create_settings(self):
"To export in raw format, type \"raw\"."
)

# self._add(settings.StringSetting('output_directory', gimp.user_directory(1))) # Documents directory
# self['output_directory'].display_name = "Output directory"
self._add(settings.DirectorySetting('output_directory', gimp.user_directory(1))) # Documents directory
self['output_directory'].display_name = "Output directory"

Expand Down
4 changes: 3 additions & 1 deletion export_layers/tee_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@

from __future__ import absolute_import
from __future__ import print_function
#from __future__ import unicode_literals
from __future__ import unicode_literals
from __future__ import division

str = unicode

#===============================================================================

import sys
Expand Down
22 changes: 14 additions & 8 deletions export_layers/tests/test_exportlayers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,29 @@

from __future__ import absolute_import
from __future__ import print_function
#from __future__ import unicode_literals
from __future__ import unicode_literals
from __future__ import division

str = unicode

#===============================================================================

import os

#===============================================================================

# This isn't a unit test, but rather a helper function to test the export to
# all file formats recognized by GIMP (+ GIMP DDS Plugin) at once.
def test_export_layers(layer_exporter, main_settings):
file_extensions = ['raw', 'xcf', 'pix', 'matte', 'mask', 'alpha', 'als', 'fli', 'flc',
'xcf.bz2', 'xcfbz2', 'c', 'h', 'xhtml', 'dds', 'dcm', 'dicom', 'eps',
'fit', 'fits', 'gif', 'gbr', 'gih', 'pat', 'xcf.gz', 'xcfgz',
'html', 'htm', 'jpg', 'jpeg', 'jpe', 'cel', 'ico', 'mng', 'ora', 'pbm',
'pgm', 'psd', 'png', 'pnm', 'pdf', 'ps', 'ppm', 'sgi', 'rgb', 'rgba',
'bw', 'icon', 'im1', 'im8', 'im24', 'im32', 'rs', 'ras', 'tga', 'tif',
'tiff', 'bmp', 'xbm', 'bitmap', 'xpm', 'xwd', 'pcx', 'pcc']
file_extensions = [
'raw', 'xcf', 'pix', 'matte', 'mask', 'alpha', 'als', 'fli', 'flc',
'xcf.bz2', 'xcfbz2', 'c', 'h', 'xhtml', 'dds', 'dcm', 'dicom', 'eps',
'fit', 'fits', 'gif', 'gbr', 'gih', 'pat', 'xcf.gz', 'xcfgz',
'html', 'htm', 'jpg', 'jpeg', 'jpe', 'cel', 'ico', 'mng', 'ora', 'pbm',
'pgm', 'psd', 'png', 'pnm', 'pdf', 'ps', 'ppm', 'sgi', 'rgb', 'rgba',
'bw', 'icon', 'im1', 'im8', 'im24', 'im32', 'rs', 'ras', 'tga', 'tif',
'tiff', 'bmp', 'xbm', 'bitmap', 'xpm', 'xwd', 'pcx', 'pcc'
]

orig_output_directory = main_settings['output_directory'].value

Expand Down
4 changes: 2 additions & 2 deletions resources/export_layers.glade
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;File format:&lt;/b&gt;</property>
<property name="label" translatable="yes">&lt;b&gt;File extension:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
Expand Down Expand Up @@ -344,7 +344,7 @@
</child>
<child>
<object class="GtkCheckButton" id="checkbutton5">
<property name="label" translatable="yes">Remove square brackets</property>
<property name="label" translatable="yes">Crop to background</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
Expand Down
Loading

0 comments on commit 8ec3139

Please sign in to comment.