Example #1
0
    def __init__(self, iconsPanel, application, dialog):
        super().__init__(application)
        self._dialog = dialog
        self._iconsPanel = iconsPanel
        self._groupsMaxWidth = 200
        self._page = None
        self._default_group_cover = getBuiltinImagePath(
            'icons_cover_default.png')
        self._default_icon_filename = os.path.abspath(
            os.path.join(getIconsDirList()[0], ICON_DEFAULT))

        guiconfig = GeneralGuiConfig(application.config)

        self._recentIconsList = RecentIconsList(
            guiconfig.iconsHistoryLength.value,
            application.config,
            getIconsDirList()[0])

        self._recentIconsList.load()

        self._iconsPanel.iconsList.Bind(EVT_ICON_SELECTED,
                                        handler=self._onIconSelected)
        self._iconsPanel.groupCtrl.Bind(EVT_SWITCH,
                                        handler=self._onGroupSelect)

        self._selectedIcon = self._default_icon_filename
        self._groupsInfo = self._getGroupsInfo()

        self._appendGroups()
        group_index = 0 if len(self._recentIconsList) else 1
        self._iconsPanel.groupCtrl.SetSelection(group_index)
Example #2
0
    def __init__(self, iconsPanel, application, dialog):
        super(IconsController, self).__init__(application)
        self._dialog = dialog
        self._iconsPanel = iconsPanel
        self._groupsMaxWidth = 200
        self._page = None
        self._default_group_cover = os.path.join(getImagesDir(),
                                                 u'icons_cover_default.png')
        guiconfig = GeneralGuiConfig(application.config)

        self._recentIconsList = RecentIconsList(
            guiconfig.iconsHistoryLength.value,
            application.config,
            getIconsDirList()[0])

        self._recentIconsList.load()

        self._iconsPanel.iconsList.Bind(EVT_ICON_SELECTED,
                                        handler=self._onIconSelected)
        self._iconsPanel.groupCtrl.Bind(EVT_SWITCH,
                                        handler=self._onGroupSelect)

        self._selectedIcon = None
        self._groupsInfo = self._getGroupsInfo()

        self._appendGroups()
        group_index = 0 if len(self._recentIconsList) else 1
        self._iconsPanel.groupCtrl.SetSelection(group_index)
Example #3
0
    def _getGroupsInfo(self):
        result = []

        for n, path in enumerate(getIconsDirList()):
            # First None is root directory
            collection = IconsCollection(path)
            for groupname in [None] + sorted(collection.getGroups(), key=self._localize):
                # Get group name
                if groupname is None:
                    title = _(u'Not in groups')
                else:
                    title = self._localize(groupname)

                iconslist = collection.getIcons(groupname)
                cover = collection.getCover(groupname)
                if cover is None:
                    cover = self._default_group_cover

                group_type = (IconsGroupInfo.TYPE_BUILTIN if n == 0
                              else IconsGroupInfo.TYPE_CUSTOM)

                result.append(IconsGroupInfo(iconslist,
                                             title,
                                             cover,
                                             group_type=group_type,
                                             sort_key=os.path.basename))

        self._addRecentIconsGroup(result)
        eventParam = IconsGroupsListInitParams(result)
        self._application.onIconsGroupsListInit(self._page, eventParam)

        return eventParam.groupsList
Example #4
0
    def _getGroupsInfo(self):
        result = []

        for n, path in enumerate(getIconsDirList()):
            # First None is root directory
            collection = IconsCollection(path)
            for groupname in [None] + sorted(collection.getGroups(), key=self._localize):
                # Get group name
                if groupname is None:
                    title = _(u'Not in groups')
                else:
                    title = self._localize(groupname)

                if n != 0:
                    title += u' *'

                iconslist = collection.getIcons(groupname)
                cover = collection.getCover(groupname)
                result.append(IconsGroupInfo(iconslist,
                                             title,
                                             cover,
                                             sort_key=os.path.basename))

        self._addRecentIconsGroup(result)
        return result
Example #5
0
    def _getGroupsInfo(self):
        result = []

        for n, path in enumerate(getIconsDirList()):
            # First None is root directory
            collection = IconsCollection(path)
            for groupname in [None] + sorted(collection.getGroups(), key=self._localize):
                # Get group name
                if groupname is None:
                    title = _(u'Not in groups')
                else:
                    title = self._localize(groupname)

                iconslist = collection.getIcons(groupname)
                cover = collection.getCover(groupname)
                if cover is None:
                    cover = self._default_group_cover

                group_type = (IconsGroupInfo.TYPE_BUILTIN if n == 0
                              else IconsGroupInfo.TYPE_CUSTOM)

                result.append(IconsGroupInfo(iconslist,
                                             title,
                                             cover,
                                             group_type=group_type,
                                             sort_key=os.path.basename))

        self._addRecentIconsGroup(result)
        eventParam = IconsGroupsListInitParams(result)
        self._application.onIconsGroupsListInit(self._page, eventParam)

        return eventParam.groupsList
Example #6
0
    def __init__(self, iconsPanel, application, dialog):
        super(IconsController, self).__init__(application)
        self._dialog = dialog
        self._iconsPanel = iconsPanel
        self._groupsMaxWidth = 200
        self._page = None
        self._default_group_cover = os.path.join(getImagesDir(),
                                                 u'icons_cover_default.png')
        guiconfig = GeneralGuiConfig(application.config)

        self._recentIconsList = RecentIconsList(
            guiconfig.iconsHistoryLength.value,
            application.config,
            getIconsDirList()[0])

        self._recentIconsList.load()

        self._iconsPanel.iconsList.Bind(EVT_ICON_SELECTED,
                                        handler=self._onIconSelected)
        self._iconsPanel.groupCtrl.Bind(EVT_SWITCH,
                                        handler=self._onGroupSelect)

        self._selectedIcon = None
        self._groupsInfo = self._getGroupsInfo()

        self._appendGroups()
        self._iconsPanel.groupCtrl.SetSelection(0)
        self._switchToCurrentGroup()
Example #7
0
    def __init__ (self, parent):
        super (IconPanel, self).__init__ (parent)

        self._iconsCollections = [IconsCollection (path) for path in getIconsDirList()]
        self.__createGui()

        self.__appendGroups ()
        self.groupCtrl.SetSelection (0)
        self.__switchToCurrentGroup()
Example #8
0
    def __init__(self, parent):
        super(IconsPanel, self).__init__(parent)

        self._iconsCollections = [
            IconsCollection(path) for path in getIconsDirList()
        ]
        self.__createGui()

        self.__appendGroups()
        self.groupCtrl.SetSelection(0)
        self.__switchToCurrentGroup()
Example #9
0
    def __init__(self, iconsPanel, application, dialog):
        super(IconsController, self).__init__(application)
        self._dialog = dialog
        self._iconsPanel = iconsPanel
        self._groupsMaxWidth = 200

        self._recentIconsList = RecentIconsList(RECENT_ICONS_COUNT,
                                                application.config,
                                                getIconsDirList()[0])
        self._recentIconsList.load()

        self._iconsPanel.iconsList.Bind(EVT_ICON_SELECTED,
                                        handler=self._onIconSelected)
        self._iconsPanel.groupCtrl.Bind(EVT_SWITCH,
                                        handler=self._onGroupSelect)

        self._selectedIcon = None
        self._groupsInfo = self._getGroupsInfo()

        self._appendGroups()
        self._iconsPanel.groupCtrl.SetSelection(0)
        self._switchToCurrentGroup()
Example #10
0
 def __getIconsCollection(self):
     return IconsCollection(getIconsDirList()[-1])
Example #11
0
 def __getIconsCollection(self):
     return IconsCollection(getIconsDirList()[-1])
Example #12
0
class WikiPage(RootWikiPage):
    """
    Страница в дереве.
    """
    paramTags = u"tags"
    paramType = u"type"

    iconController = IconController(getIconsDirList()[0])

    @staticmethod
    def getTypeString():
        return u"base"

    def __init__(self, path, title, parent, readonly=False):
        """
        Constructor.

        path -- путь до страницы
        """
        if not RootWikiPage.testDublicate(parent, title):
            logger.error(
                u'Duplicate page title in the parent page. Title: {}. Parent: {}'
                .format(title, parent.subpath))
            raise DuplicateTitle

        RootWikiPage.__init__(self, path, readonly)
        self._title = title
        self._parent = parent

    @property
    def order(self):
        """
        Вернуть индекс страницы в списке дочерних страниц
        """
        return self.parent.children.index(self)

    @order.setter
    def order(self, neworder):
        """
        Изменить положение страницы(порядок)
        """
        if self.readonly:
            raise ReadonlyException

        realorder = neworder

        if realorder < 0:
            realorder = 0

        if realorder >= len(self.parent.children):
            realorder = len(self.parent.children) - 1

        self.parent._changeChildOrder(self, realorder)
        self.root.onPageOrderChange(self)

    @property
    def alias(self):
        '''
        Added in outwiker.core 1.2
        '''
        alias = self.params.aliasOption.value
        return None if not alias else alias

    @alias.setter
    def alias(self, value):
        '''
        Added in outwiker.core 1.2
        '''
        if self.readonly:
            raise ReadonlyException

        if not value:
            self.params.aliasOption.remove_option()
        else:
            self.params.aliasOption.value = value

        self.root.onTreeUpdate(self)

    @property
    def display_title(self):
        '''
        Added in outwiker.core 1.2
        '''
        return self.alias if self.alias else self.title

    @display_title.setter
    def display_title(self, value):
        '''
        Added in outwiker.core 1.2
        '''
        if not value:
            self.alias = None
        elif self.alias is not None:
            self.alias = value
        else:
            self.title = value

    @property
    def title(self):
        return self._title

    @title.setter
    def title(self, newtitle):
        if self.readonly:
            raise ReadonlyException

        oldtitle = self.title
        oldpath = self.path
        oldsubpath = self.subpath

        if oldtitle == newtitle:
            return

        # Проверка на дубликат страниц, а также на то, что в заголовке страницы
        # может меняться только регистр букв
        if not self.canRename(newtitle):
            raise DuplicateTitle

        newpath = os.path.join(os.path.dirname(oldpath), newtitle)
        os.renames(oldpath, newpath)
        self._title = newtitle

        WikiPage._renamePaths(self, newpath)

        self.root.onPageRename(self, oldsubpath)
        self.root.onTreeUpdate(self)

    def canRename(self, newtitle):
        return (self.title.lower() == newtitle.lower()
                or self.parent[newtitle] is None)

    @staticmethod
    def _renamePaths(page, newPath):
        """
        Скорректировать пути после переименования страницы
        """
        oldPath = page.path
        page._path = newPath
        page._params = RootWikiPage._readParams(page.path)

        for child in page.children:
            newChildPath = child.path.replace(oldPath, newPath, 1)
            WikiPage._renamePaths(child, newChildPath)

    def moveTo(self, newparent):
        """
        Переместить запись к другому родителю
        """
        if self.readonly or newparent.readonly:
            raise ReadonlyException

        if self._parent == newparent:
            return

        if self.isChild(newparent):
            # Нельзя быть родителем своего родителя(предка)
            raise TreeException

        # Проверка на то, что в новом родителе нет записи с таким же заголовком
        if newparent[self.title] is not None:
            raise DuplicateTitle

        oldpath = self.path
        oldparent = self.parent

        # Новый путь для страницы
        newpath = os.path.join(newparent.path, self.title)

        # Временное имя папки.
        # Сначала попробуем переименовать папку во временную,
        # а потом уже ее переместим в нужное место с нужным именем
        tempname = self._getTempName(oldpath)

        try:
            os.renames(oldpath, tempname)
            shutil.move(tempname, newpath)
        except shutil.Error:
            raise TreeException
        except OSError:
            raise TreeException

        self._parent = newparent
        oldparent.removeFromChildren(self)
        newparent.addToChildren(self)

        WikiPage._renamePaths(self, newpath)

        self.root.onTreeUpdate(self)

    def _getTempName(self, pagepath):
        """
        Найти уникальное имя для перемещаемой страницы.
        При перемещении сначала пробуем переименовать папку со страницей,
        а потом уже перемещать.

        pagepath - текущий путь до страницы

        Метод возвращает полный путь
        """
        path, title = os.path.split(pagepath)
        template = u"__{title}_{number}"
        number = 0
        newname = template.format(title=title, number=number)

        while os.path.exists(os.path.join(path, newname)):
            number += 1
            newname = template.format(title=title, number=number)

        return os.path.join(path, newname)

    @property
    def icon(self):
        '''
        Return page icon.
        '''
        return self.iconController.get_icon(self)

    @icon.setter
    def icon(self, iconpath):
        '''
        Return page icon.
        '''
        return self.iconController.set_icon(self, iconpath)

    @property
    def tags(self):
        """
        Получить список тегов для страницы(список строк)
        """
        result = [tag.lower() for tag in self._tags]
        result.sort()
        return result

    @tags.setter
    def tags(self, tags):
        """
        Установить теги для страницы
        tags - список тегов(список строк)
        """
        if self.readonly:
            raise ReadonlyException

        lowertags = [tag.lower() for tag in tags]
        # Избавимся от дубликатов
        newtagset = set(lowertags)
        newtags = list(newtagset)

        if newtagset != set(self._tags):
            self._tags = newtags
            self.save()
            self.updateDateTime()
            self.root.onPageUpdate(self, change=events.PAGE_UPDATE_TAGS)

    @staticmethod
    def load(path, parent, readonly=False):
        """
        Загрузить страницу.
        Использовать этот метод вместо конструктора,
        когда надо загрузить страницу
        """
        from .factoryselector import FactorySelector

        title = os.path.basename(path)
        params = RootWikiPage._readParams(path, readonly)

        # Получим тип страницы по параметрам
        pageType = FactorySelector.getFactory(
            params.typeOption.value).getPageType()

        page = pageType(path, title, parent, readonly)
        page._tags = WikiPage.getTags(params)
        page.loadChildren()

        return page

    def save(self):
        """
        Сохранить страницу
        """
        if self.readonly:
            return

        if not os.path.exists(self.path):
            os.mkdir(self.path)

        self._saveOptions()

    def _saveOptions(self):
        """
        Сохранить настройки
        """
        # Тип
        self._params.typeOption.value = self.getTypeString()

        # Теги
        self._saveTags()

        # Порядок страницы
        self._params.orderOption.value = self.order

    def _saveTags(self):
        tags = reduce(lambda full, tag: full + ", " + tag, self._tags, "")

        # Удалим начальные ", "
        tags = tags[2:]
        self._params.set(RootWikiPage.sectionGeneral, WikiPage.paramTags, tags)

    def initAfterCreating(self, tags):
        """
        Инициализация после создания
        """
        self._tags = tags[:]
        self.save()
        self.creationdatetime = datetime.datetime.now()
        self.updateDateTime()
        self.parent.saveChildrenParams()
        self.root.onPageCreate(self)

    @staticmethod
    def getTags(configParser):
        """
        Выделить теги из строки конфигурационного файла
        """
        try:
            tagsString = configParser.get(RootWikiPage.sectionGeneral,
                                          WikiPage.paramTags)
        except configparser.NoOptionError:
            return []

        tags = parseTagsList(tagsString)

        return tags

    @property
    def content(self):
        """
        Прочитать файл-содержимое страницы
        """
        text = ""

        try:
            with open(os.path.join(self.path, RootWikiPage.contentFile),
                      encoding='utf8') as fp:
                text = fp.read()
        except IOError:
            pass

        text = text.replace('\r\n', '\n')
        return text

    @content.setter
    def content(self, text):
        if self.readonly:
            raise ReadonlyException

        text = text.replace('\r\n', '\n')
        if text != self.content or text == u"":
            path = os.path.join(self.path, RootWikiPage.contentFile)

            with open(path, "w", encoding='utf8') as fp:
                fp.write(text)

            self.updateDateTime()
            self.root.onPageUpdate(self, change=events.PAGE_UPDATE_CONTENT)

    @property
    def textContent(self):
        """
        Получить контент в текстовом виде.
        Используется для поиска по страницам.
        В большинстве случаев достаточно вернуть просто content
        """
        return self.content

    @property
    def subpath(self):
        result = self.title
        page = self.parent

        while page.parent is not None:
            # Пока не дойдем до корня, у которого нет заголовка,
            # и родитель - None
            result = page.title + "/" + result
            page = page.parent

        return result

    @property
    def display_subpath(self):
        '''
        Added in outwiker.core 1.3
        '''
        result = self.display_title
        page = self.parent

        while page.parent is not None:
            result = page.display_title + "/" + result
            page = page.parent

        return result

    def remove(self):
        """
        Удалить страницу
        """
        if self.readonly:
            raise ReadonlyException

        oldpath = self.path
        tempname = self._getTempName(oldpath)
        oldSelectedPage = self.root.selectedPage

        try:
            os.renames(oldpath, tempname)
            shutil.rmtree(tempname)
        except (OSError, shutil.Error):
            raise IOError

        self.root.onStartTreeUpdate(self.root)
        self._removePageFromTree(self)

        # Если выбранная страница была удалена
        if (oldSelectedPage is not None and
            (oldSelectedPage == self or self.isChild(oldSelectedPage))):
            # Новая выбранная страница взамен старой
            newselpage = oldSelectedPage
            while newselpage.parent is not None and newselpage.isRemoved:
                newselpage = newselpage.parent

            # Если попали в корень дерева
            if newselpage.parent is None:
                newselpage = None

            self.root.selectedPage = newselpage

        self.root.onEndTreeUpdate(self.root)

    def _removePageFromTree(self, page):
        page.parent.removeFromChildren(page)

        for child in page.children:
            page._removePageFromTree(child)

        self.root.onPageRemove(page)

    @property
    def isRemoved(self):
        """
        Проверить, что страница удалена
        """
        return self not in self.parent.children