// DlgListInstances.cpp : implementation file
//

#include "stdafx.h"
#include "resource.h"
#include "apl_api.h"
#include "DlgListInstances.h"
#include "icons_defines.h"


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


bool AFX_EXT_API MakeInstListTable(CaplAPI *api,aplExtent *ext,
								   bool is_hide_move_button,bool *res_move,
								   bool can_delete,bool *is_changed,CString *delete_message,bool is_context_menu_categ)
{
	if(api==0)return false;
	if(ext==0)return false;
	int res=0;
	if(res_move!=0){*res_move=false;}
	if(is_changed!=0){*is_changed=false;}
	
	CaplSetResourceHandle setres(module_inst);

	CDlgListInstances dlg;
	dlg.m_content=ext;
	dlg.m_api=api;
	dlg.m_is_hide_move_button=is_hide_move_button;
	dlg.m_can_delete=can_delete;
	dlg.m_is_context_menu_categ=is_context_menu_categ;
	if(delete_message!=0){
		dlg.m_delete_message=*delete_message;
	}
	res=dlg.DoModal();
	if(can_delete && is_changed!=0){
		*is_changed=dlg.m_changed;
	}
	if(res==ID_MOVE2TREE){
		if(res_move!=0){
			*res_move=true;
		}
	}
	return true;
}

bool AFX_EXT_API MakeNIIAOFindResult(CaplAPI *api,aplExtent *ext,
									 bool is_hide_move_button,bool *res_move)
{
	if(api==0)return false;
	if(ext==0)return false;
	int res=0;
	if(res_move!=0){*res_move=false;}
	
	CaplSetResourceHandle setres(module_inst);
	CDlgListInstances dlg;
	dlg.m_content=ext;
	dlg.m_api=api;
	dlg.m_is_hide_move_button=is_hide_move_button;
	dlg.m_can_delete=false;
	dlg.m_mode_niiao=true;
	res=dlg.DoModal();

	if(res==ID_MOVE2TREE){
		if(res_move!=0){
			*res_move=true;
		}
	}
	return true;
}


/////////////////////////////////////////////////////////////////////////////
// CDlgListInstances dialog


CDlgListInstances::CDlgListInstances(CWnd* pParent /*=NULL*/)
	: CaplResizableDialog(CDlgListInstances::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDlgListInstances)
	//}}AFX_DATA_INIT
	m_CountALlString=0;
	m_content=0;
	m_api=0;
	m_main_type=0;
	m_ListObjects.SetUniqueName(_T("CDlgListInstances_ListObjects"));
	m_is_hide_move_button=true;
	m_can_delete=false;
	m_changed=false;
	m_delete_message= APL_T("Вы действительно хотите удалить выделенные объекты из списка?");
	m_delete_message_all= APL_T("Вы действительно хотите удалить все объекты из списка?");
	m_delete_message_from_BD= APL_T("Вы действительно хотите удалить выделенные объекты из БД?");
	m_mode_niiao=false;
	m_is_context_menu_categ = false;
	m_base_inst = 0;
}


void CDlgListInstances::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgListInstances)
	DDX_Control(pDX, IDC_MOVE2TREE, m_BtnMove2Tree);
	DDX_Control(pDX, IDCANCEL, m_BtnCancel);
	DDX_Control(pDX, IDC_SAVE_TO_FILE, m_BtnSaveToFile);
	DDX_Control(pDX, ID_SELECT_CHARACTERYSTIC_SET, m_BtnSelectChsrscteristic);
	DDX_Control(pDX, IDC_BTN_SELECT_COLUMN, m_BtnSelectColumns);
	DDX_Control(pDX, IDC_COUNT_STRING, m_CountString);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlgListInstances, CaplResizableDialog)
//{{AFX_MSG_MAP(CDlgListInstances)
	ON_NOTIFY(NM_RCLICK, IDC_LIST_OBJECTS_STATIC, OnRclickListObjects)
	ON_NOTIFY(NM_CLICK, IDC_LIST_OBJECTS_STATIC, OnClickListObjects)
	ON_NOTIFY(NM_DBLCLK, IDC_LIST_OBJECTS_STATIC, OnDblclickListObjects)
	ON_BN_CLICKED(IDC_SAVE_TO_FILE, OnSaveToFile)
	ON_BN_CLICKED(IDC_MOVE2TREE, OnMove2Tree)
	ON_BN_CLICKED(ID_SELECT_CHARACTERYSTIC_SET, OnSelectCharacterysticSet)
	ON_WM_SYSCOMMAND()
	ON_BN_CLICKED(IDC_BTN_SELECT_COLUMN, OnBtnSelectColumn)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgListInstances message handlers

BOOL CDlgListInstances::OnInitDialog() 
{
	
	BOOL res=m_ListObjects.CreateFromStatic(IDC_LIST_OBJECTS_STATIC,this,0,true);
	CaplResizableDialog::OnInitDialog();

	ModifyStyleEx(0, WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT);   
	ModifyStyle(0, WS_MAXIMIZEBOX);   
	
	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		pSysMenu->AppendMenu(MF_STRING, IDC_BTN_SELECT_COLUMN,  APL_T("Выбрать столбцы"));
		pSysMenu->AppendMenu(MF_STRING, ID_SELECT_CHARACTERYSTIC_SET,  APL_T("Настройка характеристик"));
	}

	if(m_is_hide_move_button){
		m_BtnMove2Tree.ShowWindow(SW_HIDE);
		m_BtnCancel.SetWindowText( APL_T("Выход"));
		SetWindowText( APL_T("Список объектов"));
	}
	
	// TODO: Add extra initialization here
	AddAnchor(IDC_LIST_OBJECTS_STATIC,TOP_LEFT, BOTTOM_RIGHT);
	AddAnchor(IDCANCEL,BOTTOM_RIGHT, BOTTOM_RIGHT);
	AddAnchor(IDC_MOVE2TREE,BOTTOM_RIGHT, BOTTOM_RIGHT);
	AddAnchor(IDC_SAVE_TO_FILE,BOTTOM_CENTER, BOTTOM_CENTER);
	AddAnchor(ID_SELECT_CHARACTERYSTIC_SET,BOTTOM_LEFT, BOTTOM_LEFT);
	AddAnchor(IDC_BTN_SELECT_COLUMN,BOTTOM_LEFT, BOTTOM_LEFT);
	AddAnchor(IDC_COUNT_STRING,TOP_LEFT, TOP_RIGHT);

	m_BtnCancel.SetIcon(GetAplStdIco16(APLSTDICO_CANCEL));
	m_BtnCancel.SetFlat(FALSE);
	m_BtnSaveToFile.SetIcon(GetAplTableIco(APL_TABLE_SAVE));
	m_BtnSaveToFile.SetFlat(FALSE);
	m_BtnMove2Tree.SetIcon(GetAplStdIco16(APLSTDICO_TREE));
	m_BtnMove2Tree.SetFlat(FALSE);
	m_BtnSelectChsrscteristic.SetIcon(GetAplTableIco(APL_TABLE_SELECT_CHAR));
	m_BtnSelectChsrscteristic.SetFlat(FALSE);
	m_BtnSelectColumns.SetIcon(GetAplTableIco(APL_TABLE_WIDTH));
	m_BtnSelectColumns.SetFlat(FALSE);


	if(m_api==0 )return FALSE;
	// Показывать нечего
	if(m_content->GetSize()==0) return FALSE;

	// предотвращаем потерю модальности после диалога с бочками из aplSocketTransport
	CORRECT_LOOSE_MODAL_ON_CLASS(&(m_api->m_data));


	FeelTableCtrl();
	
	return TRUE;  // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
}

void CDlgListInstances::OnSysCommand(UINT nID, LPARAM lParam) 
{
	// TODO: Add your message handler code here and/or call default
	if(nID==IDC_BTN_SELECT_COLUMN){
		m_ListObjects.SelectColumnsOrder(0);
		return;
	}
	CDialog::OnSysCommand(nID, lParam);
}


bool CDlgListInstances::FeelTableCtrl()
{
	int i,j;
	// первый столбец: 0 pdf, 1 pi, 2bpi
	int first=-1;
//	CaplTAggr<S_pdf*,S_pdf*,APLAGGR_AUTOKILLREF> list_pi;
	SItemColumnData *cd_pdf,*cd_pi,*cd_bpi;
	aplExtent in_pdf,in_pi,in_bpi;
	aplExtent all_pdf,all_pi,all_bpi,all_bpi_ref,temp_ext,temp_2;
	aplExtent onl_pdf,onl_pi,onl_bpi;
	CaplLoadData ld(&(m_api->m_data),DEF_SOURCE);
	CaplInstance* inst,*inst_pdf,*inst_pi,*inst_bpi;
	in_pdf.Unique=false;
	in_pi.Unique=false;
	in_bpi.Unique=false;
	all_pdf.Unique=false;
	all_pi.Unique=false;
	all_bpi.Unique=false;
	temp_ext.Unique=false;

//	m_Mask.Clear();
	m_Items.Clear();
	if(m_content==0)return false;

	if(m_mode_niiao){
		// сортируем по типам
		for(i=0;i<m_content->GetSize();i++){
			inst=m_content->GetAt(i);
			int temp_first=-1;
			if(m_api->m_data.IsKindOf(inst,m_api->m_prd_mgr.e_pdf)){
				in_pdf.Add(inst);
				all_pdf.Add(inst);
				temp_first=0;
			}else if(m_api->m_data.IsKindOf(inst,m_api->m_prd_inst_mgr.e_prd_inst)){
				in_pi.Add(inst);
				temp_first=1;
			}else if(m_api->m_data.IsKindOf(inst,m_api->m_bp_mgr.e_apl_bp_inst)){
				in_bpi.Add(inst);
				temp_first=2;
			}
			if(first==-1 && temp_first!=-1){
				first=temp_first;
			}
		}
		// заказываем сопутствующие
		// для изделий ищем все экземпляры
		if(all_pdf.GetSize()>0){
			for(i=0;i<all_pdf.GetSize();i++){
				ld.AddQuery(0,_T('a'),all_pdf.GetAt(i)->GetId(),0,0,false);
			}
			i=ld.AddQuery(_T('r'),0,m_api->m_prd_inst_mgr.e_prd_inst,m_api->m_prd_inst_mgr.a_prd_inst_pdf,true);
			ld.AddQuery(_T('d'),i,0,m_api->m_prd_inst_mgr.a_prd_inst_pdf,true);
			temp_ext.Clear();
			temp_2.Clear();
			ld.LoadEx(true,&temp_ext);
			for(i=0;i<temp_ext.GetSize();i++){
				inst=temp_ext.GetAt(i);
				if(m_api->m_data.IsKindOf(inst,m_api->m_prd_inst_mgr.e_prd_inst)){
					all_pi.Add(inst);
					// это те pdf, у которых есть pi
					m_api->m_data.GetAttr(inst,m_api->m_prd_inst_mgr.a_prd_inst_pdf,inst_pdf);
					if(inst_pdf!=0)	temp_2.Add(inst_pdf);
				}
			}
			// ищем pdf из входных данных, у которых нет pi
			onl_pdf.Clear();
			CSortClass::SortExtentById(temp_2);
			for(i=0;i<in_pdf.GetSize();i++){
				inst=in_pdf.GetAt(i);
				if(aplQFindInstIdInExtent(temp_2,inst->GetId())==-1){
					onl_pdf.Add(inst);
				}
			}
			// ищем pi из входных данных, которых нет в all_pi - 
			// т.е. которые не принадлежат никому из in_pdf
			CSortClass::SortExtentById(all_pi);
			temp_ext.Clear();
			for(i=0;i<in_pi.GetSize();i++){
				inst=in_pi.GetAt(i);
				if(aplQFindInstIdInExtent(all_pi,inst->GetId())==-1){
					temp_ext.Add(inst);
				}
			}

		}else{
			// все pi из входных данных не принадлежат никому из in_pdf по причине его пустоты
			if(in_pi.GetSize()>0){
				for(i=0;i<in_pi.GetSize();i++){
					inst=in_pi.GetAt(i);
					temp_ext.Add(inst);
				}
			}
		}
		all_pi.Append(temp_ext);
		// получаем pdf для pi, не имеющих pdf во входных данных 
		// (или для всех если входных pdf нет)
		if(temp_ext.GetSize()>0){
			for(i=0;i<temp_ext.GetSize();i++){
				ld.AddQuery(0,_T('a'),temp_ext.GetAt(i)->GetId(),0,0,true);
			}
			i=ld.AddQuery(_T('d'),0,0,m_api->m_prd_inst_mgr.a_prd_inst_pdf,true);
			temp_ext.Clear();
			ld.LoadEx(true,&temp_ext);
			for(i=0;i<temp_ext.GetSize();i++){
				inst=temp_ext.GetAt(i);
				if(m_api->m_data.IsKindOf(inst,m_api->m_prd_mgr.e_pdf)){
					all_pdf.Add(inst);
				}
			}
		}
		// ищем bpi для всех известных pi (как входных, так и полученных для входных pdf)
		if(all_pi.GetSize()>0){
			for(i=0;i<all_pi.GetSize();i++){
				ld.AddQuery(0,_T('a'),all_pi.GetAt(i)->GetId(),0,0,false);
			}
			i=ld.AddQuery(_T('r'),0,m_api->m_bp_mgr.e_bp_inst_ref,m_api->m_bp_mgr.a_bp_inst_ref_item,true);
			ld.AddQuery(_T('d'),i,0,m_api->m_bp_mgr.a_bp_inst_ref_item,true);
			ld.AddQuery(_T('d'),i,0,m_api->m_bp_mgr.a_bp_inst_ref_process,true);
			temp_ext.Clear();
			ld.LoadEx(true,&temp_ext);
			temp_2.Clear();
			for(i=0;i<temp_ext.GetSize();i++){
				inst=temp_ext.GetAt(i);
				if(m_api->m_data.IsKindOf(inst,m_api->m_bp_mgr.e_apl_bp_inst)){
					all_bpi.Add(inst);
				}else if(m_api->m_data.IsKindOf(inst,m_api->m_bp_mgr.e_bp_inst_ref)){
					all_bpi_ref.Add(inst);
					// это те pi, у которых есть bpi
					m_api->m_data.GetAttr(inst,m_api->m_bp_mgr.a_bp_inst_ref_item,inst_pi);
					if(inst_pdf!=0)	temp_2.Add(inst_pi);
				}
			}
			// ищем pi, у которых нет bpi
			onl_pi.Clear();
			CSortClass::SortExtentById(temp_2);
			for(i=0;i<all_pi.GetSize();i++){
				inst=all_pi.GetAt(i);
				if(aplQFindInstIdInExtent(temp_2,inst->GetId())==-1){
					onl_pi.Add(inst);
				}
			}
			
			// ищем bpi из входных данных, которых нет в all_bpi
			// т.е. они не принадлежат никому из известных pi
			CSortClass::SortExtentById(all_bpi);
			temp_ext.Clear();
			for(i=0;i<in_bpi.GetSize();i++){
				inst=in_bpi.GetAt(i);
				if(aplQFindInstIdInExtent(all_bpi,inst->GetId())==-1){
					temp_ext.Add(inst);
				}
			}
		}else{
			// ищем bpi из входных данных, которые не принадлежат 
			// никому из известных pi из-за отсутствия оных
			temp_ext.Append(in_bpi);
		}

		all_bpi.Append(temp_ext);
		if(temp_ext.GetSize()>0){
			// для bpi с неизвестными pi и pdf ищем и загружаем их
			for(i=0;i<temp_ext.GetSize();i++){
				ld.AddQuery(0,_T('a'),temp_ext.GetAt(i)->GetId(),0,0,false);
			}
			i=ld.AddQuery(_T('r'),0,m_api->m_bp_mgr.e_bp_inst_ref,m_api->m_bp_mgr.a_bp_inst_ref_process,true);
			  ld.AddQuery(_T('d'),i,0,m_api->m_bp_mgr.a_bp_inst_ref_process,true);
			j=ld.AddQuery(_T('d'),i,0,m_api->m_bp_mgr.a_bp_inst_ref_item,true);
			  ld.AddQuery(_T('d'),j,0,m_api->m_prd_inst_mgr.a_prd_inst_pdf,true);
			temp_ext.Clear();
			ld.LoadEx(true,&temp_ext);
			for(i=0;i<temp_ext.GetSize();i++){
				inst=temp_ext.GetAt(i);
				if(m_api->m_data.IsKindOf(inst,m_api->m_prd_inst_mgr.e_prd_inst)){
					all_pi.Add(inst);
				}else if(m_api->m_data.IsKindOf(inst,m_api->m_prd_mgr.e_pdf)){
					all_pdf.Add(inst);
				}else if(m_api->m_data.IsKindOf(inst,m_api->m_bp_mgr.e_bp_inst_ref)){
					all_bpi_ref.Add(inst);
				}
			}		
		}
		// загружаем в кеш информацию о всех объектах
		m_api->m_prd_mgr.LoadPrdInfo(all_pdf);
		m_api->m_prd_mgr.LoadPrdInfo(onl_pdf);
		m_api->m_prd_inst_mgr.LoadPrdInstInfo(all_pi);
		m_api->m_prd_inst_mgr.LoadPrdInstInfo(onl_pi);
		m_api->m_bp_mgr.LoadBPInstInfo(all_bpi);

		// теперь все что надо есть в кеше.
		// компонуем структуру
		// сначала полные тройки
		for(i=0;i<all_bpi_ref.GetSize();i++){
			inst=all_bpi_ref.GetAt(i);
			m_api->m_data.GetAttr(inst,m_api->m_bp_mgr.a_bp_inst_ref_process,inst_bpi);
			m_api->m_data.GetAttr(inst,m_api->m_bp_mgr.a_bp_inst_ref_item,inst_pi);
			m_api->m_data.GetAttr(inst_pi,m_api->m_prd_inst_mgr.a_prd_inst_pdf,inst_pdf);
			cd_pdf=new SItemColumnData(inst_pdf);
			cd_pi=new SItemColumnData(inst_pi);
			cd_bpi=new SItemColumnData(inst_bpi);
			// определяем порядок столбцов
			if(first==1){
				cd_pi->m_next=cd_pdf;
				cd_pdf->m_next=cd_bpi;
				m_Items.Add(cd_pi);
			}else if(first==2){
				cd_bpi->m_next=cd_pi;
				cd_pi->m_next=cd_pdf;
				m_Items.Add(cd_bpi);
			}else{
				cd_pdf->m_next=cd_pi;
				cd_pi->m_next=cd_bpi;
				m_Items.Add(cd_pdf);
			}
		}
		// теперь ущербные - те что без bpi
		for(i=0;i<onl_pi.GetSize();i++){
			inst_pi=onl_pi.GetAt(i);
			m_api->m_data.GetAttr(inst_pi,m_api->m_prd_inst_mgr.a_prd_inst_pdf,inst_pdf);
			cd_pdf=new SItemColumnData(inst_pdf);
			cd_pi=new SItemColumnData(inst_pi);
			if(first==1){
				cd_pi->m_next=cd_pdf;
				m_Items.Add(cd_pi);
			}else{
				cd_pdf->m_next=cd_pi;
				m_Items.Add(cd_pdf);
			}
		}
		// теперь ущербные - только pdf
		for(i=0;i<onl_pdf.GetSize();i++){
			inst_pdf=onl_pdf.GetAt(i);
			cd_pdf=new SItemColumnData(inst_pdf);
			m_Items.Add(cd_pdf);
		}
	}else{
		for(i=0;i<m_content->GetSize();i++){
			m_Items.Add(new SItemColumnData(m_content->GetAt(i)));
		}
		m_CountALlString=m_content->GetSize();
	}

	m_ListObjects.m_api=m_api;
	m_ListObjects.SaveColumnWidths();
	if(m_mode_niiao){
		m_ListObjects.SetData(m_Items,3);
	}else{
		m_ListObjects.SetData(m_Items);
	}
	if(m_ListObjects.IsVisibleDefault())
	{
		m_ListObjects.VisibleColumnRemove(0,OBJ_COL_INSTANCE_ID);
		m_ListObjects.VisibleColumnRemove(0,OBJ_COL_COUNT);
		m_ListObjects.VisibleColumnRemove(0,OBJ_COL_UNIT);
	}

	m_ListObjects.FillTable();
	CString str=_T(""),str1;
	if(m_base_inst!=0)
	{
		if(m_api->m_data.IsKindOf(m_base_inst,m_api->m_folder_mgr.e_folder))
		{
			str=APL_T("Содержимое папки '");
		}
		else if(m_api->m_data.IsKindOf(m_base_inst,m_api->m_classifier_mgr.e_apl_classifier_system))
		{
			str=APL_T("Содержимое справочника '");
		}
		else if(m_api->m_data.IsKindOf(m_base_inst,m_api->m_classifier_mgr.e_apl_classifier_level))
		{
			str=APL_T("Содержимое элемента справочника '");
		}
		else if(m_api->m_data.IsKindOf(m_base_inst,m_api->m_categ_mgr.e_categ))
		{
			str=APL_T("Содержимое категории '");
		}
		else
		{
			str=APL_T("Содержимое объекта \'");
		}

		str += m_api->GetItemName(m_base_inst);
		str += _T("'; ");

		m_ListObjects.m_base_inst = m_base_inst;
	}
	str1.Format( APL_T("Всего объектов: %i"),m_CountALlString);
	str+=str1;
	m_CountString.SetWindowText(str);

	return true;
}

#include "SelectWFSDlg.h"


void CDlgListInstances::OnRclickListObjects(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	*pResult = 0;
	aplExtent ext;
	CUIntArray array;
	const MSG* msg;
	CaplInstance *inst;
	int i=0,j;
	aplExtent removed;
	bool has_chg_state=false, has_other=false;

	msg=GetCurrentMessage();


	m_ListObjects.GetSelectedElements(array);

	CString str;str.Format( APL_T("Всего строк %i; выделено строк %i"),m_CountALlString,array.GetSize());
	m_CountString.SetWindowText(str);

	if(m_Items.GetSize()==0)
		return;
	ext.Clear();

	for(i=0;i<array.GetSize();i++)
	{
		inst = m_Items.GetAt(array[i])->m_inst;

		if(m_api->m_data.IsKindOf(inst,m_api->m_prd_mgr.e_pdf) || m_api->m_data.IsKindOf(inst,m_api->m_doc_mgr.e_doc) || 
			m_api->m_data.IsKindOf(inst,m_api->m_bp_mgr.e_bp) || m_api->m_data.IsKindOf(inst,m_api->m_change_mgr.e_chng) || 
			m_api->m_data.IsKindOf(inst,m_api->m_req_mgr.e_requirement))
		{
			has_chg_state = true;
		}
		else
		{
			has_other = true;
		}
		ext.Add(inst);
	}

	CaplTAggr<SMenuItemDescription*,SMenuItemDescription*,APLAGGR_AUTOKILLREF> add_menu;
	add_menu.Add(new SMenuItemDescription(ID_MENU_DELETE, APL_T("Удалить выделенные объекты из списка"),true));
	add_menu.Add(new SMenuItemDescription(ID_MENU_DELETE_ALL, APL_T("Удалить все объекты из списка")));
	add_menu.Add(new SMenuItemDescription(ID_MENU_DELETE_FROM_BD, APL_T("Удалить выделенные объекты из БД")));

	if(has_chg_state)
	{
		UINT nFlags = MF_SEPARATOR;
		add_menu.Add(new SMenuItemDescription(0, _T(""),false,nFlags));
		if(!m_api->m_data.IsAdmin() || has_other) nFlags = MF_GRAYED|MF_STRING; else nFlags = 0;
		add_menu.Add(new SMenuItemDescription(ID_MENU_CHANGE_STATE, APL_T("Изменить состояние выделенных объектов"),true,nFlags));
	}

	// если от CInstPropertyCtrl нужно только стандартное контестное меню, то проще
	// не обрабатывать RClick, а вызвать в OnInitDialog функцию CInstPropertyCtrl::SetContexMenuMode
	UINT command=m_ListObjects.ProcessContextMenu(msg->pt,true,true,m_is_context_menu_categ,&add_menu,true,true,&removed);
	switch (command)
	{
	case ID_MENU_CHANGE_STATE:
		m_api->m_doc_mgr.ChangeWFState(ext);
		break;
	case ID_MENU_DELETE_ALL: 
		if(AfxMessageBox(m_delete_message_all,MB_YESNO)==IDYES){
			m_content->Clear();
			FeelTableCtrl();
			m_changed=true;
		}
		break;
	case ID_MENU_DELETE: 
		if(AfxMessageBox(m_delete_message,MB_YESNO)==IDYES){
			for(i=0;i<ext.GetSize();i++){
				for(j=0;j<m_content->GetSize();j++){
					if(ext.GetAt(i)==m_content->GetAt(j)){
						m_content->Remove(j);
						break;
					}
				}
			}
			FeelTableCtrl();
			m_changed=true;
		}
		break;
	case ID_MENU_DELETE_FROM_BD: 
		if(m_api==0){break;}
		if(AfxMessageBox(m_delete_message_from_BD,MB_YESNO)==IDYES){
			m_api->SetModeInteractive(false);
			bool prevAutoSave=m_api->m_AutoSave;
			m_api->SetAutoSave(false);
			long trd=aplStartWaitDlg( APL_T("Удаление элементов"));
			int count_not_del=0;
			bool err=false;
			for(i=0;i<ext.GetSize();i++){
				if(ext.GetAt(i)->GetAccessmode()>aplOWN){
					count_not_del++;
					continue;
				}
				CaplInstance *iItem=ext[i];

				bool bDeleted=true;

				if(0!=iItem)
				{
					if(!iItem->IsDeleted())  // Защита от ошибки при удалении свзяанных объектов
					{
						if(!m_api->DeleteItem(iItem))
						{
							err=true; 
							bDeleted=false;
						}
					}
				}

				if(bDeleted)
				{
					for(j=0;j<m_content->GetSize();j++){
						if(ext.GetAt(i)==m_content->GetAt(j)){
							m_content->Remove(j);
							break;
						}
					}
				}
			}
			aplEndWaitDlg(trd);
			m_api->SetAutoSave(prevAutoSave);
			if(prevAutoSave)m_api->SaveChanges();
			if(err)
			{
				AfxMessageBox( APL_T("Не удалось удалить некоторые элементы!"));
			}
			m_api->SetModeInteractive(true);
			FeelTableCtrl();
			m_changed=true;
			if(count_not_del!=0)
			{
				str.Format( APL_T("Не удалось удалить %i объектов - нет прав доступа"));
				AfxMessageBox(str);
			}
		}
		break;
	}
	if(removed.GetSize() > 0)
	{
		for(i=0;i<removed.GetSize();i++){
			for(j=0;j<m_content->GetSize();j++){
				if(removed.GetAt(i)==m_content->GetAt(j)){
					m_content->Remove(j);
					break;
				}
			}
		}
		FeelTableCtrl();
		m_changed=true;
	}
}

void CDlgListInstances::OnSaveToFile() 
{
	// TODO: Add your control notification handler code here
	m_ListObjects.SaveToFile(false);
}

void CDlgListInstances::OnMove2Tree() 
{
	// TODO: Add your control notification handler code here
	CaplResizableDialog::EndDialog(ID_MOVE2TREE);
}

void CDlgListInstances::OnCancel() 
{
	// TODO: Add extra cleanup here
	
	CaplResizableDialog::OnCancel();
}

void CDlgListInstances::OnSelectCharacterysticSet() 
{
	// TODO: Add your control notification handler code here
	CaplMenu menu;
	const MSG* msg;
	CPoint mouseclick;
	BOOL res;
	int num_gropup=0;
	if(m_mode_niiao){
		msg=GetCurrentMessage();
		//mouseclick - координаты клика мыши
		mouseclick=msg->pt;

		res=menu.CreatePopupMenu();
		menu.Install(this);
		res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_ORDER+0, APL_T("Для первой группы столбцов"));
		res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_ORDER+1, APL_T("Для второй группы столбцов"));
		res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_ORDER+2, APL_T("Для третьей группы столбцов"));

		res=menu.TrackPopupMenu(TPM_LEFTALIGN|
			TPM_RIGHTBUTTON|TPM_RETURNCMD,msg->pt.x, msg->pt.y,this);

		num_gropup=res-ID_MENU_ORDER;
	}
	m_ListObjects.SelectCharacterysticSet(num_gropup);
}

void CDlgListInstances::OnBtnSelectColumn() 
{
	// TODO: Add your control notification handler code here
	CaplMenu menu;
	const MSG* msg;
	CPoint mouseclick;
	BOOL res;
	int num_gropup=0;
	if(m_mode_niiao){
		msg=GetCurrentMessage();
		//mouseclick - координаты клика мыши
		mouseclick=msg->pt;

		res=menu.CreatePopupMenu();
		res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_ORDER+0, APL_T("Для первой группы столбцов"));
		res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_ORDER+1, APL_T("Для второй группы столбцов"));
		res=menu.AppendMenu(MF_ENABLED|MF_STRING,ID_MENU_ORDER+2, APL_T("Для третьей группы столбцов"));

		res=menu.TrackPopupMenu(TPM_LEFTALIGN|
			TPM_RIGHTBUTTON|TPM_RETURNCMD,msg->pt.x, msg->pt.y,this);

		num_gropup=res-ID_MENU_ORDER;
	}

	m_ListObjects.SelectColumnsOrder(num_gropup);

}

void CDlgListInstances::OnClickListObjects(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	*pResult = 0;
	CUIntArray array;
	m_ListObjects.GetSelectedElements(array);

	CString str;str.Format( APL_T("Всего строк %i; выделено строк %i"),m_CountALlString,array.GetSize());
	m_CountString.SetWindowText(str);
}

void CDlgListInstances::OnDblclickListObjects(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	*pResult = 0;
	CUIntArray array;
	m_ListObjects.GetSelectedElements(array);
	
	CString str;str.Format( APL_T("Всего строк %i; выделено строк %i"),m_CountALlString,array.GetSize());
	m_CountString.SetWindowText(str);
	
	LPNMLISTVIEW pNMListView=(LPNMLISTVIEW)pNMHDR;

	if(pNMListView==0)return;
	m_ListObjects.EditCell(pNMListView->iItem,pNMListView->iSubItem);


}
