<commit_before>#-------------------------------------------------------------------------------
#
# This file is part of pylibgimpplugin.
#
# Copyright (C) 2014 khalim19 <<EMAIL>>
# 
# pylibgimpplugin is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# pylibgimpplugin is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with pylibgimpplugin.  If not, see <http://www.gnu.org/licenses/>.
#
#-------------------------------------------------------------------------------

"""
This module defines the following classes:
* `LayerData` - an associative container that stores all layers and layer groups
* `_LayerDataElement` - wrapper for gimp.Layer objects containing custom attributes
  derived from the original gimp.Layer attributes
"""

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

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

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

import os

from collections import OrderedDict
from collections import namedtuple

import gimp

from . import libfiles
from . import objectfilter

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

pdb = gimp.pdb

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

class LayerData(object):
  
  """
  This class stores all layers of an image in an ordered dictionary,
  allowing to access the layers via their names and get various custom layer
  attributes derived from the existing layer attributes.
  
  To iterate over layers:
  
    layer_data = LayerData(image, True)
    for elem in layer_data:
      # do stuff
  
  Attributes:
  
  * `image` - GIMP image to get layer data from.
  
  * `is_filtered` - If True, ignore layers that do not match the filter
    (`ObjectFilter`) in this object when iterating.
  
  * `filter` (read-only) - `ObjectFilter` instance where you can add or remove
    filter rules or subfilters to filter layers.
  """
  
  def __init__(self, image, is_filtered=False):
    
    self.image = image
    
    self.is_filtered = is_filtered
    
    # Filters applied to all layers in self._layerdata
    self._filter = objectfilter.ObjectFilter()
    
    # Contains all layers (including layer groups) in the layer tree.
    # key: `gimp.Layer.name` (`gimp.Layer` names are unique)
    # value: `_LayerDataElement` object
    self._layerdata = OrderedDict()
    
    self._cached_layerdata = None
    
    self._fill_layer_data()
  
  @property
  def filter(self):
    return self._filter
  
  def __getitem__(self, layer_name):
    return self._layerdata[layer_name]
  
  def __contains__(self, layer_name):
    return layer_name in self._layerdata
  
  def __len__(self):
    return len([layerdata_elem for layerdata_elem in self])
  
  def __iter__(self):
    """
    If not filtered, iterate over all layers. If filtered, iterate only over
    layers that match the filter in this object.
    
    Yields:
    
    * `layerdata_elem` - The current `_LayerDataElement` object.
    """
    
    if not self.is_filtered:
      for layerdata_elem in self._layerdata.values():
        yield layerdata_elem
    else:
      if self._cached_layerdata is None:
        layerdata = self._layerdata
      else:
        layerdata = self._cached_layerdata
      
      for layerdata_elem in layerdata.values():
        if self._filter.is_match(layerdata_elem):
          yield layerdata_elem
  
  def _items(self):
    """
    Yield current (`gimp.Layer.name`, `_LayerDataElement` object) tuple.
    """
    
    if not self.is_filtered:
      for name, layerdata_elem in self._layerdata.items():
        yield name, layerdata_elem
    else:
      for name, layerdata_elem in self._layerdata.items():
        if self._filter.is_match(layerdata_elem):
          yield name, layerdata_elem
  
  def cache_layers(self):
    """
    Cache layers that match the filter in this class. If you remove filters
    after calling this method and then iterate, this class will iterate over
    the cached layers only.
    
    To clear the layer cache, simply call `clear_cache()`.
    
    Calling `cache_layers()` again renews the layer cache.
    """
    
    self._cached_layerdata = OrderedDict(self._items())
  
  def clear_cache(self):
    """
    Clear the layer cache after `cache_layers()` was called.
    
    Nothing happens if the cache is empty (since there is nothing to clear).
    """<commit_msg>Minor clarification<commit_after>#-------------------------------------------------------------------------------
#
# This file is part of pylibgimpplugin.
#
# Copyright (C) 2014 khalim19 <<EMAIL>>
# 
# pylibgimpplugin is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# pylibgimpplugin is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with pylibgimpplugin.  If not, see <http://www.gnu.org/licenses/>.
#
#-------------------------------------------------------------------------------

"""
This module defines the following classes:
* `LayerData` - an associative container that stores all layers and layer groups
* `_LayerDataElement` - wrapper for gimp.Layer objects containing custom attributes
  derived from the original gimp.Layer attributes
"""

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

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

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

import os

from collections import OrderedDict
from collections import namedtuple

import gimp

from . import libfiles
from . import objectfilter

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

pdb = gimp.pdb

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

class LayerData(object):
  
  """
  This class stores all layers of an image in an ordered dictionary,
  allowing to access the layers via their names and get various custom layer
  attributes derived from the existing layer attributes.
  
  To iterate over layers:
  
    layer_data = LayerData(image, True)
    for elem in layer_data:
      # do stuff
  
  Attributes:
  
  * `image` - GIMP image to get layer data from.
  
  * `is_filtered` - If True, ignore layers that do not match the filter
    (`ObjectFilter`) in this object when iterating.
  
  * `filter` (read-only) - `ObjectFilter` instance where you can add or remove
    filter rules or subfilters to filter layers.
  """
  
  def __init__(self, image, is_filtered=False):
    
    self.image = image
    
    self.is_filtered = is_filtered
    
    # Filters applied to all layers in self._layerdata
    self._filter = objectfilter.ObjectFilter()
    
    # Contains all layers (including layer groups) in the layer tree.
    # key: `gimp.Layer.name` (`gimp.Layer` names are unique)
    # value: `_LayerDataElement` object
    self._layerdata = OrderedDict()
    
    self._cached_layerdata = None
    
    self._fill_layer_data()
  
  @property
  def filter(self):
    return self._filter
  
  def __getitem__(self, layer_name):
    return self._layerdata[layer_name]
  
  def __contains__(self, layer_name):
    return layer_name in self._layerdata
  
  def __len__(self):
    return len([layerdata_elem for layerdata_elem in self])
  
  def __iter__(self):
    """
    If not filtered, iterate over all layers. If filtered, iterate only over
    layers that match the filter in this object.
    
    Yields:
    
    * `layerdata_elem` - The current `_LayerDataElement` object.
    """
    
    if not self.is_filtered:
      for layerdata_elem in self._layerdata.values():
        yield layerdata_elem
    else:
      if self._cached_layerdata is None:
        layerdata = self._layerdata
      else:
        layerdata = self._cached_layerdata
      
      for layerdata_elem in layerdata.values():
        if self._filter.is_match(layerdata_elem):
          yield layerdata_elem
  
  def _items(self):
    """
    Yield current (`gimp.Layer.name`, `_LayerDataElement` object) tuple.
    """
    
    if not self.is_filtered:
      for name, layerdata_elem in self._layerdata.items():
        yield name, layerdata_elem
    else:
      for name, layerdata_elem in self._layerdata.items():
        if self._filter.is_match(layerdata_elem):
          yield name, layerdata_elem
  
  def cache_layers(self):
    """
    Cache layers that match the filter in this class.
    
    If you remove filters after calling this method and then iterate with
    `is_filtered=True`, this class will iterate over the cached layers only.
    If you iterate with `is_filtered=False`, this class will iterate over all
    layers as usual.
    
    To clear the layer cache, simply call `clear_cache()`.
    
    Calling `cache_layers()` again renews the layer cache.
    """
    
    self._cached_layerdata = OrderedDict(self._items())
  
  def clear_cache(self):
    """
    Clear the layer cache after `cache_layers()` was called.
    
    Nothing happens if the cache is empty (since there is nothing to clear).
    """
{'fraction_non_alphanumeric': 0.1590729001584786, 'fraction_numerical': 0.0013866877971473852, 'mean_word_length': 2.9909090909090907, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '169807', 'n_tokens_mistral': 2714, 'n_tokens_neox': 2628, 'n_words': 991}