<filename>src/Model/Package/entries/multiple/multiple_entry.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from copy import deepcopy

from src.Model.Package.inconsistency import MultipleInconsistency

__author__ = '<NAME>'

from src.Model.Package.entries.entry import Entry


# TODO: nekonzistentní pokud mám záznamů mimom rozsah

class MultipleEntry(Entry, MultipleInconsistency):
    """Container for multiple config entries."""

    def __init__(self, entry):
        Entry.__init__(self, entry.name, entry.package)
        MultipleInconsistency.__init__(self)
        self._template = entry
        self._template.multiple = True
        self._template.multiple_entry = self
        self._template.index = -1
        self._template.inc_parents.add(self)
        self.template.init_inconsistency()
        self._entries = []
        self._defaults = []
        # Multiple properties
        self._multiple_min = None
        self._multiple_max = None
        self._inc_parents = set()

    def __deepcopy__(self, memo):
        template = deepcopy(self.template)
        newone = type(self)(template)
        # TODO: není potřeba kopíravat template, ale je v tom případě potřeba vyřešit správně směrování na parent
        newone.__dict__.update(self.__dict__)
        newone._entries = deepcopy(self.entries)
        newone._defaults = deepcopy(self._defaults)
        newone._inc_parents = set()
        return newone

    @property
    def multiple_max(self):
        return self._multiple_max

    @multiple_max.setter
    def multiple_max(self, value):
        if value > 0:
            self._multiple_max = value
        else:
            # 0 or less means multipleMax property is disabled
            self._multiple_max = None

    @property
    def multiple_min(self):
        return self._multiple_min

    @multiple_min.setter
    def multiple_min(self, value):
        if value > 0:
            self._multiple_min = value
        else:
            # 0 or less means multipleMin property is disabled
            self._multiple_min = None

    @property
    def name(self):
        """get name"""
        return self.template.name

    @name.setter
    def name(self, name):
        """set name"""
        self.template.name(name)

    @property
    def parent(self):
        """get name"""
        return self.template.parent

    @parent.setter
    def parent(self, parent):
        """set name"""
        self.inc_parents.add(parent)
        self.template._parent = parent

    @property
    def package(self):
        """get package"""
        return self.template.package

    @package.setter
    def package(self, package):
        """set package"""
        self.template.package(package)

    @property
    def group(self):
        return self.template.group

    @group.setter
    def group(self, group):
        self.template.group = group

    @property
    def multiple(self):
        return False

    @property
    def label(self):
        return self.template.label

    @label.setter
    def label(self, label):
        self.template.label = label

    @property
    def help(self):
        return self.template.help

    @help.setter
    def help(self, help):
        self.template.help = help

    @property
    def active(self):
        return self.template.active

    @active.setter
    def active(self, active):
        self.template.active = active

    @property
    def static_active(self):
        return self.template.static_active

    @static_active.setter
    def static_active(self, active):
        self.template.static_active = active

    def create_new(self, length):
        if self.multiple_max is None or length < self.multiple_max:
            newone = deepcopy(self._template)
            newone.index = length
            return newone
        return None

    def delete_entry(self, index):
        length = self.size()
        if self.multiple_min is None or length > self.multiple_min:
            entry = self._entries.pop(int(index))
            self._rename_all()
            self.check_inconsistency()
            if entry.inconsistent:
                self.change_inconsistency(False)
            return entry
        return None

    def _rename_all(self):
        for i, entry in enumerate(self._entries):
            entry.index = i

    def is_container(self):
        return self._template.is_container()

    def is_keyword(self):
        return self._template.is_keyword()

    def is_multiple_entry_container(self):
        return True

    def get_multiple_entry(self, i):
        return self._entries[i]

    def insert(self, position, entry):
        self._entries.insert(int(position), entry)
        entry.inc_parents.add(self)
        self.check_inconsistency()
        if entry.inconsistent:
            self.change_inconsistency(True)
        self._rename_all()

    def append(self, entry=None):
        entry = entry or self.create_new(self.size())
        if entry:
            self._entries.append(entry)
            self.check_inconsistency()
            entry.inc_parents.add(self)
            if entry.inconsistent:
                self.change_inconsistency(True)
        return entry

    def append_default(self, entry=None):
        entry = entry or self.create_new(self.default_size())
        if entry:
            self._defaults.append(entry)
        return entry

    @property
    def entries(self):
        return self._entries

    @property
    def template(self):
        return self._template

    @template.setter
    def template(self, template_entry):
        self._template = template_entry

    def size(self):
        return len(self._entries)

    def default_size(self):
        return len(self._defaults)

    def _swap(self, i, j):
        """Swap entries at given positions."""
        # Check range
        i = min(self.size() - 1, max(0, i))
        j = min(self.size() - 1, max(0, j))
        if i != j:
            (self._entries[i], self._entries[j]) = (
            self._entries[j], self._entries[i])
            self._rename_all()
            return True
        return False

    def move_up(self, i):
        """Move given entry up in the list. If it is on the top of the list, nothing happens."""
        i = int(i)
        return self._swap(i, i - 1)

    def move_down(self, i):
        """Move given entry down in the list. If it is no the bottom of the list, nothing happens."""
        i = int(i)
        return self._swap(i, i + 1)

    @property
    def type(self):
        return self.template.type

    def find_entry(self, relative_name):
        """Find entry in tree. Name is given in format: a/b/c../entry"""
        try:
            (number, rest) = relative_name.split('/', 1)
            if self.is_container:
                return self._entries[int(number)].find_entry(rest)
        except ValueError:
            return self._entries[int(relative_name)]
        return None

    def check_inconsistency(self):
        length = self.size()
        if self.multiple_min is not None and length < self.multiple_min or self.multiple_max is not None and length > self.multiple_max:
            self.change_self_inconsistency(True)
        else:
            self.change_self_inconsistency(False)

    def init_inconsistency(self):
        self.check_inconsistency()
        for entry in self._entries:
            entry.init_inconsistency()
        self.template.inc_parents.clear()
        self.template.init_inconsistency()
        self.template.inc_parents.add(self)

    def set_default(self):
        self._entries = deepcopy(self._defaults)
        for entry in self._entries:
            entry.set_default()

<filename>src/Model/Package/entries/multiple/multiple_entry.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from copy import deepcopy

from src.Model.Package.inconsistency import MultipleInconsistency

__author__ = '<NAME>'

from src.Model.Package.entries.entry import Entry


# TODO: nekonzistentní pokud mám záznamů mimom rozsah

class MultipleEntry(Entry, MultipleInconsistency):
    """Container for multiple config entries."""

    def __init__(self, entry):
        Entry.__init__(self, entry.name, entry.package)
        MultipleInconsistency.__init__(self)
        self._template = entry
        self._template.multiple = True
        self._template.multiple_entry = self
        self._template.index = -1
        self._template.inc_parents.add(self)
        self.template.init_inconsistency()
        self._entries = []
        self._defaults = []
        # Multiple properties
        self._multiple_min = None
        self._multiple_max = None
        self._inc_parents = set()

    def __deepcopy__(self, memo):
        template = deepcopy(self.template)
        newone = type(self)(template)
        # TODO: není potřeba kopíravat template, ale je v tom případě potřeba vyřešit správně směrování na parent
        newone.__dict__.update(self.__dict__)
        newone._entries = deepcopy(self.entries)
        newone._defaults = deepcopy(self._defaults)
        newone._inc_parents = set()
        return newone

    @property
    def multiple_max(self):
        return self._multiple_max

    @multiple_max.setter
    def multiple_max(self, value):
        if value > 0:
            self._multiple_max = value
        else:
            # 0 or less means multipleMax property is disabled
            self._multiple_max = None

    @property
    def multiple_min(self):
        return self._multiple_min

    @multiple_min.setter
    def multiple_min(self, value):
        if value > 0:
            self._multiple_min = value
        else:
            # 0 or less means multipleMin property is disabled
            self._multiple_min = None

    @property
    def name(self):
        """get name"""
        return self.template.name

    @name.setter
    def name(self, name):
        """set name"""
        self.template.name(name)

    @property
    def parent(self):
        """get name"""
        return self.template.parent

    @parent.setter
    def parent(self, parent):
        """set name"""
        self.inc_parents.add(parent)
        self.template._parent = parent

    @property
    def package(self):
        """get package"""
        return self.template.package

    @package.setter
    def package(self, package):
        """set package"""
        self.template.package(package)

    @property
    def group(self):
        return self.template.group

    @group.setter
    def group(self, group):
        self.template.group = group

    @property
    def multiple(self):
        return False

    @property
    def label(self):
        return self.template.label

    @label.setter
    def label(self, label):
        self.template.label = label

    @property
    def help(self):
        return self.template.help

    @help.setter
    def help(self, help):
        self.template.help = help

    @property
    def active(self):
        return self.template.active

    @active.setter
    def active(self, active):
        self.template.active = active

    @property
    def static_active(self):
        return self.template.static_active

    @static_active.setter
    def static_active(self, active):
        self.template.static_active = active

    def create_new(self, length):
        if self.multiple_max is None or length < self.multiple_max:
            newone = deepcopy(self._template)
            newone.index = length
            return newone
        return None

    def delete_entry(self, index):
        length = self.size()
        if self.multiple_min is None or length > self.multiple_min:
            entry = self._entries.pop(int(index))
            self._rename_all()
            self.check_inconsistency()
            if entry.inconsistent:
                self.change_inconsistency(False)
            return entry
        return None

    def _rename_all(self):
        for i, entry in enumerate(self._entries):
            entry.index = i

    def is_container(self):
        return self._template.is_container()

    def is_keyword(self):
        return self._template.is_keyword()

    def is_multiple_entry_container(self):
        return True

    def get_multiple_entry(self, i):
        return self._entries[i]

    def insert(self, position, entry):
        self._entries.insert(int(position), entry)
        entry.inc_parents.add(self)
        self.check_inconsistency()
        if entry.inconsistent:
            self.change_inconsistency(True)
        self._rename_all()

    def append(self, entry=None):
        entry = entry or self.create_new(self.size())
        if entry:
            self._entries.append(entry)
            self.check_inconsistency()
            entry.inc_parents.add(self)
            if entry.inconsistent:
                self.change_inconsistency(True)
        return entry

    def append_default(self, entry=None):
        entry = entry or self.create_new(self.default_size())
        if entry:
            self._defaults.append(entry)
        return entry

    @property
    def entries(self):
        return self._entries

    @property
    def template(self):
        return self._template

    @template.setter
    def template(self, template_entry):
        self._template = template_entry

    def size(self):
        return len(self._entries)

    def default_size(self):
        return len(self._defaults)

    def _swap(self, i, j):
        """Swap entries at given positions."""
        # Check range
        i = min(self.size() - 1, max(0, i))
        j = min(self.size() - 1, max(0, j))
        if i != j:
            (self._entries[i], self._entries[j]) = (
            self._entries[j], self._entries[i])
            self._rename_all()
            return True
        return False

    def move_up(self, i):
        """Move given entry up in the list. If it is on the top of the list, nothing happens."""
        i = int(i)
        return self._swap(i, i - 1)

    def move_down(self, i):
        """Move given entry down in the list. If it is no the bottom of the list, nothing happens."""
        i = int(i)
        return self._swap(i, i + 1)

    @property
    def type(self):
        return self.template.type

    def find_entry(self, relative_name):
        """Find entry in tree. Name is given in format: a/b/c../entry"""
        try:
            (number, rest) = relative_name.split('/', 1)
            if self.is_container:
                return self._entries[int(number)].find_entry(rest)
        except ValueError:
            return self._entries[int(relative_name)]
        return None

    def check_inconsistency(self):
        length = self.size()
        if self.multiple_min is not None and length < self.multiple_min or self.multiple_max is not None and length > self.multiple_max:
            self.change_self_inconsistency(True)
        else:
            self.change_self_inconsistency(False)

    def init_inconsistency(self):
        self.check_inconsistency()
        for entry in self._entries:
            entry.init_inconsistency()
        self.template.inc_parents.clear()
        self.template.init_inconsistency()
        self.template.inc_parents.add(self)

    def set_default(self):
        self._entries = deepcopy(self._defaults)
        for entry in self._entries:
            entry.set_default()

#!/usr/bin/python3 # -*- coding: utf-8 -*- # TODO: nekonzistentní pokud mám záznamů mimom rozsah Container for multiple config entries. # Multiple properties # TODO: není potřeba kopíravat template, ale je v tom případě potřeba vyřešit správně směrování na parent # 0 or less means multipleMax property is disabled # 0 or less means multipleMin property is disabled get name set name get name set name get package set package Swap entries at given positions. # Check range Move given entry up in the list. If it is on the top of the list, nothing happens. Move given entry down in the list. If it is no the bottom of the list, nothing happens. Find entry in tree. Name is given in format: a/b/c../entry