# -*- coding: utf-8 -*-
#|L_Attribut

#----------------------------------------------------------
# Примеры взяты из SDK - Step8
# и конвертированы на Python.
#
# Дополнительно написан вариант для API7
#
# Хранение типов атрибутов выполняется в файле
# с расширением .lat
# На самом деле это оправдано только
# при их многократном использовании в разных приложениях
# Лучше тиаы атрибутов хранить в документе
# В этом случае не надо переносить вместе с файлом чертежа
# файл типов атрибутов.
#
# В оригинале номер атрибута запрашивается через ksReadDouble,
# но фактически введеное значение урезается до 9 знаков
# что естетсвенно приводит к отрицательному результату.
# Для устранения этой проблемы в данном примере
# используется ksReadString с дальнейшим преобразованием
# через функцию Python - int().
#
# В примерах пароль и уникальный номер запрашиваются у пользователя.
# В реальных приложениях пользователь не долджен о них знать:
# - пароль определяет программист и заносит через константу;
# - уникальный номер считывается программно.
#
#----------------------------------------------------------

import pythoncom
from win32com.client import Dispatch, gencache

import LDefin2D
import MiscellaneousHelpers as MH

# Подключение библиотеки создания диалоговых окон
from tkinter import *

#  Подключим константы API Компас
const_2d = gencache.EnsureModule("{75C9F5D0-B5B8-4526-8681-9903C567D2ED}", 0, 1, 0).constants

#  Подключим описание интерфейсов API5
kapi_5 = gencache.EnsureModule("{0422828C-F174-495E-AC5D-D31014DBBE87}", 0, 1, 0)
iKompas_5 = kapi_5.KompasObject(Dispatch("Kompas.Application.5")._oleobj_.QueryInterface(kapi_5.KompasObject.CLSID, pythoncom.IID_IDispatch))
MH.iKompasObject = iKompas_5

#  Подключим описание интерфейсов API7
kapi_7 = gencache.EnsureModule("{69AC2981-37C0-4379-84FD-5DD2F3C0A520}", 0, 1, 0)
iApplication_7 = kapi_7.IApplication(Dispatch("Kompas.Application.7")._oleobj_.QueryInterface(kapi_7.IApplication.CLSID, pythoncom.IID_IDispatch))
MH.iApplication = iApplication_7

#  Получим активный документ
iDocuments_7 = iApplication_7.Documents
iDocument_7 = iApplication_7.ActiveDocument
iDocument1_7 = kapi_7.IKompasDocument1(iDocument_7)
iDocument2D_5 = iKompas_5.ActiveDocument2D()



#---------------------
# Работа с атрибутами
#---------------------

#--------
# API5  |
#--------

# Получим указатель на интерфейс атрибутов
attr_5 = kapi_5.ksAttributeObject(iKompas_5.GetAttributeObject())

#--------------------------
# Вспомогательные функции
#--------------------------

# Функция Показать колонку
def ShowCol(par, iCol, fl):
    if fl:
        s = "структура"
    else:
        s ='\n'

    # выдадим поля колонки не указатели
    strMes = s + " i = " + '{0:d}'.format(iCol) + " header = " + par.header \
    + " type = " + '{0:d}'.format(par.type)\
    + " flagEnum = " + '{0:d}'.format(par.flagEnum)
    iKompas_5.ksMessage(strMes)
    if (par.type == LDefin2D.RECORD_ATTR_TYPE):
        pCol = iAttributeTypeParam_5.GetColumns()
        if pCol:
            # Рекурсивный вызов, если колонка сама является записью
            ShowColumns(pCol, true)
            pCol.ksDeleteArray()


# Функция Показать колонки
def ShowColumns(pCol, fl):
    par = kapi_5.ksColumnInfoParam(iKompas_5.GetParamStruct(const_2d.ko_ColumnInfoParam))
    if (par):
        par.Init();
        n = pCol.ksGetArrayCount()

        for i in range(n-1):
            if (pCol.ksGetArrayItem(i, par) ):
                ShowCol(par,i, fl )
            else:
                iKompas_5.ksMessageBoxResult()  # проверяем результат работы нашей функции


#------------------------------
# Операции с типами атрибутами
#------------------------------

# Создать тип атрибута
def FuncAttrType():
    iAttributeTypeParam_5 = kapi_5.ksAttributeTypeParam(iKompas_5.GetParamStruct(const_2d.ko_AttributeType))
    iColumnInfoParam_5 = kapi_5.ksColumnInfoParam(iKompas_5.GetParamStruct(const_2d.ko_ColumnInfoParam))
    if (iAttributeTypeParam_5 and iColumnInfoParam_5):

        iAttributeTypeParam_5.Init()
        iColumnInfoParam_5.Init()
        iAttributeTypeParam_5.header      = "double_str_long"   # заголовoк-комментарий типа
        iAttributeTypeParam_5.rowsCount   = 1                   # кол-во строк в таблице
        iAttributeTypeParam_5.flagVisible = True                # видимый, невидимый   в таблице
        iAttributeTypeParam_5.password    = ""                  # пароль, если не пустая строка  - защищает от несанкционированного изменения типа
        iAttributeTypeParam_5.key1        = 10
        iAttributeTypeParam_5.key2        = 20
        iAttributeTypeParam_5.key3        = 30
        iAttributeTypeParam_5.key4        = 0
        iDynamicArray_5 = iAttributeTypeParam_5.GetColumns()
        if iDynamicArray_5:
            # первая колонка  структуры
            iColumnInfoParam_5.header = "double"        # заголовoк-комментарий столбца
            iColumnInfoParam_5.type = LDefin2D.DOUBLE_ATTR_TYPE    # тип данных в столбце - см.ниже
            iColumnInfoParam_5.key = 0                  # дополнительный признак, который позволит отличить две переменные с одинаковым типом

            # Python не допускает параметр def, т.к. это слово зарезервировано (функция)
##            iColumnInfoParam_5.def = "123456789"        # значение по умолчанию

            iColumnInfoParam_5.flagEnum = False         # флаг включающий режим, когда значение поля атрибута
            iDynamicArray_5.ksAddArrayItem(-1, iColumnInfoParam_5)

            # вторая колонка структуры
            iColumnInfoParam_5.header = "str"           # заголовoк-комментарий столбца
            iColumnInfoParam_5.type = LDefin2D.STRING_ATTR_TYPE    # тип данных в столбце - см.ниже
            iColumnInfoParam_5.key = 0                  # дополнительный признак, который позволит отличить две переменные с одинаковым типом
##            iColumnInfoParam_5.def      = _T("string");       # значение по умолчанию
            iColumnInfoParam_5.flagEnum = False         # флаг включающий режим, когда значение поля атрибута
            iDynamicArray_5.ksAddArrayItem(-1, iColumnInfoParam_5 )

            # третья колонка структуры
            iColumnInfoParam_5.header = "long"       # заголовoк-комментарий столбца
            iColumnInfoParam_5.type = LDefin2D.LINT_ATTR_TYPE    # тип данных в столбце - см.ниже
            iColumnInfoParam_5.key = 0                 # дополнительный признак, который позволит отличить две переменные с одинаковым типом
            ##      iColumnInfoParam_5.def       = "1000000"     # значение по умолчанию
            iColumnInfoParam_5.flagEnum = False             # флаг включающий режим, когда значение поля атрибута
            iDynamicArray_5.ksAddArrayItem( -1, iColumnInfoParam_5 )

        # Создать тип атрибута в текущем документе
        # numbType_5 = attr_5.ksCreateAttrType( iAttributeTypeParam_5, "")   # информация о типе атрибута

        # Запросить имя библиотеки
        nameFile = iKompas_5.ksSaveFile("*.lat", "TestAtr.lat", "", False)

        # Создать тип атрибута в файле
        numbType_5 = attr_5.ksCreateAttrType( iAttributeTypeParam_5, nameFile)   # информация о типе атрибута


        if (numbType_5 > 1):
            strMes = "numbType = " + '{0:f}'.format(numbType_5)

            # Для копировния номера во время проверки
            print(numbType_5)

            iKompas_5.ksMessage(strMes)
        else:
            iKompas_5.ksMessageBoxResult()  # проверяем результат работы нашей функции

    #удалим  массив колонок
    iDynamicArray_5.ksDeleteArray()


# Удалить  тип атрибута
def DelTypeAttr():
    # Запросить имя библиотеки
    nameFile = iKompas_5.ksChoiceFile( "*.lat", "", False )

##    numb = 267109573674.0
##    password = ""
##    j = iKompas_5.ksReadDouble("Ввести номер типа атрибута", 1000000000000, 0, 1e12, numb)
##    if j:
##        password = iKompas_5.ksReadString( "Ввести пароль типа атрибута", "")
##        ret = attr_5.ksDeleteAttrType(j[1], "", password)

    # Это работающий вариант с преобразованием строки в число

    strNumAttr = iKompas_5.ksReadString ("Ввести номер типа атрибута", '123456789012')
    dNumAttr = int(strNumAttr)
    password = iKompas_5.ksReadString( "Ввести пароль типа атрибута", "")
##    ret = attr_5.ksDeleteAttrType(dNumAttr, "", password)
    ret = attr_5.ksDeleteAttrType(dNumAttr, nameFile, password)

    if ret == 0:
        iKompas_5.ksMessageBoxResult()  # проверяем результат работы нашей функции

# Получить  тип атрибута
def ShowTypeAttr():
    # Запросить имя библиотеки
    nameFile = iKompas_5.ksChoiceFile( "*.lat", "", False )

    iAttributeTypeParam_5 = kapi_5.ksAttributeTypeParam(iKompas_5.GetParamStruct(const_2d.ko_AttributeType))
    if (iAttributeTypeParam_5):
        iAttributeTypeParam_5.Init()

        # Для записи в документ
        # rNumb = attr_5.ksChoiceAttrTypes("")

        rNumb = attr_5.ksChoiceAttrTypes(nameFile)
        while (rNumb):

            # Для записи в документ
            # ret = attr_5.ksGetAttrType(rNumb, "", iAttributeTypeParam_5)

            ret = attr_5.ksGetAttrType(rNumb, nameFile, iAttributeTypeParam_5)
            if (ret == 0):
                iKompas_5.ksMessageBoxResult()  # проверяем результат работы нашей функции
            else:
                strMes = "key1 = " + '{0:d}'.format(iAttributeTypeParam_5.key1) \
                + " key2 = "  + '{0:d}'.format(iAttributeTypeParam_5.key2) \
                + " key3 = " + '{0:d}'.format(iAttributeTypeParam_5.key3) \
                + " key4 = " + '{0:d}'.format(iAttributeTypeParam_5.key4)
                iKompas_5.ksMessage(strMes)
                strMes = "header = " + iAttributeTypeParam_5.header \
                + " rowsCount = "  + '{0:d}'.format(iAttributeTypeParam_5.rowsCount) \
                + " flagVisible = " + '{0:d}'.format(iAttributeTypeParam_5.flagVisible) \
                + " password = " + iAttributeTypeParam_5.password
                iKompas_5.ksMessage(strMes)

                iDynamicArray_5 = iAttributeTypeParam_5.GetColumns()
                if iDynamicArray_5:
                    ShowColumns( iDynamicArray_5, False )
                    iDynamicArray_5.ksDeleteArray()

            rNumb = attr_5.ksChoiceAttrTypes(nameFile)


# Заменить  тип атрибута
def ChangeType():
    # Запросить имя библиотеки
    nameFile = iKompas_5.ksChoiceFile( "*.lat", "", False )

    iAttributeTypeParam_5 = kapi_5.ksAttributeTypeParam(iKompas_5.GetParamStruct(const_2d.ko_AttributeType))
    if (iAttributeTypeParam_5):
        iAttributeTypeParam_5.Init()
        strNumAttr = iKompas_5.ksReadString ("Ввести номер типа атрибута", '123456789012')
        dNumAttr = int(strNumAttr)
        password = iKompas_5.ksReadString( "Ввести пароль типа атрибута", "")
        rNumb = attr_5.ksChoiceAttrTypes(nameFile)
        while (rNumb):
##            ret = attr_5.ksGetAttrType(rNumb, "", iAttributeTypeParam_5)
            ret = attr_5.ksGetAttrType(rNumb, nameFile, iAttributeTypeParam_5)
            if ret == 0:
                iKompas_5.ksMessageBoxResult()  # проверяем результат работы нашей функции
            else:
                iAttributeTypeParam_5.password = password
                iDynamicArray_5 = iAttributeTypeParam_5.GetColumns()
                par1 = kapi_5.ksColumnInfoParam( iKompas_5.GetParamStruct(const_2d.ko_ColumnInfoParam) )
                parN = kapi_5.ksColumnInfoParam( iKompas_5.GetParamStruct(const_2d.ko_ColumnInfoParam) )

                if ( iDynamicArray_5 and par1 and parN ):
                    par1.Init()
                    parN.Init()
                    # число колонок
                    n = iDynamicArray_5.ksGetArrayCount();
                    #считаем первую колонку
                    iDynamicArray_5.ksGetArrayItem( 0, par1 );
                    #считаем последнюю колонку
                    iDynamicArray_5.ksGetArrayItem( n-1, parN );
                    #заменим первую колонку
                    iDynamicArray_5.ksSetArrayItem( 0, parN );
                    #заменим последнюю колонку
                    iDynamicArray_5.ksSetArrayItem( n-1, par1 );

                    #заменим  тип атрибута  на новый
                    numbType = attr_5.ksSetAttrType(rNumb, nameFile, iAttributeTypeParam_5, password )
                    if ( numbType > 1 ):
                        strMes = " numbType = "  + '{0:f}'.format(numbType)
                        iKompas_5.ksMessage(strMes)
                    else:
                          kompas.ksMessageBoxResult()  # неудачное завершение - выдадим результат работы нашей функции
                    iDynamicArray_5.ksDeleteArray()

            rNumb = attr_5.ksChoiceAttrTypes(nameFile)


#-----------------------
# Операции с атрибутами
#-----------------------

# Создать атрибут типа, полученного из функции FuncTypeAttr
def NewAttr():
    attrPar = kapi_5.ksAttributeParam(iKompas_5.GetParamStruct(const_2d.ko_Attribute))
    iUserParam_5 = kapi_5.ksUserParam(iKompas_5.GetParamStruct(const_2d.ko_UserParam))
    fVisibl = kapi_5.ksDynamicArray(iKompas_5.GetDynamicArray(23))
    colKeys = kapi_5.ksDynamicArray(iKompas_5.GetDynamicArray(23))

    if ( attrPar and iUserParam_5 and fVisibl and colKeys ):
        attrPar.Init()
        iUserParam_5.Init()
        attrPar.SetValues( iUserParam_5 )
        attrPar.SetColumnKeys( colKeys )
        attrPar.SetFlagVisible( fVisibl )
        attrPar.key1 = 1
        attrPar.key2 = 10
        attrPar.key3 = 100
        attrPar.password = "111"
        item = kapi_5.ksLtVariant(iKompas_5.GetParamStruct(const_2d.ko_LtVariant))
        arr = kapi_5.ksDynamicArray(iKompas_5.GetDynamicArray(23))

        if ( item and arr ):
            iUserParam_5.SetUserArray( arr )
            item.Init()
            item.doubleVal = 987654321.0
            arr.ksAddArrayItem( -1, item )
            item.Init()
            item.strVal = "qwerty"
            arr.ksAddArrayItem( -1, item )
            item.Init()
            item.longVal = 999991
            arr.ksAddArrayItem( -1, item )

            item.Init()
            item.uCharVal = 1
            fVisibl.ksAddArrayItem( -1, item )
            fVisibl.ksAddArrayItem( -1, item )
            fVisibl.ksAddArrayItem( -1, item )

            info = kapi_5.ksRequestInfo(iKompas_5.GetParamStruct(const_2d.ko_RequestInfo))
            if ( info ):
                info.Init()
                info.prompt = "Укажите объект"
                x = 0
                y = 0
                j = iDocument2D_5.ksCursor( info, x, y, None )
                if ( j ):
                    x = j[1]
                    y = j[2]
                    pObj = iDocument2D_5.ksFindObj( x, y, iDocument2D_5.ksGetCursorLimit() )
                    if( iDocument2D_5.ksExistObj(pObj) ):
                        iDocument2D_5.ksLightObj( pObj, 1 )

                        # Запросить имя библиотеки
                        nameFile = iKompas_5.ksChoiceFile( "*.lat", "", False )
                        strNumAttr = iKompas_5.ksReadString ("Ввести номер типа атрибута", '123456789012')
                        dNumAttr = int(strNumAttr)

                        pAttr = attr_5.ksCreateAttr( pObj, attrPar, dNumAttr, nameFile )
                        if( pAttr == 0 ):
                            iKompas_5.ksMessageBoxResult()  # неудачное завершение - выдадим результат работы нашей функции
                        iDocument2D_5.ksLightObj( pObj, 0 )


# Удалить первый атрибут  у данного объекта
def DelObjAttr():
    info = kapi_5.ksRequestInfo(iKompas_5.GetParamStruct(const_2d.ko_RequestInfo))
    if ( info ):
        info.Init()
        info.prompt = "Укажите объект"
        x = 0
        y = 0
        j = iDocument2D_5.ksCursor( info, x, y, None )
        while (j[0] == -1):
            x = j[1]
            y = j[2]
            pObj = iDocument2D_5.ksFindObj( x, y, iDocument2D_5.ksGetCursorLimit() )
            if( iDocument2D_5.ksExistObj(pObj) ):
                iDocument2D_5.ksLightObj( pObj, 1 )

                # Создадим итератор для хождения по атрибутам объекта
                iter = kapi_5.ksIterator( iKompas_5.GetIterator() )
                if ( iter and iter.ksCreateAttrIterator(pObj, 0, 0, 0, 0, 0) ):
                    # Встали на первый атрибут
                    pAttr = iter.ksMoveAttrIterator( "F", 0 )
                    if ( pAttr[0] > 0 ):
                        password = (iKompas_5.ksReadString("Ввести пароль типа атрибута", "" ) )
                        ret = attr_5.ksDeleteAttr(pObj, pAttr[0], password)

                        if (ret == 0 ):
                            iKompas_5.ksMessageBoxResult()
                    else:
                        iKompas_5.ksMessage( "атрибут не найден" )
                iDocument2D_5.ksLightObj( pObj, 0 )

            j = iDocument2D_5.ksCursor( info, x, y, None )


# Считать атрибут типа double_str_long
def ReadObjAttr():
    res = False
    usPar = kapi_5.ksUserParam(iKompas_5.GetParamStruct(const_2d.ko_UserParam) )
    if ( usPar ):
        usPar.Init()
        item = kapi_5.ksLtVariant(iKompas_5.GetParamStruct(const_2d.ko_LtVariant) )
        arr = kapi_5.ksDynamicArray(iKompas_5.GetDynamicArray(23) )
        if ( item and arr ):
            usPar.SetUserArray( arr )
            item.Init()
            item.doubleVal = 987654321.0
            arr.ksAddArrayItem( -1, item )
            item.Init()
            item.strVal = "qwerty"
            arr.ksAddArrayItem( -1, item )
            item.Init()
            item.longVal = 999991
            arr.ksAddArrayItem( -1, item )
            res = True
    if ( res ):
        info = kapi_5.ksRequestInfo(iKompas_5.GetParamStruct(const_2d.ko_RequestInfo) )
        if ( info ):
            info.Init()
            info.prompt = "Укажите объект"
            x = 0
            y = 0
            j = iDocument2D_5.ksCursor( info, x, y, None )
            while (j[0] == -1):
                x = j[1]
                y = j[2]
                pObj = iDocument2D_5.ksFindObj( x, y, iDocument2D_5.ksGetCursorLimit() )
                if( iDocument2D_5.ksExistObj(pObj) ):
                    iDocument2D_5.ksLightObj( pObj, 1 )
                    # Создадим итератор для хождения по атрибутам объекта
                    iter = kapi_5.ksIterator( iKompas_5.GetIterator() )
                    if ( iter and iter.ksCreateAttrIterator(pObj, 0, 0, 0, 0, 0) ):
                        # Встали на первый атрибут
                        pAttr = iter.ksMoveAttrIterator( "F", 0 )
                        if ( pAttr[0] > 0 ):

                            iKompas_5.ksMessage( "тип и ключи атрибута" )
                            k1 = 0
                            k2 = 0
                            k3 = 0
                            k4 = 0
                            numb = 0.0
                            attr_5.ksGetAttrKeysInfo( pAttr[0], k1, k2, k3, k4, numb )
                            strMes = "k1 = " + '{0:d}'.format(k1) \
                            + " k2 = "  + '{0:d}'.format(k2) \
                            + " k3 = "  + '{0:d}'.format(k3) \
                            + " k4 = "  + '{0:d}'.format(k4) \
                            + " numb = " + '{0:f}'.format(numb)
                            iKompas_5.ksMessage(strMes)

                            iKompas_5.ksMessage( "строка атрибута")
                            flagvis = kapi_5.ksLtVariant(iKompas_5.GetParamStruct(const_2d.ko_LtVariant) )
                            colkey = kapi_5.ksLtVariant(iKompas_5.GetParamStruct(const_2d.ko_LtVariant) )
                            attr_5.ksGetAttrRow( pAttr[0], 0, flagvis, colkey, usPar )

                            iKompas_5.ksMessage( "заменим строку атрибута")
                            item = kapi_5.ksLtVariant(iKompas_5.GetParamStruct(const_2d.ko_LtVariant) )
                            arr = kapi_5.ksDynamicArray( usPar.GetUserArray() )
                            if ( item and arr ):
                                item.Init()
                                item.doubleVal = numb
                                arr.ksSetArrayItem( 0, item )
                                item.Init()
                                item.strVal = "1234567\nasdfgh\nzxcvb"
                                arr.ksSetArrayItem( 1, item )
                                item.Init()
                                item.longVal = 888881
                                arr.ksSetArrayItem( 2, item )
                                attr_5.ksSetAttrRow( pAttr[0], 0, flagvis, colkey, usPar, "111" )
                        else:
                            iKompas_5.ksMessage( "атрибут не найден")
                    iDocument2D_5.ksLightObj( pObj, 0 )
                j = iDocument2D_5.ksCursor( info, x, y, None )


# Просмотреть атрибут
def ShowObjAttr():
    info = kapi_5.ksRequestInfo(iKompas_5.GetParamStruct(const_2d.ko_RequestInfo) )
    if ( info ):
        info.Init()
        info.prompt = "Укажите объект"

        x = 0
        y = 0
        j = iDocument2D_5.ksCursor( info, x, y, None )
        while (j[0] == -1):
            x = j[1]
            y = j[2]
            pObj = iDocument2D_5.ksFindObj( x, y, 1e6 )
            if ( iDocument2D_5.ksExistObj(pObj) ):
                iDocument2D_5.ksLightObj( pObj, 1 )
                attr_5.ksChoiceAttr( pObj )
                iDocument2D_5.ksLightObj( pObj, 0 )
            j = iDocument2D_5.ksCursor( info, x, y, None )


#----------------------------------
# Операции с библиотекой атрибутов
#----------------------------------

# Просмотреть библиотеку
def ShowLib():
    # Запросить имя библиотеки
    nameFile = iKompas_5.ksChoiceFile( "*.lat", "", False )

    numb = attr_5.ksChoiceAttrTypes( nameFile )
    if ( numb > 1 ):
        strMes = "numbType = " + '{0:f}'.format(numb)
        iKompas_5.ksMessage(strMes)

# Просмотреть тип
def ShowType():
    # Запросить имя библиотеки
    nameFile = iKompas_5.ksChoiceFile( "*.lat", "", False )
    strNumAttr = iKompas_5.ksReadString ("Ввести номер типа атрибута", '123456789012')
    dNumAttr = int(strNumAttr)

    if ( dNumAttr > 0 ):
        password = iKompas_5.ksReadString("Ввести пароль типа атрибута", "")
        attr_5.ksViewEditAttrType( nameFile, 2, dNumAttr, password )


# Просмотреть атрибут
# пройтись у объекта, по атрибутам  с ключом
# key1=10 и выдать количество  колонок и строк для данного атрибута
def WalkFromObjWithAttr():
    info = kapi_5.ksRequestInfo(iKompas_5.GetParamStruct(const_2d.ko_RequestInfo) )
    if ( info ):
        info.Init()
        info.prompt = "Укажите объект"

        x = 0
        y = 0
        j = iDocument2D_5.ksCursor( info, x, y, None )
        while (j[0] == -1):
            x = j[1]
            y = j[2]
            pObj = iDocument2D_5.ksFindObj( x, y, 1e6 )
            if ( iDocument2D_5.ksExistObj(pObj) ):
                # Создадим итератор для движения по атрибутам с ключом 10
                iter = kapi_5.ksIterator( iKompas_5.GetIterator() )
                if ( iter and iter.ksCreateAttrIterator(pObj, 0, 0, 0, 0, 0) ):
                    iDocument2D_5.ksLightObj( pObj, 1 )
                    # Встали на первый атрибут
                    pAttr = iter.ksMoveAttrIterator( "F", 0 )
                    while ( pAttr[0] > 0 ):
                        attr_5.ksViewEditAttr( pAttr[0], 1, "")
                        pAttr = iter.ksMoveAttrIterator( "N", 0 )

                iDocument2D_5.ksLightObj( pObj, 0 )

            j = iDocument2D_5.ksCursor( info, x, y, None )


#--------
# API7  |
#--------

#--------------------------------------------
# Для API7 структуру полей (типы атрибутов)
# сохраняем в файле чертежа
# имя файла заносим в переменную nameFile
# для наглядности ее применения
#--------------------------------------------
# Имя файла типов атрибутов (структуры полей)
nameFile = ""

# Получим указатель на интерфейс менеждера типов атрибутов
iAttrTypeMng_7 = kapi_7.IAttrTypeMng(iApplication_7)


#------------------------------
# Операции с типами атрибутами
#------------------------------

# Создать тип атрибута
def FuncAttrType_7():

    iAttributeType_7 = iAttrTypeMng_7.CreateAttrType(nameFile)
    iAttributeType_7.TypeName = "double_str_long"   # заголовoк-комментарий типа
    iAttributeType_7.RowsCount = 1                  # Количество строк в таблице
    iAttributeType_7.SetKeysInfo(10, 20, 30, 0)     # Установить информацию о ключах атрибута
##    iAttributeType_7.SetPassword("","")             # Установить новый пароль на изменение данных атрибута

    # Добавить 1 колонку
    iColumnInfo_7 = iAttributeType_7.AddColumn(0, const_2d.ksValueTypeFloat, "double")
    iColumnInfo_7.Key  = 0                          # Ключ колонки
    iColumnInfo_7.DefValue = 123456789              # Значение по умолчанию

    # Добавить 2 колонку
    iColumnInfo_7 = iAttributeType_7.AddColumn(0, const_2d.ksValueTypeString, "str")
    iColumnInfo_7.Key  = 0                          # Ключ колонки
    iColumnInfo_7.DefValue = "string"               # Значение по умолчанию

    # Добавить 3 колонку
    iColumnInfo_7 = iAttributeType_7.AddColumn(0, const_2d.ksValueTypeInteger, "long")
    iColumnInfo_7.Key  = 0                          # Ключ колонки
    iColumnInfo_7.DefValue = 1000000                # Значение по умолчанию

    # Обновляем атррибуты
    iAttributeType_7.Update("")

    # Информация о номере типа атрибута
    numbType_7 = iAttributeType_7.UniqueNumb
    strMes = "Номер типа атрибута = " + '{0:f}'.format(numbType_7)
    # Для копировния номера во время проверки
    print(numbType_7)
    iKompas_5.ksMessage(strMes)

# Удалить  тип атрибута
def DelTypeAttr_7():

    strNumAttr = iKompas_5.ksReadString ("Ввести номер типа атрибута", '123456789012')
    dNumAttr = int(strNumAttr)
    password = iKompas_5.ksReadString( "Ввести пароль типа атрибута", "")

    iAttributeType_7 = iAttrTypeMng_7.GetAttrType(dNumAttr, nameFile)
    if (iAttributeType_7.Delete("") == False):
        iKompas_5.ksMessageBoxResult()  # проверяем результат удаления

# Получить  тип атрибута
def ShowTypeAttr_7():
    # Получаем дискриптор окна Windows
    iHWnd = iKompas_5.ksGetHWindow()

    iAttributeType_7 = 1
    while (iAttributeType_7):
        iAttributeType_7 = iAttrTypeMng_7.ChoiceAttrTypes(iHWnd,nameFile)
##        printprop(iAttributeType_7)
        if (iAttributeType_7):
            key1 = 0
            key2 = 0
            key3 = 0
            key4 = 0
            ret = iAttributeType_7.GetKeysInfo(key1, key2, key3, key4)
            key1 = ret[1]
            key2 = ret[2]
            key3 = ret[3]
            key4 = ret[4]

            strMes = "key1 = " + '{0:d}'.format(key1) \
            + " key2 = "  + '{0:d}'.format(key2) \
            + " key3 = " + '{0:d}'.format(key3) \
            + " key4 = " + '{0:d}'.format(key4)
            iKompas_5.ksMessage(strMes)

            strMes = "header = " + iAttributeType_7.TypeName  \
            + " rowsCount = "  + '{0:d}'.format(iAttributeType_7.RowsCount) \
            + " columnsCount = " + '{0:d}'.format(iAttributeType_7.ColumnsCount)
            iKompas_5.ksMessage(strMes)
            iAttributeType_7 = iAttrTypeMng_7.ChoiceAttrTypes(iHWnd,nameFile)

# Заменить  тип атрибута
def ChangeType_7():
    password = iKompas_5.ksReadString( "Введиеи новый пароль типа атрибута", "")

    # Получаем дискриптор окна Windows
    iHWnd = iKompas_5.ksGetHWindow()

    iAttributeType_7 = 1
    while (iAttributeType_7):
        iAttributeType_7 = iAttrTypeMng_7.ChoiceAttrTypes(iHWnd,nameFile)
##        printprop(iAttributeType_7)
        if (iAttributeType_7):
            iAttributeType_7.SetPassword("", password)
            # Число колонок
            n = iAttributeType_7.ColumnsCount
            # Cчитаем первую колонку
            par1 = iAttributeType_7.ColumnInfo(0)
            printprop(par1)

            # Cчитаем последнюю колонку
            parN = iAttributeType_7.ColumnInfo(n - 1)
            printprop(parN)
            # Заменим первую колонку
            # Заменим последнюю колонку

            # Заменим тип атрибута  на новый
            iAttributeType_7.Update(password)

            # Информация о номере типа атрибута
            numbType_7 = iAttributeType_7.UniqueNumb
            strMes = "Номер типа атрибута = " + '{0:f}'.format(numbType_7)
            # Для копировния номера во время проверки
            print(numbType_7)
            iKompas_5.ksMessage(strMes)

#-----------------------
# Операции с атрибутами
#-----------------------

# Создать атрибут типа, полученного из функции FuncTypeAttr
def NewAttr_7():
    strNumAttr = iKompas_5.ksReadString ("Ввести номер типа атрибута", '123456789012')
    dNumAttr = int(strNumAttr)
    password = iKompas_5.ksReadString( "Ввести пароль типа атрибута", "")

    # Указатель на интерфейс типа атрибутов
    iAttributeType_7 = iAttrTypeMng_7.GetAttrType(dNumAttr, nameFile)

    # Запрашиваем объект, которому необходим атрибут
    info = kapi_5.ksRequestInfo(iKompas_5.GetParamStruct(const_2d.ko_RequestInfo))
    if ( info ):
        info.Init()
        info.prompt = "Укажите объект"
        x = 0
        y = 0
        j = iDocument2D_5.ksCursor( info, x, y, None )
        if ( j ):
            x = j[1]
            y = j[2]
            pObj_5 = iDocument2D_5.ksFindObj( x, y, iDocument2D_5.ksGetCursorLimit() )
            iObj_7 = iKompas_5.TransferReference(pObj_5, 0)
            # Создаем атрибут
            iAttribute_7 = iDocument1_7.CreateAttr(dNumAttr, "", iObj_7)
            # Добавляем строку и заполням данными
            iAttribute_7.AddRow("111", 0)
            iAttribute_7.SetValue("111", 0, 0, 987654321.0)
            iAttribute_7.SetValue("111", 0, 1, "qwerty")
            iAttribute_7.SetValue("111", 0, 2, 999991)

# Удалить первый атрибут  у данного объекта
def DelObjAttr_7():
    # Запрашиваем объект, которому необходим атрибут
    info = kapi_5.ksRequestInfo(iKompas_5.GetParamStruct(const_2d.ko_RequestInfo))
    if ( info ):
        info.Init()
        info.prompt = "Укажите объект"
        x = 0
        y = 0
        j = iDocument2D_5.ksCursor( info, x, y, None )
        if ( j ):
            x = j[1]
            y = j[2]
            pObj_5 = iDocument2D_5.ksFindObj( x, y, iDocument2D_5.ksGetCursorLimit() )
            iObj_7 = iKompas_5.TransferReference(pObj_5, 0)
            # Получаем атрибут
            iAttributes_7 = iDocument1_7.Attributes(0, 0, 0, 0, 0, iObj_7)
            iAttribute_7 = iAttributes_7[0]
            if (iAttribute_7):
                # Удаляем первую строку атрибута
                if (iAttribute_7.DeleteRow("111", 0) == False):
                    iKompas_5.ksMessage( "Атрибут не найден" )

# Считать атрибут типа double_str_long и заменить значения
def ReadObjAttr_7():
    info = kapi_5.ksRequestInfo(iKompas_5.GetParamStruct(const_2d.ko_RequestInfo))
    if ( info ):
        info.Init()
        info.prompt = "Укажите объект"
        x = 0
        y = 0
        j = iDocument2D_5.ksCursor( info, x, y, None )
        if ( j ):
            x = j[1]
            y = j[2]
            pObj_5 = iDocument2D_5.ksFindObj( x, y, iDocument2D_5.ksGetCursorLimit() )
            iObj_7 = iKompas_5.TransferReference(pObj_5, 0)
            # Получаем атрибут
            iAttributes_7 = iDocument1_7.Attributes(0, 0, 0, 0, 0, iObj_7)
            iAttribute_7 = iAttributes_7[0]
            if (iAttribute_7):
                iRow_7 = iAttribute_7.RowsCount
                for i in range(iRow_7):
                    k1 = 0
                    k2 = 0
                    k3 = 0
                    k4 = 0
                    numb = 0.0
                    retKey_7 = iAttribute_7.GetKeysInfo(k1, k2, k3, k4, numb)
                    numb = retKey_7[5]

                    iKompas_5.ksMessage( "Тип и ключи атрибута" )
                    strMes = "k1 = " + '{0:d}'.format(retKey_7[1]) \
                    + " k2 = "  + '{0:d}'.format(retKey_7[2]) \
                    + " k3 = "  + '{0:d}'.format(retKey_7[3]) \
                    + " k4 = "  + '{0:d}'.format(retKey_7[4]) \
                    + " numb = " + '{0:f}'.format(numb)
                    iKompas_5.ksMessage(strMes)

                    iKompas_5.ksMessage( "Заменим строку атрибута")
                    iAttribute_7.SetValue("111", i, 0, numb)
                    iAttribute_7.SetValue("111", i, 1, "1234567\nasdfgh\nzxcvb")
                    iAttribute_7.SetValue("111", i, 0, 888881)

# Просмотреть атрибут
def ShowObjAttr_7():
    password = iKompas_5.ksReadString( "Введиеи пароль типа атрибута", "")

    # Получаем дискриптор окна Windows
    iHWnd = iKompas_5.ksGetHWindow()

    info = kapi_5.ksRequestInfo(iKompas_5.GetParamStruct(const_2d.ko_RequestInfo))
    if ( info ):
        info.Init()
        info.prompt = "Укажите объект"
        x = 0
        y = 0
        j = iDocument2D_5.ksCursor( info, x, y, None )
        if ( j ):
            x = j[1]
            y = j[2]
            pObj_5 = iDocument2D_5.ksFindObj( x, y, iDocument2D_5.ksGetCursorLimit() )
            iObj_7 = iKompas_5.TransferReference(pObj_5, 0)
            # Получаем атрибут (первоначально возвращается список)
            iAttributes_7 = iDocument1_7.Attributes(0, 0, 0, 0, 0, iObj_7)
            iAttribute_7 = iAttributes_7[0]
            if (iAttribute_7):
                iAttribute_7.ViewEdit(iHWnd, password, True)

#----------------------------------
# Операции с библиотекой атрибутов
#----------------------------------

# Просмотреть библиотеку
def ShowLib_7():
    # Получаем дискриптор окна Windows
    iHWnd = iKompas_5.ksGetHWindow()

    numb = 1        # Уникальный номер типа атрибута
    while (numb > 0):
        numb = 0
        iAttributeType_7 = iAttrTypeMng_7.ChoiceAttrTypes(iHWnd, nameFile )
        if (iAttributeType_7):
            numb = iAttributeType_7.UniqueNumb
            strMes = "numbType = " + '{0:f}'.format(numb)
            iKompas_5.ksMessage(strMes)

# Просмотреть тип
def ShowType_7():
    # Получаем дискриптор окна Windows
    iHWnd = iKompas_5.ksGetHWindow()

    strNumAttr = iKompas_5.ksReadString ("Ввести номер типа атрибута", '123456789012')
    dNumAttr = int(strNumAttr)
    if ( dNumAttr > 0 ):
        password = iKompas_5.ksReadString("Ввести пароль типа атрибута", "")
        iAttributeType_7 = iAttrTypeMng_7.GetAttrType(dNumAttr, nameFile )
        if (iAttributeType_7):
            iAttributeType_7.ViewEdit(iHWnd, password, True)

# Просмотреть атрибут
# пройтись у объекта, по атрибутам  с ключом
# key1=10 и выдать количество  колонок и строк для данного атрибута
def WalkFromObjWithAttr_7():
    # Получаем дискриптор окна Windows
    iHWnd = iKompas_5.ksGetHWindow()
    password = iKompas_5.ksReadString("Ввести пароль типа атрибута", "")

    info = kapi_5.ksRequestInfo(iKompas_5.GetParamStruct(const_2d.ko_RequestInfo) )
    if ( info ):
        info.Init()
        info.prompt = "Укажите объект"

        x = 0
        y = 0
        j = iDocument2D_5.ksCursor( info, x, y, None )
        while (j[0] == -1):
            x = j[1]
            y = j[2]
            pObj_5 = iDocument2D_5.ksFindObj( x, y, 1e6 )
            if ( iDocument2D_5.ksExistObj(pObj_5) ):
                iObj_7 = iKompas_5.TransferReference(pObj_5, 0)
                # Получаем атрибут (первоначально возвращается список)
                iAttributes_7 = iDocument1_7.Attributes(10, 0, 0, 0, 0, iObj_7)
                for i in range(len(iAttributes_7)):
                   iAttribute_7 = iAttributes_7[i]
                   if (iAttribute_7):
                    iAttribute_7.ViewEdit(iHWnd, password, True)
            j = iDocument2D_5.ksCursor( info, x, y, None )


#------------------
# Диалоговое окно
#------------------

def quit():
    global dialog
    dialog.destroy()


dialog = Tk()
dialog.title("Выберите вариант работы с атрибутами")
dialog.geometry('400x500')

lbl1 = Label(dialog, text="Операции с типами атрибутов:", fg="blue2")
lbl1.grid(column=0, row=1, sticky="w")

lbl1Btn1 = Button(dialog, text="Создать тип атрибута")
lbl1Btn1.grid(column=0, row=2)
Btn1 = Button(dialog, text="API5", command = FuncAttrType)
Btn1.grid(column=2, row=2)
Btn2 = Button(dialog, text="API7", command = FuncAttrType_7)
Btn2.grid(column=3, row=2)

lbl1Btn3 = Button(dialog, text="Удалить тип атрибута")
lbl1Btn3.grid(column=0, row=3)
Btn3 = Button(dialog, text="API5", command = DelTypeAttr)
Btn3.grid(column=2, row=3)
Btn4 = Button(dialog, text="API7", command = DelTypeAttr_7)
Btn4.grid(column=3, row=3)

lbl1Btn5 = Button(dialog, text="Получить тип атрибута")
lbl1Btn5.grid(column=0, row=4)
Btn5 = Button(dialog, text="API5", command = ShowTypeAttr)
Btn5.grid(column=2, row=4)
Btn6 = Button(dialog, text="API7", command = ShowTypeAttr_7)
Btn6.grid(column=3, row=4)

lbl1Btn7 = Button(dialog, text="Заменить тип атрибута")
lbl1Btn7.grid(column=0, row=5)
Btn7 = Button(dialog, text="API5", command = ChangeType)
Btn7.grid(column=2, row=5)
Btn8 = Button(dialog, text="API7", command = ChangeType_7)
Btn8.grid(column=3, row=5)

lbl2b = Label(dialog, text="")
lbl2b.grid(column=0, row=6)
lbl2 = Label(dialog, text="Операции с атрибутами:", fg="blue2")
lbl2.grid(column=0, row=7, sticky="w")

lbl1Btn9 = Button(dialog, text="Создать атрибут")
lbl1Btn9.grid(column=0, row=8)
Btn9 = Button(dialog, text="API5", command = NewAttr)
Btn9.grid(column=2, row=8)
Btn10 = Button(dialog, text="API7", command = NewAttr_7)
Btn10.grid(column=3, row=8)

lbl1Btn11 = Button(dialog, text="Удалить первый атрибут")
lbl1Btn11.grid(column=0, row=9)
Btn11 = Button(dialog, text="API5", command = DelObjAttr)
Btn11.grid(column=2, row=9)
Btn12 = Button(dialog, text="API7", command = DelObjAttr_7)
Btn12.grid(column=3, row=9)

lbl1Btn13 = Button(dialog, text="Считать атрибут")
lbl1Btn13.grid(column=0, row=10)
Btn13 = Button(dialog, text="API5", command = ReadObjAttr)
Btn13.grid(column=2, row=10)
Btn14 = Button(dialog, text="API7", command = ReadObjAttr_7)
Btn14.grid(column=3, row=10)

lbl1Btn15 = Button(dialog, text="Просмотреть атрибут")
lbl1Btn15.grid(column=0, row=11)
Btn15 = Button(dialog, text="API5", command = ShowObjAttr)
Btn15.grid(column=2, row=11)
Btn16 = Button(dialog, text="API7", command = ShowObjAttr_7)
Btn16.grid(column=3, row=11)

lbl3b = Label(dialog, text="")
lbl3b.grid(column=0, row=12)
lbl3 = Label(dialog, text="Операции с библиотекой атрибутов:", fg="blue2")
lbl3.grid(column=0, row=13, sticky="w")

lbl1Btn17 = Button(dialog, text="Просмотреть библиотеку")
lbl1Btn17.grid(column=0, row=14)
Btn17 = Button(dialog, text="API5", command = ShowLib)
Btn17.grid(column=2, row=14)
Btn18 = Button(dialog, text="API7", command = ShowLib_7)
Btn18.grid(column=3, row=14)

lbl1Btn19 = Button(dialog, text="Просмотреть тип")
lbl1Btn19.grid(column=0, row=15)
Btn19 = Button(dialog, text="API5", command = ShowType)
Btn19.grid(column=2, row=15)
Btn20 = Button(dialog, text="API7", command = ShowType_7)
Btn20.grid(column=3, row=15)

lbl1Btn21 = Button(dialog, text="Просмотреть тип")
lbl1Btn21.grid(column=0, row=16)
Btn21 = Button(dialog, text="API5", command = WalkFromObjWithAttr)
Btn21.grid(column=2, row=16)
Btn22 = Button(dialog, text="API7", command = WalkFromObjWithAttr_7)
Btn22.grid(column=3, row=16)

lbl4 = Label(dialog, text="")
lbl4.grid(column=0, row=17)
Btn23 = Button(dialog, text="Выход", command = quit, fg="brown4")
Btn23.grid(column=0, row=18)

dialog.mainloop()
