// ProcessDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ProcessDlg.h"

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

#include "dictionary.h"
#include <apl_api.h>
#include "ListDialog.h"
#include "QueryStartPointDialog.h"

#include "aplWorkFlowManager.h"
#include <aplguiex.h>

/////////////////////////////////////////////////////////////////////////////
// CProcessDlg dialog

typedef std::pair<CaplInstance*,CaplInstance*> PAIR;

CProcessDlg::CProcessDlg(CWnd* pParent /*=NULL*/)
	: CaplResizableDialog(CProcessDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CProcessDlg)
	m_d_check = COleDateTime::GetCurrentTime();
	m_d_finish = COleDateTime::GetCurrentTime();
	m_d_start = COleDateTime::GetCurrentTime();
	m_t_check = COleDateTime::GetCurrentTime();
	m_t_finish = COleDateTime::GetCurrentTime();
	m_t_start = COleDateTime::GetCurrentTime();
	m_sDscr = _T("");
	m_sId = _T("");
	m_sName = _T("");
	m_iPrior = -1;
	m_iState = -1;
	m_sTmplId = _T("");
	m_iSub = -1;
	m_iPercent = 0;
	m_sPercent = _T("");
	m_sFactDate = APL_T("Контрольная дата:");
	m_sPlanDate = APL_T("Дата завершения:");
	m_sManager = _T("");
	m_iProtScema = 0;
	//}}AFX_DATA_INIT

	m_wf_mgr= NULL;
	m_curDate = COleDateTime::GetCurrentTime();

	m_woListView = NULL;
	m_api= NULL;
	m_process= NULL;
	m_process_tmpl= NULL;
	m_up_level_task= NULL;
	m_manager= NULL;
	m_old_up_level_task= NULL;
	m_sState= _T("initiated");
	m_sOldState= _T("initiated");
	m_sPriority= _T("medium");
	
	m_toolTip.m_hWnd = NULL;
	m_bReadOnly= TRUE;
}

void CProcessDlg::DoDataExchange(CDataExchange* pDX)
{
	CaplResizableDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CProcessDlg)
	DDX_Control(pDX, IDC_PROC_ADD_FILE, m_addFileBtn);
	//DDX_Control(pDX, IDC_PROC_WO_LIST, m_woList);
	DDX_Control(pDX, IDC_PROC_TAB, m_woTabCtrl);
	DDX_Control(pDX, IDC_PROC_DELETE, m_deleteBtn);
	DDX_Control(pDX, IDC_PROC_SELECT, m_mgrSelectBtn);
	DDX_Control(pDX, IDC_PROC_START_BUTTON, m_startBtn);
	DDX_Control(pDX, IDOK, m_okBtn);
	DDX_Control(pDX, IDCANCEL, m_cancelBtn);
	DDX_Control(pDX, IDC_PROC_DELETE_WO, m_deleteWoBtn);
	DDX_Control(pDX, IDC_PROC_ADD_WO, m_addWoBtn);
	DDX_Control(pDX, IDC_PROC_EDIT_PROT, m_editProtScemaBtn);
	DDX_Control(pDX, IDC_PROC_PER_SLIDER, m_percentCtrl);
	DDX_Control(pDX, IDC_PROC_ID, m_id);
	DDX_Control(pDX, IDC_PROC_NAME, m_name);
	DDX_Control(pDX, IDC_PROC_DSCR, m_dscr);
	DDX_Control(pDX, IDC_PROC_TIME_OUT, m_to);
	DDX_Control(pDX, IDC_PROC_STATE, m_state);
	DDX_Control(pDX, IDC_PROC_PRIORITY, m_prior);
	DDX_Control(pDX, IDC_SUB_PROCESS_COMBO, m_subCB);
	DDX_Control(pDX, IDC_PROC_PROTOTYPE, m_protCBCtrl);
	DDX_Control(pDX, IDC_PROC_T_START, m_t_start_ctrl);
	DDX_Control(pDX, IDC_PROC_T_CHECK, m_t_check_ctrl);
	DDX_Control(pDX, IDC_PROC_D_START, m_d_start_ctrl);
	DDX_Control(pDX, IDC_PROC_D_FINISH, m_d_finish_ctrl);
	DDX_Control(pDX, IDC_PROC_D_CHECK, m_d_check_ctrl);
	DDX_Control(pDX, IDC_PROC_T_FINISH, m_t_finish_ctrl);
	DDX_DateTimeCtrl(pDX, IDC_PROC_D_CHECK, m_d_check);
	DDX_DateTimeCtrl(pDX, IDC_PROC_D_FINISH, m_d_finish);
	DDX_DateTimeCtrl(pDX, IDC_PROC_D_START, m_d_start);
	DDX_DateTimeCtrl(pDX, IDC_PROC_T_CHECK, m_t_check);
	DDX_DateTimeCtrl(pDX, IDC_PROC_T_FINISH, m_t_finish);
	DDX_DateTimeCtrl(pDX, IDC_PROC_T_START, m_t_start);
	DDX_CBIndex(pDX, IDC_PROC_PRIORITY, m_iPrior);
	DDX_CBIndex(pDX, IDC_PROC_STATE, m_iState);
	DDX_CBIndex(pDX, IDC_SUB_PROCESS_COMBO, m_iSub);
	DDX_Slider(pDX, IDC_PROC_PER_SLIDER, m_iPercent);
	DDX_CBIndex(pDX, IDC_PROC_PROTOTYPE, m_iProtScema);
	DDX_Text(pDX, IDC_PROC_ID, m_sId);
	DDX_Text(pDX, IDC_PROC_NAME, m_sName);
	DDX_Text(pDX, IDC_PROC_DSCR, m_sDscr);
	DDX_Text(pDX, IDC_PROC_TMPL_ID, m_sTmplId);
	DDX_Text(pDX, IDC_PROC_PER_STATIC, m_sPercent);
	DDX_Text(pDX, IDC_PLAN_STATIC, m_sPlanDate);
	DDX_Text(pDX, IDC_FACT_STATIC, m_sFactDate);
	DDX_Text(pDX, IDC_PROC_MANAGER, m_sManager);
	DDX_Control(pDX, IDC_PROC_VIEW, m_viewBtn);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CProcessDlg, CaplResizableDialog)
	//{{AFX_MSG_MAP(CProcessDlg)
	ON_CBN_SELCHANGE(IDC_PROC_PRIORITY, OnSelchangeProcPriority)
	ON_CBN_SELCHANGE(IDC_PROC_STATE, OnSelchangeProcState)
	ON_WM_HSCROLL()
	ON_BN_CLICKED(IDC_PROC_START_BUTTON, OnProcStartButton)
	ON_CBN_SELCHANGE(IDC_SUB_PROCESS_COMBO, OnSelchangeSubProcessCombo)
	ON_BN_CLICKED(IDC_PROC_SELECT, OnProcSelect)
	ON_BN_CLICKED(IDC_PROC_DELETE, OnProcDelete)
	ON_WM_KEYDOWN()
	ON_BN_CLICKED(IDC_PROC_EDIT_PROT, OnProcEditProt)
	ON_BN_CLICKED(IDC_PROC_ADD_WO, OnProcAddWo)
	ON_BN_CLICKED(IDC_PROC_DELETE_WO, OnProcDeleteWo)
	ON_NOTIFY(TCN_SELCHANGE, IDC_PROC_TAB, OnSelchangeProcTab)
	ON_BN_CLICKED(IDC_PROC_ADD_FILE, OnProcAddFile)
	ON_BN_CLICKED(IDC_PROC_VIEW, OnBnClickedProcView)
	ON_WM_DESTROY()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CProcessDlg message handlers

void CProcessDlg::TreeListInit()
{
	//инициализируем список-дерево для рабочих объектов
	RECT rect;
	CWnd *pic = NULL;
	DWORD dwStyles=0;

	pic=(CWnd*)GetDlgItem(IDC_PROC_WO_LIST);
	pic->GetWindowRect(&rect);
	ScreenToClient(&rect);
		
	m_woListView = (CaplTreeListCtrlView*)(RUNTIME_CLASS(CaplTreeListCtrlView)->CreateObject());
	m_woListView->m_bUseCheckboxes = true;
		
	ASSERT(m_woListView);
	m_woListView->Create(0,0,TVS_CHECKBOXES|WS_BORDER|WS_VISIBLE|WS_CHILD|AFX_WS_DEFAULT_VIEW,rect,this,IDC_TREE_LIST);

	m_woListView->OnInitialUpdate();
	m_woListView->m_tree.m_bSortRoot=true;
	m_woListView->m_bAutofit=true;
	m_woListView->m_tree.m_wndHeader.SetAutofit();
	m_woListView->m_tree.m_dlg=this;
	m_woListView->MoveWindow(&rect);
	m_woListView->n_bNoParentNotify = false;		

	m_woListView->m_tree.SetImageList(aplGetInstImageList(), TVSIL_NORMAL);
	m_woListView->m_tree.SetItemHeight(m_woListView->m_tree.GetItemHeight()+2);
	
	// колонки для дерева-объектов
	m_woListView->m_tree.DeleteAllColumns();
	m_woListView->m_tree.InsertColumn(0, APL_T("Наименование"),			LVCFMT_LEFT, 500);
	m_woListView->m_tree.InsertColumn(1, APL_T("Тип объекта"),				LVCFMT_LEFT, 100);
	m_woListView->m_tree.m_wndHeader.SetAutofit();
}

BOOL CProcessDlg::OnInitDialog() 
{
	CaplResizableDialog::OnInitDialog();

	m_prior.ResetContent();
	m_prior.InsertString(0,APL_T("Высокий"));
	m_prior.InsertString(1,APL_T("Обычный"));
	m_prior.InsertString(2,APL_T("Низкий"));

	m_state.ResetContent();
	m_state.InsertString(0,APL_T("Не выполняется"));
	m_state.InsertString(1,APL_T("Выдано"));
	m_state.InsertString(2,APL_T("Выполняется"));
	m_state.InsertString(3,APL_T("Остановлено"));
	m_state.InsertString(4,APL_T("Отозвано"));
	m_state.InsertString(5,APL_T("Выполнено"));

	
	m_cancelBtn.SetIcon(GetAplStdIco16(APLSTDICO_CANCEL));
	m_cancelBtn.SetFlat(FALSE);
	m_okBtn.SetIcon(GetAplStdIco16(APLSTDICO_OK));
	m_okBtn.SetFlat(FALSE);
	
	m_mgrSelectBtn.SetIcon(aplGetButtonIco(APL_24_SELECT));
	m_mgrSelectBtn.SetFlat(FALSE);
	m_mgrSelectBtn.SetTooltipText(APL_T("Выбрать координатора"));
	m_deleteBtn.SetIcon(aplGetButtonIco(APL_24_DELETE));
	m_deleteBtn.SetFlat(FALSE);
	m_deleteBtn.SetTooltipText(APL_T("Удалить"));

	m_addWoBtn.SetFlat(FALSE);
	m_addWoBtn.SetIcon(aplGetButtonIco(APL_24_PLUS));
	m_addWoBtn.SetTooltipText(APL_T("Добавить объект"));
	m_deleteWoBtn.SetFlat(FALSE);
	m_deleteWoBtn.SetIcon(aplGetButtonIco(APL_24_DELETE));
	m_deleteWoBtn.SetTooltipText(APL_T("Удалить"));
	m_addFileBtn.SetFlat(FALSE);
	m_addFileBtn.SetIcon(aplGetButtonIco(APL_24_OPEN_FILE));
	m_addFileBtn.SetTooltipText(APL_T("Добавить файл с диска"));
	m_viewBtn.SetFlat(FALSE);
	m_viewBtn.SetIcon(aplGetButtonIco(APL_24_VIEW));
	m_viewBtn.SetTooltipText(APL_T("Открыть документ/файл для просмотра"));

	m_editProtScemaBtn.SetFlat(FALSE);
	m_editProtScemaBtn.SetIcon(aplGetButtonIco(APL_24_EDIT));
	m_editProtScemaBtn.SetTooltipText(APL_T("Редактировать схему прототипов"));

	m_t_start_ctrl.SetFormat(_T("HH:mm"));
	m_t_check_ctrl.SetFormat(_T("HH:mm"));
	m_t_finish_ctrl.SetFormat(_T("HH:mm"));


	TCITEM tcItem;
	tcItem.mask= TCIF_PARAM;
		
	m_woTabCtrl.InsertItem(APL_WFWO_FORWORK, APL_T("Рабочие"), -1);
	tcItem.lParam= (LPARAM)APL_WFWO_FORWORK;
	m_woTabCtrl.SetItem(APL_WFWO_FORWORK, &tcItem);
	m_woTabCtrl.InsertItem(APL_WFWO_FORNOTE, APL_T("Для справки"), -1);	
	tcItem.lParam= (LPARAM)APL_WFWO_FORNOTE;
	m_woTabCtrl.SetItem(APL_WFWO_FORNOTE, &tcItem);

	TreeListInit();
	/*m_woList.InsertColumn(0, APL_T("Наименование"), LVCFMT_LEFT, 250);
	m_woList.InsertColumn(1, APL_T("Тип"), LVCFMT_LEFT, 100);
	m_woList.SetImageList(aplGetInstImageList(), LVSIL_SMALL);*/

	if(m_api && apidata.IsConnected())
	{
		m_api->m_data.NET_GetServerDateTime(m_curDate);
		m_d_check= m_curDate;
		m_d_finish= m_curDate;
		m_d_start= m_curDate;
		m_t_check= m_curDate;
		m_t_finish= m_curDate;
		m_t_start= m_curDate;
		
		//COleDateTimeSpan odts;
		COleDateTime odt, odtSt;
		apidata.NET_GetServerDateTime(odt);

		aplExtent ext;
		double rDuration, d= 10;
		CaplInstance* inst= NULL, *owner= NULL;
		CString buf;
		int i, iNum;

		int iVal;
		m_api->m_options_mgr.GetOptionValueBN(APL_NO_T("Настройка Workflow\\Отключить настройку прототипов"), iVal, 0);
		if(0!=iVal)
		{
			m_editProtScemaBtn.ModifyStyle(WS_VISIBLE, 0, 0);		
			GetDlgItem(IDC_PROT_STATIC)->ModifyStyle(WS_VISIBLE, 0, 0);
			GetDlgItem(IDC_PROC_PROTOTYPE)->ModifyStyle(WS_VISIBLE, 0, 0);
		}
		
		if(m_process)
			apidata.GetAttr(m_process, m_wf_mgr->a_proc_of_tmpl, m_process_tmpl);

		if(m_process_tmpl)
		{
			if(m_sId.IsEmpty())
			{
				m_api->m_data.GetAttr(m_process_tmpl, m_wf_mgr->a_action_id, m_sTmplId); 
				m_sId= m_curDate.Format(_T("%Y.%m.%d %H:%M:%S"));
			}

			if(m_sName.IsEmpty())
			{
				m_api->m_data.GetAttr(m_process_tmpl, m_wf_mgr->a_action_name, buf);
				m_sName= buf;
				m_sTmplId+=_T(" : "); m_sTmplId+=buf;
			}
			
			m_api->m_data.GetAttr(m_process_tmpl, m_wf_mgr->a_proc_tmpl_duration, rDuration);
			m_api->m_data.GetAttr(m_process_tmpl, m_wf_mgr->a_proc_tmpl_managers, m_procMgrs);
			if(!m_procMgrs.GetSize())
			{
				m_mgrSelectBtn.EnableWindow(FALSE);
				m_deleteBtn.EnableWindow(FALSE);				
			}
			
			m_wf_mgr->GetProcessPrototypes(m_process_tmpl, ext);
			for(i= 0; i<ext.GetSize(); i++)
			{
				m_api->m_data.GetAttr(ext[i], m_wf_mgr->a_proc_prot_name, buf);
				if(!buf.IsEmpty())
				{
					iNum= m_protCBCtrl.InsertString(i, buf);
					m_protCBCtrl.SetItemData(iNum, (DWORD)ext[i]);
				}
			}
			
			iNum= m_protCBCtrl.InsertString(0, APL_T("<Не задан>"));
		}
	
		/*odts.m_span= rDuration;
		odts.SetStatus(COleDateTimeSpan::valid);
		odt+=odts;
		m_d_finish= m_t_finish= odt;
		odt-=odts;
//		odt= COleDateTime::GetCurrentTime();
		odts.m_span= rDuration*2/3;
		odt+=odts;
		m_d_check= m_t_check= odt;*/

		// ЯАИ 10.10.2011:  замена предыдущего
		m_api->m_appr_mgr.LoadHolydaysInCash();
		m_wf_mgr->FillWfDates(odt,rDuration,m_d_check,m_d_finish);
		m_t_check=m_d_check;
		m_t_finish=m_d_finish;
		
		CaplLoadData ld(&m_api->m_data,DEF_SOURCE);

		CaplInstance* user= m_api->m_appr_mgr.GetCurrentPerson();
		if(user)
		{	
			aplExtent ext;
			m_wf_mgr->GetUserTaskList(user, ext);

			if(ext.GetSize())
			{
				m_subCB.InsertString(0, _T(""));
				m_subCB.SetItemData(0, 0);
			}

			for(i= 0; i<ext.GetSize(); i++)
			{
				buf= _T("");
				inst= NULL;
				apidata.GetAttr(ext[i], m_wf_mgr->a_task_state, buf);
				if(buf==_T("work")  || buf==_T("active"))
				{
					apidata.GetAttr(ext[i], m_wf_mgr->a_task_performer, inst);
					if(user==inst)//только если он исполнитель
					{
						//apidata.GetAttr(ext[i], m_wf_mgr->a_action_name, buf);
						m_api->GetItemName(ext[i], buf);
						int n1= m_subCB.AddString(buf);
						m_subCB.SetItemData(n1, (DWORD)ext[i]);
					}
				}
			}
		}

		if(m_process)
		{
			apidata.GetAttr(m_process, m_wf_mgr->a_action_id, m_sId);
			apidata.GetAttr(m_process, m_wf_mgr->a_action_name, m_sName);
			apidata.GetAttr(m_process, m_wf_mgr->a_action_dscr, m_sDscr);

			apidata.GetAttr(m_process, m_wf_mgr->a_proc_state, m_sOldState);
			m_sState= m_sOldState;
			apidata.GetAttr(m_process, m_wf_mgr->a_act_inst_prior, m_sPriority);
			CString buf;
			apidata.GetAttr(m_process, m_wf_mgr->a_act_inst_start_date, buf);
			if(!buf.IsEmpty()){aplString2Date(buf, m_d_start); m_t_start= m_d_start;}
			if(m_sState==_T("completed") || m_sState==_T("terminated"))
			{
				m_sFactDate = APL_T("Дата завершения:");
				m_sPlanDate = APL_T("Планировалось завершить:");

				apidata.GetAttr(m_process, m_wf_mgr->a_act_inst_finish_date, buf);
				if(!buf.IsEmpty()){aplString2Date(buf, m_d_finish); m_t_finish= m_d_finish;}				
				apidata.GetAttr(m_process, m_wf_mgr->a_act_inst_end_date, buf);
				if(!buf.IsEmpty()){aplString2Date(buf, m_d_check); m_t_check= m_d_check;}
				
			}
			else
			{
				apidata.GetAttr(m_process, m_wf_mgr->a_act_inst_check_date, buf);
				if(!buf.IsEmpty()){aplString2Date(buf, m_d_check); m_t_check= m_d_check;}
				apidata.GetAttr(m_process, m_wf_mgr->a_act_inst_finish_date, buf);
				if(!buf.IsEmpty()){aplString2Date(buf, m_d_finish); m_t_finish= m_d_finish;}				
			}
			
			double dbl;
			apidata.GetAttr(m_process, m_wf_mgr->a_act_inst_percent, dbl);
			m_iPercent= (int)dbl;			
			m_sPercent.Format(_T("%i"), m_iPercent);
			m_sPercent+=_T("%");
			m_percentCtrl.SetSelection(0, m_iPercent);

			apidata.GetAttr(m_process, m_wf_mgr->a_proc_task_prot, m_prot_items);
			m_api->m_data.GetAttr(m_process, m_wf_mgr->a_proc_process_prot, m_proc_prot);
			
			if(m_prot_items.GetSize())
			{
				m_iProtScema= m_protCBCtrl.InsertString(1, APL_T("<Настройки пользователя>"));				
			}

			CString sProtName;
			if(m_proc_prot)
			{
				m_api->m_data.GetAttr(m_proc_prot, m_wf_mgr->a_proc_prot_name, sProtName);
				m_iProtScema= m_protCBCtrl.SelectString(-1, sProtName);
			}

			aplExtent aeItems;
			apidata.GetAttr(m_process, m_wf_mgr->a_proc_wo, m_wo_items);
			apidata.GetAttr(m_process, m_wf_mgr->a_proc_not_for_work, aeItems);
			for(int x=0; x<aeItems.GetSize(); x++) m_MapOfUnCheckedItems.insert(PAIR(aeItems[x], (CaplInstance*)NULL));

			ShowWorkObjects();

			CaplAttrValue val[3];
			aplExtent ext;
			
			val[0].value.Set(m_process);
			val[0].attr= m_wf_mgr->a_task_sub_proc;
			apidata.NET_FindInstancesWithAttrValues(m_wf_mgr->e_task, 1, &val[0], ext, false);
			
			if(ext.GetSize()>0)
			{
				m_wf_mgr->LoadTaskInfo(ext);

				m_old_up_level_task= ext[0];

				apidata.GetAttr(m_old_up_level_task, m_wf_mgr->a_action_name, buf);
				bool bFind= false;
				for(int j= 0; j<m_subCB.GetCount(); j++)
				{
					if(m_old_up_level_task==(CaplInstance*)m_subCB.GetItemData(j))
					{
						m_iSub= j;
						bFind= true;
						break;
					}
				}
				
				if(!bFind)
				{
					m_iSub= m_subCB.AddString(buf);
					m_subCB.SetItemData(m_iSub, (DWORD)m_old_up_level_task);
				}
			}

			m_api->m_data.GetAttr(m_process, m_wf_mgr->a_proc_owner, owner);
			m_api->m_data.GetAttr(m_process, m_wf_mgr->a_proc_manager, m_manager);
			
			if(m_manager)
			{
				m_api->m_appr_mgr.GetPersonName(m_manager, m_sManager);
				m_deleteBtn.EnableWindow();

				// ЯАИ этот кусок приводил к замене абонента на сторудника при нажатии Ok
				// Убрано и дальнейшая обработка заменена на функцию
				/*if(m_api->m_data.IsKindOf(m_manager,m_api->m_appr_mgr.e_official))
				{
					m_api->m_data.GetAttr(m_manager,m_api->m_appr_mgr.a_official_act_person,m_manager);
				}*/
			}
			else
			{
				m_sManager= APL_T("<Сотрудник не указан>");
				m_deleteBtn.EnableWindow(FALSE);
			}

			// ЯАИ пределано на функцию для обработки абонента
			//if(user==owner || m_manager==user)
			//	m_bReadOnly= FALSE;
			
			if(aplIsPersonOrgElement(m_api, owner, user) /*user!=owner*/ || 
			aplIsPersonOrgElement(m_api, m_manager, user) /*m_manager!=user*/)
				m_bReadOnly= FALSE;


			if(m_sState==_T("initiated"))
			{
				if(user==owner)
					m_startBtn.ModifyStyle(0, WS_VISIBLE, 0);
				m_percentCtrl.EnableWindow(FALSE);
//				m_subCB.EnableWindow(FALSE);/*!!!*/
			}
		}
		else
		{
			CaplInstance* new_wo= NULL;
			for(i=0; i<m_new_wo_items.GetSize(); i++)
			{
				new_wo= m_api->m_data.CreateInstance(m_wf_mgr->e_wo);
				if(new_wo)
				{
					m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_object, m_new_wo_items[i]);
					m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_for_note, false);
					m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_action, (CaplInstance*)NULL);

					m_wo_items.Add(new_wo);
				}
			}

			for(i=0; i<m_new_items_4_notes.GetSize(); i++)
			{
				new_wo= m_api->m_data.CreateInstance(m_wf_mgr->e_wo);
				if(new_wo)
				{
					m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_object, m_new_items_4_notes[i]);
					m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_for_note, true);
					m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_action, (CaplInstance*)NULL);

					m_wo_items.Add(new_wo);
				}
			}
			ShowWorkObjects();
			m_new_wo_items.Clear();
		}

		if(m_sPriority==_T("low")) buf= APL_T("Низкий");
		else if(m_sPriority==_T("medium")) buf= APL_T("Обычный");
		else if(m_sPriority==_T("hight")) buf= APL_T("Высокий");
		
		m_api->m_options_mgr.GetOptionValueBN(APL_NO_T("Настройка Workflow\\Оставить два (обычный и высокий) приоритета процессов и заданий"), iVal, 0);
		if(0!=iVal)
		{
			if(m_sPriority==_T("low"))buf= APL_T("Обычный");
			m_prior.DeleteString(2);
		}
		
		m_iPrior= m_prior.FindString(-1, buf);
		buf= _T("");
		
		if(m_sState==_T("initiated"))
		{
			buf= APL_T("Создан");
			m_state.DeleteString(2);
			m_state.DeleteString(2);
			m_state.DeleteString(2);
		}
		else if(m_sState==_T("running")) 
		{
			buf= APL_T("Выполняется");
			m_state.DeleteString(0);
			m_state.DeleteString(2);
			m_state.DeleteString(2);
		}
		else if(m_sState==_T("suspended")) 
		{
			buf= APL_T("Остановлен");
			m_state.DeleteString(0);
			m_state.DeleteString(2);
			m_state.DeleteString(2);
		}
		else if(m_sState==_T("terminated")) buf= APL_T("Прерван");
		else if(m_sState==_T("completed")) buf= APL_T("Завершен");
		else if(m_sState==_T("jammed")) buf= APL_T("Завис");
		m_iState= m_state.FindString(-1, buf);
		if(m_iState<0) m_iState=m_state.AddString(buf);

		if(m_sState!=_T("initiated"))
		{
			m_d_start_ctrl.EnableWindow(FALSE);
			m_t_start_ctrl.EnableWindow(FALSE);			
			if(m_sState!=_T("running"))
				m_subCB.EnableWindow(FALSE);
		}
		else
			m_bReadOnly= FALSE;

		if(m_process==NULL)
		{
			m_state.EnableWindow(FALSE);
			m_percentCtrl.EnableWindow(FALSE);
		}

		odt= m_curDate;
		if(m_process)
		{
			CString str;
			apidata.GetAttr(m_process, m_wf_mgr->a_act_inst_end_date, str);
			if(!str.IsEmpty())
				aplString2Date(str, odt);
		}
		if(m_d_finish<odt)
		{
			m_to.ModifyStyle(0, WS_VISIBLE, 0);
			COLORREF crTextColor= RGB(255, 0, 0);
			m_to.SetTextColor(crTextColor);
			m_to.SetText(APL_T("Процесс просрочен!"));		
		}

		if(m_process /*&& m_process->GetAccessmode()>aplRW*/ && 
			!aplIsPersonOrgElement(m_api, owner, user) /*user!=owner*/ && 
			!aplIsPersonOrgElement(m_api, m_manager, user) /*m_manager!=user*/)
		{		
			m_bReadOnly= TRUE;
			
			m_id.SetReadOnly();
			m_name.SetReadOnly();
			m_dscr.SetReadOnly();

			m_prior.EnableWindow(FALSE);
			m_state.EnableWindow(FALSE);
			m_protCBCtrl.EnableWindow(FALSE);

			m_d_start_ctrl.EnableWindow(FALSE);
			m_t_start_ctrl.EnableWindow(FALSE);
			m_d_check_ctrl.EnableWindow(FALSE);
			m_t_check_ctrl.EnableWindow(FALSE);
			m_d_finish_ctrl.EnableWindow(FALSE);
			m_t_finish_ctrl.EnableWindow(FALSE);
			m_percentCtrl.EnableWindow(FALSE);

			m_addWoBtn.EnableWindow(FALSE);
			m_deleteWoBtn.EnableWindow(FALSE);
			m_addFileBtn.EnableWindow(FALSE);
			m_editProtScemaBtn.EnableWindow(FALSE);			
			
			m_okBtn.EnableWindow(FALSE);
			
			if(user!=owner)
			{
				m_deleteBtn.EnableWindow(FALSE);
				m_mgrSelectBtn.EnableWindow(FALSE);
			}
		}

		if(m_sState==_T("completed") || m_sState==_T("terminated"))
		{
			m_bReadOnly= TRUE;
			
			m_id.SetReadOnly();
			m_name.SetReadOnly();
			m_dscr.SetReadOnly();

			m_d_start_ctrl.EnableWindow(FALSE);
			m_t_start_ctrl.EnableWindow(FALSE);
			m_d_check_ctrl.EnableWindow(FALSE);
			m_t_check_ctrl.EnableWindow(FALSE);
			m_d_finish_ctrl.EnableWindow(FALSE);
			m_t_finish_ctrl.EnableWindow(FALSE);
			m_percentCtrl.EnableWindow(FALSE);

			m_addWoBtn.EnableWindow(FALSE);
			m_deleteWoBtn.EnableWindow(FALSE);
			m_addFileBtn.EnableWindow(FALSE);
			m_editProtScemaBtn.EnableWindow(FALSE);
			m_okBtn.EnableWindow(FALSE);
			
			m_prior.EnableWindow(FALSE);
			m_state.EnableWindow(FALSE);
			m_protCBCtrl.EnableWindow(FALSE);
			
			m_deleteBtn.EnableWindow(FALSE);
			m_mgrSelectBtn.EnableWindow(FALSE);
		}
		SetWindowText(m_sTitle);
	}

	UpdateData(FALSE);
	AddAllAnchor();


	int iVal=0;
	if(m_sId==APL_T("<Автономер>")) iVal=1;
	else m_api->m_options_mgr.GetOptionValueBN( APL_NO_T("Настройка Workflow\\Запретить изменение обозначений процессов"),iVal,0);
	if(1==iVal)m_id.SetReadOnly();

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

void CProcessDlg::OnOK() 
{
	UpdateData();
	
	int i;
	int iVal;
	aplExtent proc_mgrs;
	double dbl= m_iPercent;
	COleDateTime odt, odtOld;
	CString buf;
	
	if(m_sId.IsEmpty())
	{
		AfxMessageBox(APL_T("Не задано поле \"Обозначение\"."), MB_ICONERROR|MB_OK);
		return;
	}
	if(m_sName.IsEmpty())
	{
		AfxMessageBox(APL_T("Не задано поле \"Наименование\"."), MB_ICONERROR|MB_OK);
		return;
	}
	if(m_iSub!=CB_ERR)
		m_up_level_task= (CaplInstance*)m_subCB.GetItemData(m_iSub);

	if(!IsValidDates())
	{
		return;
	}
	
	if(m_api && apidata.IsConnected())
	{
		m_api->m_options_mgr.GetOptionValueBN(APL_NO_T("Настройка Workflow\\Обязательно указывать координатора процесса"), iVal, 0);
		if(0!=iVal)
		{
			if(m_process_tmpl)
			{
				m_api->m_data.GetAttr(m_process_tmpl, m_wf_mgr->a_proc_tmpl_managers, proc_mgrs);
				if(proc_mgrs.GetSize() && !m_manager)
				{
					AfxMessageBox(APL_T("Укажите координатора процесса."), MB_OK|MB_ICONERROR);
					return;
				}
			}
		}

		// "раскручиваем" объекты "не для работы"				
		for(IMap_Iter=m_MapOfUnCheckedItems.begin(); IMap_Iter!=m_MapOfUnCheckedItems.end(); ++IMap_Iter)
			m_aeItemsNotForWork.Add(IMap_Iter->first);

		if(m_process && m_process->GetType())
		{
			if(!IsValidDates())
			{
				return;
			}

			if(m_sOldState!=_T("completed") && m_sOldState!=_T("terminated"))
			{
				ProcessWorkObjects();
				ProcessTaskProts();	

				// процесс без рабочих объектов, в большинстве случаев, не имеет смысла
				if(!m_wo_items.GetSize())
				{
					if(AfxMessageBox(APL_T("Процесс не содержит ни одного рабочего объекта! Все равно продолжить?"), MB_ICONQUESTION|MB_YESNO) == IDNO)
						return;
				}
				
				// аттрибуты процесса
				apidata.PutAttr(m_process, m_wf_mgr->a_proc_not_for_work, m_aeItemsNotForWork);
				apidata.PutAttr(m_process, m_wf_mgr->a_proc_wo, m_wo_items);
				apidata.PutAttr(m_process, m_wf_mgr->a_proc_task_prot, m_prot_items);
				m_api->m_data.PutAttr(m_process, m_wf_mgr->a_proc_process_prot, m_proc_prot);

				apidata.PutAttr(m_process, m_wf_mgr->a_action_id, m_sId);
				apidata.PutAttr(m_process, m_wf_mgr->a_action_name, m_sName);
				apidata.PutAttr(m_process, m_wf_mgr->a_action_dscr, m_sDscr);

				apidata.PutAttr(m_process, m_wf_mgr->a_act_inst_prior, m_sPriority);
				apidata.PutAttr(m_process, m_wf_mgr->a_act_inst_percent, dbl);

				apidata.GetAttr(m_process, m_wf_mgr->a_act_inst_start_date, buf);
				aplString2Date(buf, odtOld);
				odt.SetDateTime(m_d_start.GetYear(), m_d_start.GetMonth(), m_d_start.GetDay(),
					m_t_start.GetHour(), m_t_start.GetMinute(), 0);
				if(odt!=odtOld)
				{
					aplDate2String(odt, buf);
					apidata.PutAttr(m_process, m_wf_mgr->a_act_inst_start_date, buf);
				}
				apidata.GetAttr(m_process, m_wf_mgr->a_act_inst_check_date, buf);
				aplString2Date(buf, odtOld);
				odt.SetDateTime(m_d_check.GetYear(), m_d_check.GetMonth(), m_d_check.GetDay(),
					m_t_check.GetHour(), m_t_check.GetMinute(), 0);
				if(odt!=odtOld)
				{
					aplDate2String(odt, buf);
					apidata.PutAttr(m_process, m_wf_mgr->a_act_inst_check_date, buf);
				}
				apidata.GetAttr(m_process, m_wf_mgr->a_act_inst_finish_date, buf);
				aplString2Date(buf, odtOld);
				odt.SetDateTime(m_d_finish.GetYear(), m_d_finish.GetMonth(), m_d_finish.GetDay(),
					m_t_finish.GetHour(), m_t_finish.GetMinute(), 0);

				m_api->m_data.PutAttr(m_process, m_wf_mgr->a_proc_manager, m_manager);

				if(odt!=odtOld)
				{
					aplDate2String(odt, buf);
					apidata.PutAttr(m_process, m_wf_mgr->a_act_inst_finish_date, buf);
				}

				if(m_sOldState!=m_sState)
				{
					if(m_sState==_T("running"))
						m_lAction= APL_WF_EVENT_RUN;
					if(m_sState==_T("suspended"))
						m_lAction= APL_WF_EVENT_SUSPEND;
					if(m_sState==_T("completed"))
						m_lAction= APL_WF_EVENT_COMPLETE;
					if(m_sState==_T("terminated"))
						m_lAction= APL_WF_EVENT_TERMINATE;			
				}

				//переопределение подпроцесса
				if((m_up_level_task!=m_old_up_level_task) && (m_up_level_task || m_old_up_level_task))
				{
					CaplLoadData ld(&m_api->m_data,DEF_SOURCE);
					int n= 0;
					if(m_up_level_task)
						ld.AddQuery(0,m_up_level_task);
					if(m_old_up_level_task)
						ld.AddQuery(0,m_old_up_level_task);
					ld.AddQuery(_T('d'), n, 0, m_wf_mgr->a_task_sub_proc, true);
					ld.LoadEx();
					
					CaplInstance* inst= NULL;
					aplExtent subProc;

					if(m_old_up_level_task)
					{
						apidata.GetAttr(m_old_up_level_task, m_wf_mgr->a_task_sub_proc, subProc);
						for(i= 0; i<subProc.GetSize(); i++)
						{
							if(subProc[i]==m_process)
							{
								subProc.Remove(i);
								i--;
								break;
							}
						}
						apidata.PutAttr(m_old_up_level_task, m_wf_mgr->a_task_sub_proc, subProc);
					}
					
					if(m_up_level_task)
					{
						apidata.GetAttr(m_up_level_task, m_wf_mgr->a_task_sub_proc, subProc);
						subProc.Add(m_process);
						apidata.PutAttr(m_up_level_task, m_wf_mgr->a_task_sub_proc, subProc);
					}
				}

				m_api->SaveChanges();
			}
		}//if(m_process && m_process->type)
		else
		{
			/*?????*/
			
			ProcessTaskProts();			
			if(m_sState!=_T("initiated"))
			{
				bool bSave= false;
				for(i= 0; i<m_wo_items.GetSize(); i++)
				{
					if(m_wo_items[i] && m_wo_items[i]->GetType())
					{
						apidata.DeleteInstance(m_wo_items[i]);
						bSave= true;
					}
				}
				for(i= 0; i<m_prot_items.GetSize(); i++)
				{
					if(m_prot_items[i] && m_prot_items[i]->GetType())
					{
						apidata.DeleteInstance(m_prot_items[i]);
						bSave= true;
					}
				}
				if(bSave)
					apidata.NET_SaveChanges();
			}
			else
			{
				// процесс без рабочих объектов, в большинстве случаев, не имеет смысла
				ProcessWorkObjects();
				if(!m_wo_items.GetSize())
				{
					if(AfxMessageBox(APL_T("Процесс не содержит ни одного рабочего объекта! Все равно продолжить?"), MB_ICONQUESTION|MB_YESNO) == IDNO)
						return;
				}
			}
		}
	}//IsConnected()

	CaplResizableDialog::OnOK();
}

void CProcessDlg::OnSelchangeProcPriority() 
{
	UpdateData();

	switch (m_iPrior)
	{
		case 0: m_sPriority= _T("hight");
			break;
		case 1: m_sPriority= _T("medium");
			break;
		case 2: m_sPriority= _T("low");
			break;
	}
}

void CProcessDlg::OnSelchangeProcState() 
{
	UpdateData();
	CString buf;
	m_state.GetLBText(m_iState, buf);
		
	if(buf==APL_T("Создан"))
		m_sState= _T("initiated");
	else if(buf==APL_T("Выполняется")) 
		m_sState= _T("running");
	else if(buf==APL_T("Остановлен")) 
		m_sState= _T("suspended");
	else if(buf==APL_T("Прерван")) 
		m_sState= _T("terminated");
	else if(buf==APL_T("Завершен")) 
		m_sState= _T("completed");	
}
  
void CProcessDlg::OnCancel() 
{
	int i;
	if(!m_process)
	{
		//вообще все зафигачить!
		for(i= 0; i<m_prot_items.GetSize(); i++)
			apidata.DeleteInstance(m_prot_items[i]);
		for(i= 0; i<m_wo_items.GetSize(); i++)
//			if(apidata.IsKindOfBN(m_wo_items[i], _T("apl_stored_document")) ||	apidata.IsKindOfBN(m_wo_items[i], _T("apl_assigned_document")))
			apidata.DeleteInstance(m_wo_items[i]);
		apidata.NET_SaveChanges();
	}
	else
	{
		//все фигачить нехорошо...
		bool bDelete;
		aplExtent ext;
		CaplInstance* obj;
		
		apidata.GetAttr(m_process, m_wf_mgr->a_proc_task_prot, ext);
		
		for(i= 0; i<m_prot_items.GetSize(); i++)
		{
			bDelete= true;
			for(int j= 0; j<ext.GetSize(); j++)
			{
				if(ext[j]==m_prot_items[i])
				{
					bDelete= false;
					break;
				}
			}
			if(bDelete)
				apidata.DeleteInstance(m_prot_items[i]);
		}

		apidata.GetAttr(m_process, m_wf_mgr->a_proc_wo, ext);
		
		for(i= 0; i<m_wo_items.GetSize(); i++)
		{
			bDelete= true;
			for(int j= 0; j<ext.GetSize(); j++)
			{
				if(ext[j]==m_wo_items[i])
				{
					bDelete= false;
					break;
				}
			}

			if(bDelete)
			{
				m_api->m_data.GetAttr(m_wo_items[i], m_wf_mgr->a_wo_object, obj);

				if(m_api->m_data.IsKindOf(obj, m_api->m_doc_mgr.e_apl_stored_document))
					m_api->m_data.NET_DeleteBlob(obj, m_api->m_doc_mgr.a_apl_stored_document_source);

				m_api->m_data.DeleteInstance(m_wo_items[i]);
			}
		}
		apidata.NET_SaveChanges();
	}

	CaplResizableDialog::OnCancel();
}

void CProcessDlg::OnProcStartButton() 
{
	if(m_wf_mgr)
	{
		if(!m_process || !m_process->GetType()) return;

		apidata.PutAttr(m_process, m_wf_mgr->a_proc_task_prot, m_prot_items);

		aplExtent acts, st_points;
		m_wf_mgr->GetProcessComponents(m_process, acts);
		
		for(int i= 0; i<acts.GetSize(); i++)
		{
			if(apidata.IsKindOf(acts[i], m_wf_mgr->e_start_point))
			{	
				st_points.Add(acts[i]);
			}
		}
		
		CaplInstance* first_activity= NULL, *st_point= NULL;

		if(st_points.GetSize()>1)
		{
			CQueryStartPointDialog dlg;
			dlg.m_data= &m_api->m_data;
			dlg.m_wf_mgr= m_wf_mgr;
			dlg.m_st_points= &st_points;

			if(IDOK==dlg.DoModal())
			{
				st_point= dlg.m_start_point;
			}
			else return;
		}
		else
		{
			st_point= st_points[0];
		}
		
		if(st_point)
		{
			aplExtent ext1, ext2;
			m_wf_mgr->GetConnectors(st_point, ext1, ext2);
			
			if(ext2[0])
			{
				apidata.GetAttr(ext2[0], m_wf_mgr->a_act_rel_to, first_activity);
			}
		}
		
		CString buf;

		if(m_wf_mgr->RunWfProcess(m_process, true, first_activity))
		{
			apidata.GetAttr(m_process, m_wf_mgr->a_proc_state, m_sOldState);
			m_sState=m_sOldState;

			m_d_start_ctrl.EnableWindow(FALSE);
			m_t_start_ctrl.EnableWindow(FALSE);

			m_state.DeleteString(m_state.FindString(-1, APL_T("Создан")));
			
			if(m_sOldState==_T("running"))
			{
				m_state.InsertString(1, APL_T("Остановлен"));
				m_iState= m_state.FindString(-1, APL_T("Выполняется"));
				
				m_percentCtrl.EnableWindow();
			}
			else if(m_sOldState==_T("completed"))
			{//действие было не только первым, но и последним
				m_iState= m_state.InsertString(1, APL_T("Завершен"));
				m_state.EnableWindow(FALSE);
				
				m_sFactDate = APL_T("Дата завершения:");
				m_sPlanDate = APL_T("Планировалось завершить:");

				apidata.GetAttr(m_process, m_wf_mgr->a_act_inst_finish_date, buf);
				if(!buf.IsEmpty()){aplString2Date(buf, m_d_finish); m_t_finish= m_d_finish;}				
				apidata.GetAttr(m_process, m_wf_mgr->a_act_inst_end_date, buf);
				if(!buf.IsEmpty()){aplString2Date(buf, m_d_check); m_t_check= m_d_check;}

				m_id.SetReadOnly();
				m_name.SetReadOnly();
				m_dscr.SetReadOnly();

				m_subCB.EnableWindow(FALSE);
				
				m_prior.EnableWindow(FALSE);
				
				m_iPercent= 100;
				m_percentCtrl.SetSelection(0, m_iPercent);
				m_percentCtrl.RedrawWindow();
				m_percentCtrl.EnableWindow(FALSE);
				m_sPercent.Format(_T("%i"), m_iPercent);
				m_sPercent+=_T("%");

				m_d_check_ctrl.EnableWindow(FALSE);
				m_t_check_ctrl.EnableWindow(FALSE);
				m_d_finish_ctrl.EnableWindow(FALSE);
				m_t_finish_ctrl.EnableWindow(FALSE);

				m_bReadOnly= TRUE;
				m_okBtn.EnableWindow(FALSE);
			}

			m_startBtn.ModifyStyle(WS_VISIBLE, 0, 0);
			RedrawWindow();
		}

		UpdateData(FALSE);
	}
}

void CProcessDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	UpdateData();
	m_percentCtrl.SetSelection(0, m_iPercent);
	m_percentCtrl.RedrawWindow();
	m_sPercent.Format(_T("%i"), m_iPercent);
	m_sPercent+=_T("%");
	UpdateData(FALSE);
	
	CaplResizableDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CProcessDlg::OnSelchangeSubProcessCombo() 
{
	int n= m_iSub;
	CaplInstance* inst= m_up_level_task;

	UpdateData();
	m_up_level_task= (CaplInstance*)m_subCB.GetItemData(m_iSub);
	if(m_up_level_task)
	{
		CaplInstance* activity;
		aplExtent ext;

		int iVal;
		m_api->m_options_mgr.GetOptionValueBN(APL_NO_T("Настройка Workflow\\Не давать запускать подпроцессы, не указанные в настройке действия"), iVal, 0);
		if(iVal==1)
		{	
			m_api->m_data.GetAttr(m_up_level_task, m_wf_mgr->a_task_activity, activity);
			m_api->m_data.GetAttr(activity, m_wf_mgr->a_activity_sub_proc_tmpl, ext);
			if(-1==ext.Find(m_process_tmpl))
			{
				AfxMessageBox(APL_T("Шаблон процесса не задан как возможный подпроцесс выбранного задания."), MB_OK|MB_ICONERROR);
				m_iSub= n;
				m_up_level_task= inst;
				UpdateData(FALSE);
				return;
			}
		}
		
		if(m_up_level_task!=m_old_up_level_task && m_process && //когда процесс не создан, цикла быть не может
			m_up_level_task && 1!=aplTestCyrcleInProcess(m_wf_mgr, m_up_level_task, m_process))
		{
			m_iSub= n;
			m_up_level_task= inst;
			UpdateData(FALSE);
		}
	}
}

BOOL CProcessDlg::IsValidDates()
{
	COleDateTime odt_s= COleDateTime::GetCurrentTime(), 
		odt_f= COleDateTime::GetCurrentTime(), 
		odt_ch= COleDateTime::GetCurrentTime(),
		odt_t= COleDateTime::GetCurrentTime();

	odt_s.SetDateTime(m_d_start.GetYear(), m_d_start.GetMonth(), m_d_start.GetDay(),
		m_t_start.GetHour(), m_t_start.GetMinute(), 0);

	odt_f.SetDateTime(m_d_finish.GetYear(), m_d_finish.GetMonth(), m_d_finish.GetDay(),
		m_t_finish.GetHour(), m_t_finish.GetMinute(), 0);

	odt_ch.SetDateTime(m_d_check.GetYear(), m_d_check.GetMonth(), m_d_check.GetDay(),
		m_t_check.GetHour(), m_t_check.GetMinute(), 0);
	
	m_curDate.SetDateTime(m_curDate.GetYear(), m_curDate.GetMonth(), m_curDate.GetDay(),
		m_curDate.GetHour(), m_curDate.GetMinute(), 0);
	
	if(::IsWindowEnabled(m_d_start_ctrl.m_hWnd) && odt_s<m_curDate)
	{
		if(m_sOldState==_T("initiated"))
		{
			m_d_start=m_t_start=m_curDate;
			odt_s.SetDateTime(m_d_start.GetYear(), m_d_start.GetMonth(), m_d_start.GetDay(),
				m_t_start.GetHour(), m_t_start.GetMinute(), 0);
			UpdateData(FALSE);
		}
		else
		{
			AfxMessageBox(APL_T("Дата начала меньше текущей даты."), MB_OK|MB_ICONERROR);
			return FALSE;
		}
	}

	if(odt_s>=odt_ch)
	{
		AfxMessageBox(APL_T("Контрольная дата меньше или равна дате начала."), MB_OK|MB_ICONERROR);
		return FALSE;				
	}
	
	if(odt_s>=odt_f)
	{
		AfxMessageBox(APL_T("Дата завершения меньше или равна дате начала."), MB_OK|MB_ICONERROR);
		return FALSE;
	}
	
	if(!(odt_ch>odt_s && odt_ch<odt_f))
	{
//		if(IDNO==MessageBox(APL_T("Дата контроля находится вне интервала исполнения процесса.\nПродолжить выполнение?"), APL_T("Ошибка"), 
//		MB_YESNO|MB_ICONWARNING))
		AfxMessageBox(APL_T("Дата контроля находится вне интервала исполнения процесса."), MB_OK|MB_ICONERROR);
			return FALSE;
	}
	
	CString buf;
	if(m_up_level_task)
	{
		apidata.GetAttr(m_up_level_task, m_wf_mgr->a_act_inst_finish_date, buf);
		if(!buf.IsEmpty())
		{
			aplString2Date(buf, odt_t);
			CString sMes;
			sMes= odt_t.Format(_T("%d.%m.%Y  %H:%M"));
			if(odt_f>odt_t)
			{
				AfxMessageBox(APL_T("Дата завершения подпроцесса не может быть больше даты завершения задания, \nдля выполнения которого он инициализирован.\n\nДата завершения задания: ")+sMes, 
					MB_OK|MB_ICONERROR);
				return FALSE;			
			}
		}
	}

	return TRUE;
}

void CProcessDlg::OnProcSelect() 
{
	CaplInstance* per= m_api->m_appr_mgr.SelectPersonOrOrganization(APL_MODE_SELECT_PERSON|APL_MODE_SELECT_OFFICIAL, m_procMgrs,
		APL_T("Выбор координатора процесса"), APL_T("Выберите координатора процесса:"));

	UpdateData();
	
	if(per)
	{
		m_manager= per;
		m_api->m_appr_mgr.GetPersonName(m_manager, m_sManager);	
		m_deleteBtn.EnableWindow();
	}

	UpdateData(FALSE);
}

void CProcessDlg::OnProcDelete() 
{
	if(!m_manager) return;
	if(IDNO==AfxMessageBox(APL_T("Вы действительно хотите удалить ответственного за процесс?"), MB_YESNO|MB_ICONQUESTION))
		return;

	UpdateData();
	
	m_manager= NULL;
	m_sManager= APL_T("<Сотрудник не указан>");
	m_deleteBtn.EnableWindow(FALSE);

	UpdateData(FALSE);
}

void CProcessDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	
	CaplResizableDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}

BOOL CProcessDlg::PreTranslateMessage(MSG* pMsg) 
{
	// TODO: Add your specialized code here and/or call the base class
	if(pMsg->message==WM_KEYDOWN)
	{
		if(pMsg->wParam==VK_F3)
		{
			int i= 0;
		}
	}	
	
	return CaplResizableDialog::PreTranslateMessage(pMsg);
}

void CProcessDlg::OnProcEditProt() 
{
	UpdateData();
	m_proc_prot= (CaplInstance*)m_protCBCtrl.GetItemData(m_iProtScema);

	m_wf_mgr->ShowPrototypes((m_process!=NULL)?m_process:m_process_tmpl, &m_prot_items, (m_bReadOnly==TRUE)?true:false);

	CString buf;
	if(m_protCBCtrl.GetCount()>1)
		m_protCBCtrl.GetLBText(1, buf);
	buf.MakeLower();
	if(buf==APL_T("<настройки пользователя>"))
	{
		m_protCBCtrl.DeleteString(1);
		m_iProtScema= 0;
	}

	if(m_prot_items.GetSize())
	{
		m_iProtScema= m_protCBCtrl.InsertString(1, APL_T("<Настройки пользователя>"));		
	}
	else if(m_proc_prot)
	{
		m_api->m_data.GetAttr(m_proc_prot, m_wf_mgr->a_proc_prot_name, buf);
		m_iProtScema= m_protCBCtrl.SelectString(-1, buf);
	}
	
	UpdateData(FALSE);
}

void CProcessDlg::OnProcAddFile() 
{
	if(m_process!=0)
	{
		if(!m_wf_mgr->CanChangeWorkObjectsList(m_process))return;
	}
	int iIndex = m_woTabCtrl.GetCurSel();
	if(-1==iIndex) return;

	CFileDialog dlg(TRUE,0,0,OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT,
		_T("All Files (*.*)|*.*||"));
	
	CString buf;
	LPTSTR szFilesNames= buf.GetBuffer(2048);
	dlg.m_ofn.lpstrFile= szFilesNames;
	dlg.m_ofn.nMaxFile= 2048;

	if(dlg.DoModal()==IDOK)
	{
		CStringArray *arr;
		if(1==iIndex) arr= &m_fileItemsSprav;
		else arr= &m_fileItems;

		POSITION pos=dlg.GetStartPosition();
		while(pos!=0) 
		{
			CString buf1= dlg.GetNextPathName(pos);		

			/*LVFINDINFO info;
			info.flags= LVFI_STRING;		
			info.psz= buf1;
			
			if(m_woList.FindItem(&info, -1)==-1)
			{
				UINT ico= APL_ICON_FILE;
				arr->Add(buf1);
			}
			else
			{
				AfxMessageBox(buf1+APL_T(": файл уже находится в списке рабочих объектов."));
			}*/
			
			HTREEITEM hItem = m_woListView->m_tree.GetRootItem();
			while(hItem)
			{
				if(m_woListView->m_tree.GetItemText(hItem) == buf1)
				{
					AfxMessageBox(buf1+APL_T(": файл уже находится в списке рабочих объектов."));
					return;
				}

				hItem = m_woListView->m_tree.GetNextSiblingItem(hItem);
			}

			arr->Add(buf1);
		}
	}
	
	ShowWorkObjects((iIndex==0)?APL_WFWO_FORWORK:APL_WFWO_FORNOTE);
}

void CProcessDlg::OnProcAddWo() 
{
	if(m_process!=0)
	{
		if(!m_wf_mgr->CanChangeWorkObjectsList(m_process))return;
	}

	int iIndex = m_woTabCtrl.GetCurSel();
	if(-1==iIndex) return;	
	
	aplExtent res;
	m_wf_mgr->SelectInstanceEx(
								APL_MODE_SELECT_PRD |
								APL_MODE_SELECT_PDF |
								APL_MODE_SELECT_PRDINST  |
								APL_MODE_SELECT_LOT |
								APL_MODE_SELECT_DOC |
								APL_MODE_SELECT_DOC_REVISION |
								APL_MODE_SELECT_CATEG_REVISION |
								APL_MODE_SELECT_CATEGORY |
								APL_MODE_SELECT_FOLDER   |
								APL_MODE_SELECT_BP	|
								APL_MODE_SELECT_BP_REVISION	|
								APL_MODE_SELECT_BPINST	|
								APL_MODE_SELECT_CLASSIF_SYSTEM	|
								APL_MODE_SELECT_CLASSIF_ELEMENT |
								APL_MODE_SELECT_PROJECT  |
								APL_MODE_SELECT_CHANGE	|
								APL_MODE_SELECT_CHARACT	|
								APL_MODE_SELECT_CHARACT_REVISION  |
								APL_MODE_SELECT_ORG	|
//								APL_MODE_SELECT_PERSORG	|
								APL_MODE_SELECT_PERSON |
								APL_MODE_SELECT_OFFICIAL |
								APL_MODE_SELECT_ORDER |
								APL_MODE_SELECT_MULTY								
								,res);
	
	bool bNew;
	CaplInstance* inst;

	for(int i= 0; i<res.GetSize(); i++)
	{
		bNew= true;

		for(int j= 0; j<m_wo_items.GetSize(); j++)
		{
			m_api->m_data.GetAttr(m_wo_items[j], m_wf_mgr->a_wo_object, inst);
			if(inst==res[i])
			{
				bNew= false;
				m_del_wo_items.Remove(m_del_wo_items.Find(m_wo_items[j]));

				m_api->m_data.PutAttr(m_wo_items[j], m_wf_mgr->a_wo_for_note, (iIndex==1));
				break;
			}
		}

		if(bNew && m_wf_mgr->CanAddInstanceInProcess(m_process, res[i]))
		{
			CaplInstance* new_wo= m_api->m_data.CreateInstance(m_wf_mgr->e_wo);
			if(new_wo)
			{
				m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_object, res[i]);
				m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_for_note, (iIndex==1));
				m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_action, m_process);
				
				m_wo_items.Add(new_wo);
			}
		}
	}

	ShowWorkObjects((iIndex==0)?APL_WFWO_FORWORK:APL_WFWO_FORNOTE);
}

void CProcessDlg::OnProcDeleteWo() 
{
	if(m_process!=0)
	{
		if(!m_wf_mgr->CanChangeWorkObjectsList(m_process))return;
	}
	int iIndex = m_woTabCtrl.GetCurSel();
	if(-1==iIndex) return;
		
	CString buf;

	CStringArray *arr;
	if(1==iIndex) arr= &m_fileItemsSprav;
	else arr= &m_fileItems;

	HTREEITEM hItem = GetSelectedItem();
	if(!hItem) return;

	CSelectInstanceTreeItemEx *pItem = (CSelectInstanceTreeItemEx*)m_woListView->m_tree.GetItemData(hItem);
	if(pItem)
	{
		m_del_wo_items.Add(GetWOByInstance(pItem->m_inst));		
	}
	else
	{
		buf= m_woListView->m_tree.GetItemText(hItem, 0);
		for(int j= 0; j<arr->GetSize(); j++)
		{
			if((*arr)[j]==buf)
			{
				arr->RemoveAt(j);
				break;
			}
		}
	}	

	ShowWorkObjects((iIndex==0)?APL_WFWO_FORWORK:APL_WFWO_FORNOTE);
}


void CProcessDlg::OnBnClickedProcView()
{
	int iIndex = m_woTabCtrl.GetCurSel();
	if(-1==iIndex) return;

	CString buf;
	CString sPath;
	CaplInstance* docInst;

	CStringArray *arr;
	if(1==iIndex) arr= &m_fileItemsSprav;
	else arr= &m_fileItems;

	HTREEITEM hItem = GetSelectedItem();
	if(!hItem) return;

	CSelectInstanceTreeItemEx *pItem = (CSelectInstanceTreeItemEx*)m_woListView->m_tree.GetItemData(hItem);
	if(pItem)
	{
		docInst= pItem->m_inst;
		if(m_api->m_data.IsKindOf(docInst, m_api->m_doc_mgr.e_doc) || 
			m_api->m_data.IsKindOf(docInst, m_api->m_doc_mgr.e_apl_doc_rev) || 
			m_api->m_data.IsKindOf(docInst, m_api->m_doc_mgr.e_apl_stored_document))
			m_api->m_doc_mgr.View(docInst);
		else
		{
			AfxMessageBox(APL_T("Выберите файл или документ для просмотра!"), MB_OK|MB_ICONERROR);
			return;
		}
	}
	else
	{
		sPath= m_woListView->m_tree.GetItemText(hItem, 0);
		if(sPath.IsEmpty())
		{
			AfxMessageBox(APL_T("Не найден путь к файлу."), MB_OK|MB_ICONERROR);
			return;
		}
		else
		{
			CFile file;
			if(!file.Open(sPath,CFile::modeRead|CFile::shareDenyNone))
			{
				CString sMsg;
				sMsg.Format(APL_T("Файл \"%s\" не найден!"), sPath);
				AfxMessageBox(sMsg, MB_OK|MB_ICONERROR);
				return;	
			}
			else file.Close();
		}
		aplShellExecute(NULL, _T("open"), sPath, NULL, NULL, SW_SHOW);
	}
}

void CProcessDlg::OnSelchangeProcTab(NMHDR* pNMHDR, LRESULT* pResult) 
{
	int iIndex = m_woTabCtrl.GetCurSel();
	if(-1==iIndex) return;
		
	TCITEM tcItem;
	tcItem.mask = TCIF_PARAM;
	m_woTabCtrl.GetItem(iIndex, &tcItem);
	
	ShowWorkObjects(tcItem.lParam);

	*pResult = 0;
}

void CProcessDlg::ProcessTaskProts()
{
	m_proc_prot= (CaplInstance*)m_protCBCtrl.GetItemData(m_iProtScema);
	if(m_iProtScema==0)// <Не задан>
	{
		for(int i= 0; i<m_prot_items.GetSize(); i++)
			m_api->m_data.DeleteInstance(m_prot_items[i]);
		m_prot_items.Clear();
	}
}

void CProcessDlg::ProcessWorkObjects()
{
	CaplInstance* inst;
	CaplInstance* new_wo;

	int i;
	for(i= 0; i<m_del_wo_items.GetSize(); i++)
	{
		m_wo_items.Remove(m_wo_items.Find(m_del_wo_items[i]));					
		
		m_api->m_data.GetAttr(m_del_wo_items[i], m_wf_mgr->a_wo_object, inst);

		if(m_api->m_data.IsKindOf(inst, m_api->m_doc_mgr.e_apl_stored_document))
			m_api->m_data.NET_DeleteBlob(inst, m_api->m_doc_mgr.a_apl_stored_document_source);
		
		apidata.DeleteInstance(m_del_wo_items[i]);
	}
	m_del_wo_items.Clear();
	
	for(i= 0; i<m_fileItems.GetSize(); i++)
	{
		inst= m_api->m_doc_mgr.CreateFile(m_fileItems[i]);
		if(!inst) continue;

		new_wo= m_api->m_data.CreateInstance(m_wf_mgr->e_wo);
		if(new_wo)
		{
			m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_object, inst);
			m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_for_note, false);
			m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_action, m_process);

			m_wo_items.Add(new_wo);
		}		
	}

	for(i= 0; i<m_fileItemsSprav.GetSize(); i++)
	{
		inst= m_api->m_doc_mgr.CreateFile(m_fileItemsSprav[i]);
		if(!inst) continue;

		new_wo= m_api->m_data.CreateInstance(m_wf_mgr->e_wo);
		if(new_wo)
		{
			m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_object, inst);
			m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_for_note, true);
			m_api->m_data.PutAttr(new_wo, m_wf_mgr->a_wo_action, m_process);

			m_wo_items.Add(new_wo);
		}		
	}
}

void CProcessDlg::ShowWorkObjects(BOOL bWo/* = APL_WFWO_FORWORK */)
{
	//m_woList.DeleteAllItems();
	m_Array.Clear();
	m_woListView->m_tree.DeleteAllItems();
	
	CaplInstance *cit = NULL, *ciRel = NULL;
	bool bForNote= false;
	bool bFlag;
	UINT ico;
	int iNum;
	CString sName, sType;
	aplExtent ext;
	
	if(bWo==APL_WFWO_FORNOTE) bForNote= true;
	
	int i;
	for(i= 0; i<m_wo_items.GetSize(); i++)
	{
		if(!m_wo_items[i] || !m_wo_items[i]->GetType()) continue;
		if(m_wo_items[i]->GetAccessmode()==aplNO) continue;
		
		m_api->m_data.GetAttr(m_wo_items[i], m_wf_mgr->a_wo_object, cit);
		ext.Add(cit);
	}

	m_api->LoadExtentInfo(ext);

	for(i= 0; i<m_wo_items.GetSize(); i++)
	{
		if(-1!=m_del_wo_items.Find(m_wo_items[i])) continue;

		if(!m_wo_items[i] || !m_wo_items[i]->GetType()) continue;
		if(m_wo_items[i]->GetAccessmode()==aplNO) continue;
		
		m_api->m_data.GetAttr(m_wo_items[i], m_wf_mgr->a_wo_for_note, bFlag);
		if(bFlag==bForNote)
		{			
			m_api->m_data.GetAttr(m_wo_items[i], m_wf_mgr->a_wo_object, cit);
			if(!cit) continue;
			if(cit->GetAccessmode()==aplNO) continue;
			
			m_api->GetItemName(cit, sName);
			ico = m_api->GetInstIco(cit);
			sType= GetTypeName(cit);
			
			if(sName.IsEmpty()) sName.Format(_T("%s -> id %i"), cit->GetType()->name, cit->GetId());
			iNum= m_woListView->m_tree.GetItemCount();

			CSelectInstanceTreeItemEx *pItem = new CSelectInstanceTreeItemEx(m_api, &(m_woListView->m_tree), &m_Array, cit, ciRel);
			if(pItem->CreateTreeItem(NULL, NULL))
			{
				m_woListView->m_tree.SetItemData(pItem->m_item, (DWORD)pItem);
				m_woListView->m_tree.SetItemText(pItem->m_item, 1, sType);				
			}
			else 
			{
				AfxMessageBox(APL_T("Не удалось отобразить объект (CProcessDlg::ShowWorkObjects)"));
			}

		}
	}

	CStringArray *arr;
	if(bWo==APL_WFWO_FORNOTE) arr= &m_fileItemsSprav;
	else arr= &m_fileItems;

	for(i= 0; i<arr->GetSize(); i++)
	{
		HTREEITEM hItem = m_woListView->m_tree.InsertItem((*arr)[i], ICON_DOCUMENT_COPY, ICON_DOCUMENT_COPY);
		m_woListView->m_tree.SetItemData(hItem, (DWORD)NULL);
		m_woListView->m_tree.SetItemText(hItem, 1, APL_T("Файл"));
		m_woListView->m_tree.SetItemImage(hItem, ICON_DOCUMENT_COPY, ICON_DOCUMENT_COPY);		
	}

	FillAdditionalInfoAboutChilds(NULL);
}

CString CProcessDlg::GetTypeName(CaplInstance* inst)
{
	CString sType;
	
	if(!inst) return sType;
	if(!inst->GetType()) return sType;

	if(apidata.IsKindOf(inst, m_api->m_doc_mgr.e_apl_doc))
		sType= APL_T("Документ");
	else if(apidata.IsKindOf(inst, m_api->m_doc_mgr.e_apl_doc_rev))
		sType = APL_T("Версия документа");
	else if(apidata.IsKindOf(inst, m_api->m_doc_mgr.e_apl_stored_document))
		sType= APL_T("Файл");
	else if(apidata.IsKindOf(inst, m_api->m_prd_mgr.e_prd))
		sType= APL_T("Изделие");
	else if(apidata.IsKindOf(inst, m_api->m_prd_mgr.e_apl_pdf))
		sType= APL_T("Версия изделия");
	else if(apidata.IsKindOf(inst, m_api->m_prd_inst_mgr.e_prd_inst))
		sType= APL_T("Экземпляр изделия");
	else if(apidata.IsKindOf(inst, m_api->m_prd_inst_mgr.e_lot))
		sType= APL_T("Партия");
	else if(apidata.IsKindOf(inst, m_api->m_change_mgr.e_chng))
		sType = APL_T("Пакет изменений");
	else if(apidata.IsKindOf(inst, m_api->m_change_mgr.e_avc))
		sType = APL_T("Изменение документа");
	else if(apidata.IsKindOf(inst, m_api->m_change_mgr.e_psc))
		sType = APL_T("Изменение изделия");
	else if(apidata.IsKindOf(inst, m_api->m_bp_mgr.e_bp))
		sType= APL_T("Бизнес-процесс");
	else if(apidata.IsKindOf(inst, m_api->m_bp_mgr.e_apl_bp_inst))
		sType= APL_T("Экземпляр бизнес-процесса");
	else if(0!= m_api->m_expl_mgr && apidata.IsKindOf(inst, m_api->m_expl_mgr->e_apl_refusal))
		sType= APL_T("Неисправность");
	else if(apidata.IsKindOf(inst, m_api->m_classifier_mgr.e_apl_classifier_system))
		sType= APL_T("Справочник");
	else if(apidata.IsKindOf(inst, m_api->m_classifier_mgr.e_apl_classifier_level))
		sType= APL_T("Элемент справочника");
	else if(apidata.IsKindOf(inst, m_api->m_folder_mgr.e_folder))
		sType= APL_T("Папка");
	else if(apidata.IsKindOf(inst, m_api->m_project_mgr->e_project))
		sType= APL_T("Проект");
	else if(apidata.IsKindOf(inst, m_api->m_appr_mgr.e_person))
		sType= APL_T("Сотрудник");
	else if(apidata.IsKindOf(inst, m_api->m_appr_mgr.e_org))
		sType= APL_T("Организация");
	else if(apidata.IsKindOf(inst, m_api->m_appr_mgr.e_org))
		sType= APL_T("Организация");
	else if(apidata.IsKindOf(inst, m_api->m_message_mgr.e_message))
		sType= APL_T("Сообщение");
	else if(apidata.IsKindOf(inst, m_api->m_doc_mgr.e_doc_copy_order))
	{
		m_api->m_data.GetAttr(inst, m_api->m_doc_mgr.a_purchase_order_type, sType);
		sType.MakeLower();

		if(sType==_T("print")) sType= APL_T("Заказ-наряд");
		else if(sType==_T("destroy")) sType = APL_T("Акт об уничтожении");
		else sType = inst->GetType()->name;
	}
	else sType= inst->GetType()->name;

	return sType;
}

bool CProcessDlg::Expanded( HTREEITEM hItem,UINT action, HWND hWnd )
{
	CString buf;
	aplExtent ext, ext2, rel_ext;
	CaplInstance *inst = NULL;
	
	m_woListView->m_tree.SetRedraw(FALSE);
		
	{
		CSelectInstanceTreeItemEx *pItem = (CSelectInstanceTreeItemEx*)m_woListView->m_tree.GetItemData(hItem);
		if(!pItem) {m_woListView->m_tree.SetRedraw(TRUE);return false;}

		if(pItem!=NULL && (m_woListView->m_tree.GetItemState(hItem, TVIS_EXPANDED) != TVIS_EXPANDED))
			pItem->Expand(action);													
		
		// добавляем имена типов для объектов
		if(action == TVE_EXPAND) FillAdditionalInfoAboutChilds(pItem);

		m_woListView->m_tree.SetRedraw(TRUE);		
	}
	
	return true;	
}

void CProcessDlg::OnDestroy() 
{
	CWnd *wnd=CWnd::GetFocus();
	m_Array.Clear();
	m_woListView->m_tree.DeleteAllItems();
	if(wnd) wnd->SetFocus();
	
	CaplResizableDialog::OnDestroy();
}

void CProcessDlg::FillAdditionalInfoAboutChilds( CSelectInstanceTreeItemEx *pItem )
{
	HTREEITEM hItem = NULL;
	
	if(pItem) hItem = m_woListView->m_tree.GetChildItem(pItem->m_item);
	else hItem = m_woListView->m_tree.GetRootItem();
	
	while(hItem)
	{
		CSelectInstanceTreeItemEx *pChildItem = (CSelectInstanceTreeItemEx*)m_woListView->m_tree.GetItemData(hItem);
		if(pChildItem) 
		{
			m_woListView->m_tree.SetItemText(hItem, 1, GetTypeName(pChildItem->m_inst));

			if(m_MapOfUnCheckedItems.find(pChildItem->m_inst) == m_MapOfUnCheckedItems.end()) m_woListView->m_tree.SetCheck(hItem);
			else m_woListView->m_tree.SetCheck(hItem, FALSE);
		}
		else
		{
			m_woListView->m_tree.SetCheck(hItem);
		}

		hItem = m_woListView->m_tree.GetNextSiblingItem(hItem);
	}
}

bool CProcessDlg::ItemChange( NM_TREEVIEW* pNMTreeView )
{
	HTREEITEM hItem = GetSelectedItem();
	if(!hItem) return false;

	hItem = m_woListView->m_tree.GetParentItem(hItem);
	m_deleteWoBtn.EnableWindow(hItem?FALSE:TRUE);
	
	return true;
}

bool CProcessDlg::CheckItem()
{
	CString strText, strHeader;
	HTREEITEM hItem = GetSelectedItem();
	if(!hItem) return NULL;

	if(m_bReadOnly) 
	{
		AfxMessageBox(APL_T("Диалог представлен в режиме чтения."), MB_ICONINFORMATION);
		return false;
	}
	
	if(m_woListView->m_tree.GetCheck(hItem))
	{
		strHeader = APL_T("Снять выделение с рабочих объектов");
		strText = APL_T("Снять выделение со всех входящих объектов?\n\nВНИМАНИЕ! Выделение будет снято только с тех объектов, которые раскрыты в дереве!");
	}
	else
	{
		strHeader = APL_T("Выделить рабочие объекты");
		strText = APL_T("Выделить все входящие объекты?\n\nВНИМАНИЕ! Будут выделены только те объекты, которые раскрыты в дереве!");
	}

	BOOL bCheck = CheckUncheck(hItem, !m_woListView->m_tree.GetCheck(hItem));

	if(AfxMessageBox(strText, MB_ICONWARNING|MB_YESNO) == IDYES) 
	{
		HTREEITEM hChildItem = m_woListView->m_tree.GetChildItem(hItem);
		CString str = m_woListView->m_tree.GetItemText(hChildItem);
		CheckUncheckInside(hChildItem, bCheck);
	}	

	Invalidate();
	return true;	
}

void CProcessDlg::CheckUncheckInside(HTREEITEM hItem, BOOL bCheck)
{
	if(!hItem) return;

	while(hItem)
	{
		// выделяем (убираем выделение) с элемента
		CheckUncheck(hItem, bCheck);

		// проделываем тоже самое с дочерними
		if(m_woListView->m_tree.ItemHasChildren(hItem))
		{
			HTREEITEM hChildItem = m_woListView->m_tree.GetChildItem(hItem);
			CheckUncheckInside(hChildItem, bCheck);
		}

		hItem = m_woListView->m_tree.GetNextSiblingItem(hItem);
	}
}

BOOL CProcessDlg::CheckUncheck(HTREEITEM hItem, BOOL bCheck)
{
	CSelectInstanceTreeItemEx *pItem = (CSelectInstanceTreeItemEx*)m_woListView->m_tree.GetItemData(hItem);
	if(!pItem) return FALSE;

	if(!bCheck)
	{
		m_MapOfUnCheckedItems.insert(PAIR(pItem->m_inst, (CaplInstance*)NULL));						
	}
	else
	{
		IMap_Iter = m_MapOfUnCheckedItems.find(pItem->m_inst);
		if(IMap_Iter != m_MapOfUnCheckedItems.end()) m_MapOfUnCheckedItems.erase(IMap_Iter);						
	}

	m_woListView->m_tree.SetCheck(hItem, bCheck);
	return bCheck;
}

HTREEITEM CProcessDlg::GetSelectedItem()
{
	CArray<HTREEITEM, HTREEITEM> cArray;
	m_woListView->m_tree.GetListSelected(cArray);

	if(!cArray.GetSize()) return NULL;
	return cArray[0];
}

CaplInstance* CProcessDlg::GetParentItemInst( HTREEITEM hItem )
{
	CaplInstance *cit = NULL;
		
	while(hItem)
	{
		cit = (CaplInstance*)m_woListView->m_tree.GetItemData(hItem);
		hItem = m_woListView->m_tree.GetParentItem(hItem);
	}

	return cit;
}

CaplInstance* CProcessDlg::GetWOByInstance( CaplInstance *cit )
{
	CaplInstance *ciTmp = NULL;

	for(int i=0; i<m_wo_items.GetSize(); i++)
	{
		m_api->m_data.GetAttr(m_wo_items[i], m_wf_mgr->a_wo_object, ciTmp);
		if(cit == ciTmp) return  m_wo_items[i];
	}

	return NULL;
}

void CProcessDlg::AddAllAnchor()
{
	AddAnchor(IDC_PROC_START_BUTTON,						BOTTOM_LEFT);
	AddAnchor(IDOK,										BOTTOM_RIGHT);
	AddAnchor(IDCANCEL,										BOTTOM_RIGHT);

	AddAnchor(IDC_PROC_TAB,				TOP_LEFT, BOTTOM_RIGHT);
	AddAnchor(IDC_STATIC_BORDER,		TOP_LEFT, BOTTOM_RIGHT);
	AddAnchor(IDC_TREE_LIST,			TOP_LEFT, BOTTOM_RIGHT);

	AddAnchor(IDC_PROC_ADD_WO,				TOP_RIGHT);
	AddAnchor(IDC_PROC_ADD_FILE,				TOP_RIGHT);
	AddAnchor(IDC_PROC_DELETE_WO,				TOP_RIGHT);

	AddAnchor(IDC_STATIC_PROC,				TOP_LEFT,TOP_RIGHT);
	AddAnchor(IDC_STATIC_SHABL,				TOP_LEFT, TOP_RIGHT);

	AddAnchor(IDC_PROC_TMPL_ID,				TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_PROC_DSCR,				TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_SUB_PROCESS_COMBO,			TOP_LEFT, TOP_RIGHT);

	AddAnchor(IDC_STATIC_NAME,				TOP_CENTER, TOP_CENTER);
	AddAnchor(IDC_PROC_ID,				TOP_LEFT, TOP_CENTER);
	AddAnchor(IDC_PROC_NAME,			TOP_CENTER, TOP_RIGHT);

	AddAnchor(IDC_PROC_MANAGER, TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_PROC_SELECT, TOP_RIGHT);
	AddAnchor(IDC_PROC_DELETE,	TOP_RIGHT);
	
	AddAnchor(IDC_PROC_PROTOTYPE,	TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_PROC_EDIT_PROT,	TOP_RIGHT);

	AddAnchor(IDC_PROC_D_START, TOP_LEFT, TOP_CENTER);
	AddAnchor(IDC_PROC_T_START, TOP_CENTER, TOP_RIGHT);

	AddAnchor(IDC_PROC_D_CHECK, TOP_LEFT, TOP_CENTER);
	AddAnchor(IDC_PROC_T_CHECK, TOP_CENTER, TOP_RIGHT);

	AddAnchor(IDC_PROC_D_FINISH, TOP_LEFT, TOP_CENTER);
	AddAnchor(IDC_PROC_T_FINISH, TOP_CENTER, TOP_RIGHT);
	AddAnchor(IDC_PROC_VIEW, TOP_RIGHT);
}

void CProcessDlg::OnSize(UINT nType, int cx, int cy) 
{
	CaplResizableDialog::OnSize(nType, cx, cy);
	
	if(m_woListView)
	{
		CRect rect;
		m_woListView->GetWindowRect(&rect);
		ScreenToClient(&rect);
		int cx = rect.right - rect.left;
			
		int k = m_woListView->m_tree.m_wndHeader.GetItemCount();				
		if(k>0)
		{
			int dx=0;
			int i;
			for(i=0;i<k;i++) dx += m_woListView->m_tree.GetColumnWidth(i);
								
			for(i=0; i<m_woListView->m_tree.m_wndHeader.GetItemCount(); i++)
			{
				int l = m_woListView->m_tree.GetColumnWidth(i);
				if(l <= 0) break;
								
				HD_ITEM hHeader;
				hHeader.mask = HDI_WIDTH;												
				m_woListView->m_tree.m_wndHeader.GetItem(i, &hHeader);				
				hHeader.cxy = ((cx*l)/dx)+1;
				m_woListView->m_tree.m_wndHeader.SetItem(i, &hHeader);				
			}		
		}

		m_woListView->Invalidate();
	}
	
}

