// InstPropertyCtrl.cpp: implementation of the CInstPropertyCtrl class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"
#include "apl_api.h"
#include "InstPropertyCtrl.h"
#include "icons_defines.h"
#include "ProgressDialog.h"
#include "SetAccessContentAndRecursive.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

extern HINSTANCE CaplFormManagerDlgDLL;

int (*FShowForm2)(CaplAPI* pApi,CaplInstance* ciForm,
				 aplExtent& aeInInsts,aplExtent& aeOutInsts,
				 aplExtent* aeChars,LPCTSTR csInstChg,
				 CString csPath/*=_T("")*/,
				 BOOL bAutoSave/*=TRUE*/,BOOL bTst/*=FALSE*/,
				 BOOL bHideAdd/*=FALSE*/)=0;


///////////////////////////////////////////////////////////////
// Методы вспомогательных структур

SEntColumnsMask::SEntColumnsMask(CaplEntity* entity,long mask)
{
	m_entity=entity;
	m_mask=mask;

}

SItemColumnData::SItemColumnData(CaplInstance* inst,
			double count,CaplInstance* unit,CString add_text,CString add_text_2)
{
	m_inst=inst;
	m_unit=unit;
	m_count=count;
	m_add_text=add_text;
	m_add_text_2=add_text_2;
	m_next=0;
}

SItemColumnData::~SItemColumnData()
{
	if(m_next!=0) delete m_next;
	m_next = 0;
}

///////////////////////////////////////////////////////////////
SEntityColumns::SEntityColumns(CaplEntity* entity,CString name/*,CInstPropertyCtrl* parent*/)
{
	m_list_avail_columns.RemoveAll();
	m_entity=entity;
	m_real_entity=0;
	m_name=name;
	m_all_visible=false;
	Add(OBJ_COL_INSTANCE_ID,0);
}

bool SEntityColumns::Add(DWORD type_column,CaplAttr* attr1,CaplAttr* attr2,CaplAttr* attr3,bool is_date)
{
	SColumnDescr* column=0;
	m_list_avail_columns.Add(type_column);
	column=new SColumnDescr();
	if(column==0)return false;
	column->m_type_column=type_column;
	//D column->m_index=CInstPropertyCtrl::Type2Index(type_column);
	column->m_attr1=attr1;
	column->m_attr2=attr2;
	column->m_attr3=attr3;
	column->m_is_date=is_date;
	m_list_columns.Add(column);
	return true;
}


///////////////////////////////////////////////////////////////
SColumnDescr::SColumnDescr()
{
	m_type_column=0;
	m_attr1=0;
	m_attr2=0;
	m_attr3=0;
	int num_group;
	for(num_group=0;num_group<MAX_GROUPS;num_group++){
		m_real_position[num_group]=-1;
	}
	m_is_date=false;
}

///////////////////////////////////////////////////////////////
// Методы таблицы

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CInstPropertyCtrl::CInstPropertyCtrl()
{
	int j;
	m_create_assoc_doc=false;
	m_def_file_name=_T("");
	m_add_column_name=_T("");
	m_add_column_name_2=_T("");
	m_api=0;
//	m_my_width=400;
	int num_group;
	m_columns_def=true;

	for(num_group=0;num_group<MAX_GROUPS;num_group++)
	{
		for(j=0;j<NUM_OBJ_COL;j++)
		{
			m_AllVisibleColumns[num_group][j]=1;
			m_order[num_group][j]=j;
		}
	}

	//m_EntColumnsMask=0;
	m_Items_Columns=0;
	m_Items_String=0;
	m_TableFull=false;
	m_column_data=0;
	m_ReadyCharacteristicColumn=false;

	m_context_menu_processed=false;
	m_context_menu_save2file=false;
	m_context_menu_save2folder=false;
	m_context_menu_save2categ=false;
	m_context_menu_set_access=false;

	m_res_dlg_mode=false;
	m_FindNewCharacteristic=true;

	m_base_inst=0;
	
	if(FShowForm2==0){
		if(CaplFormManagerDlgDLL!=0){
			(FARPROC&)FShowForm2= GetProcAddress(CaplFormManagerDlgDLL,"_ShowFormI");
		}
	}
	
	m_filter_entity = NULL;
	m_sorting_field = NULL;


	ClearView();
}

CInstPropertyCtrl::~CInstPropertyCtrl()
{
	if(m_column_data!=0)delete m_column_data;
	m_column_data=0;
	ClearView();
}


bool CInstPropertyCtrl::SetColumnData(CaplDataBuf &dbuf)
{
	if(m_column_data!=0){delete m_column_data;m_column_data=0;}
	if(dbuf.m_Size!=0){
		m_column_data=new CaplDataBuf();
		m_column_data->Add(dbuf.GetBuffer(),dbuf.m_Size);
	}
	return true;
}

bool CInstPropertyCtrl::GetColumnData(CaplDataBuf &dbuf)
{
	dbuf.Clear();
	if(m_column_data==0){
		m_column_data=new CaplDataBuf();
	}
	if(m_column_data!=0){
		if(m_column_data->m_Size==0){
			SaveColumnWidths();
		}
		dbuf.Add(m_column_data->GetBuffer(),m_column_data->m_Size);
	}
	return true;
}


BOOL CInstPropertyCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID,bool internal_icons)
{
	
	if(CSortListCtrl::Create(dwStyle,rect,pParentWnd,nID)!=TRUE) return FALSE;

	CImageList* imageList;
	if(internal_icons){
		CaplSetResourceHandle setres(module_inst);
		imageList=aplGetInstImageList();
		SetImageList(imageList, LVSIL_SMALL);
	}
	return TRUE;
}

BOOL CInstPropertyCtrl::CreateFromStatic(UINT nID, CWnd* pParent,UINT additional_param,bool internal_icons)
{
	if(CSortListCtrl::CreateFromStatic(nID,pParent,additional_param)!=TRUE)return FALSE;

	CImageList* imageList;

	if(internal_icons){
		CaplSetResourceHandle setres(module_inst);
		imageList=aplGetInstImageList();
		SetImageList(imageList, LVSIL_SMALL);
	}

	return TRUE;

}


///////////////////////////////////////////////////////////////
// очистка внутренних массивов данных

void CInstPropertyCtrl::ClearView()
{
	m_LastEntityColumn=0;
	m_properties_form=0;
	int num_group;
	for(num_group=0;num_group<MAX_GROUPS;num_group++){
		m_first_free_column[num_group]=0;
		m_first_used_column[num_group]=0;
		m_icon_column[num_group]=-1;
		m_enable_icon_column[num_group]=true;
		for(int i=0;i<NUM_OBJ_COL;i++){m_real_position[num_group][i]=-1;}
	}
}

bool CInstPropertyCtrl::ReadCoumnWidth()
{
	int i,j,width;

	bool read_from_reg=m_column_data==0;
	CString strEntry( m_strUniqueName );
	CString strValue, strSubString;
	CString strTemp;
	int pos1,pos2;
	char* header;
	// очищаем массивы характеристик, столбцов и пр.
	// значения характеристик тоже надо будет перечитать
	int num_group;
	for(num_group=0;num_group<MAX_GROUPS;num_group++){
		m_ReReadCharact[num_group]=true;
		m_characts_and_types[num_group].Clear();
		m_SelectedCharMask[num_group].RemoveAll();
	}

	if(!read_from_reg){
		// читаем из буфера
		// Заголовок
		i=_strlen(CInstPropertyCtrl_ColumnsData)+1;
		header=new char[i];
		if(!m_column_data->Read(header,i)){
			read_from_reg=true;
		}else{
			if(CString(CInstPropertyCtrl_ColumnsData)!=header){
				read_from_reg=true;
			}
		}
		delete header;
	}
	if(!read_from_reg){
		// ширина столбцов
		if(!m_column_data->Read(&i,4)){
			read_from_reg=true;
		}
		header=new char[i+1];
		if(!m_column_data->Read(header,i)){
			delete header;
			read_from_reg=true;
		}
		header[i]=0;
		strValue=header;
		delete header;

		for(num_group=0;num_group<MAX_GROUPS;num_group++)
		{
			for(i=0;i<NUM_OBJ_COL;i++)
			{
				AfxExtractSubString(strSubString, strValue, NUM_OBJ_COL*num_group+i, _T(','));
				width= _atoi( (LPCTSTR )strSubString );
				if(width<MIN_WIDTH_COLUMN || width>MAX_WIDTH_COLUMN){
					width=DEF_WIDTH_COLUMN;
				}
				m_column_width[num_group][i]=width;
			}
		}
	}
	if(read_from_reg){
		//for(i=0;i<NUM_OBJ_COL;i++){m_column_width[i]=80;}
		if(m_strUniqueName!=_T("")){
			for(num_group=0;num_group<MAX_GROUPS;num_group++){
				for(i=0;i<NUM_OBJ_COL;i++){
					width=GetRegColumnWidth(NUM_OBJ_COL*num_group+i);
					if(width<MIN_WIDTH_COLUMN || width>MAX_WIDTH_COLUMN){
						width=DEF_WIDTH_COLUMN;
					}
					m_column_width[num_group][i]=width;
				}
			}
		}else{
			for(num_group=0;num_group<MAX_GROUPS;num_group++){
				for(i=0;i<NUM_OBJ_COL;i++){
					m_column_width[num_group][i]=DEF_WIDTH_COLUMN;
				}
			}
		}
	}
	// Маска столбцов
	if(!read_from_reg){
		if(!m_column_data->Read(&i,4)){
			read_from_reg=true;
		}
		header=new char[i+1];
		if(!m_column_data->Read(header,i)){
			delete header;
			read_from_reg=true;
		}
		header[i]=0;
		strValue=header;
		delete header;
	}
	if(read_from_reg)
	{
		// Маска столбцов
		strValue=_T("");
		CWinApp *app=AfxGetApp(); // При вызове из ActiveX возвращает 0
		if(0!=app) strValue = app->GetProfileString( m_strColumnWidthSection, strEntry+_T("___AllColumnsMask"), _T("") );
	}
	pos2=0;
	bool is_all;
	int def_state;
	for(num_group=0;num_group<MAX_GROUPS;num_group++)
	{	
		is_all=false;
		strTemp.Format(_T("G%02i("),num_group);
		pos1=strValue.Find(strTemp,pos2);
		if(pos1==-1) is_all=true;
		else
		{
			pos2=strValue.Find(_T(")"),pos1);
			if(pos2==-1) is_all=true;
		}
		if(is_all)
		{
			def_state=1;
		}
		else
		{
			def_state=0;
			strSubString = strValue.Mid(pos1+4,pos2-pos1-4);
		}
		for(j=0;j<NUM_OBJ_COL;j++)
		{
			m_AllVisibleColumns[num_group][j]=def_state;
		}
		if(is_all) continue;
		for(j=0;j<NUM_OBJ_COL;j++)
		{
			if(!AfxExtractSubString(strTemp, strSubString, j, _T(',')))break;
			if(strTemp==_T("")) continue;
			strTemp.Trim();
			pos1 = _atoi( (LPCTSTR )strTemp );
			if(pos1==0 && strTemp!=_T("0")) continue;

			m_AllVisibleColumns[num_group][pos1]=1;
		}
	}

	// Порядок столбцов
	if(!read_from_reg){
		if(!m_column_data->Read(&i,4)){
			read_from_reg=true;
		}
		header=new char[i+1];
		if(!m_column_data->Read(header,i)){
			delete header;
			read_from_reg=true;
		}
		header[i]=0;
		strValue=header;
		delete header;
	}
	if(read_from_reg){
		// Порядок столбцов
		strValue=_T("");
		CWinApp *app=AfxGetApp(); // При вызове из ActiveX возвращает 0
		if(0!=app) strValue = app->GetProfileString( m_strColumnWidthSection, strEntry+_T("___ColumnsOrder"), _T("") );
	}
	for(num_group=0;num_group<MAX_GROUPS;num_group++)
	{
		for(i=0;i<NUM_OBJ_COL;i++)
		{
			AfxExtractSubString(strTemp, strValue, i, _T(','));
			if(strTemp==_T("")){
				m_order[num_group][i]=i;
			}else{
				m_order[num_group][i]=_atoi( (LPCTSTR ) strTemp);
			}
		}
	}

	int ival,multiplisity_buf,size;
	CaplInstance *inst0,*type;
	// данные о столбцах характеристик (хранятся только в буфере)
	if(!read_from_reg){
		// количество групп
		if(!m_column_data->Read(&multiplisity_buf,4))return true;
		if(m_multiplicity!=multiplisity_buf){
			// надо ли тут ругаться?Данные ведь не совпадают со столбцами, каша будет
			// пока используем только те группы для которых есть данные
		}
		// данные о возможных характеристиках для каждой группы
		for(num_group=0;num_group<multiplisity_buf;num_group++)
		{
			// количество характеристик для каждой группы
			if(!m_column_data->Read(&size,4))return true;
			
			for (i = 0; i < size; i++)
			{
				if(!m_column_data->Read(&ival,4))return true;
				inst0=m_api->m_data.GetInstById(ival);
				if(!m_column_data->Read(&ival,4))return true;
				type=m_api->m_data.GetInstById(ival);

				CaplCharacteristicManager::SCharType *chval=
					new CaplCharacteristicManager::SCharType(inst0,type);
				m_characts_and_types[num_group].Add(chval);
			}
			// порядок следования и видимость столбцов
			if(!m_column_data->Read(&size,4))return true;
			for (i = 0; i < size; i++)
			{
				if(!m_column_data->Read(&ival,4))return true;
				m_SelectedCharMask[num_group].Add((UINT)(ival));
			}
		}
		// если выбранных характеристик нет - очистим список характеристик чтобы заново перечитать
		bool flag=true;
		for(num_group=0;num_group<MAX_GROUPS;num_group++){
			flag&=(m_SelectedCharMask[num_group].GetSize()==0);
		}
		if(flag)
		{
			for(num_group=0;num_group<MAX_GROUPS;num_group++){
				m_SelectedCharMask[num_group].RemoveAll();
			}
		}
	}

	return true;
}

void CInstPropertyCtrl::SaveColumnWidths()
{	
	CWinApp *app=AfxGetApp(); // При вызове из ActiveX возвращает 0
	if(0==app) return; 
	//You must set a unique name for every listctrl
	ASSERT( m_strUniqueName.GetLength() );
	CString strEntry( m_strUniqueName );
	CString strValue;
	CString strTemp;
	// ширина столбцов
	int i,j,col,width,num_group,ival;
	strValue=_T("");
	if(!m_TableFull)
		return;

	if(m_column_data!=0){
		//заголовок
		m_column_data->Clear();
		TCHAR* header=CInstPropertyCtrl_ColumnsData;
		m_column_data->Add(header,(_strlen(header)+1));
	}
	if(m_Items_Columns!=0){
		// попытаемся сохранить ширину значимых столбцов
		for(j=0;j<m_multiplicity;j++){
			for(i=0;i<NUM_OBJ_COL;i++)
			{
				col=m_real_position[j][i];
				if(col!=-1){
					width=GetColumnWidth(col);
					m_column_width[j][i]=width;
				}
				strTemp.Format(_T("%d,"),m_column_width[j][i]);
				strValue += strTemp;
			}
		}
	}
	
	if(strValue==_T("") || m_Items_Columns==0){
		// Происки врагов, надо просто сохранить все ширины столбцов
		CSortListCtrl::SaveColumnWidths();
	}else{
		// ширина столбцов
		if(m_column_data!=0){
			i=strValue.GetLength();
			m_column_data->Add(&i,4);
			m_column_data->Add(strValue.GetBuffer(i),i);
		}
		if(0!=app) app->WriteProfileString( m_strColumnWidthSection, strEntry, strValue );
	}

	if(m_Items_Columns==0){
		// когда данные заданы строками - порядок и маску сохранять бессмысленно
		return;
	}
	// Маска столбцов
	// в начало строки пишем -1 - чтобы старая версия контрола показала все столбцы
	strValue=_T("-1,");
	for(num_group=0;num_group<m_multiplicity;num_group++)
	{
		i=0;
		strTemp.Format(_T("G%02i("),num_group);
		strValue+=strTemp;
		for(j=0;j<NUM_OBJ_COL;j++)
		{
			if(m_AllVisibleColumns[num_group][j]==0) continue;
			if(i>0)strValue+=_T(",");
			strTemp.Format(_T("%i"),j);
			strValue+=strTemp;
			i++;
		}
		strValue+=_T(")");
	}
	if(m_column_data!=0){
		i=strValue.GetLength();
		m_column_data->Add(&i,4);
		m_column_data->Add(strValue.GetBuffer(i),i);
	}
	app->WriteProfileString( m_strColumnWidthSection, strEntry+_T("___AllColumnsMask"), strValue );

	// Порядок столбцов
	strValue=_T("");
	for(j=0;j<m_multiplicity;j++){
		for(i=0;i<NUM_OBJ_COL;i++)
		{
			strTemp.Format(_T("%d,"),m_order[j][i]);
			strValue += strTemp;
		}
	}
	if(m_column_data!=0){
		i=strValue.GetLength();
		m_column_data->Add(&i,4);
		m_column_data->Add(strValue.GetBuffer(i),i);
	}

	if(0!=app) app->WriteProfileString( m_strColumnWidthSection, strEntry+_T("___ColumnsOrder"), strValue );

	// данные о столбцах характеристик (хранятся только в буфере)
	if(m_column_data!=0){
		// если выбранных характеристик нет - сохранять незачем, лучше заново перечитать
		if(m_SelectedCharMask[0].GetSize()==0 && m_SelectedCharMask[1].GetSize()==0 &&
			m_SelectedCharMask[2].GetSize()==0)
		{
			return;
		}

		// количество групп
		m_column_data->Add(&m_multiplicity,4);
		// данные о возможных характеристиках для каждой группы
		for(num_group=0;num_group<m_multiplicity;num_group++){
			// количество характеристик для каждой группы
			ival=m_characts_and_types[num_group].Size;
			m_column_data->Add(&ival,4);

			for (i = 0; i < m_characts_and_types[num_group].Size; i++)
			{
				ival=m_characts_and_types[num_group].GetAt(i)->charact->GetId();
				m_column_data->Add(&ival,4);
				ival=(m_characts_and_types[num_group].GetAt(i)->type==0)?0:m_characts_and_types[num_group].GetAt(i)->type->GetId();
				m_column_data->Add(&ival,4);
			}
			// порядок следования и видимость столбцов
			ival=m_SelectedCharMask[num_group].GetSize();
			m_column_data->Add(&ival,4);
			for (i = 0; i < m_SelectedCharMask[num_group].GetSize(); i++)
			{
				ival=m_SelectedCharMask[num_group].GetAt(i);
				m_column_data->Add(&ival,4);
			}
		}
	}
}


///////////////////////////////////////////////////////////////
// установка внутренних массивов данных

// строки-заголовки столбцов и строки-значения
bool CInstPropertyCtrl::SetData(CStringArray &Columns,
			 CaplTAggr<SItemStringData*,SItemStringData*,APLAGGR_LIST_OR_AUTOKILLREF> &Items,int multiplicity)
{
	//m_EntColumnsMask=0;
	m_Items_Columns=0;
	m_properties_form=0;
	
	m_ColumnsHeader.RemoveAll();
	m_ColumnsHeader.Append(Columns);
	m_Items_String=&Items;
	m_multiplicity=multiplicity;
	if(m_multiplicity>MAX_GROUPS)m_multiplicity=MAX_GROUPS;
	if(m_multiplicity<1)m_multiplicity=1;
	DWORD style;
	style=ListView_GetExtendedListViewStyle(m_hWnd);
	if(!(style & LVS_EX_HEADERDRAGDROP)){
		style=style |LVS_EX_HEADERDRAGDROP;
		ListView_SetExtendedListViewStyle(m_hWnd, style);
	}
	ListView_SetExtendedListViewStyle(m_hWnd, style);

	return true;
}

// маска на отображаемые столбцы и список инстансов на значения
bool CInstPropertyCtrl::SetData(
			CaplTAggr<SEntColumnsMask*,SEntColumnsMask*,APLAGGR_LIST_OR_AUTOKILLREF> &EntMask,
			CaplTAggr<SItemColumnData*,SItemColumnData*,APLAGGR_LIST_OR_AUTOKILLREF> &Items,
			int multiplicity)
{
	m_Items_String=0;
	m_properties_form=0;
	m_ColumnsHeader.RemoveAll();
	//m_EntColumnsMask=&EntMask;
	m_Items_Columns=&Items;
	m_multiplicity=multiplicity;
	if(m_multiplicity>MAX_GROUPS)m_multiplicity=MAX_GROUPS;
	if(m_multiplicity<1)m_multiplicity=1;
	DWORD style;
	style=ListView_GetExtendedListViewStyle(m_hWnd);
	if(style & LVS_EX_HEADERDRAGDROP){
		style=style ^LVS_EX_HEADERDRAGDROP;
		ListView_SetExtendedListViewStyle(m_hWnd, style);
	}

	// дальше нужно определять столбцы, которые встречается
	InitAvailableColumns();
	ReadCoumnWidth();
	return true;
}

void CInstPropertyCtrl::VisibleColumnAdd(int num_group,DWORD column)
{
	if(num_group<0 || num_group>=MAX_GROUPS) return;
	if(column<0 || column>=NUM_OBJ_COL) return;
	m_columns_def = false;
	
	m_AllVisibleColumns[num_group][column]=1;
}

void CInstPropertyCtrl::VisibleColumnRemove(int num_group,DWORD column)
{
	if(num_group<0 || num_group>=MAX_GROUPS) return;
	if(column<0 || column>=NUM_OBJ_COL) return;
	m_columns_def = false;

	m_AllVisibleColumns[num_group][column]=0;
}

bool CInstPropertyCtrl::IsVisibleColumn(int num_group,DWORD column)
{
	if(num_group<0 || num_group>=MAX_GROUPS) return false;
	if(column<0 || column>=NUM_OBJ_COL) return false;
	return m_AllVisibleColumns[num_group][column]==1;
}

/*D
bool CInstPropertyCtrl::SetGlobalMask(long Mask,int num_group)
{
	if(m_add_column_name==_T("")){
		Mask^=OBJ_COL_ADD_TEXT;
	}else{
		Mask|=OBJ_COL_ADD_TEXT;
	}
	m_AllColumnsMask[num_group]=Mask;

	// дальше нужно определять столбцы, которые встречается
	InitAvailableColumns();
	return true;
}*/

bool CInstPropertyCtrl::SetAdditionalColumnName(LPCTSTR add_column_name, LPCTSTR add_column_name_2)
{
	m_add_column_name=add_column_name;
	m_add_column_name_2=add_column_name_2;
	return true;
}


// список инстансов на значения
bool CInstPropertyCtrl::SetData(
			CaplTAggr<SItemColumnData*,SItemColumnData*,APLAGGR_LIST_OR_AUTOKILLREF> &Items,
			int multiplicity)
{
	m_Items_String=0;
	m_Items_Columns=&Items;
	m_properties_form=0;
	m_multiplicity=multiplicity;
	if(m_multiplicity>MAX_GROUPS)m_multiplicity=MAX_GROUPS;
	if(m_multiplicity<1)m_multiplicity=1;
	DWORD style;
	style=ListView_GetExtendedListViewStyle(m_hWnd);
	if(style & LVS_EX_HEADERDRAGDROP){
		style=style ^LVS_EX_HEADERDRAGDROP;
		ListView_SetExtendedListViewStyle(m_hWnd, style);
	}

	// дальше нужно определять столбцы, которые встречается
	InitAvailableColumns();
	ReadCoumnWidth();
	return true;
}


// заполняет список отображаемых ентитей и столбцов для них (маска накладывается внутри Add)
void CInstPropertyCtrl::InitAvailableColumns()
{
	SEntityColumns* entity_columns;
	// показывать столбцы "кол-во" и "ед изм" (для полного/подетального состава)
	bool is_show_count_unit = false;

	CaplAttr* attr=0;
	m_AvailableColumns.Clear();
	if(m_api==0)return;

	if(m_Items_Columns != 0)
	{
		for(int i=0; i< m_Items_Columns->GetSize(); i++)
		{
			SItemColumnData *item_Data=m_Items_Columns->GetAt(i);
			if(0==item_Data) continue;
			if(item_Data->m_unit !=0  || item_Data->m_count!=-1)
			{
				is_show_count_unit = true;
				break;
			}
		}
	}
	
	// инстансы любого типа, явно не заданного
	entity_columns=new SEntityColumns(0, APL_T("объект низкого уровня")/*,this*/);
	entity_columns->Add(OBJ_COL_TYPE,0);
	m_AvailableColumns.Add(entity_columns);

	// изделия
	entity_columns=new SEntityColumns(m_api->m_prd_mgr.e_prd, APL_T("Изделие")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_ID,m_api->m_prd_mgr.a_prd_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_prd_mgr.a_prd_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_prd_mgr.a_prd_descr);
	entity_columns->Add(OBJ_COL_CODE_OBJ,m_api->m_prd_mgr.a_prd_code);
	m_AvailableColumns.Add(entity_columns);

	// версия изделия
	entity_columns=new SEntityColumns(m_api->m_prd_mgr.e_pdf, APL_T("Версия изделия")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_ID,m_api->m_prd_mgr.a_pdf_prd,m_api->m_prd_mgr.a_prd_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_prd_mgr.a_pdf_prd,m_api->m_prd_mgr.a_prd_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_prd_mgr.a_pdf_prd,m_api->m_prd_mgr.a_prd_descr);
	entity_columns->Add(OBJ_COL_CODE_OBJ,m_api->m_prd_mgr.a_pdf_prd,m_api->m_prd_mgr.a_prd_code);
	entity_columns->Add(OBJ_COL_TYPE,m_api->m_prd_mgr.a_apl_pdf_type);
	entity_columns->Add(OBJ_COL_VER,m_api->m_prd_mgr.a_pdf_id);
	entity_columns->Add(OBJ_COL_SOURCE,m_api->m_prd_mgr.a_pdfwss_source);
	entity_columns->Add(OBJ_COL_STANDART,m_api->m_prd_mgr.a_apl_pdf_standard);
	entity_columns->Add(OBJ_COL_CODE_VER,m_api->m_prd_mgr.a_pdf_code);
	entity_columns->Add(OBJ_COL_STATE,m_api->m_prd_mgr.a_apl_pdf_state);
	if(is_show_count_unit)
	{
		entity_columns->Add(OBJ_COL_COUNT,m_api->m_prd_mgr.a_apl_pdf_refusal_count);
		entity_columns->Add(OBJ_COL_UNIT,0);
	}
	entity_columns->Add(OBJ_COL_BASE_UNIT,m_api->m_prd_mgr.a_apl_pdf_unit);
	entity_columns->Add(OBJ_COL_CODE_1,m_api->m_prd_mgr.a_pdf_code1);
	entity_columns->Add(OBJ_COL_CODE_2,m_api->m_prd_mgr.a_pdf_code2);
	m_AvailableColumns.Add(entity_columns);

	// документ
	entity_columns=new SEntityColumns(m_api->m_doc_mgr.e_doc, APL_T("Документ")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_ID,m_api->m_doc_mgr.a_doc_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_doc_mgr.a_doc_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_doc_mgr.a_doc_descr);
	entity_columns->Add(OBJ_COL_DOC_TYPE,m_api->m_doc_mgr.a_doc_kind,m_api->m_doc_mgr.a_dt_pdt);
	entity_columns->Add(OBJ_COL_STATE,m_api->m_doc_mgr.a_apl_doc_wf_state);
	entity_columns->Add(OBJ_COL_DOC_FILENAME,m_api->m_doc_mgr.a_apl_doc_active,m_api->m_doc_mgr.a_apl_doc_rev_access_form,m_api->m_doc_mgr.a_apl_stored_document_file_name);
	m_AvailableColumns.Add(entity_columns);
	
	// версия документа
	entity_columns=new SEntityColumns(m_api->m_doc_mgr.e_apl_doc_rev, APL_T("Версия документа")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_ID,m_api->m_doc_mgr.a_apl_doc_rev_doc,m_api->m_doc_mgr.a_doc_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_doc_mgr.a_apl_doc_rev_doc,m_api->m_doc_mgr.a_doc_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_doc_mgr.a_apl_doc_rev_doc,m_api->m_doc_mgr.a_doc_descr);
	entity_columns->Add(OBJ_COL_VER,m_api->m_doc_mgr.a_apl_doc_rev_id);
	entity_columns->Add(OBJ_COL_DOC_FILENAME,m_api->m_doc_mgr.a_apl_doc_rev_access_form,m_api->m_doc_mgr.a_apl_stored_document_file_name);
	m_AvailableColumns.Add(entity_columns);

	// партия изделий
	entity_columns=new SEntityColumns(m_api->m_prd_inst_mgr.e_lot, APL_T("Партия изделий")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_ID,m_api->m_prd_inst_mgr.a_lot_pdf,m_api->m_prd_mgr.a_pdf_prd,m_api->m_prd_mgr.a_prd_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_prd_inst_mgr.a_lot_pdf,m_api->m_prd_mgr.a_pdf_prd,m_api->m_prd_mgr.a_prd_name);
	entity_columns->Add(OBJ_COL_ID_LOT,m_api->m_prd_inst_mgr.a_lot_id);
	if(m_res_dlg_mode){
		entity_columns->Add(OBJ_COL_COUNT,0);
		entity_columns->Add(OBJ_COL_UNIT,0);
		entity_columns->Add(OBJ_COL_TYPE,m_api->m_prd_inst_mgr.a_lot_pdf,m_api->m_prd_mgr.a_apl_pdf_type);
		entity_columns->Add(OBJ_COL_VER,m_api->m_prd_inst_mgr.a_lot_pdf,m_api->m_prd_mgr.a_pdf_id);
		entity_columns->Add(OBJ_COL_SOURCE,m_api->m_prd_inst_mgr.a_lot_pdf,m_api->m_prd_mgr.a_pdfwss_source);
		entity_columns->Add(OBJ_COL_STANDART,m_api->m_prd_inst_mgr.a_lot_pdf,m_api->m_prd_mgr.a_apl_pdf_standard);
	}else{
		//entity_columns->Add(OBJ_COL_ID,m_api->m_prd_inst_mgr.a_lot_id);
		entity_columns->Add(OBJ_COL_COUNT,m_api->m_prd_inst_mgr.a_lot_size,
			m_api->m_unit_exch_mgr.a_apl_measure_with_unit_value_comp);
		entity_columns->Add(OBJ_COL_UNIT,m_api->m_prd_inst_mgr.a_lot_size,
			m_api->m_unit_exch_mgr.a_apl_measure_with_unit_unit_comp,m_api->m_unit_exch_mgr.a_apl_unit_name);
	}
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_prd_inst_mgr.a_lot_descr);
	m_AvailableColumns.Add(entity_columns);

	// экземпляр изделия
	entity_columns=new SEntityColumns(m_api->m_prd_inst_mgr.e_prd_inst, APL_T("Экземпляр изделия")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_ID,m_api->m_prd_inst_mgr.a_prd_inst_pdf,m_api->m_prd_mgr.a_pdf_prd,m_api->m_prd_mgr.a_prd_id);
	entity_columns->Add(OBJ_COL_ID_INST,m_api->m_prd_inst_mgr.a_prd_inst_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_prd_inst_mgr.a_prd_inst_pdf,m_api->m_prd_mgr.a_pdf_prd,m_api->m_prd_mgr.a_prd_name);
	if(m_res_dlg_mode){
		entity_columns->Add(OBJ_COL_TYPE,m_api->m_prd_inst_mgr.a_prd_inst_pdf,m_api->m_prd_mgr.a_apl_pdf_type);
		entity_columns->Add(OBJ_COL_VER,m_api->m_prd_inst_mgr.a_prd_inst_pdf,m_api->m_prd_mgr.a_pdf_id);
		entity_columns->Add(OBJ_COL_SOURCE,m_api->m_prd_inst_mgr.a_prd_inst_pdf,m_api->m_prd_mgr.a_pdfwss_source);
		entity_columns->Add(OBJ_COL_STANDART,m_api->m_prd_inst_mgr.a_prd_inst_pdf,m_api->m_prd_mgr.a_apl_pdf_standard);
	}else{
		//entity_columns->Add(OBJ_COL_ID,m_api->m_prd_inst_mgr.a_prd_inst_id);
	}
	entity_columns->Add(OBJ_COL_SERNUM,m_api->m_prd_inst_mgr.a_prd_inst_sn);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_prd_inst_mgr.a_prd_inst_descr);
// 	entity_columns->Add(OBJ_COL_COUNT,0);
// 	entity_columns->Add(OBJ_COL_UNIT,0);
	m_AvailableColumns.Add(entity_columns);

	// бизнес процесс
	entity_columns=new SEntityColumns(m_api->m_bp_mgr.e_bp, APL_T("Бизнес-процесс")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_ID,m_api->m_bp_mgr.a_bp_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_bp_mgr.a_bp_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_bp_mgr.a_bp_descr);
	entity_columns->Add(OBJ_COL_TYPE,
		m_api->m_bp_mgr.a_bp_type,m_api->m_bp_mgr.a_bp_type_name);
// 	entity_columns->Add(OBJ_COL_COUNT,0);
// 	entity_columns->Add(OBJ_COL_UNIT,0);
	m_AvailableColumns.Add(entity_columns);
	
	// версия бизнес процесс
	entity_columns=new SEntityColumns(m_api->m_bp_mgr.e_apl_bp_ver, APL_T("Версия бизнес-процесса")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_ID,m_api->m_bp_mgr.a_bp_ver_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_bp_mgr.a_bp_ver_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_bp_mgr.a_bp_ver_descr);
	entity_columns->Add(OBJ_COL_TYPE,
		m_api->m_bp_mgr.a_bp_ver_type,m_api->m_bp_mgr.a_bp_type_name);
// 	entity_columns->Add(OBJ_COL_COUNT,0);
// 	entity_columns->Add(OBJ_COL_UNIT,0);
	m_AvailableColumns.Add(entity_columns);
	
	// экземпляр бизнесс процесса
	entity_columns=new SEntityColumns(m_api->m_bp_mgr.e_apl_bp_inst, APL_T("Экземпляр бизнес-процесса")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_ID,m_api->m_bp_mgr.a_bp_inst_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_bp_mgr.a_bp_inst_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_bp_mgr.a_bp_inst_descr);
// 	entity_columns->Add(OBJ_COL_COUNT,0);
// 	entity_columns->Add(OBJ_COL_UNIT,0);
	m_AvailableColumns.Add(entity_columns);
	
	// категория
	entity_columns=new SEntityColumns(m_api->m_categ_mgr.e_categ, APL_T("Категория")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_ID,m_api->m_categ_mgr.a_categ_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_categ_mgr.a_categ_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_categ_mgr.a_categ_descr);
	m_AvailableColumns.Add(entity_columns);
	
	// папка
	entity_columns=new SEntityColumns(m_api->m_folder_mgr.e_folder, APL_T("Папка")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_folder_mgr.a_folder_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_folder_mgr.a_folder_descr);
	m_AvailableColumns.Add(entity_columns);
	
	// запрос
	entity_columns=new SEntityColumns(m_api->m_query_mgr.e_apl_query, APL_T("Запрос")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_query_mgr.a_apl_query_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_query_mgr.a_apl_query_description);
	m_AvailableColumns.Add(entity_columns);

	// комбинированная таблица
	entity_columns=new SEntityColumns(m_api->m_query_mgr.e_apl_ct, APL_T("Сводная таблица")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_query_mgr.a_apl_ct_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_query_mgr.a_apl_ct_description);
	m_AvailableColumns.Add(entity_columns);

	// изменение
	entity_columns=new SEntityColumns(m_api->m_change_mgr.e_chng, APL_T("Изменение")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_ID,m_api->m_change_mgr.a_chng_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_change_mgr.a_chng_name);
	entity_columns->Add(OBJ_COL_TYPE,m_api->m_change_mgr.a_chng_type);
	entity_columns->Add(OBJ_COL_PERSON,m_api->m_change_mgr.a_chng_create_autor);
	entity_columns->Add(OBJ_COL_REF_DOC_TYPE,m_api->m_change_mgr.a_chng_doc_id);
	entity_columns->Add(OBJ_COL_REF_DOC_DATE_APPL,m_api->m_change_mgr.a_chng_apply_date,0,0,true);
	entity_columns->Add(OBJ_COL_CHNG_CODE_PLNT,m_api->m_change_mgr.a_chng_org_code,m_api->m_appr_mgr.a_org_id);
	entity_columns->Add(OBJ_COL_CHNG_CODE_ORG,m_api->m_change_mgr.a_chng_grp_num);
	entity_columns->Add(OBJ_COL_CHNG_CODE_BASIS,m_api->m_change_mgr.a_chng_basis_code);
	entity_columns->Add(OBJ_COL_CHNG_BASIS,m_api->m_change_mgr.a_chng_basis);
	entity_columns->Add(OBJ_COL_CHNG_USAGE,m_api->m_change_mgr.a_chng_usage);
	entity_columns->Add(OBJ_COL_CHNG_COMPL_NUM,m_api->m_change_mgr.a_chng_complect_num);
	entity_columns->Add(OBJ_COL_CHNG_STOCK,m_api->m_change_mgr.a_chng_stock);
	entity_columns->Add(OBJ_COL_CHNG_STOCK_INTR,m_api->m_change_mgr.a_chng_stock_introd);
	entity_columns->Add(OBJ_COL_CHNG_TO_DATE,m_api->m_change_mgr.a_chng_to_date);
	entity_columns->Add(OBJ_COL_CHNG_OTD_DATE,m_api->m_change_mgr.a_chng_otd_date);
	entity_columns->Add(OBJ_COL_CHNG_CRIT_DATE,m_api->m_change_mgr.a_chng_critical_date);
	entity_columns->Add(OBJ_COL_CHNG_DEIST_DATE,m_api->m_change_mgr.a_chng_validity_pi_date);

	m_AvailableColumns.Add(entity_columns);

	// характеристика
	entity_columns=new SEntityColumns(m_api->m_charact_mgr.e_apl_charact, APL_T("Характеристика")/*,this*/);
//	entity_columns->Add(OBJ_COL_TYPE_OBJ,0);
	entity_columns->Add(OBJ_COL_ID,m_api->m_charact_mgr.a_apl_charact_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_charact_mgr.a_apl_charact_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_charact_mgr.a_apl_charact_descr);
	entity_columns->Add(OBJ_COL_CODE_OBJ,m_api->m_charact_mgr.a_apl_charact_code);
	entity_columns->Add(OBJ_COL_UNIT,m_api->m_charact_mgr.a_apl_charact_unit,
					m_api->m_charact_mgr.a_apl_unit_name);
	m_AvailableColumns.Add(entity_columns);

	// сотрудник
	entity_columns=new SEntityColumns(m_api->m_appr_mgr.e_person, APL_T("Сотрудник")/*,this*/);
	entity_columns->Add(OBJ_COL_ID,m_api->m_appr_mgr.a_pers_id);
	entity_columns->Add(OBJ_COL_LNAME,m_api->m_appr_mgr.a_pers_last_name);
	entity_columns->Add(OBJ_COL_FNAME,m_api->m_appr_mgr.a_pers_first_name);
	entity_columns->Add(OBJ_COL_MNAME,m_api->m_appr_mgr.a_pers_middle_names);
	m_AvailableColumns.Add(entity_columns);

	// Рабочая группа
	entity_columns=new SEntityColumns(m_api->m_appr_mgr.e_org, APL_T("Рабочая группа")/*,this*/);
	entity_columns->Add(OBJ_COL_ID,m_api->m_appr_mgr.a_org_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_appr_mgr.a_org_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_appr_mgr.a_org_descr);
	entity_columns->Add(OBJ_COL_ORG_INN,m_api->m_appr_mgr.a_org_inn);
	entity_columns->Add(OBJ_COL_ORG_KPP,m_api->m_appr_mgr.a_org_kpp);
	entity_columns->Add(OBJ_COL_ORG_OGRN,m_api->m_appr_mgr.a_org_ogrn);
	entity_columns->Add(OBJ_COL_ORG_OKPO,m_api->m_appr_mgr.a_org_okpo);
	entity_columns->Add(OBJ_COL_ORG_LEG_ADR,m_api->m_appr_mgr.a_org_legal_address);
	entity_columns->Add(OBJ_COL_ORG_ACT_ADR,m_api->m_appr_mgr.a_org_actual_address);
	entity_columns->Add(OBJ_COL_ORG_POST_ADR,m_api->m_appr_mgr.a_org_postal_address);
	entity_columns->Add(OBJ_COL_ORG_PHONE,m_api->m_appr_mgr.a_org_phone);
	entity_columns->Add(OBJ_COL_ORG_EMAIL,m_api->m_appr_mgr.a_org_e_mail);
	entity_columns->Add(OBJ_COL_ORG_WEB,m_api->m_appr_mgr.a_org_web);
	if(is_show_count_unit)
	{
		entity_columns->Add(OBJ_COL_COUNT,m_api->m_prd_mgr.a_apl_pdf_refusal_count);
		entity_columns->Add(OBJ_COL_UNIT,0);
	}
	m_AvailableColumns.Add(entity_columns);

	// apl_user
	entity_columns=new SEntityColumns(m_api->m_appr_mgr.e_apl_user, APL_T("Пользователь")/*,this*/);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_appr_mgr.a_apl_user_name);
	attr=m_api->m_data.GetAttrDefinition(m_api->m_appr_mgr.e_apl_user,_T("description"));
	entity_columns->Add(OBJ_COL_DESCRIPT,attr);
	attr=m_api->m_data.GetAttrDefinition(m_api->m_appr_mgr.e_apl_user,_T("password"));
	entity_columns->Add(OBJ_COL_PASSWORD,attr);
	entity_columns->Add(OBJ_COL_USER_DIS,m_api->m_appr_mgr.a_apl_user_is_disabled);
	entity_columns->Add(OBJ_COL_USER_RO,m_api->m_appr_mgr.a_apl_user_is_ro);
	if(m_api->m_appr_mgr.a_apl_user_is_ar!=0)entity_columns->Add(OBJ_COL_USER_AR,m_api->m_appr_mgr.a_apl_user_is_ar);

 	entity_columns->Add(OBJ_COL_LNAME,m_api->m_appr_mgr.a_apl_user_po,m_api->m_appr_mgr.a_po_the_pers,m_api->m_appr_mgr.a_pers_last_name);
 	entity_columns->Add(OBJ_COL_FNAME,m_api->m_appr_mgr.a_apl_user_po,m_api->m_appr_mgr.a_po_the_pers,m_api->m_appr_mgr.a_pers_first_name);
 	entity_columns->Add(OBJ_COL_MNAME,m_api->m_appr_mgr.a_apl_user_po,m_api->m_appr_mgr.a_po_the_pers,m_api->m_appr_mgr.a_pers_middle_names);
	entity_columns->Add(OBJ_COL_ACCESS_PAT,m_api->m_appr_mgr.a_apl_user_access_pattern,m_api->m_appr_mgr.a_apl_acc_pat_name);
	m_AvailableColumns.Add(entity_columns);

// 	// Рабочая группа
// 	entity_columns=new SEntityColumns(m_api->m_appr_mgr.e_org,APL_T("Рабочая группа")/*,this*/);
// 	entity_columns->Add(OBJ_COL_ID,m_api->m_appr_mgr.a_org_id);
// 	entity_columns->Add(OBJ_COL_NAME,m_api->m_appr_mgr.a_org_name);
// 	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_appr_mgr.a_org_descr);
// 	m_AvailableColumns.Add(entity_columns);


	// проект
	entity_columns=new SEntityColumns(m_api->m_project_mgr->e_project, APL_T("Проект")/*,this*/);
	entity_columns->Add(OBJ_COL_ID,m_api->m_project_mgr->a_project_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_project_mgr->a_project_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_project_mgr->a_project_descr);
	entity_columns->Add(OBJ_COL_TYPE,
		m_api->m_project_mgr->a_project_type,m_api->m_project_mgr->a_project_type_name);
	entity_columns->Add(OBJ_COL_STATE,m_api->m_project_mgr->a_project_state);
	m_AvailableColumns.Add(entity_columns);

	// процесс // задача
	CaplEntity* e_apl_action_i=m_api->m_data.GetEntityBN(_T("apl_action_instance"));
	if(e_apl_action_i!=0)
	{
		// чтобы apl_task показывалась как задача, а остальное - как процесс
		entity_columns=new SEntityColumns(m_api->m_data.GetEntityBN(_T("apl_task")), APL_T("Задача")/*,this*/);
		entity_columns->Add(OBJ_COL_ID,m_api->m_data.GetAttrDefinition(e_apl_action_i,_T("id")));
		entity_columns->Add(OBJ_COL_NAME,m_api->m_data.GetAttrDefinition(e_apl_action_i,_T("name")));
		entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_data.GetAttrDefinition(e_apl_action_i,_T("description")));
		m_AvailableColumns.Add(entity_columns);

		entity_columns=new SEntityColumns(m_api->m_data.GetEntityBN(_T("apl_process")), APL_T("Процесс")/*,this*/);
		entity_columns->Add(OBJ_COL_ID,m_api->m_data.GetAttrDefinition(e_apl_action_i,_T("id")));
		entity_columns->Add(OBJ_COL_NAME,m_api->m_data.GetAttrDefinition(e_apl_action_i,_T("name")));
		entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_data.GetAttrDefinition(e_apl_action_i,_T("description")));
		m_AvailableColumns.Add(entity_columns);
	}

	// Справочник
	entity_columns=new SEntityColumns(m_api->m_classifier_mgr.e_apl_classifier_system, APL_T("Справочник")/*,this*/);
	entity_columns->Add(OBJ_COL_ID,m_api->m_classifier_mgr.a_apl_classifier_system_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_classifier_mgr.a_apl_classifier_system_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_classifier_mgr.a_apl_classifier_system_descr);
	m_AvailableColumns.Add(entity_columns);

	// Элемент структуры справочника
	entity_columns=new SEntityColumns(m_api->m_classifier_mgr.e_apl_classifier_level, APL_T("Элемент структуры справочника")/*,this*/);
	entity_columns->Add(OBJ_COL_ID,m_api->m_classifier_mgr.a_apl_classifier_level_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_classifier_mgr.a_apl_classifier_level_name);
	entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_classifier_mgr.a_apl_classifier_level_descr);
	entity_columns->Add(OBJ_COL_CODE_OBJ,m_api->m_classifier_mgr.a_apl_classifier_level_code);
	m_AvailableColumns.Add(entity_columns);

	// Требование
	entity_columns=new SEntityColumns(m_api->m_req_mgr.e_requirement, APL_T("Требование")/*,this*/);
	entity_columns->Add(OBJ_COL_ID,m_api->m_req_mgr.a_req_id);
	entity_columns->Add(OBJ_COL_NAME,m_api->m_req_mgr.a_req_name);
	//entity_columns->Add(OBJ_COL_ADD_TEXT,m_api->m_req_mgr.a_req_html);
	m_AvailableColumns.Add(entity_columns);

	// Сообщение
	entity_columns=new SEntityColumns(m_api->m_message_mgr.e_message, APL_T("Почтовое сообщение")/*,this*/);
	entity_columns->Add(OBJ_COL_MESS_FROM,m_api->m_message_mgr.a_message_sender);
	entity_columns->Add(OBJ_COL_MESS_TO,m_api->m_message_mgr.a_message_recipient);
	entity_columns->Add(OBJ_COL_MESS_SUBJ,m_api->m_message_mgr.a_message_subject);
	entity_columns->Add(OBJ_COL_MESS_DATE,m_api->m_message_mgr.a_message_date_send);
	m_AvailableColumns.Add(entity_columns);

	// неисправность
	if (NULL != m_api->m_expl_mgr)
	{
		entity_columns=new SEntityColumns(m_api->m_expl_mgr->e_apl_refusal , APL_T("Неисправность")/*,this*/);
		entity_columns->Add(OBJ_COL_TYPE,m_api->m_expl_mgr->a_apl_refusal_type,m_api->m_classifier_mgr.a_apl_classifier_level_name);
		entity_columns->Add(OBJ_COL_STATE,m_api->m_expl_mgr->a_apl_refusal_state);
		entity_columns->Add(OBJ_COL_REF_DOC_TYPE,m_api->m_expl_mgr->a_apl_refusal_doc_type);
		entity_columns->Add(OBJ_COL_REF_DOC_NUM,m_api->m_expl_mgr->a_apl_refusal_doc_num);
		entity_columns->Add(OBJ_COL_REF_DOC_DATE_DRAW,m_api->m_expl_mgr->a_apl_refusal_doc_date,0,0,true);
		entity_columns->Add(OBJ_COL_DESCRIPT,m_api->m_expl_mgr->a_apl_refusal_description);

		entity_columns->Add(OBJ_COL_REF_ORG,m_api->m_expl_mgr->a_apl_refusal_org);
		entity_columns->Add(OBJ_COL_REF_SECTOR,m_api->m_expl_mgr->a_apl_refusal_sector);

		entity_columns->Add(OBJ_COL_REF_STAGE,m_api->m_expl_mgr->a_apl_refusal_stage);
		entity_columns->Add(OBJ_COL_REF_DOC_DATE_DETECT,m_api->m_expl_mgr->a_apl_refusal_date_detection,0,0,true);
		entity_columns->Add(OBJ_COL_REF_DOC_DATE_REMOVAL,m_api->m_expl_mgr->a_apl_refusal_date_removal,0,0,true);
		entity_columns->Add(OBJ_COL_REF_EXT_VIEW,m_api->m_expl_mgr->a_apl_refusal_ext_view);

		entity_columns->Add(OBJ_COL_REF_MAIN_PDF,m_api->m_expl_mgr->a_apl_refusal_planer,m_api->m_prd_inst_mgr.a_prd_inst_pdf);
		//	FO_INSERT_ATTR_IN_TYPE_2(APL_T("Основное изделие"),TFO_RefMainPDF,_T(".planer"),_T("apl_product_instance"),_T(".formation"));	//!!!! CaplFaultMgr::SelectMainPdf 

		entity_columns->Add(OBJ_COL_REF_MAIN_PI,m_api->m_expl_mgr->a_apl_refusal_planer);
		//	FO_INSERT_ATTR_IN_TYPE(APL_T("Экземпляр основного изделия"),TFO_RefMainItem,_T(".planer"));	//!!!! CaplFaultMgr::SelectItem 

		entity_columns->Add(OBJ_COL_REF_MAIN_FAILED_ITEM,m_api->m_expl_mgr->a_apl_refusal_item);
		//	FO_INSERT_ATTR_IN_TYPE(APL_T("Компонент (блок)"),TFO_RefFailedItem,_T(".item"));	//!!!! CaplFaultMgr::SelectItem 

		entity_columns->Add(OBJ_COL_REF_MAIN_FAILED_PART,m_api->m_expl_mgr->a_apl_refusal_part);
		//	FO_INSERT_ATTR_IN_TYPE(APL_T("Отказавший элемент"),TFO_RefFailedPart,_T(".part"));	//!!!! CaplFaultMgr::SelectItem 
	
		entity_columns->Add(OBJ_COL_REF_MAIN_CONDITIONS,m_api->m_expl_mgr->a_apl_refusal_conditions);
		//	FO_INSERT_ATTR_IN_TYPE(APL_T("Обстоятельства обнаружения"),TFO_RefConditions,_T(".conditions"));	//!!!!  

		entity_columns->Add(OBJ_COL_REF_DOF,m_api->m_expl_mgr->a_apl_refusal_dof);
		//	FO_INSERT_ATTR_IN_TYPE(APL_T("Характер"),TFO_RefDof,_T(".dof"));	//!!!!  

		entity_columns->Add(OBJ_COL_REF_FAULTREASON,m_api->m_expl_mgr->a_apl_refusal_faultreason);
		//	FO_INSERT_ATTR_IN_TYPE(APL_T("Причина"),TFO_RefFaultReason,_T(".faultreason"));	//!!!!  

		entity_columns->Add(OBJ_COL_REF_METHOD,m_api->m_expl_mgr->a_apl_refusal_method);
		//	FO_INSERT_ATTR_IN_TYPE(APL_T("Способ устранения"),TFO_RefMethod,_T(".method"));	//!!!!  

		entity_columns->Add(OBJ_COL_REF_CONSEQUENCES,m_api->m_expl_mgr->a_apl_refusal_consequences);
		//	FO_INSERT_ATTR_IN_TYPE(APL_T("Последствия"),TFO_RefConsequence,_T(".consequences"));	//!!!!  

		entity_columns->Add(OBJ_COL_REF_CULPRIT,m_api->m_expl_mgr->a_apl_refusal_culprit);

		entity_columns->Add(OBJ_COL_REF_MANIFESTATION,m_api->m_expl_mgr->a_apl_refusal_manifestation);
		//	FO_INSERT_ATTR_IN_TYPE(APL_T("Внешние проявления"),TFO_RefManif,_T(".manifestation"));	//!!!!  

		entity_columns->Add(OBJ_COL_REF_MANIF_STR,m_api->m_expl_mgr->a_apl_refusal_manifestation_str);

		m_AvailableColumns.Add(entity_columns);
	}

	for(int i=0;i<m_AvailableColumns.GetSize();i++)
	{
		entity_columns = m_AvailableColumns.GetAt(i);
		if(m_add_column_name!=_T(""))entity_columns->Add(OBJ_COL_ADD_TEXT,0);
		if(m_add_column_name_2!=_T(""))entity_columns->Add(OBJ_COL_ADD_TEXT_2,0);
	}

	// ВНИМАНИЕ! При обновлении списка не забыть поменять 
	// 1) CaplStepManager::GetListTopLevelEntities(TUListPEntity &list_entities) ! 
	// 2) CaplAPI::ShowItemProperties
	// Или сообщить ДИВ-у //D
}

///////////////////////////////////////////////////////////////
// небольшие служебные функции

void CInstPropertyCtrl::SaveToFile(bool save_all) 
{
	apl_SaveListCtrlToFile(this,LPCTSTR(m_def_file_name),0,false,true);
}
void CInstPropertyCtrl::SaveToFileAll() 
{
	apl_SaveListCtrlToFile(this,LPCTSTR(m_def_file_name),0,true,false);
}
void CInstPropertyCtrl::SaveToFileSel() 
{
	apl_SaveListCtrlToFile(this,LPCTSTR(m_def_file_name),0,false,true);
}

CString CInstPropertyCtrl::Type2Name(DWORD type)
{
	CString val=_T("");
	switch(type){
//	case OBJ_COL_TYPE_OBJ	:val=APL_T("Тип объекта");break;
	case OBJ_COL_INSTANCE_ID:val= APL_T("#system ID");break;
	case OBJ_COL_ID			:if(m_res_dlg_mode){val= APL_T("Обозначение изделия");}else{val= APL_T("Обозначение");};break;
	case OBJ_COL_NAME		:if(m_res_dlg_mode){val= APL_T("Наименование изделия");}else{val= APL_T("Наименование");};break;
	case OBJ_COL_SERNUM		:val= APL_T("Серийный номер");break;
	case OBJ_COL_VER		:val= APL_T("Версия");break;
	case OBJ_COL_DESCRIPT	:val= APL_T("Описание");break;
	case OBJ_COL_TYPE		:val= APL_T("Тип");break;
	case OBJ_COL_CODE_OBJ	:val= APL_T("Код");break;
	case OBJ_COL_SOURCE		:val= APL_T("Источник");break;
	case OBJ_COL_COUNT		:val= APL_T("Количество");break;
	case OBJ_COL_UNIT		:val= APL_T("Ед.изм.");break;
	case OBJ_COL_STANDART	:val= APL_T("Стандартное");break;
	case OBJ_COL_CODE_VER	:val= APL_T("Код версии");break;
	case OBJ_COL_LNAME		:val= APL_T("Фамилия");break;
	case OBJ_COL_FNAME		:val= APL_T("Имя");break;
	case OBJ_COL_MNAME		:val= APL_T("Отчество");break;
	case OBJ_COL_STATE		:val= APL_T("Состояние");break;
	case OBJ_COL_ADD_TEXT	:val=m_add_column_name;break;
	case OBJ_COL_ADD_TEXT_2	:val=m_add_column_name_2;break;
	case OBJ_COL_ID_INST	:val= APL_T("Обозначение экземпляра");break;
	case OBJ_COL_ID_LOT		:val= APL_T("Обозначение партии");break;
	case OBJ_COL_INST_ID	:val= APL_T("Идентификатор instance");break;
	case OBJ_COL_BASE_UNIT	:val= APL_T("Основная ед.изм.");break;
	case OBJ_COL_PASSWORD	:val= APL_T("Пароль");break;
	case OBJ_COL_USER_DIS	:val= APL_T("Запретить вход в систему");break;
	case OBJ_COL_USER_RO	:val= APL_T("Режим \"Только чтение\"");break;
	case OBJ_COL_DOC_TYPE	:val= APL_T("Вид документа");break;
	case OBJ_COL_USER_AR	:val= APL_T("Режим \"Доступ ко всем объектам\"");break;
	case OBJ_COL_CODE_1		:val= APL_T("Код 1");break;
	case OBJ_COL_CODE_2		:val= APL_T("Код 2");break;
	case OBJ_COL_REF_DOC_TYPE		:val= APL_T("Документ");break;
	case OBJ_COL_REF_DOC_NUM		:val= APL_T("Номер");break;
	case OBJ_COL_REF_DOC_DATE_DRAW		:val= APL_T("Дата оформления");break;
	case OBJ_COL_PERSON		:val= APL_T("Сотрудник");break;
	case OBJ_COL_REF_DOC_DATE_APPL		:val= APL_T("Дата проведения");break;
	case OBJ_COL_CHNG_CODE_PLNT		:val= APL_T("Код предприятия");break;
	case OBJ_COL_CHNG_CODE_ORG		:val= APL_T("Номер подразделения");break;
	case OBJ_COL_CHNG_CODE_BASIS		:val= APL_T("Код причины изменения");break;
	case OBJ_COL_CHNG_BASIS		:val= APL_T("Описание причины изменения");break;
	case OBJ_COL_CHNG_USAGE		:val= APL_T("Применяемость");break;
	case OBJ_COL_CHNG_COMPL_NUM		:val= APL_T("Номер комплекта изменений");break;
	case OBJ_COL_CHNG_STOCK		:val= APL_T("Указание о заделе");break;
	case OBJ_COL_CHNG_STOCK_INTR		:val= APL_T("Указание о внедрении");break;
	case OBJ_COL_CHNG_TO_DATE		:val= APL_T("Срок доработки ТО");break;
	case OBJ_COL_CHNG_OTD_DATE		:val= APL_T("Дата передачи в ОТД");break;
	case OBJ_COL_CHNG_CRIT_DATE		:val= APL_T("Срок изменений");break;
	case OBJ_COL_CHNG_DEIST_DATE		:val= APL_T("Срок действия ПИ");break;

	case OBJ_COL_REF_ORG		:	val= APL_T("Цех, где обнаружена неисправность");break;
	case OBJ_COL_REF_SECTOR		:	val= APL_T("Участок, где обнаружена неисправность");break;
	case OBJ_COL_REF_STAGE		:	val= APL_T("Этап");break;
	case OBJ_COL_REF_DOC_DATE_DETECT		:	val= APL_T("Дата обнаружения");break;
	case OBJ_COL_REF_DOC_DATE_REMOVAL		:	val= APL_T("Дата устранения");break;
	case OBJ_COL_REF_EXT_VIEW		:	val= APL_T("Внешний вид");break;
	case OBJ_COL_REF_MAIN_PDF		:	val= APL_T("Основное изделие");break;
	case OBJ_COL_REF_MAIN_PI		:	val= APL_T("Экземпляр основного изделия");break;
	case OBJ_COL_REF_MAIN_FAILED_ITEM		:	val= APL_T("Компонент (блок)");break;
	case OBJ_COL_REF_MAIN_FAILED_PART		:	val= APL_T("Отказавший элемент");break;
	case OBJ_COL_REF_MAIN_CONDITIONS		:	val= APL_T("Обстоятельства обнаружения");break;
	case OBJ_COL_REF_DOF		:	val= APL_T("Характер");break;
	case OBJ_COL_REF_FAULTREASON		:	val= APL_T("Причина");break;
	case OBJ_COL_REF_METHOD		:	val= APL_T("Способ устранения");break;
	case OBJ_COL_REF_CONSEQUENCES		:	val= APL_T("Последствия");break;
	case OBJ_COL_REF_CULPRIT		:	val= APL_T("Виновник");break;
	case OBJ_COL_REF_MANIFESTATION		:	val= APL_T("Внешние проявления");break;
	case OBJ_COL_REF_MANIF_STR		:	val= APL_T("Описание внешнего проявления");break;
	case OBJ_COL_ORG_INN				:	val= APL_T("ИНН");break;
	case OBJ_COL_ORG_KPP				:	val= APL_T("КПП");break;
	case OBJ_COL_ORG_OGRN			:	val= APL_T("ОГРН");break;
	case OBJ_COL_ORG_OKPO			:	val= APL_T("ОКПО");break;
	case OBJ_COL_ORG_LEG_ADR			:	val= APL_T("Юридический адрес");break;
	case OBJ_COL_ORG_ACT_ADR			:	val= APL_T("Фактический адрес");break;
	case OBJ_COL_ORG_POST_ADR		:	val= APL_T("Почтовый адрес");break;
	case OBJ_COL_ORG_PHONE			:	val= APL_T("Телефон");break;
	case OBJ_COL_ORG_EMAIL			:	val= APL_T("Email");break;
	case OBJ_COL_ORG_WEB				:	val= APL_T("Web");break;
	case OBJ_COL_DOC_FILENAME		:	val= APL_T("Имя файла");break;
	case OBJ_COL_MESS_FROM			:	val= APL_T("От кого");break;
	case OBJ_COL_MESS_TO			:	val= APL_T("Кому");break;
	case OBJ_COL_MESS_SUBJ			:	val= APL_T("Тема");break;
	case OBJ_COL_MESS_DATE			:	val= APL_T("Отправлено");break;
	case OBJ_COL_ACCESS_PAT			:	val= APL_T("Шаблон доступа");break;


	}
	return val;
}

int CInstPropertyCtrl::GetInstIcon(CaplInstance *inst)
{
	int retval=APL_ICON_NULL;
//	CaplInstance *inst1;
	CString str;
	aplExtent ext;
	if(m_api==0)return 0;

	retval=m_api->GetInstIco(inst);
	return retval;
}

/* Старый вариант. После отладки - удалить 
inline long CInstPropertyCtrl::Index2Type(int index)
{
	long type=1;
	type <<=index;
	return type;
}	

inline int CInstPropertyCtrl::Type2Index(long type)
{
	int index=0;
	while(!(type & 1 )){
		type>>=1;
		index++;
	}
	return index;
}	
*/

int CInstPropertyCtrl::Type2Order(DWORD type,int num_group)
{
	/* Старый вариант. После отладки - удалить 
	int index=Type2Index(type);
	*/
	if(type>=0 && type<NUM_OBJ_COL){
		return m_order[num_group][type];
	}
	return NUM_OBJ_COL;
}

int CInstPropertyCtrl::Type2WidthCol(DWORD type,int num_group)
{
	/* Старый вариант. После отладки - удалить 
	int index=Type2Index(type);
	*/
	if(type>=0 && type<NUM_OBJ_COL){
		return m_column_width[num_group][type];
	}
	return -1;
}


void CInstPropertyCtrl::SetTypeRealPos(DWORD type,int position,int num_group)
{
	/* Старый вариант. После отладки - удалить 
	int index=Type2Index(type);
	*/
	if(type>=0 && type<NUM_OBJ_COL){
		m_real_position[num_group][type]=position;
	}
}



void CInstPropertyCtrl::Renumerate()
{
	int i,j,k;
	SEntityColumns* entity_columns=0;
	SColumnDescr* column=0;
	for(i=0;i<m_AvailableColumns.GetSize();i++){
		entity_columns=m_AvailableColumns.GetAt(i);
		if(entity_columns==0)continue;
		for(j=0;j<entity_columns->m_list_columns.GetSize();j++){
			column=entity_columns->m_list_columns.GetAt(j);
			if(column==0)continue;
			for(k=0;k<MAX_GROUPS;k++){
				if(column->m_type_column==OBJ_COL_COUNT){
					UnsetColumnNumeric(column->m_real_position[k]);
				}
				column->m_real_position[k]=m_real_position[k][column->m_type_column];

				if(column->m_type_column==OBJ_COL_COUNT){
					SetColumnNumeric(column->m_real_position[k]);
				}
				/*
				if(column->m_real_position[k]==-1){
					m_order[k][column->m_index]=NUM_OBJ_COL;
				}else{
					m_order[k][column->m_index]=
						column->m_real_position[k]-m_first_used_column[k];
				}
				*/
			}
		}
	}
}

/* 
long CInstPropertyCtrl::GetEntityMask(CaplEntity* ent)
{
	int i=0,retval=OBJ_COL_ALL;
	if(m_EntColumnsMask!=0){
		for(i=0;i<m_EntColumnsMask->GetSize();i++){
			if(m_EntColumnsMask->GetAt(i)->m_entity==ent){
				retval=m_EntColumnsMask->GetAt(i)->m_mask;
				break;
			}
		}
	}
	return retval & m_AllColumnsMask;
}
*/

bool CInstPropertyCtrl::GetSelectedElements(CUIntArray &ext_out)
{
	ext_out.RemoveAll();
	int num_curr= GetNextItem( -1 , LVNI_ALL | LVNI_SELECTED );
	while( num_curr!= -1){
		ext_out.Add(GetItemData(num_curr));
		num_curr= GetNextItem( num_curr , LVNI_ALL | LVNI_SELECTED );
	}
	return true;
}

bool CInstPropertyCtrl::SetSelectedElements(CUIntArray &ext_in)
{
	for(int i=0;i<ext_in.GetSize();i++){
		if(!SetSelectedElement(ext_in[i]))
			return false;
	}
	return true;
}

bool CInstPropertyCtrl::SetSelectedElement(int pos)
{
	BOOL state;
	if(pos<0 || pos>=GetItemCount())
		return false;
	state=SetItemState(pos , LVNI_ALL| LVNI_SELECTED ,LVNI_ALL| LVNI_SELECTED );
	return (state==TRUE);
}

// 
SEntityColumns* CInstPropertyCtrl::GetInstColumns( CaplInstance * inst)
{
	int i;
	if(m_api==0)return 0;
	if(inst==0)return 0;
	if(inst->GetType()==0)return 0;
	// проверяем, если тип такой же, как и предыдущий
	if(m_LastEntityColumn!=0){
		if(m_LastEntityColumn->m_entity==0){
			if(m_LastEntityColumn->m_real_entity==inst->GetType()){
				return m_LastEntityColumn;
			}
		}else if(m_api->m_data.IsKindOf(inst,m_LastEntityColumn->m_entity)){
			return m_LastEntityColumn;
		}
	}
	m_LastEntityColumn=0;
	for(i=1;i<m_AvailableColumns.GetSize();i++)
	{
		if(m_api->m_data.IsKindOf(inst,m_AvailableColumns.GetAt(i)->m_entity))
		{
			m_LastEntityColumn=m_AvailableColumns.GetAt(i);
			break;
		}
	}
	if(m_LastEntityColumn==0)
	{
		m_LastEntityColumn=m_AvailableColumns.GetAt(0);
	}
	if(m_LastEntityColumn!=0 && m_LastEntityColumn->m_entity==0)
	{
		m_LastEntityColumn->m_real_entity=inst->GetType();
	}
	return m_LastEntityColumn;
}

int	CInstPropertyCtrl::AddItem(SItemColumnData *pItem,bool redraw)
{	
	if(m_api==0)return -1;
	int new_pos=-1;
	if(m_Items_Columns!=0){
		new_pos=m_Items_Columns->GetSize();
		m_Items_Columns->Add(pItem);
		if(redraw){
			FillTable(true,new_pos,1);
		}
	}
	return new_pos;
}

void CInstPropertyCtrl::PrintVal(CaplValue &val, CString &buf, SColumnDescr* column)
{
	if(val.type==aplSTRING){
		val.Get(buf);
		if(column->m_is_date)
		{
			COleDateTime odt;
			aplString2Date(buf, odt);
			buf= odt.Format(_T("%d.%m.%Y"));
		}
	}else if(val.type==aplBOOL){
		if(val.bval)buf= APL_T("Да");
	}else if(val.type==aplINSTANCE || val.type==aplSELECT){
		CaplInstance* inst1;
		val.Get(inst1);
		m_api->m_appr_mgr.GetItemName(inst1,buf);
	}else{
		val.Print(buf,0,0,aplWIN,0,true);
	}

}

//////////////////////////////////////////////////////////////////////////
// Собственно заполнение таблицы
bool CInstPropertyCtrl::FillTable(bool talk_about_empty,int draw_inst_start,int draw_inst_size)
{
	if(m_Items_Columns==0 && (m_Items_String==0 || m_ColumnsHeader.GetSize()==0)){
		return false;
	}
	if(m_multiplicity<1)return false;
	
	CRect rect;
	GetWindowRect(&rect);
	CString err_descr=_T(""),buf,buf1;
	CaplValue val;
	int width_all,width_col;
	width_all=rect.Width()-5;
	width_col=width_all/10;
	int i,j,k;
	int num_icon=0;
	SItemColumnData* ecd=0;
	SEntityColumns* ecolumns=0;
	SColumnDescr* column=0;
	SItemStringData* esd=0;
	CaplAggr aggr;
	int real_position=-1;
	int insert_column_pos;
	int insert_line_pos;
	int num_group;
	int my_order;
	CaplInstance *inst1,*inst2;
	bool is_position_real=false;
	int start_pos,end_pos;
	bool is_user_ro,is_user_ar,is_user_disabled;
	SColumnDescr* sorted_by_filter = NULL;


	if(draw_inst_start==-1){
		DeleteAllColumns();
		DeleteAllItems();
		ClearView();
		for(i=0;i<MAX_GROUPS;i++){
			m_ColumnsInsertedInstances[i].RemoveAll();
		}
	}else if(GetItemCount()==0){
		InitAvailableColumns();
		DeleteAllColumns();
		ClearView();
		for(i=0;i<MAX_GROUPS;i++){
			m_ColumnsInsertedInstances[i].RemoveAll();
		}
	}


	if(m_Items_Columns!=0){
		if(m_Items_Columns->GetSize()==0){
			if(talk_about_empty){
				InsertColumn(0,_T("..."),LVCFMT_LEFT,width_all);
				InsertItem(0, APL_T("Список пуст"),-1);
			}else{
				InsertColumn(0,_T(" "),LVCFMT_LEFT,width_all);
			}
			return true;
		}
		m_TableFull=true;

		if(draw_inst_start==-1){
			start_pos=0;end_pos=m_Items_Columns->GetSize();
		}else{
			start_pos=draw_inst_start;
			if(draw_inst_size==-1){
				end_pos=m_Items_Columns->GetSize();
			}else{
				end_pos=draw_inst_start+draw_inst_size;
				if(end_pos>m_Items_Columns->GetSize()){end_pos=m_Items_Columns->GetSize();}
			}
		}
		// при заполнении сами определяем аттрибуты
		for(i=start_pos;i<end_pos;i++){
			ecd=m_Items_Columns->GetAt(i);
			num_group=0;
			do{
				if(ecd==0)break;
				if(ecd->m_inst==0){
					ecd=ecd->m_next;
					num_group++;
					continue;
				}
				if(ecd->m_inst->GetType()==0){
					//buf.Format(APL_T("нулевой тип у инстансы #%i\n"),ecd->m_inst->GetId());
					buf.Format( APL_T("инстанс #%i была удалена\n"),ecd->m_inst->GetId());
					err_descr+=buf;
					ecd=ecd->m_next;
					num_group++;
					continue;
				}
				if(ecd->m_inst->GetAccessmode()==aplNO){
					// убрал ayatsk 15.12.2011, т.к. это штатная ситуация
					//buf.Format( APL_T("нет доступа к инстанс #%i\n"),ecd->m_inst->GetId());
					//err_descr+=buf;
					ecd=ecd->m_next;
					num_group++;
					continue;
				}
				// столбец для иконок
				if(m_enable_icon_column[num_group]){
					real_position=InsertColumn(m_first_used_column[num_group], APL_T("Тип объекта"),LVCFMT_LEFT,22);
					m_icon_column[num_group]=real_position;
					m_enable_icon_column[num_group]=false;
					// сдвигаем номера границ диапазона следующих групп
					m_first_free_column[num_group]++;
					for(k=num_group+1;k<MAX_GROUPS;k++){
						m_icon_column[k]++;
						m_first_free_column[k]++;
						m_first_used_column[k]++;
					}

				}
				// Если задан фильтр - показываем только инстансы заданного типа
				if(NULL != m_filter_entity && ecd->m_inst->GetType() != m_filter_entity)
				{
					ecd=ecd->m_next;
					num_group++;
					continue;
				}

				ecolumns=GetInstColumns(ecd->m_inst);
				if(ecolumns==0){
//					buf.Format(APL_T("нельзя отобразить инстанс #%i с типом %s (#%i)\n"),
//						ecd->m_inst->GetId(),ecd->m_inst->GetType()->name,ecd->m_inst->GetType()->id);
					if(ecd->m_inst->GetType()==0){
						buf.Format( APL_T("ошибка при отображении удаленного инстанс #%i)\n"),
							ecd->m_inst->GetId());
					}else{
						buf.Format( APL_T("ошибка при отображении инстанс #%i с типом %s (#%i)\n"),
							ecd->m_inst->GetId(),ecd->m_inst->GetType()->name,ecd->m_inst->GetType()->id);
					}
					err_descr+=buf;
					ecd=ecd->m_next;
					num_group++;
					continue;
					
				}else{
					// все ли столбцы для данной ентити отображены
					if(!ecolumns->m_all_visible){
						// заполняем таблицу столбцов, доступных для выбора
						for(j=0;j<ecolumns->m_list_avail_columns.GetSize();j++){
							m_ColumnsInsertedInstances[num_group].Add(ecolumns->m_list_avail_columns.GetAt(j));
						}
						// добавляем столбцы в форму
						for(j=0;j<ecolumns->m_list_columns.GetSize();j++){
							column=ecolumns->m_list_columns.GetAt(j);
							if(column==0){
								continue;
							}
							if(NULL != m_filter_entity && m_filter_attrs.GetSize() > 0)
							{
								// Если задана ентити для фильтрации и список атрибутов - отображаем только их 
								// И не показываем столбец с идентификатором инстанса
								if(OBJ_COL_INSTANCE_ID == column->m_type_column)
									continue;
								bool not_visible = true;
								for(int l=0;l<m_filter_attrs.GetSize();l++)
								{
									if(m_filter_attrs[l] == column->m_attr1)
									{
										not_visible = false;
										break;
									}
								}
								if(not_visible)
									continue;

								if(m_sorting_field == column->m_attr1)
									sorted_by_filter = column;
							}
							else if(!IsVisibleColumn(num_group,column->m_type_column))
							{
								// Если ентити для фильтрации не задана - проверяем на соответствие маске
								column->m_real_position[num_group]=-1;
								continue;
							}
							// Вставляем?
							real_position=m_real_position[num_group][column->m_type_column];
							if(real_position==-1){
								is_position_real=false;
								// определяем позицию для вставки,
								// сначала берем порядковый номер столбца
								my_order=m_order[num_group][column->m_type_column];
								insert_column_pos=my_order;
								for(k=0;k<NUM_OBJ_COL;k++){
									if(m_real_position[num_group][k]!=-1 && 
										m_order[num_group][k]>my_order)
									{
										// наш порядковый номер меньше.
										if(is_position_real){
											// а далеко ли этот столбец?
											if(m_real_position[num_group][k]<insert_column_pos){
												// влезаем перед ним
												insert_column_pos=m_real_position[num_group][k];
												is_position_real=true;
											}
										}else{
											// влезаем перед ним
											insert_column_pos=m_real_position[num_group][k];
											is_position_real=true;
										}
									}
								}
								if(is_position_real){
									// позиция реальная, учитывать первый элемент и иконку не надо
								}else{
									// мы знаем только порядковый номер, нужно учесть столбец начала группы
									insert_column_pos+=m_first_used_column[num_group];
									// и учесть столбец иконки, если он есть
									if(m_icon_column[num_group]!=-1)insert_column_pos++;
								}
								// сдвигаем номера уже вставленных справа столбцов этой группы
								for(k=0;k<NUM_OBJ_COL;k++){
									if(m_real_position[num_group][k]>=insert_column_pos)
									{
										m_real_position[num_group][k]++;
									}
								}
								// сдвигаем номера следующих групп и границ диапазона
								m_first_free_column[num_group]++;
								for(k=num_group+1;k<MAX_GROUPS;k++){
									m_icon_column[k]++;
									m_first_free_column[k]++;
									m_first_used_column[k]++;
									for(int l=0;l<NUM_OBJ_COL;l++){
										if(m_real_position[k][l]>-1){
											m_real_position[k][l]++;
										}
									}
								}
								// вставляем
								real_position=InsertColumn(insert_column_pos,
												Type2Name(column->m_type_column),
												LVCFMT_LEFT,
												Type2WidthCol(column->m_type_column,num_group));
								
								m_real_position[num_group][column->m_type_column]=real_position;
							}
						}
						ecolumns->m_all_visible=true;
						Renumerate();
					}			
					// добавляем строчку в таблицу
					if(num_group==0){
						bool found=false;
						if(draw_inst_start!=-1){
							// ищем, а нет ли уже такого
							for(int z=0;z<GetItemCount();z++){
								if(GetItemData(z)==(DWORD)i){
									insert_line_pos=z;
									found=true;
									break;
								}
							}
						}
						if(!found){
							insert_line_pos=InsertItem(GetItemCount(),_T(""),num_icon);
							SetItemData(insert_line_pos,(DWORD)i);
						}
					}
					// определяем значения атрибутов и выводим строки
					for(j=0;j<ecolumns->m_list_columns.GetSize();j++)
					{
						buf=_T("");
						column=ecolumns->m_list_columns.GetAt(j);
						if(column==0){continue;}
						if(column->m_real_position[num_group]==-1){continue;}
						switch(column->m_type_column){
						//case OBJ_COL_TYPE_OBJ	:
						//	buf=ecolumns->m_name;
						//	break;
						case OBJ_COL_PASSWORD	:
							m_api->m_data.GetAttr(ecd->m_inst,column->m_attr1,buf);
							if(buf==_T("^ECOGJDMFKBJFBEEBNFDBBGECEHBDEFHEABGGGDHGKCJHOHLGNCKEAADFEEOAJEPAEBKHODJHHDFEMBMD") || buf.IsEmpty()==TRUE)
							{
								buf=_T("");
							}else{
								buf=_T("********");
							}
							break;
						case OBJ_COL_ADD_TEXT	:
							buf=ecd->m_add_text;
							break;
						case OBJ_COL_ADD_TEXT_2	:
							buf=ecd->m_add_text_2;
							break;
						case OBJ_COL_MNAME		:
							m_api->m_data.GetAttr(ecd->m_inst,column->m_attr1,aggr);
							aggr.GetByIndex(0,buf);
							break;
						case OBJ_COL_BASE_UNIT	:
							if(column->m_attr1!=0){
								m_api->m_data.GetAttr(ecd->m_inst,column->m_attr1,inst1);
								if(inst1!=0){
									m_api->m_charact_mgr.GetUnitName(inst1,buf);
								}
							}
							break;
						case OBJ_COL_COUNT		:
							// атрибуты определены специальным образом
							if(ecd->m_count!=-1)
								buf.Format(_T("%0.2f"),ecd->m_count);
							else
								buf=_T("");

							break;

						case OBJ_COL_UNIT		:
							// атрибуты определены специальным образом
							if(ecd->m_unit!=0)
								m_api->m_charact_mgr.GetUnitName(ecd->m_unit,buf);
							else
								buf=_T("");

							break;

						case OBJ_COL_INSTANCE_ID			:
							buf.Format(_T("#%i"),ecd->m_inst->GetId());
							break;

						case OBJ_COL_STATE		:
							// иначе по стандартному порядку
							if(ecolumns->m_entity==m_api->m_appr_mgr.e_apl_user){
								m_api->m_data.GetAttr(ecd->m_inst,m_api->m_appr_mgr.a_apl_user_is_ro,is_user_ro);
								if(m_api->m_appr_mgr.a_apl_user_is_ar!=0)m_api->m_data.GetAttr(ecd->m_inst,m_api->m_appr_mgr.a_apl_user_is_ar,is_user_ar);
								m_api->m_data.GetAttr(ecd->m_inst,m_api->m_appr_mgr.a_apl_user_is_disabled,is_user_disabled);
								buf= APL_T("Доступ: ");
								if(is_user_ro){buf+= APL_T("только чтение");}
								else if(is_user_ar){buf+= APL_T("ко всем объектам");}
								else{buf+=_T("ok");};
								buf+= APL_T("; Вход : ");
								if(is_user_disabled){buf+= APL_T("запрещен");}else{buf+=_T("ok");};
								break;
							}
							// здесь break не нужен, если не выбрано то что выше, то по стандартному порядку
						case OBJ_COL_ID			:
						case OBJ_COL_NAME		:
						case OBJ_COL_SERNUM		:
						case OBJ_COL_VER		:
						case OBJ_COL_DESCRIPT	:
						case OBJ_COL_CODE_OBJ	:
						case OBJ_COL_SOURCE		:
						case OBJ_COL_TYPE		:
							// иначе по стандартному порядку
							if(ecolumns->m_entity==0){
								buf=_T("entity: '")+ecd->m_inst->GetType()->name;
								break;
							}
							// здесь break не нужен, если не выбрано то что выше, то по стандартному порядку
						case OBJ_COL_CODE_VER	:
						case OBJ_COL_FNAME		:
						case OBJ_COL_LNAME		:
						case OBJ_COL_ID_INST	:
						case OBJ_COL_ID_LOT		:
						case OBJ_COL_STANDART	:
						case OBJ_COL_USER_DIS	:
						case OBJ_COL_USER_RO	:
						case OBJ_COL_USER_AR	:
						case OBJ_COL_DOC_TYPE	:
						case OBJ_COL_CODE_1		:
						case OBJ_COL_CODE_2		:
						case OBJ_COL_REF_DOC_TYPE:
						case OBJ_COL_REF_DOC_NUM:
						case OBJ_COL_REF_DOC_DATE_DRAW:
						case OBJ_COL_REF_DOC_DATE_APPL:
						case OBJ_COL_REF_DOC_DATE_DETECT:
						case OBJ_COL_REF_DOC_DATE_REMOVAL:
						case OBJ_COL_REF_EXT_VIEW:
						case OBJ_COL_REF_MANIF_STR:
						case OBJ_COL_PERSON		:
						case OBJ_COL_REF_ORG:
						case OBJ_COL_REF_SECTOR:
						case OBJ_COL_REF_CULPRIT:
						case OBJ_COL_REF_STAGE:
						case OBJ_COL_REF_MAIN_PDF:
						case OBJ_COL_REF_MAIN_PI:
						case OBJ_COL_REF_MAIN_FAILED_ITEM:
						case OBJ_COL_REF_MAIN_FAILED_PART:
						case OBJ_COL_REF_MAIN_CONDITIONS:
						case OBJ_COL_REF_DOF:
						case OBJ_COL_REF_FAULTREASON:
						case OBJ_COL_REF_METHOD:
						case OBJ_COL_REF_CONSEQUENCES:
						case OBJ_COL_REF_MANIFESTATION:
						case OBJ_COL_ORG_INN		:
						case OBJ_COL_ORG_KPP		:
						case OBJ_COL_ORG_OGRN		:
						case OBJ_COL_ORG_OKPO		:
						case OBJ_COL_ORG_LEG_ADR	:
						case OBJ_COL_ORG_ACT_ADR	:
						case OBJ_COL_ORG_POST_ADR	:
						case OBJ_COL_ORG_PHONE		:
						case OBJ_COL_ORG_EMAIL		:
						case OBJ_COL_ORG_WEB		:
						case OBJ_COL_DOC_FILENAME	:
						case OBJ_COL_MESS_TO		:
						case OBJ_COL_MESS_SUBJ		:
						case OBJ_COL_ACCESS_PAT		:
							// атрибуты определены массивом атрибутов
							if(column->m_attr1!=0){
								if(column->m_attr2==0){
									m_api->m_data.GetAttr(ecd->m_inst,column->m_attr1,val);
									PrintVal(val,buf,column);
								}else{
									m_api->m_data.GetAttr(ecd->m_inst,column->m_attr1,inst1);
									if(inst1!=0){
										if(column->m_attr3==0){
											m_api->m_data.GetAttr(inst1,column->m_attr2,val);
											PrintVal(val,buf,column);
										}else{
											m_api->m_data.GetAttr(inst1,column->m_attr2,inst2);
											if(inst2!=0){
												m_api->m_data.GetAttr(inst2,column->m_attr3,val);
												PrintVal(val,buf,column);
											}
										}
									}
								}
							}
							if(m_api->m_data.IsKindOf(ecd->m_inst,m_api->m_prd_mgr.e_pdf)){
								if(column->m_type_column==OBJ_COL_SOURCE){
									buf=CaplProductManager::StrConvertMakeOrBuy2Rus(buf);
// 									if(buf==_T("made")) buf=APL_T("Изготавливается");
// 									else if(buf==_T("bought")) buf=APL_T("Покупается");
// 									else buf=_T("?");
								}
								if(column->m_type_column==OBJ_COL_TYPE)
								{
									buf1=m_api->m_prd_mgr.StrConvertPdfType2Rus(buf);
									buf=buf1;
								}
								if(column->m_type_column==OBJ_COL_STATE)
								{
									buf1=m_api->m_doc_mgr.GetWFStateName(buf);
									buf=buf1;
								}
							}
							else if(m_api->m_data.IsKindOf(ecd->m_inst,m_api->m_doc_mgr.e_doc))
							{
								if(column->m_type_column==OBJ_COL_STATE)
								{
									buf1=m_api->m_doc_mgr.GetWFStateName(buf);
									buf=buf1;
								}
							}
							break;
						case OBJ_COL_MESS_FROM		:
							// атрибуты определены массивом атрибутов
							if(column->m_attr1!=0)
							{
								m_api->m_data.GetAttr(ecd->m_inst,column->m_attr1,val);
								PrintVal(val,buf,column);
								if(buf == _T(""))
								{
									buf = _T("<Система>");
								}
							}
							break;

						case OBJ_COL_MESS_DATE		:
							// атрибуты определены массивом атрибутов
							if(column->m_attr1!=0)
							{
								m_api->m_data.GetAttr(ecd->m_inst,column->m_attr1,buf1);
								COleDateTime odt;
								if (aplString2Date(buf1,odt))
								{
									buf.Format(_T("%.2d.%.2d.%.4d"), odt.GetDay(), odt.GetMonth(), odt.GetYear());			
								//			buf = odt.Format(_T("%d.%m.%Y  %H:%M:%S"));
									SetColumnDate(column->m_real_position[num_group]);
								}
								else
									buf = buf1;

							}
							break;

	//					case OBJ_COL_STANDART	:
	//						// атрибуты определены массивом атрибутов, но тип bool
	//						m_api->m_data.GetAttr(ecd->m_inst,column->m_attr1,bval);
	//						if(bval)buf=APL_T("Да");
	//						break;
						}
						SetItemText(insert_line_pos,column->m_real_position[num_group],buf);
					}
				}
		
				// определяем иконку
				num_icon=GetInstIcon(ecd->m_inst);
				if(num_icon==-1)num_icon=ICON_FILE;
				SetItem(insert_line_pos,m_icon_column[num_group],LVIF_IMAGE,_T(""),num_icon,0,0,0);
				if(ecolumns==0){
					if(ecd->m_inst->GetType()!=0)
					buf=ecd->m_inst->GetType()->name;
				}else{
					buf=ecolumns->m_name;
					if(m_api->m_data.IsKindOf(ecd->m_inst,m_api->m_prd_mgr.e_pdf)){
						m_api->m_data.GetAttr(ecd->m_inst,m_api->m_prd_mgr.a_apl_pdf_type,buf1);
						buf+=CString(_T(" : "))+m_api->m_prd_mgr.StrConvertPdfType2Rus(buf1);
					}
				}
				SetItemText(insert_line_pos,m_icon_column[num_group],buf);
				ecd=ecd->m_next;
				num_group++;
			}while(ecd!=0);
		}
	}else{
		// при заполнении берем аттрибуты из массива строк
		width_col=width_all/m_ColumnsHeader.GetSize();
		for(i=0;i<m_ColumnsHeader.GetSize();i++){
			InsertColumn(i,m_ColumnsHeader.GetAt(i),LVCFMT_LEFT,width_col);
		}
		if(draw_inst_start==-1){
			start_pos=0;end_pos=m_Items_String->GetSize();
		}else{
			start_pos=draw_inst_start;
			if(draw_inst_size==-1){
				end_pos=m_Items_String->GetSize();
			}else{
				end_pos=draw_inst_start+draw_inst_size;
				if(end_pos>m_Items_String->GetSize()){end_pos=m_Items_String->GetSize();}
			}
		}
		for(i=start_pos;i<end_pos;i++){
			esd=m_Items_String->GetAt(i);
			if(esd==0){continue;}
			// добавляем строчку в таблицу
			int pos=GetItemCount();
			insert_line_pos=InsertItem(i,_T(""));
			SetItemData(insert_line_pos,(DWORD)i);
			for(j=0;j<esd->m_values.GetSize();j++){
				if(j>=m_ColumnsHeader.GetSize())break;
				SetItemText(insert_line_pos,j,esd->m_values.GetAt(j));
			}
		}
	}


	if(NULL == m_filter_entity)
	{
		// Если не задан фильтр
		// и если есть выбранные характеристики - надо прочитать значения (если они 
		// еще не прочитаны) и вставить в таблицу; только без диалога выбора		
		bool flag=false;
		for(i=0;i<MAX_GROUPS;i++){
			flag|=(m_SelectedCharMask[i].GetSize()!=0);
		}
		if(flag)
		{
			for(i=0;i<m_multiplicity;i++){
				SelectCharacterysticSet(i,false,draw_inst_start,draw_inst_size);
			}
		}
	}
	else if(NULL != sorted_by_filter)
	{
		// если с фильтром задана сортировка по заданному столбцу
		SetItemSortState(sorted_by_filter->m_real_position[0], ASCENDING );
		SortColumn(sorted_by_filter->m_real_position[0]);
	}

	if(err_descr!=_T("")){
		AfxMessageBox( APL_T("Обнаружены следующие ошибки:\n")+err_descr);
	}
	return true;
}

bool CInstPropertyCtrl::SelectCharacterysticSet(int num_group,bool is_dlg,int draw_inst_start,int draw_inst_size,bool forsed_reread) 
{
	// TODO: Add your control notification handler code here
	int i,j,k,index,size=0;
	CString buf,buf1;
	aplExtent ext_load,ext_rel,extGroup;
	CaplInstance *inst,*inst0,*unit,*type;
	CaplInstance *prd_02;
	CStringArray Columns;
	CStringArray* array;
	SItemColumnData* ecd=0;
	SItemStringData* esd=0;
	aplExtent* char_vals=0;
	int start_pos,end_pos;

	if(m_api==0) return false;
	if(m_Items_Columns==0 && (m_Items_String==0 || m_ColumnsHeader.GetSize()==0)){
		return false;
	}
	if(m_Items_Columns==0){
		size=m_Items_String->GetSize();
	}else{
		size=m_Items_Columns->GetSize();
	}
	if(size==0){
		AfxMessageBox( APL_T("Список пуст. Выбрать характеристики невозможно."));
		return true;
	}
	if(forsed_reread)m_FindNewCharacteristic=true;
	if(m_ReReadCharact[num_group] || draw_inst_start!=-1 || forsed_reread)
	{

		if(draw_inst_start==-1){
			m_names_characts_and_types[num_group].Clear();
			m_is_characts_number[num_group].RemoveAll();
			m_is_characts_date[num_group].RemoveAll();

//			m_characts_and_types[num_group].Clear();
//			m_charact_values_array[num_group].Clear();
//			m_SelectedCharMask[num_group].RemoveAll();

			start_pos=0;end_pos=size;
		}else{
			start_pos=draw_inst_start;
			if(draw_inst_size==-1){
				end_pos=size;
			}else{
				end_pos=draw_inst_start+draw_inst_size;
				if(end_pos>size){end_pos=size;}
			}
		}

		CaplSetResourceHandle setres(module_inst);
		CProgressDialog prgdlg;
		prgdlg.Create(IDD_PROGRESS_DLG,this);
		buf.Format( APL_T("Чтение характеристик группы %i"),num_group);
		prgdlg.m_name.SetWindowText(buf);
		prgdlg.m_progress.SetRange32(0,size);
		prgdlg.ShowWindow(TRUE);

		int prg_del=0;
		char_vals=new aplExtent[end_pos];
		// загрузка в кеш списка (значений) характеристик, заданных на массиве входных инстансов
		ext_load.Clear();
		for(i=start_pos;i<end_pos;i++)
		{
			prg_del++;
			inst=0;
			if(prg_del==10){prg_del=0; prgdlg.m_progress.SetPos(i);}
			if(m_Items_Columns==0){
				inst=m_Items_String->GetAt(i)->m_inst;
			}else{
				ecd=m_Items_Columns->GetAt(i);
				inst=ecd->m_inst;
				for(j=0;j<num_group;j++){
					if(ecd->m_next!=0){
						ecd=ecd->m_next;
						inst=ecd->m_inst;
					}else{
						inst=0;
						break;
					}
				}
			}
			if(inst==0)continue;
			ext_load.Add(inst);
			apidata.GetAttr(inst,m_api->m_prd_mgr.a_pdf_prd,prd_02);				
			if(prd_02==0)continue;
			ext_load.Add(prd_02);
		}
		if(ext_load.GetSize()>0){
			// Важен флаг show_status_dlg==true
			m_api->m_charact_mgr.FindAssociatedCharacteristic(ext_load,ext_rel,extGroup,false,false,true);
		}
		// формирование списка (значений) характеристик, заданных на массиве входных инстансов
		for(i=start_pos;i<end_pos;i++)
		{
			prg_del++;
			inst=0;
			if(prg_del==10){prg_del=0; prgdlg.m_progress.SetPos(i);}
			if(m_Items_Columns==0){
				inst=m_Items_String->GetAt(i)->m_inst;
			}else{
				ecd=m_Items_Columns->GetAt(i);
				inst=ecd->m_inst;
				for(j=0;j<num_group;j++){
					if(ecd->m_next!=0){
						ecd=ecd->m_next;
						inst=ecd->m_inst;
					}else{
						inst=0;
						break;
					}
				}
			}
			if(inst==0)continue;
			// Важен флаг from_base==false !
			m_api->m_charact_mgr.FindAssociatedCharacteristic(inst,ext_rel,extGroup,false,false,false,false);
			for( j=0;j<ext_rel.Size;j++)
			{
				char_vals[i].Add(ext_rel[j]);
				apidata.GetAttr(ext_rel[j],m_api->m_charact_mgr.a_apl_charact_val_charact,inst0);
				apidata.GetAttr(ext_rel[j],m_api->m_charact_mgr.a_apl_charact_val_type,type);
				index=-1;
				if(inst0!=0)
				{
					for(k=0;k<m_characts_and_types[num_group].Size;k++)
					{
						if((m_characts_and_types[num_group].GetAt(k)->charact==inst0)&&
							(m_characts_and_types[num_group].GetAt(k)->type==type)) 
						{
							index=k;
							break;
						}
					}
					if(index==-1 && m_FindNewCharacteristic)
					{
						CaplCharacteristicManager::SCharType *chval=
							new CaplCharacteristicManager::SCharType(inst0,type);
						m_characts_and_types[num_group].Add(chval);
					}
				}
			}
			apidata.GetAttr(inst,m_api->m_prd_mgr.a_pdf_prd,prd_02);				
			if(prd_02==0)continue;
			// Важен флаг from_base==false !
			m_api->m_charact_mgr.FindAssociatedCharacteristic(prd_02,ext_rel,extGroup,false,false,false,false);
			for( j=0;j<ext_rel.Size;j++)
			{
				char_vals[i].Add(ext_rel[j]);
				apidata.GetAttr(ext_rel[j],m_api->m_charact_mgr.a_apl_charact_val_charact,inst0);
				apidata.GetAttr(ext_rel[j],m_api->m_charact_mgr.a_apl_charact_val_type,type);
				index=-1;
				if(inst0!=0)
				{
					for(k=0;k<m_characts_and_types[num_group].Size;k++)
					{
						if((m_characts_and_types[num_group].GetAt(k)->charact==inst0)&&
							(m_characts_and_types[num_group].GetAt(k)->type==type)) 
						{
							index=k;
							break;
						}
					}
					if(index==-1 && m_FindNewCharacteristic)
					{
						CaplCharacteristicManager::SCharType *chval=
							new CaplCharacteristicManager::SCharType(inst0,type);
						m_characts_and_types[num_group].Add(chval);
					}
				}
			}

		}
		if(m_ReReadCharact[num_group] || m_FindNewCharacteristic)
		{
			// Если старт первый раз для группы или если могут найтись новые характеристики -
			// надо формировать массив описаний. Иначе-он уже есть
			// перевод списка характеристик и их типов в строковый массив
			for (i = 0; i < m_characts_and_types[num_group].Size; i++)
			{
				array=new CStringArray();
				CString name=_T(""),type=_T(""),unit_name=_T("");
				apidata.GetAttr(m_characts_and_types[num_group].GetAt(i)->charact,
											m_api->m_charact_mgr.a_apl_charact_name,name);
				if(m_characts_and_types[num_group].GetAt(i)->type!=0)
				{
					apidata.GetAttr(m_characts_and_types[num_group].GetAt(i)->type,
						m_api->m_charact_mgr.a_apl_charact_type_name,type);
				}
				apidata.GetAttr(m_characts_and_types[num_group].GetAt(i)->charact,
					m_api->m_charact_mgr.a_apl_charact_unit,unit);
				m_api->m_charact_mgr.GetUnitName(unit,unit_name);
				array->Add(name);
				array->Add(type);
				array->Add(unit_name);
				m_names_characts_and_types[num_group].Add(array);
				m_is_characts_number[num_group].Add(m_api->m_charact_mgr.IsCharacteristicNumber(unit));
				m_is_characts_date[num_group].Add(m_api->m_charact_mgr.IsCharacteristicDate(unit));
			}
		}
		// для каждого входного инстанса формируем строковый массив значений характеристик в порядке,
		// соответствующем характеристикам и типам в m_characts_and_types
		m_charact_values_array[num_group].SetSize(size);
		for(i=start_pos;i<end_pos;i++)
		{
			if(m_Items_Columns==0){
				esd=m_Items_String->GetAt(i);
				for(j=0;j<num_group;j++){
					if(esd->m_next!=0)
						esd=esd->m_next;
				}
				inst=esd->m_inst;
			}else{
				ecd=m_Items_Columns->GetAt(i);
				for(j=0;j<num_group;j++){
					if(ecd->m_next!=0)
						ecd=ecd->m_next;
				}
				inst=ecd->m_inst;
			}
			if(inst==0)continue;
			array=new CStringArray;
			array->SetSize(m_characts_and_types[num_group].Size);
			for(int j=0;j<char_vals[i].Size;j++)
			{
				apidata.GetAttr(char_vals[i][j],m_api->m_charact_mgr.a_apl_charact_val_item,inst0);				
				if(inst0==inst)
				{
					apidata.GetAttr(char_vals[i][j],m_api->m_charact_mgr.a_apl_charact_val_charact,inst0);
					apidata.GetAttr(char_vals[i][j],m_api->m_charact_mgr.a_apl_charact_val_type,type);
					for(k=0;k<m_characts_and_types[num_group].Size;k++)
					{
						buf=_T("");
						if((m_characts_and_types[num_group].GetAt(k)->charact==inst0)&&
							(m_characts_and_types[num_group].GetAt(k)->type==type)) 
						{
							m_api->m_charact_mgr.PrintCharacteristicValue(char_vals[i][j],0,buf);
							array->SetAt(k,buf);
							break;
						}
					}
				}
				else
				{
					CaplInstance *prd_02;
					apidata.GetAttr(inst,m_api->m_prd_mgr.a_pdf_prd,prd_02);				

					if(inst0==prd_02)
					{
						apidata.GetAttr(char_vals[i][j],m_api->m_charact_mgr.a_apl_charact_val_charact,inst0);
						apidata.GetAttr(char_vals[i][j],m_api->m_charact_mgr.a_apl_charact_val_type,type);
						for(k=0;k<m_characts_and_types[num_group].Size;k++)
						{
							buf=_T("");
							if((m_characts_and_types[num_group].GetAt(k)->charact==inst0)&&
								(m_characts_and_types[num_group].GetAt(k)->type==type)) 
							{
								m_api->m_charact_mgr.PrintCharacteristicValue(char_vals[i][j],0,buf);
								array->SetAt(k,buf);
								break;
							}
						}
					}
				}
			}
			m_charact_values_array[num_group].SetAt(i,array);
		}
		delete[] char_vals;
		prgdlg.ShowWindow(FALSE);
		m_ReReadCharact[num_group]=false;
	}
	if(m_characts_and_types[num_group].Size<=0)
	{
		if(is_dlg){
			if(m_FindNewCharacteristic){
				AfxMessageBox( APL_T("Для всех элементов характеристики не найдены!"),MB_ICONINFORMATION);
			}else{
				AfxMessageBox( APL_T("Для всех элементов не определены характеристики из \nпредварительно заданного списка !"),MB_ICONINFORMATION);
			}
		}
		return false;
	}
	bool res=true;
	if(is_dlg){
		Columns.Add( APL_T("Наименование"));
		Columns.Add( APL_T("Тип"));
		Columns.Add( APL_T("Единица измерения"));

		res=DoChooseCharacteristicsDlg(&Columns,&(m_names_characts_and_types[num_group]),
			&(m_SelectedCharMask[num_group]),_T(""),_T(""),_T(""));
	}

	if(!res)return false;
	FillCharacteristik(num_group);
	return true;
}

bool CInstPropertyCtrl::SetCharacterysticFromExt(aplExtent &chars_and_type,int num_group,bool forsed_reread,bool load_from_bd) 
{
	// TODO: Add your control notification handler code here
	int i,j,k,index,size=0;
	CString buf,buf1;
	aplExtent ext_rel,extGroup;
	CaplInstance *inst,*inst0,*unit,*charact,*type;
	CStringArray* array;
	SItemColumnData* ecd=0;
	SItemStringData* esd=0;

	if(m_api==0) return false;
	if(m_Items_Columns==0 && (m_Items_String==0 || m_ColumnsHeader.GetSize()==0)){
		return false;
	}
	if(m_Items_Columns==0){
		size=m_Items_String->GetSize();
	}else{
		size=m_Items_Columns->GetSize();
	}
	


	m_FindNewCharacteristic=false;
	if(m_ReReadCharact[num_group] || forsed_reread)
	{
		m_ReReadCharact[num_group]=false;
		m_characts_and_types[num_group].Clear();
		m_names_characts_and_types[num_group].Clear();
		m_is_characts_number[num_group].RemoveAll();
		m_charact_values_array[num_group].Clear();
		m_SelectedCharMask[num_group].RemoveAll();

		// перевод списка характеристик и их типов в массив внутренних данных и в строковый массив
		for( j=0;j<chars_and_type.Size;j++)
		{
			// проверим тип инстансы
			if(!apidata.IsKindOf(chars_and_type[j],m_api->m_charact_mgr.e_apl_characteristic_and_type)){
				continue;
			}
			apidata.GetAttr(chars_and_type[j],m_api->m_charact_mgr.a_apl_characteristic_and_type_characteristic,charact);
			apidata.GetAttr(chars_and_type[j],m_api->m_charact_mgr.a_apl_characteristic_and_type_type,type);
			index=-1;
			if(charact!=0)
			{
				// ищем, не заносили ли такой комплект
				for(k=0;k<m_characts_and_types[num_group].Size;k++)
				{
					if((m_characts_and_types[num_group].GetAt(k)->charact==charact)&&
						(m_characts_and_types[num_group].GetAt(k)->type==type)) 
					{
						index=k;
						break;
					}
				}
				if(index==-1)
				{
					// заносим пару во внутренний массив
					CaplCharacteristicManager::SCharType *chval=
						new CaplCharacteristicManager::SCharType(charact,type);
					m_characts_and_types[num_group].Add(chval);
					// заносим имя пары - для заголовка столбца
					array=new CStringArray();
					CString charact_name=_T(""),type_name=_T(""),unit_name=_T("");
					apidata.GetAttr(charact,
						m_api->m_charact_mgr.a_apl_charact_name,charact_name);
					if(type!=0)
					{
						apidata.GetAttr(type,
							m_api->m_charact_mgr.a_apl_charact_type_name,type_name);
					}
					apidata.GetAttr(charact,
						m_api->m_charact_mgr.a_apl_charact_unit,unit);
					m_api->m_charact_mgr.GetUnitName(unit,unit_name);
					array->Add(charact_name);
					array->Add(type_name);
					array->Add(unit_name);
					k=m_names_characts_and_types[num_group].Add(array);
					m_SelectedCharMask[num_group].Add(k);
					m_is_characts_number[num_group].Add(m_api->m_charact_mgr.IsCharacteristicNumber(unit));

				}
			}
		}
		if(m_characts_and_types[num_group].GetSize()==0){
			return true;
		}
		// формируем экстент всех инстансов в контроле и загружаем все характеристики для него
/*	Типа старый вариант
		aplExtent ext_all,out_ext,out_group;
		for(i=0;i<size;i++)
		{
			if(m_Items_Columns==0){
				esd=m_Items_String->GetAt(i);
				for(j=0;j<num_group;j++){
					if(esd->m_next!=0)
						esd=esd->m_next;
				}
				inst=esd->m_inst;
			}else{
				ecd=m_Items_Columns->GetAt(i);
				for(j=0;j<num_group;j++){
					if(ecd->m_next!=0)
						ecd=ecd->m_next;
				}
				inst=ecd->m_inst;
			}
			if(inst!=0){ext_all.Add(inst);}
		}
		m_api->m_charact_mgr.FindAssociatedCharacteristic(ext_all,out_ext,out_group);
*/
		// Типа новый вариант. Новая функция только загружаетзначения характеристик в кеш, а
		// по структурам контрола их распределяет отдельный код: новая функция возвращает 
		// столбцы характеристик (для многих инстансов одну характеристику), а в структуру
		// надо заносить строки (для одной инстансы несколько характеристик)
		// при перекрестном преобразовании немудрено ошибиться, поэтому формирование структур 
		// из кеша оставлено в старом виде.
		CaplMap map_inst;
		for(i=0;i<size;i++)
		{
			if(m_Items_Columns==0){
				esd=m_Items_String->GetAt(i);
				for(j=0;j<num_group;j++){
					if(esd->m_next!=0)
						esd=esd->m_next;
				}
				inst=esd->m_inst;
			}else{
				ecd=m_Items_Columns->GetAt(i);
				for(j=0;j<num_group;j++){
					if(ecd->m_next!=0)
						ecd=ecd->m_next;
				}
				inst=ecd->m_inst;
			}
			if(inst!=0){map_inst.Add((long)inst,0);}
		}
		
		for(k=0;k<m_characts_and_types[num_group].Size;k++)
		{
			for(i=0;i<map_inst.Size;i++){
				map_inst.Data[i].out=0;
			}
			charact=m_characts_and_types[num_group].GetAt(k)->charact;
			type=m_characts_and_types[num_group].GetAt(k)->type;
			m_api->m_charact_mgr.GetInstancesCharact (map_inst,charact,type,load_from_bd);
		}

		// для каждого входного инстанса формируем строковый массив значений характеристик в порядке,
		// соответсвующем характеристикам и типам в m_characts_and_types
		m_charact_values_array[num_group].SetSize(size);
		for(i=0;i<size;i++)
		{
			if(m_Items_Columns==0){
				esd=m_Items_String->GetAt(i);
				for(j=0;j<num_group;j++){
					if(esd->m_next!=0)
						esd=esd->m_next;
				}
				inst=esd->m_inst;
			}else{
				ecd=m_Items_Columns->GetAt(i);
				for(j=0;j<num_group;j++){
					if(ecd->m_next!=0)
						ecd=ecd->m_next;
				}
				inst=ecd->m_inst;
			}
			if(inst==0)continue;
			array=new CStringArray;
			array->SetSize(m_characts_and_types[num_group].Size);
			for(k=0;k<m_characts_and_types[num_group].Size;k++)
			{
				buf=_T("");
				charact=m_characts_and_types[num_group].GetAt(k)->charact;
				type=m_characts_and_types[num_group].GetAt(k)->type;
				inst0=m_api->m_charact_mgr.FindCharacteristic(inst,charact,type,false,false);
				if(inst0==0){
					CaplInstance *prd;
					apidata.GetAttr(inst,m_api->m_prd_mgr.a_pdf_prd,prd);				
					if(prd==0)continue;
					inst0=m_api->m_charact_mgr.FindCharacteristic(prd,charact,type,false,false);
				}
				if(inst0==0)continue;
				m_api->m_charact_mgr.PrintCharacteristicValue(inst0,0,buf);
				array->SetAt(k,buf);
			}
			m_charact_values_array[num_group].SetAt(i,array);
		}
	}
	FillCharacteristik(num_group);
	return true;
}

bool CInstPropertyCtrl::FillCharacteristik(int num_group)
{
	int i,j,k,index,size;
	SItemColumnData* ecd=0;
	SItemStringData* esd=0;
	CString buf,buf1;
	aplExtent ext_rel,extGroup;
	CStringArray Columns;
	CStringArray* array;
	int num_kill=0;
	int displacement=0;
	if(m_Items_Columns==0 && m_Items_String==0){
		return false;
	}

	if(m_Items_Columns==0){
		size=m_Items_String->GetSize();
	}else{
		size=m_Items_Columns->GetSize();
	}
	// удаление колонок между-до
	if(num_group==m_multiplicity-1){
		while (DeleteColumn(m_first_free_column[num_group]));
	}else{
		num_kill=m_first_used_column[num_group+1]-m_first_free_column[num_group];
		for(i=0;i<num_kill;i++){
			DeleteColumn(m_first_free_column[num_group]);
		}
	}
	int col_num;
	// Изменение колонок
	for(i=0;i<m_SelectedCharMask[num_group].GetSize();i++)
	{
		array=m_names_characts_and_types[num_group].GetAt(m_SelectedCharMask[num_group].GetAt(i));
		if(array==0)
			continue;
		if(array->GetSize()>0)buf=array->GetAt(0);
		if(array->GetSize()>1)buf+=_T(" (")+array->GetAt(1)+_T(")");
		if(array->GetSize()==3)buf+=_T(" [")+array->GetAt(2)+_T("]");
		col_num=InsertColumn(i+m_first_free_column[num_group],buf,LVCFMT_LEFT,80);
		if(m_is_characts_number[num_group].GetAt(m_SelectedCharMask[num_group].GetAt(i))){
			SetColumnNumeric(col_num);
		}
		if(m_is_characts_number[num_group].GetAt(m_SelectedCharMask[num_group].GetAt(i))){
			SetColumnDate(col_num);
		}
	}
	// Изменение данных
	k=GetItemCount();
	for(i=0;i<k;i++)
	{
		index=GetItemData(i);
		if(index<0 || index >= size){
			// ошибка, лучше ничего не делать
		}else{
			for(int i1=0;i1<m_SelectedCharMask[num_group].GetSize();i1++)
			{
				buf=m_charact_values_array[num_group].GetAt(index)->GetAt(m_SelectedCharMask[num_group].GetAt(i1));
				SetItemText(i,i1+m_first_free_column[num_group],buf);
			}
		}
	}
	// перенос индексов столбцов следующих групп
	displacement=m_SelectedCharMask[num_group].GetSize()-num_kill;
	if(displacement!=0){
		for(i=num_group+1;i<m_multiplicity;i++){
			m_first_free_column[i]+=displacement;
			m_first_used_column[i]+=displacement;
			for(j=0;j<NUM_OBJ_COL;j++){
				m_real_position[i][j]+=displacement;
			}
		}
		Renumerate();
	}

	return true;
}


bool CInstPropertyCtrl::SelectColumnsOrder(int num_group)
{
	int i,j;
	bool flag;
	CaplMap map;
	CStringArray Columns;
	CUIntArray ColumnMask,map_inserted;
	Columns.Add( APL_T("Наименование"));
	CStringArray* el;
	CaplTAggr<CStringArray*,CStringArray*,APLAGGR_LIST_OR_AUTOKILLREF> columns_names;
	int position=0;
	SaveColumnWidths();

	if(m_Items_Columns==0 && m_Items_String==0){
		return false;
	}else if(m_Items_Columns!=0 && m_Items_Columns->GetSize()==0){
		return false;
	}else if(m_Items_String!=0 && m_Items_String->GetSize()==0){
		return false;
	}
	for(i=0;i<NUM_OBJ_COL;i++){
		flag=false;
		// ищем, есть ли данный столбец для имеющихся инстансов
		if(m_ColumnsInsertedInstances[num_group].GetSize()>0)
		{
			flag=true;
			for(j=0;j<m_ColumnsInsertedInstances[num_group].GetSize();j++)
			{
				if(m_ColumnsInsertedInstances[num_group].GetAt(j)==(UINT)i)
				{
					flag=false;
					break;
				}
			}
		}
		if(flag)
			continue;
		// заполняем строчки-имена столбцов
		el=new CStringArray();
		el->Add(Type2Name(i));
		columns_names.Add(el);
		map_inserted.Add(i);
		// параллельно определяем маску видимых
		if(IsVisibleColumn(num_group,i))
		{
			map.Add((m_order[num_group][i]),position);
		}
		position++;
	}
	map.SortIn();
	ColumnMask.RemoveAll();
	for(i=0;i<map.Size;i++){
		ColumnMask.Add(map[i].out);
	}
	bool res;
	res=DoChooseCharacteristicsDlg(&Columns,&columns_names,&ColumnMask,
		 APL_T("Выбор столбцов"), APL_T("Отображаемые столбцы"), APL_T("Неотображаемые столбцы"));
	if(!res)return false;
	// порядок столбцов
	for(j=0;j<NUM_OBJ_COL;j++)m_AllVisibleColumns[num_group][j]=0;

	for(i=0;i<ColumnMask.GetSize();i++)
	{
		position=map_inserted.GetAt(ColumnMask.GetAt(i));
		m_order[num_group][position]=i;
		m_AllVisibleColumns[num_group][position]=1;
	}
	// пересоздаем структуры столбцов - 
	// они теперь в новом порядке
	InitAvailableColumns();
	// перезаливаем таблицу
	FillTable();
	SaveColumnWidths();
	

	return true;
}

void CInstPropertyCtrl::SetContexMenuMode(bool context_menu_processed,bool context_menu_save2file,
					   bool context_menu_save2folder,bool context_menu_save2categ,bool context_menu_set_access)
{
	m_context_menu_processed	=context_menu_processed;
	m_context_menu_save2file	=context_menu_save2file;
	m_context_menu_save2folder	=context_menu_save2folder;
	m_context_menu_save2categ	=context_menu_save2categ;
	m_context_menu_set_access	=context_menu_set_access;
}

void CInstPropertyCtrl::OnContextMenu(CWnd* pWnd, CPoint pos  )
{
	if(!m_context_menu_processed)return;
	ProcessContextMenu(pos,m_context_menu_save2file,m_context_menu_save2folder,
			m_context_menu_save2categ,0,m_context_menu_set_access);
}

UINT CInstPropertyCtrl::ProcessContextMenu(CPoint pos ,bool context_menu_save2file,
			bool context_menu_save2folder,bool context_menu_save2categ,
			CaplTAggr<SMenuItemDescription*,SMenuItemDescription*,APLAGGR_AUTOKILLREF> *additional_menu,
			bool context_menu_set_access,bool context_menu_save2classifier, aplExtent* removed)
{
	CUIntArray array;
	UINT flag;
	CaplInstance* folder;
	BOOL res;
	int i=0;
	aplExtent ext,ext_doc;
	CaplMenu menu;
	CaplAggr aggr;
	CString pattern;

	if(m_Items_Columns!=0 )
	{
		i+=m_Items_Columns->GetSize();
	}
	if( m_Items_String!=0 )
	{
		i+=m_Items_String->GetSize();
	}
	if(i==0)
	{
		return 0;
	}
	
	// для данных заданных массивом строк допустимо только меню "сохранить в файл"
	if(m_Items_Columns==0 && !m_context_menu_save2file)return 0;
	// незачем показывать пустое меню
	if(!context_menu_save2categ && !context_menu_save2folder && 
		!context_menu_save2file && additional_menu==0 && !context_menu_set_access)return 0;

	GetSelectedElements(array);
	ext.Clear();
	if(m_Items_Columns!=0)
	{
		for(i=0;i<array.GetSize();i++)
		{
			ext.Add(m_Items_Columns->GetAt(array[i])->m_inst);
		}
	}

	// Есть ли PDF среди выделенных 
	bool bExpEsi4sel=false,bExpEsi4all=false;
	for(i=0;i<ext.GetSize();i++)
	{
		if(m_api->m_data.IsKindOf(ext[i],m_api->m_prd_mgr.e_pdf))  bExpEsi4sel=true;
	}
	// Есть ли PDF среди всех 
	if(bExpEsi4sel) bExpEsi4all=true;
	else
	{
		for(i=0;i<m_Items_Columns->GetSize();i++)
		{
			if(m_api->m_data.IsKindOf(m_Items_Columns->GetAt(i)->m_inst,m_api->m_prd_mgr.e_pdf)) bExpEsi4all=true;
		}
	}



	CString mess = _T("");
	bool base_folder=false,base_class_level=false;
	UINT nFlags_move = MF_GRAYED|MF_STRING, nFlags_groupe = MF_GRAYED|MF_STRING, nFlags_move_groupe = MF_GRAYED|MF_STRING; 
	if(m_base_inst!=0)
	{
		if(m_api->m_data.IsKindOf(m_base_inst,m_api->m_folder_mgr.e_folder))
		{
			base_folder = true;
		}
		if(m_api->m_data.IsKindOf(m_base_inst,m_api->m_classifier_mgr.e_apl_classifier_system))
		{
			//
		}
		else if(m_api->m_data.IsKindOf(m_base_inst,m_api->m_classifier_mgr.e_apl_classifier_level))
		{
			base_class_level = true;
		}
		else if(m_api->m_data.IsKindOf(m_base_inst,m_api->m_categ_mgr.e_categ))
		{
			//
		}
	}
	if(base_folder || base_class_level)
	{
		if(m_base_inst->GetAccessmode() <= aplRW)
			nFlags_move = MF_ENABLED|MF_STRING;
		if(array.GetSize()>0)
		{
			nFlags_move_groupe = MF_ENABLED|MF_STRING;
		}
	}
	if(array.GetSize()>0)
	{
		nFlags_groupe = MF_ENABLED|MF_STRING;
	}

	res=menu.CreatePopupMenu();
	menu.Install(this);
	if(context_menu_save2folder && m_Items_Columns!=0)
	{
		res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_ADDALL2FOLDER, APL_T("Скопировать все объекты в папку..."));
		if(base_folder)res=menu.AppendMenu(nFlags_move,ID_MENU_MOVEALL2FOLDER, APL_T("Переместить все объекты в папку..."));
		res=menu.AppendMenu(nFlags_groupe,ID_MENU_ADD2FOLDER, APL_T("Скопировать выделенные объекты в папку..."));
		if(base_folder)res=menu.AppendMenu(nFlags_move_groupe,ID_MENU_MOVE2FOLDER, APL_T("Переместить выделенные объекты в папку..."));

		if(context_menu_save2categ || context_menu_save2file || context_menu_save2classifier || context_menu_set_access || additional_menu!=0)
		{
			res=menu.AppendMenu(MF_SEPARATOR,0,_T(""));
		}
	}
	if(context_menu_save2categ)
	{
		res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_ADDALL2CATEGORY, APL_T("Скопировать все объекты в категорию..."));
		res=menu.AppendMenu(nFlags_groupe,ID_MENU_ADD2CATEGORY, APL_T("Скопировать выделенные объекты в категорию..."));

		if(context_menu_save2file || context_menu_set_access || context_menu_save2classifier || additional_menu!=0)
		{
			res=menu.AppendMenu(MF_SEPARATOR,0,_T(""));
		}
	}
	if(context_menu_save2classifier)
	{
		res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_ADDALL2CLASSIFIER, APL_T("Скопировать все объекты в справочник..."));
		if(base_class_level)res=menu.AppendMenu(nFlags_move,ID_MENU_MOVEALL2CLASSIFIER, APL_T("Переместить все объекты в справочник..."));
		res=menu.AppendMenu(nFlags_groupe,ID_MENU_ADD2CLASSIFIER, APL_T("Скопировать выделенные объекты в справочник..."));
		if(base_class_level)res=menu.AppendMenu(nFlags_move_groupe,ID_MENU_MOVE2CLASSIFIER, APL_T("Переместить выделенные объекты в справочник..."));

		if(context_menu_save2file || context_menu_set_access || additional_menu!=0)
		{
			res=menu.AppendMenu(MF_SEPARATOR,0,_T(""));
		}
	}

	//if(context_menu_save2classifier)
	{
		res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_COPY_ALL_DOCS_TO_CHANGE, APL_T("Добавить все документы в пакет изменений..."));
		res=menu.AppendMenu(nFlags_groupe,ID_MENU_COPY_DOCS_TO_CHANGE, APL_T("Добавить выделенные документы в пакет изменений..."));
		res=menu.AppendMenu(MF_SEPARATOR,0,_T(""));

		res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_CREATE_REFS_ALL_DOCS_TO_ITEM, APL_T("Связать все документы с объектом..."));
		res=menu.AppendMenu(nFlags_groupe,ID_MENU_CREATE_REFS_DOCS_TO_ITEM, APL_T("Связать выделенные документы с объектом..."));
		res=menu.AppendMenu(MF_SEPARATOR,0,_T(""));
	}

	if(context_menu_save2file)
	{
		res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_SAVE_ALL, APL_T("Сохранить список всех объектов в файл..."));
		res=menu.AppendMenu(nFlags_groupe,ID_MENU_SAVE_SELECTED, APL_T("Сохранить список выделенных объектов в файл..."));

		if(context_menu_set_access || additional_menu!=0)
		{
			res=menu.AppendMenu(MF_SEPARATOR,0,_T(""));
		}
	}

	if(bExpEsi4all || bExpEsi4sel)
	{
		if(bExpEsi4sel) res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_EXP_STUCT_SEL_TO_ESI, APL_T("Экспортировать структуру в документ ЭСИ для выделенных"));
		if(bExpEsi4all) res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_EXP_STUCT_ALL_TO_ESI, APL_T("Экспортировать структуру в документ ЭСИ для всех"));
		res=menu.AppendMenu(MF_SEPARATOR,0,_T(""));
	}

	if(context_menu_set_access)
	{
		res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_SET_ACCESS_ALL, APL_T("Назначить доступ всем объектам..."));
		res=menu.AppendMenu(nFlags_groupe,ID_MENU_SET_ACCESS_SELECTED, APL_T("Назначить доступ выделенным объектам..."));

		if(additional_menu!=0)
		{
			res=menu.AppendMenu(MF_SEPARATOR,0,_T(""));
		}
	}
	
	if(additional_menu!=0)
	{
		for(i=0;i<additional_menu->GetSize();i++)
		{
			if(additional_menu->GetAt(i)->nFlags !=0)
			{
				flag = additional_menu->GetAt(i)->nFlags;
			}
			else if( additional_menu->GetAt(i)->need_content && array.GetSize()==0)
			{
				flag = MF_GRAYED|MF_STRING;
			}
			else
			{
				flag = MF_ENABLED|MF_STRING;
			}
			res=menu.AppendMenu(flag,additional_menu->GetAt(i)->id,additional_menu->GetAt(i)->menu_text);
		}
	}
	if(context_menu_save2classifier || context_menu_save2folder || context_menu_save2file || context_menu_set_access || additional_menu!=0)
	{
		res=menu.AppendMenu(MF_SEPARATOR,0,_T(""));
	}
	if(ext.GetSize()==1)
	{
		res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_SHOW_PROPERTIES, APL_T("Свойства..."));
	}


	res=menu.TrackPopupMenu(TPM_LEFTALIGN|
		TPM_RIGHTBUTTON|TPM_RETURNCMD,pos.x, pos.y,this);

	//в зависимости от выбора строки контекстного меню :
	bool move = (res == ID_MENU_MOVEALL2CLASSIFIER || res == ID_MENU_MOVE2CLASSIFIER || 
		res == ID_MENU_MOVEALL2FOLDER || res == ID_MENU_MOVE2FOLDER);
	switch (res)
	{
	case ID_SHOW_PROPERTIES:
		m_api->ShowItemProperties(ext.GetAt(0));
		break;
	case ID_MENU_ADDALL2FOLDER:
	case ID_MENU_MOVEALL2FOLDER:
		ext.Clear();
		if(m_Items_Columns!=0)
		{
			for(i=0;i<m_Items_Columns->GetSize();i++)
			{
				ext.Add(m_Items_Columns->GetAt(i)->m_inst);
			}
		}
		// break нет специально!
	case ID_MENU_ADD2FOLDER: 
	case ID_MENU_MOVE2FOLDER: 
		while(true)
		{
			folder=m_api->m_folder_mgr.SelectInstanceEx(APL_MODE_SELECT_FOLDER);
			if(folder==0)return 0;
			if(folder->GetAccessmode()>aplRW)
			{
				MessageBox( APL_T("К указанной папке нет доступа!"), APL_T("Выбор объекта"),MB_OK);
				continue;
			}
			m_api->m_data.GetAttr(folder,m_api->m_folder_mgr.a_folder_content,aggr);
			if(aggr.GetSize()>0)
			{
				if(AfxMessageBox( APL_T("В указанной папке уже есть содержимое.\nДобавить в эту папку?"),
					MB_YESNO)==IDNO)continue;
			}
			ext_doc.Clear();
			long wd_thread=aplStartWaitDlg( APL_T("Перенос данных в папку"));
			for(int i=0;i<ext.GetSize();i++)
			{
				if(m_create_assoc_doc){
					if(m_api->m_data.IsKindOf(ext.GetAt(i),m_api->m_doc_mgr.e_doc)){
						ext_doc.Add(ext.GetAt(i));
					}else{
						aggr.Add(ext.GetAt(i));
					}
				}else{
					aggr.Add(ext.GetAt(i));
				}
			}
			m_api->m_data.PutAttr(folder,m_api->m_folder_mgr.a_folder_content,aggr);
			if(m_create_assoc_doc){
				for(int i=0;i<ext_doc.GetSize();i++){
					m_api->m_doc_mgr.CreateAssociation(folder,ext_doc.GetAt(i));
				}
			}
			if(move)
			{
				m_api->m_folder_mgr.RemoveFromFolder(m_base_inst,ext);
				mess = APL_T("Объекты перенесены");
			}
			else
				mess = APL_T("Объекты скопированы");
			aplEndWaitDlg(wd_thread);
			if(m_api->m_classifier_mgr.m_AutoSave)m_api->m_data.NET_SaveChanges();
			AfxMessageBox( mess );
			break;
		}
		break;

	case ID_MENU_COPY_ALL_DOCS_TO_CHANGE:
		{
			ext.Clear(); // здесь были выделенные
			if(m_Items_Columns!=0)
			{
				for(i=0;i<m_Items_Columns->GetSize();i++) ext.Add(m_Items_Columns->GetAt(i)->m_inst);
			}	
			m_api->m_change_mgr.AddItemsToChange(ext,0);
		}
		break;
	case ID_MENU_COPY_DOCS_TO_CHANGE:
		{
			m_api->m_change_mgr.AddItemsToChange(ext,0);
		}
		break;


	case ID_MENU_CREATE_REFS_ALL_DOCS_TO_ITEM:
		{
			ext.Clear(); // здесь были выделенные
			if(m_Items_Columns!=0)
			{
				for(i=0;i<m_Items_Columns->GetSize();i++) ext.Add(m_Items_Columns->GetAt(i)->m_inst);
			}	
			m_api->m_doc_mgr.CreateAssociation(0, ext);
		}
		break;
	case ID_MENU_CREATE_REFS_DOCS_TO_ITEM :
		{
			m_api->m_doc_mgr.CreateAssociation(0, ext);
		}
		break;


	case ID_MENU_ADDALL2CATEGORY:
		ext.Clear();
		if(m_Items_Columns!=0)
		{
			for(i=0;i<m_Items_Columns->GetSize();i++){
				ext.Add(m_Items_Columns->GetAt(i)->m_inst);
			}
		}
		// break нет специально!
	case ID_MENU_ADD2CATEGORY:
		while(true){
			CaplInstance* category,*inst1,*inst2;
			bool is_error=true,load_categ_info=true,old_AutoSave;
			category=m_api->m_query_mgr.SelectInstance(APL_MODE_SELECT_CATEGORY);
			if(category==0)
				break;
			if(category->GetAccessmode()>aplRW){
				if(MessageBox( APL_T("У Вас нет доступа на выбранную категорию!\nВыбрать другую категорию?"), 
					APL_T("Выбор категории"),MB_YESNO)==IDYES)
				{
					continue;
				}else{
					return 0;
				}
			}
			old_AutoSave=m_api->m_categ_mgr.m_AutoSave;
			m_api->m_categ_mgr.m_AutoSave=false;
			long wd_thread=aplStartWaitDlg( APL_T("Перенос данных в категорию"));
			m_api->m_categ_mgr.CheckOut(category);
			for(int i=0;i<ext.GetSize();i++)
			{
				inst1=ext.GetAt(i);
				if(m_api->m_data.IsKindOf(inst1,m_api->m_prd_mgr.e_prd)){
					inst2=inst1;
				}else if(m_api->m_data.IsKindOf(inst1,m_api->m_prd_mgr.e_pdf)){
					m_api->m_data.GetAttr(inst1,m_api->m_prd_mgr.a_pdf_prd,inst2);
				}else
				{
					is_error=false;
					break;
				}
				m_api->m_categ_mgr.AddPrdToCategory(inst2,category,load_categ_info);
				load_categ_info=false;
			}
			aplEndWaitDlg(wd_thread);
			if(is_error){
				m_api->m_categ_mgr.CheckIn(category);
				AfxMessageBox( APL_T("Объекты скопированы"));
			}else{
				m_api->m_categ_mgr.UndoCheckOut(category);
				AfxMessageBox( APL_T("В категорю можно скопировать только изделия! Копирование отменено"));
			}
			m_api->m_categ_mgr.m_AutoSave=old_AutoSave;
			break;
		}
		
		if(m_api->m_classifier_mgr.m_AutoSave)m_api->m_data.NET_SaveChanges();
		break;
		
	case ID_MENU_ADDALL2CLASSIFIER:
	case ID_MENU_MOVEALL2CLASSIFIER:
		ext.Clear();
		if(m_Items_Columns!=0)
		{
			for(i=0;i<m_Items_Columns->GetSize();i++){
				ext.Add(m_Items_Columns->GetAt(i)->m_inst);
			}
		}
		// break нет специально!
	case ID_MENU_ADD2CLASSIFIER:
	case ID_MENU_MOVE2CLASSIFIER:
		while(true)
		{
			CaplInstance* classifier_el;
			bool is_error=true,load_categ_info=true,old_AutoSave;
			classifier_el=m_api->m_query_mgr.SelectInstance(APL_MODE_SELECT_CLASSIF_ELEMENT);
			if(classifier_el==0)
				break;
			if(classifier_el->GetAccessmode()>aplRW){
				if(MessageBox( APL_T("У Вас нет доступа к выбранному справочнику!\nВыбрать другой справочник?"), 
					APL_T("Выбор справочника"),MB_YESNO)==IDYES)
				{
					continue;
				}else{
					return 0;
				}
			}
			old_AutoSave=m_api->m_classifier_mgr.m_AutoSave;
			m_api->m_classifier_mgr.m_AutoSave=false;
			long wd_thread=aplStartWaitDlg( APL_T("Перенос данных в справочник"));

			is_error = m_api->m_classifier_mgr.CreateClassifierAssociation(ext,classifier_el,!move);
			if(is_error && move)
			{
				for(i=0;i<ext.GetSize();i++)
				{
					is_error = m_api->m_classifier_mgr.DeleteClassifierAssociation(ext[i],m_base_inst);
					if(!is_error) break;
				}
				mess = APL_T("Объекты перенесены");
			}
			else
				mess = APL_T("Объекты скопированы");

			aplEndWaitDlg(wd_thread);
			if(is_error){
				AfxMessageBox( mess );
			}else{
				AfxMessageBox( APL_T("Копирование прервано"));
			}
			m_api->m_classifier_mgr.m_AutoSave=old_AutoSave;
			break;
		}
		
		if(m_api->m_classifier_mgr.m_AutoSave)m_api->m_data.NET_SaveChanges();
		break;	

	case ID_MENU_SET_ACCESS_ALL:
		ext.Clear();
		if(m_Items_Columns!=0)
		{
			for(i=0;i<m_Items_Columns->GetSize();i++){
				ext.Add(m_Items_Columns->GetAt(i)->m_inst);
			}
		}
		// break нет специально!
	case ID_MENU_SET_ACCESS_SELECTED:
		for(i=0;i<ext.GetSize();i++){
			if(ext.GetAt(i)->GetAccessmode()>aplRW){
				AfxMessageBox( APL_T("У Вас не хватает прав чтобы изменить степень\nдоступа для выбранных объектов\nОперация невозможна"));
				return 0;
			}
		}

		/* Специально по просьбе омска в этом диалоге покажываем все галочки
		if(!ShowDlgAccessProperties(m_api,APL_T("Назначение доступа на группу объектов"),pattern)){return false;};		
		// Ну и собсвенно назначение доступа
		if(pattern==_T(""))
		{
			return m_api->m_data.NET_SetInstancesAccess(&ext,_T(""));
		}else{
			if(m_api->m_data.NET_SetAccessFromPattern(&ext,pattern,APL_T("Установка доступа")))
			{
				AfxMessageBox(APL_T("Доступ установлен!"));
			}else{
				return false;
			}
		}
		*/
		folder=m_api->m_data.CreateInstance(m_api->m_query_mgr.e_apl_query,true);
		m_api->m_data.PutAttr(folder,m_api->m_query_mgr.a_apl_query_content,ext);
		m_api->SetRecursiveAccess(folder);
		m_api->m_data.DeleteInstance(folder);
		break;
		
	case ID_MENU_SAVE_ALL:
		SaveToFileAll();
		break;

	case ID_MENU_SAVE_SELECTED: 
		SaveToFileSel();
		break;

	case ID_MENU_EXP_STUCT_ALL_TO_ESI: 
		{
			aplExtent ext1;
			for(i=0;i<m_Items_Columns->GetSize();i++)
			{
				CaplInstance *inst1=m_Items_Columns->GetAt(i)->m_inst;
				ext1.Add(inst1);
			}
			m_api->m_prd_mgr.GenerateESI4Ext(ext1,true);
		}
		
		break;
	case ID_MENU_EXP_STUCT_SEL_TO_ESI: 
		m_api->m_prd_mgr.GenerateESI4Ext(ext,true);
		break;

	default:
		return res;
		break;
	}
	if(move && removed!=0)
	{
		removed->Append(ext);
	}
	return 0;
}

bool CInstPropertyCtrl::GetCharacteristicByRC(int row, int col, CaplInstance **base_inst, int &pos_in_data, CaplInstance **charact, CaplInstance **type,CaplInstance **char_val,int &_num_group)
{
	bool check_charact=false;
	SItemColumnData* ecd =0;
	SItemStringData* esd =0;
	int num_group;
	bool is_inst_attr=false,is_charact=false;

	if(m_api==0)return false;
	if(base_inst==0){return false;}
	if(charact!=0 && type!=0 && char_val!=0)
	{
		check_charact=true;
	}
	else
	{
		if(charact!=0 || type!=0 || char_val!=0)
		{
			return false;
		}
	}
	if(row < 0 || col < 0) return false;

	*base_inst=0;*charact=0;*type=0;*char_val=0;


	// Определяем, к какой группе относится столбец, и относится он к характеристикам или атрибутам
	for(num_group=0;num_group<MAX_GROUPS;num_group++)
	{
		if(col >= m_first_used_column[num_group] && col< m_first_free_column[num_group])
		{
			is_inst_attr=true;
			break;
		}
		if(col >= m_first_free_column[num_group] && 
			col <m_first_free_column[num_group]+ m_SelectedCharMask[num_group].GetSize())
		{
			is_charact=true;
			break;
		}
	}
	if(num_group==MAX_GROUPS || (!is_inst_attr && !is_charact ))
	{
		// во блин, куда-то улез столбец не туда. Может, в иконку ткнули или за границы 
		// заполненного
		return false;
	}
	pos_in_data=(int)GetItemData(row);
	int j;
	_num_group=num_group;
	if(m_Items_Columns!=0)
	{
		if(pos_in_data>=m_Items_Columns->GetSize()){pos_in_data=-1;return false;}
		ecd=m_Items_Columns->GetAt(pos_in_data);
		if(ecd==0){return false;}
		*base_inst=ecd->m_inst;
		for(j=0;j<num_group;j++){
			if(ecd->m_next!=0){
				ecd=ecd->m_next;
				*base_inst=ecd->m_inst;
			}else{
				*base_inst=0;
				break;
			}
		}
	}else{
		if(pos_in_data>=m_Items_String->GetSize()){pos_in_data=-1;return false;}
		esd=m_Items_String->GetAt(pos_in_data);
		if(esd==0){return 0;}
		*base_inst=esd->m_inst;
		for(j=0;j<num_group;j++){
			if(esd->m_next!=0){
				esd=esd->m_next;
				*base_inst=esd->m_inst;
			}else{
				*base_inst=0;
				break;
			}
		}
	}
	if(*base_inst==0)return false;
	if(is_inst_attr || !check_charact){
		return true;
	}
	// а вот теперь определяем, что за характеристику нам бог послал
	CaplCharacteristicManager::SCharType* char_and_type;
	char_and_type=m_characts_and_types[num_group].
		GetAt(m_SelectedCharMask[num_group].GetAt(col -m_first_free_column[num_group]));
	if(char_and_type==0)return false;
	*charact=char_and_type->charact;
	*type=char_and_type->type;
	*char_val=m_api->m_charact_mgr.FindCharacteristic(*base_inst,*charact,*type,true);

	return true;
}

bool CInstPropertyCtrl::EditCell(int row, int col)
{
	int pos_in_data;
	bool retval=false;
	bool is_form=false;
	CString form_ent_name=_T("");
	CaplInstance *base_inst=0,*charact=0,*type=0,*char_val=0,*charact_type=0;
	int num_group=0;
	int k;
	if(GetCharacteristicByRC(row,col,&base_inst,pos_in_data,&charact,&type,&char_val,num_group))
	{
		if(m_properties_form!=0 && base_inst!=0 && FShowForm2!=0){
			// проверяем подходит ли форма под entity
			m_api->m_form_mgr.GetFormEntityName(m_properties_form,form_ent_name);
			if(form_ent_name.CompareNoCase(base_inst->GetType()->name)!=0){
				AfxMessageBox( APL_T("Тип формы не совпадает с типом объекта"));
			}else{
				is_form=true;
			}
		}
		if(is_form){
			aplExtent ext_in,ext_out;
			aplExtent ext_charact;
			aplExtent all_char_type;
			m_api->m_data.GetEntityExtent(m_api->m_charact_mgr.e_apl_characteristic_and_type,all_char_type);
			ext_in.Add(base_inst);
			// определяем набор характеристик для отображения в форме
			// берем все характеристики отображаемые в таблице и передаем их объекты в форму

			bool old_ModeInteractive=m_api->m_ModeInteractive;
			m_api->m_ModeInteractive=false;
			for(k=0;k<m_characts_and_types[num_group].Size;k++)
			{
				charact=m_characts_and_types[num_group].GetAt(k)->charact;
				type=m_characts_and_types[num_group].GetAt(k)->type;
				charact_type=m_api->m_charact_mgr.CreateCharacteristicAndType(charact,type,0,false,false,&all_char_type);
				if(charact_type!=0){
					if(charact_type->GetId()==0)charact_type->SetTemporary(true);// нам левые связки в БД не нужны
				}
				ext_charact.Add(charact_type);
			}
			m_api->m_ModeInteractive=old_ModeInteractive;

			FShowForm2(m_api,m_properties_form,ext_in,ext_out,&ext_charact,form_ent_name, _T(""), TRUE, FALSE, FALSE);
			FillTable(true,pos_in_data,1);
		}else{
			if(charact==0){
				// здесь надо показать свойства базового инстанса - когда будет глобальная такая функция
				if(m_api->m_show.m_doc__view_on_dblclick && m_api->m_data.IsKindOf(base_inst,m_api->m_doc_mgr.e_doc))
				{
					m_api->m_doc_mgr.View(base_inst,false);
				}
				else
				{
					retval=m_api->ShowItemProperties(base_inst);
					FillTable(true,pos_in_data,1);
				}
			}else{
				if(char_val!=0){
					retval=m_api->m_charact_mgr.ShowProperties(char_val,true);
				}else{
					retval=m_api->m_charact_mgr.CreateCharacteristic(base_inst,0,&char_val,charact,0,false,0,true,type);
				}
				/*if(retval)*/{SelectCharacterysticSet(0,false,pos_in_data,1);}
			}
		}

	}
	return retval;
}

SItemColumnData* CInstPropertyCtrl::GetItemColumnData(int nItem)
{
	int indx=(int)GetItemData(nItem);
	if(m_Items_Columns==0)return 0;
	if(indx<0)return 0;
	if(indx>m_Items_Columns->GetSize())return 0;
	return m_Items_Columns->GetAt(indx);
}

SItemStringData* CInstPropertyCtrl::GetItemStringData(int nItem)
{
	int indx=(int)GetItemData(nItem);
	if(m_Items_String==0)return 0;
	if(indx<0)return 0;
	if(indx>m_Items_String->GetSize())return 0;
	return m_Items_String->GetAt(indx);
}


