Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабы / 2 / lab.02.by mice / dormouse / src / main / dm_ui

.cpp
Скачиваний:
10
Добавлен:
17.04.2013
Размер:
34.71 Кб
Скачать
/*******************************************************************************
* file:         dm_ui.cpp                                                      *
* version:      0.9.0                                                          *
* author:       d-evil [tmd] (mailto:d-evil.tmd@mail.ru)                       *
* description:  not available                                                  *
*******************************************************************************/

#include "dm_ui.h"

namespace dm_ui {

////////////////////////////////////////////////////////////////////////////////
// cdm_ui public definition
cdm_ui::cdm_ui(): CDialog(IDD_MAIN_WND) {
	_cool_stuff_thread_h = NULL;
	_list_mtx = CreateMutex(NULL, FALSE, NULL);
	_list_changed = false;
	_can_quit = false;
	_quit_started = false;
}


cdm_ui::~cdm_ui() {
	if (NULL != _list_mtx) CloseHandle(_list_mtx);
}


int cdm_ui::set_core(cdm_core *const core) {
	_core = core;

	return 0;
}


BOOL cdm_ui::OnInitDialog() {
	// init dialog window
	 SetIcon(_hicon, FALSE);

	// init controls variables
	edit_host = (CEdit *)GetDlgItem(IDC_EDIT_HOST);
	edit_port = (CEdit *)GetDlgItem(IDC_EDIT_PORT);
	edit_file = (CEdit *)GetDlgItem(IDC_EDIT_FILE);
	btn_recv = (CButton *)GetDlgItem(IDC_BTN_RECV);
	btn_browse = (CButton *)GetDlgItem(IDC_BTN_BROWSE);
	btn_send = (CButton *)GetDlgItem(IDC_BTN_SEND);

	btn_rs = (CButton *)GetDlgItem(IDC_BTN_RS);
	btn_pr = (CButton *)GetDlgItem(IDC_BTN_PR);
	btn_kill = (CButton *)GetDlgItem(IDC_BTN_KILL);

	btn_exit = (CButton *)GetDlgItem(IDC_BTN_EXIT);
	tree = (CTreeCtrl *)GetDlgItem(IDC_TREE);
	list = (CListCtrl *)GetDlgItem(IDC_LIST);

	// init edit controls
	edit_host->SetWindowText(_core->get_hostname());
	CString str;
	str.Format("%u", (unsigned int)_core->get_defport());
	edit_port->SetWindowText(str);

	// init tree view
	_list_changed = false;
	_ti_active = NULL;
	_load_str(str, RS_UI_SERVERS_ROOT);
	_tr_servers = tree->InsertItem(str);
	tree->SetItemData(_tr_servers, NULL);
	_load_str(str, RS_UI_SENDERS_ROOT);
	_tr_senders = tree->InsertItem(str);
	tree->SetItemData(_tr_senders, NULL);
	_load_str(str, RS_UI_RECEIVERS_ROOT);
	_tr_recvers = tree->InsertItem(str);
	tree->SetItemData(_tr_recvers, NULL);

	// init list view
	list->SetExtendedStyle(LVS_EX_FULLROWSELECT);
	list->InsertColumn(0, "Field", LVCFMT_LEFT, _lst_field_w, 0);
	list->InsertColumn(1, "Value", LVCFMT_LEFT, _lst_value_w, 1);
	// list->InsertItem(0, "field");
	// list->SetItemText(0, 1, "value");

	// buttons
	_btn_state_rs = _BTN_RS_NA;
	_btn_state_pr = _BTN_PR_NA;
	_btn_state_kill = _BTN_KILL_NA;

	// run cool stuff
	if (0 != _run_cool_stuff()) {
		error_message(RS_UI_CS_ERS_RUN, GetLastError());
	}

	return TRUE;
}


void cdm_ui::OnClose() {
	if (!_quit_started) {
		_quit_started = true;
		_stop_cool_stuff();
		_core->quit();
	}

	if (!_can_quit) {
		// Sleep(20);
		PostMessage(WM_CLOSE);
	} else EndDialog(0);
}


int cdm_ui::error_message(const int dm_error, const int os_error) {
	CString dm_str;
	_load_str(dm_str, dm_error);
	
	CString os_str;
	if (0 != os_error) _get_os_error_str(os_str, os_error);
		else _load_str(os_str, RS_UI_OS_ERROR_NA);

	CString msg;
	msg.FormatMessage(RS_UI_ERROR_MSG_STR, dm_str, os_str);

	CString dlg_cap;
	_load_str(dlg_cap, RS_UI_ERMSG_CAPTION);
	MessageBox(msg, dlg_cap, MB_OK|MB_APPLMODAL|MB_ICONERROR);

	return 0;
}


int cdm_ui::on_pure_dm_error(const int dm_error) {
	return error_message(dm_error, 0);
}


int cdm_ui::on_error(const int dm_error, const int os_error) {
	return error_message(dm_error, os_error);
}


int cdm_ui::on_ext_error(void *const error) {
	return error_message(RS_UI_EXT_ERROR_DM, 0);
}


int cdm_ui::on_frecver_ch(cdm_frecver *const frecver, const int ch_mask) {
	HTREEITEM item = (HTREEITEM)frecver->ui_data();
	if (_ti_active != item) goto exit_label;

	if (_list_changed) {
		_updt_serv_info(frecver, FRECVER_CH_ALL);
		_list_changed = false;
	} else _updt_serv_info(frecver, ch_mask);
	// SendMessage(CDM_MSG_SERV, (WPARAM)frecver, ch_mask);

exit_label:
	return 0;
}


int cdm_ui::on_fsender_ch(cdm_fsender *const fsender, const int ch_mask) {
	HTREEITEM item = (HTREEITEM)fsender->ui_data();
	if (_ti_active != item) goto exit_label;

	if (_list_changed) {
		_updt_sender_info(fsender, FSENDER_CH_ALL);
		_list_changed = false;
	} else _updt_sender_info(fsender, ch_mask);
	// SendMessage(CDM_MSG_SEND, (WPARAM)fsender, ch_mask);

exit_label:
	return 0;
}

int cdm_ui::on_subs_ch(cdm_frecv_subs *const subs, const int ch_mask) {
	HTREEITEM item = (HTREEITEM)subs->ui_data();
	if (_ti_active != item) goto exit_label;

	if (_list_changed) {
		_updt_recver_info(subs, FSENDER_CH_ALL);
		_list_changed = false;
	} else _updt_recver_info(subs, ch_mask);
	// SendMessage(CDM_MSG_RECV, (WPARAM)subs, ch_mask);

exit_label:
	return 0;
}


LRESULT cdm_ui::on_msg_serv(WPARAM hz, LPARAM msk) {
	_updt_serv_info((cdm_frecver *)hz, (int)msk);
	return TRUE;
}


LRESULT cdm_ui::on_msg_send(WPARAM hz, LPARAM msk) {
	_updt_sender_info((cdm_fsender *)hz, (int)msk);
	return TRUE;
}


LRESULT cdm_ui::on_msg_recv(WPARAM hz, LPARAM msk) {
	_updt_recver_info((cdm_frecv_subs *)hz, (int)msk);
	return TRUE;
}


int cdm_ui::on_frecver_rm(cdm_frecver *const frecver) {
	HTREEITEM item = (HTREEITEM)frecver->ui_data();
	if (NULL == item) return -1;

	if (_ti_active == item) {
		_ti_active = NULL;
		_show_blank();
	}
	tree->DeleteItem(item);

	return 0;
}


int cdm_ui::on_fsender_rm(cdm_fsender *const fsender) {
	HTREEITEM item = (HTREEITEM)fsender->ui_data();
	if (NULL == item) return -1;

	if (_ti_active == item) {
		_ti_active = NULL;
		_show_blank();
	}
	tree->DeleteItem(item);

	return 0;
}


int cdm_ui::on_subs_rm(cdm_frecv_subs *const subs) {
	HTREEITEM item = (HTREEITEM)subs->ui_data();
	if (NULL == item) return -1;

	if (_ti_active == item) {
		_ti_active = NULL;
		_show_blank();
	}
	tree->DeleteItem(item);

	return 0;
}


int cdm_ui::on_accept(cdm_frecv_subs *const frecv_subs) {
	CString str;
	str.Format("Incoming connection from [%s:%s] (ip: [%s])\n\n",
		frecv_subs->iaddr()->host(),
		frecv_subs->iaddr()->port_str(),
		frecv_subs->iaddr()->ip_str()
	);
	CString str_sz;
	_ui_size_to_str(frecv_subs->ifile()->sz(), str_sz);
	str.AppendFormat("Incoming object is [file]\nname: %s\nsize: %s\n\nAccept?", 
		frecv_subs->ifile()->name(),
		str_sz
	);
	_tree_add_recver(frecv_subs);

	int rev = MessageBox(str, "Dormouse incoming", MB_YESNO|MB_APPLMODAL|MB_ICONQUESTION);
	if (IDYES != rev) return -1;
	if (0 != _ui_get_save_file(frecv_subs->ifile()->name(), str)) return -1;
	frecv_subs->ifile()->set_path(str);

	return 0;
}


int cdm_ui::on_quit() {
	_can_quit = true;

	return 0;
}


////////////////////////////////////////////////////////////////////////////////
// cdm_ui protected definition
BEGIN_MESSAGE_MAP(cdm_ui, CDialog)
	ON_WM_CLOSE()
	ON_COMMAND(IDC_BTN_EXIT, _on_btn_exit)
	ON_COMMAND(IDC_BTN_BROWSE, _on_btn_browse)
	ON_COMMAND(IDC_BTN_RECV, _on_btn_recv)
	ON_COMMAND(IDC_BTN_SEND, _on_btn_send)
	ON_COMMAND(IDC_BTN_HELP, _on_btn_help)
	ON_COMMAND(IDC_BTN_ABOUT, _on_btn_about)
	ON_COMMAND(IDC_CHECK_BUGS, _on_check_bugs)

	ON_COMMAND(IDC_BTN_RS, _on_btn_rs)
	ON_COMMAND(IDC_BTN_PR, _on_btn_pr)
	ON_COMMAND(IDC_BTN_KILL, _on_btn_kill)

	ON_NOTIFY(TVN_SELCHANGED, IDC_TREE, _on_tree_selch)
	ON_NOTIFY(TVN_SELCHANGING, IDC_TREE, _on_tree_selching)

	ON_MESSAGE(CDM_MSG_SERV, on_msg_serv)
	ON_MESSAGE(CDM_MSG_SEND, on_msg_send)
	ON_MESSAGE(CDM_MSG_RECV, on_msg_recv)
END_MESSAGE_MAP()


void cdm_ui::_on_btn_exit() {
	SendMessage(WM_CLOSE, 0, 0);
}


void cdm_ui::_on_btn_browse() {
	CString fname;
	edit_file->GetWindowText(fname);
	CString filter;
	_load_str(filter, RS_UI_FILTERSTR);
	CFileDialog fdlg(TRUE, NULL, fname,
		OFN_DONTADDTORECENT|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_NOTESTFILECREATE,
		filter, this, 0
	);
	if (IDOK == fdlg.DoModal()) {
		edit_file->SetWindowText(fdlg.GetPathName());
	}
}


void cdm_ui::_on_btn_recv() {
	// gather information about new recver
	CString host;
	edit_host->GetWindowText(host);
	unsigned short port = _ui_get_port();

	// create new recver and tune it
	cdm_frecver *recver = _core->new_frecver(host, port);
	if (NULL == recver) {
		error_message(_core->last_dm_error(), _core->last_error());
		return;
	}

	// add new recver to core recvers list
	if (0 != _core->add_frecver(recver)) {
		error_message(_core->last_dm_error(), _core->last_error());
		_core->free_frecver(recver);
		return;
	}

	// add recver to ui recvers list
	_tree_add_server(recver);

	// run recver
	if (0 != _core->start_frecver(recver, true)) {
		error_message(_core->last_dm_error(), _core->last_error());
		_core->del_frecver(recver);
		_core->free_frecver(recver);
		return;
	}
}


void cdm_ui::_on_btn_send() {
	// gather information about new sender
	CString host;
	edit_host->GetWindowText(host);
	unsigned short port = _ui_get_port();

	// create new sender and tune it
	cdm_fsender *sender = _core->new_fsender(host, port);
	if (NULL == sender) {
		error_message(_core->last_dm_error(), _core->last_error());
		return;
	}
	CString path;
	edit_file->GetWindowText(path);
	sender->ifile()->set_path(path);

	// add new sender to core senders list
	if (0 != _core->add_fsender(sender)) {
		error_message(_core->last_dm_error(), _core->last_error());
		_core->free_fsender(sender);
		return;
	}

	// add sender to ui senders list
	_tree_add_sender(sender);

	// run sender
	if (0 != _core->start_fsender(sender, true)) {
		error_message(_core->last_dm_error(), _core->last_error());
		_core->del_fsender(sender);
		_core->free_fsender(sender);
		return;
	}
}


void cdm_ui::_on_btn_rs() {
	if (NULL == _ti_active) return;
	sdm_ti_data *data = (sdm_ti_data *)tree->GetItemData(_ti_active);
	if (NULL == data) return;

	if (OBJT_SERVER == data->objt) {
		cdm_frecver *recver = (cdm_frecver *)data->obj;
		if (NULL == recver) return;
		if (_BTN_RS_R == _btn_state_rs) recver->start(true);
		else if (_BTN_RS_S == _btn_state_rs) recver->stop();
		_ui_set_server_btns(recver);
		_updt_serv_info(recver, FRECVER_CH_ALL);
	} else if (OBJT_RECVER == data->objt) {
		cdm_frecv_subs *subs = (cdm_frecv_subs *)data->obj;
		if (NULL == subs) return;
		if (_BTN_RS_R == _btn_state_rs) subs->start(true);
		else if (_BTN_RS_S == _btn_state_rs) subs->stop();
		_ui_set_recver_btns(subs);
		_updt_recver_info(subs, FSUBS_CH_ALL);
	} else if (OBJT_SENDER == data->objt) {
		cdm_fsender *sender = (cdm_fsender *)data->obj;
		if (NULL == sender) return;
		if (_BTN_RS_R == _btn_state_rs) sender->start(true);
		else if (_BTN_RS_S == _btn_state_rs) sender->stop();
		_ui_set_sender_btns(sender);
		_updt_sender_info(sender, FSENDER_CH_ALL);
	}
}


void cdm_ui::_on_btn_pr() {
	if (NULL == _ti_active) return;
	sdm_ti_data *data = (sdm_ti_data *)tree->GetItemData(_ti_active);
	if (NULL == data) return;

	if (OBJT_SERVER == data->objt) {
		cdm_frecver *recver = (cdm_frecver *)data->obj;
		if (NULL == recver) return;
		if (_BTN_PR_P == _btn_state_pr) recver->pause();
		else if (_BTN_PR_R == _btn_state_pr) recver->resume();
		_ui_set_server_btns(recver);
		_updt_serv_info(recver, FRECVER_CH_ALL);
	} else if (OBJT_RECVER == data->objt) {
		cdm_frecv_subs *subs = (cdm_frecv_subs *)data->obj;
		if (NULL == subs) return;
		if (_BTN_PR_P == _btn_state_pr) subs->pause();
		else if (_BTN_PR_R == _btn_state_pr) subs->resume();
		_ui_set_recver_btns(subs);
		_updt_recver_info(subs, FSUBS_CH_ALL);
	} else if (OBJT_SENDER == data->objt) {
		cdm_fsender *sender = (cdm_fsender *)data->obj;
		if (NULL == sender) return;
		if (_BTN_PR_P == _btn_state_pr) sender->pause();
		else if (_BTN_PR_R == _btn_state_pr) sender->resume();
		_ui_set_sender_btns(sender);
		_updt_sender_info(sender, FSENDER_CH_ALL);
	}
}


void cdm_ui::_on_btn_kill() {
	if (NULL == _ti_active) return;
	sdm_ti_data *data = (sdm_ti_data *)tree->GetItemData(_ti_active);
	if (NULL == data) return;

	if (OBJT_SERVER == data->objt) {
		cdm_frecver *recver = (cdm_frecver *)data->obj;
		if (NULL == recver) return;
		recver->die(true);
		_ui_set_server_btns(recver);
		_updt_serv_info(recver, FRECVER_CH_ALL);
	} else if (OBJT_RECVER == data->objt) {
		cdm_frecv_subs *subs = (cdm_frecv_subs *)data->obj;
		if (NULL == subs) return;
		subs->die(true);
		_ui_set_recver_btns(subs);
		_updt_recver_info(subs, FSUBS_CH_ALL);
	} else if (OBJT_SENDER == data->objt) {
		cdm_fsender *sender = (cdm_fsender *)data->obj;
		if (NULL == sender) return;
		sender->die(true);
		_ui_set_sender_btns(sender);
		_updt_sender_info(sender, FSENDER_CH_ALL);
	}
}


void cdm_ui::_on_btn_help() {
	SetCurrentDirectory(_core->def_dir());
	ShellExecute(NULL, NULL, "help/dormouse.html", NULL, "", SW_SHOW);
}


void cdm_ui::_on_btn_about() {
	SetCurrentDirectory(_core->def_dir());
	ShellExecute(NULL, NULL, "about/dormouse.html", NULL, "", SW_SHOW);
}


void cdm_ui::_on_check_bugs() {
	if (IsDlgButtonChecked(IDC_CHECK_BUGS)) _core->set_use_bugs(true);
	else _core->set_use_bugs(false);
}


void cdm_ui::_on_tree_selch(NMHDR *phdr, LRESULT *pinfo) {
	HTREEITEM item = tree->GetSelectedItem();
	if (_ti_active == item) goto exit_label;
	_ti_active = item;
	if (NULL == item) goto exit_label;

	sdm_ti_data *data = (sdm_ti_data *)tree->GetItemData(item);
	if (NULL == data) {
		_ui_set_btn_rs(_BTN_RS_NA);
		_ui_set_btn_pr(_BTN_PR_NA);
		_ui_set_btn_kill(_BTN_KILL_NA);
		_show_blank();
		goto exit_label;
	}

	switch(data->objt) {
		case OBJT_SERVERS:
			_show_servs_info(data);
			break;

		case OBJT_SERVER:
			_show_serv_info((cdm_frecver *)data->obj);
			break;

		case OBJT_RECVERS:
			_show_recvers_info(data);
			break;

		case OBJT_RECVER:
			_show_recver_info((cdm_frecv_subs *)data->obj);
			break;

		case OBJT_SENDERS:
			_show_senders_info(data);
			break;

		case OBJT_SENDER:
			_show_sender_info((cdm_fsender *)data->obj);
			break;

		default:
			break;
	}

exit_label:
	_list_changed = true;
	return;
}


void cdm_ui::_on_tree_selching(NMHDR *phdr, LRESULT *pinfo) {
	// _ui_list_lock(INFINITE);
	// _ti_active = NULL;
	// _ui_list_ulock();

}


unsigned short cdm_ui::_ui_get_port() {
	CString port_str;
	edit_port->GetWindowText(port_str);
	unsigned short port = atoi(port_str);
	port_str.Format("%i", (int)port);
	edit_port->SetWindowText(port_str);

	return port;
}


void cdm_ui::_ui_size_to_str(const unsigned int sz, CString &str) {
	if (sz < 1024) {
		str.Format("%u b", sz);
	} else if (sz < 1024*1024) {
		str.Format("%.3f kb", (float)sz/(1024));
	} else if (sz < 1024*1024*1024) {
		str.Format("%.3f mb", (float)sz/(1024*1024));
	} else {
		str.Format("%.3f gb", (float)sz/(1024*1024*1024));
	}
}


void cdm_ui::_ui_percent_str(const int total, const int done, CString &str) {
	float pt;
	if (0 != done) {
		pt = (float)100 * (float)done / (float)total;
	} else pt = 0;
	str.Format("%.2f %%", pt);
}


void cdm_ui::_ui_time_str(const time_t t, CString &str) {
	int s = (int)(t / CLOCKS_PER_SEC);
	int secs = s % 60; s /= 60;
	int mins = s % 60; s /= 60;
	int hors = s % 60;
	str.Format("%02i:%02i:%02i", hors, mins, secs);
}


void cdm_ui::_ui_remtime_str(const clock_t up_time, const int total, const int done, CString &str) {
	clock_t t;
	if (0 != done) t = (clock_t)(up_time*(float)total / (float)done - up_time);
	else t = 0;
	_ui_time_str(t, str);
	if (0 != total && done == total) str += " [done]";
}


int cdm_ui::_ui_get_save_file(const CString &name, CString &path) {
	CString filter;
	_load_str(filter, RS_UI_FILTERSTR);
	CFileDialog fdlg(FALSE, NULL, name,
		OFN_DONTADDTORECENT|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_NOTESTFILECREATE,
		filter, this, 0
	);
	if (IDOK != fdlg.DoModal()) return -1;
	path = fdlg.GetPathName();

	return 0;
}


void cdm_ui::_ui_set_btn_rs(const int state) {
	if (state == _btn_state_rs) return;
	_btn_state_rs = state;
	switch (_btn_state_rs) {
		case _BTN_RS_NA:
			btn_rs->EnableWindow(FALSE);
			btn_rs->SetWindowText("N/A");
			break;

		case _BTN_RS_R:
			btn_rs->EnableWindow(TRUE);
			btn_rs->SetWindowText("Run");
			break;

		case _BTN_RS_S:
			btn_rs->EnableWindow(TRUE);
			btn_rs->SetWindowText("Stop");
			break;

		default:
			break;
	}
}


void cdm_ui::_ui_set_btn_pr(const int state) {
	if (state == _btn_state_pr) return;
	_btn_state_pr = state;
	switch (_btn_state_pr) {
		case _BTN_PR_NA:
			btn_pr->EnableWindow(FALSE);
			btn_pr->SetWindowText("N/A");
			break;

		case _BTN_PR_P:
			btn_pr->EnableWindow(TRUE);
			btn_pr->SetWindowText("Pause");
			break;

		case _BTN_PR_R:
			btn_pr->EnableWindow(TRUE);
			btn_pr->SetWindowText("Resume");
			break;

		default:
			break;
	}
}


void cdm_ui::_ui_set_btn_kill(const int state) {
	if (state == _btn_state_kill) return;
	_btn_state_kill = state;
	switch (_btn_state_kill) {
		case _BTN_KILL_NA:
			btn_kill->EnableWindow(FALSE);
			btn_kill->SetWindowText("Kill");
			break;

		case _BTN_KILL_K:
			btn_kill->EnableWindow(TRUE);
			btn_kill->SetWindowText("Kill");
			break;

		default:
			break;
	}
}


void cdm_ui::_ui_set_server_btns(cdm_frecver *const recver) {
	if (NULL == recver) {
		_ui_set_btn_rs(_BTN_RS_NA);
		_ui_set_btn_pr(_BTN_PR_NA);
		_ui_set_btn_kill(_BTN_KILL_NA);
		return;
	} else _ui_set_btn_kill(_BTN_KILL_K);

	if (cdm_frecver::STATE_RUNNING == recver->state()) {
		_ui_set_btn_rs(_BTN_RS_S);
		_ui_set_btn_pr(_BTN_PR_P);
	} else if (cdm_frecver::STATE_PAUSED == recver->state()) {
		_ui_set_btn_rs(_BTN_RS_S);
		_ui_set_btn_pr(_BTN_PR_R);
	} else if (cdm_frecver::STATE_STOPED == recver->state()) {
		_ui_set_btn_rs(_BTN_RS_R);
		_ui_set_btn_pr(_BTN_PR_NA);
	} else {
		_ui_set_btn_rs(_BTN_RS_NA);
		_ui_set_btn_pr(_BTN_PR_NA);
	}
}


void cdm_ui::_ui_set_sender_btns(cdm_fsender *const sender) {
	if (NULL == sender) {
		_ui_set_btn_rs(_BTN_RS_NA);
		_ui_set_btn_pr(_BTN_PR_NA);
		_ui_set_btn_kill(_BTN_KILL_NA);
		return;
	} else _ui_set_btn_kill(_BTN_KILL_K);

	if (cdm_fsender::STATE_RUNNING == sender->state()) {
		_ui_set_btn_rs(_BTN_RS_S);
		_ui_set_btn_pr(_BTN_PR_P);
	} else if (cdm_fsender::STATE_PAUSED == sender->state()) {
		_ui_set_btn_rs(_BTN_RS_S);
		_ui_set_btn_pr(_BTN_PR_R);
	} else if (cdm_fsender::STATE_STOPED == sender->state()) {
		_ui_set_btn_rs(_BTN_RS_R);
		_ui_set_btn_pr(_BTN_PR_NA);
	} else {
		_ui_set_btn_rs(_BTN_RS_NA);
		_ui_set_btn_pr(_BTN_PR_NA);
	}
}


void cdm_ui::_ui_set_recver_btns(cdm_frecv_subs *const subs) {
	if (NULL == subs || cdm_frecver::STATE_RUNNING != subs->parent()->state()) {
		_ui_set_btn_rs(_BTN_RS_NA);
		_ui_set_btn_pr(_BTN_PR_NA);
		_ui_set_btn_kill(_BTN_KILL_NA);
		return;
	} else _ui_set_btn_kill(_BTN_KILL_K);

	if (cdm_frecv_subs::STATE_RUNNING == subs->state()) {
		_ui_set_btn_rs(_BTN_RS_S);
		_ui_set_btn_pr(_BTN_PR_P);
	} else if (cdm_frecv_subs::STATE_PAUSED == subs->state()) {
		_ui_set_btn_rs(_BTN_RS_S);
		_ui_set_btn_pr(_BTN_PR_R);
	} else if (cdm_frecv_subs::STATE_STOPED == subs->state()) {
		_ui_set_btn_rs(_BTN_RS_R);
		_ui_set_btn_pr(_BTN_PR_NA);
	} else {
		_ui_set_btn_rs(_BTN_RS_NA);
		_ui_set_btn_pr(_BTN_PR_NA);
	}
}


int cdm_ui::_ui_list_lock(const int timeout, const int dbg) {
	if (WAIT_TIMEOUT == WaitForSingleObject(_list_mtx, timeout))
		return -1;

	return 0;
}


int cdm_ui::_ui_list_ulock(const int dbg) {
	if (0 == ReleaseMutex(_list_mtx))
		return -1;
	
    return 0;
}


int cdm_ui::_clear_list() {
	for (int i = list->GetItemCount()-1; 0 <= i; --i)
		list->DeleteItem(i);

	return 0;
}


int cdm_ui::_show_blank() {
	_clear_list();

	return 0;
}


int cdm_ui::_show_servs_info(sdm_ti_data *const data) {
	_ui_set_server_btns(NULL);
	_clear_list();

	return 0;
}


int cdm_ui::_show_serv_info(cdm_frecver *const frecver) {
	_ui_set_server_btns(frecver);
	_clear_list();

	CString str;

	list->InsertItem(0, "receivers count");
	str.Format("%i", frecver->subs_count());
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "status");
	_load_str(str, frecver->ext_state());
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "state");
	_load_str(str, frecver->state());
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "port");
	list->SetItemText(0, 1, frecver->addr_info()->port_str());

	list->InsertItem(0, "ip");
	list->SetItemText(0, 1, frecver->addr_info()->ip_str());

	list->InsertItem(0, "host");
	list->SetItemText(0, 1, frecver->addr_info()->host());

	return 0;
}


int cdm_ui::_updt_serv_info(cdm_frecver *const frecver, const int ch_mask) {
	CString str;

	if (0 != (FRECVER_CH_STATE & ch_mask)) {
		// list->InsertItem(0, "receivers count");
		str.Format("%i", frecver->subs_count());
		list->SetItemText(5, 1, str);
		// list->InsertItem(0, "status");
		_load_str(str, frecver->ext_state());
		list->SetItemText(4, 1, str);
		// list->InsertItem(0, "state");
		_load_str(str, frecver->state());
		list->SetItemText(3, 1, str);

		_ui_set_server_btns(frecver);
	}

	if (0 != (FSUBS_CH_IADDR & ch_mask)) {
		// list->InsertItem(0, "port");
		list->SetItemText(2, 1, frecver->addr_info()->port_str());
		// list->InsertItem(0, "ip");
		list->SetItemText(1, 1, frecver->addr_info()->ip_str());
		// list->InsertItem(0, "host");
		list->SetItemText(0, 1, frecver->addr_info()->host());
	}

	return 0;
}


int cdm_ui::_show_recvers_info(sdm_ti_data *const data) {
	_ui_set_recver_btns(NULL);
	_clear_list();

	return -1;
}


int cdm_ui::_show_recver_info(cdm_frecv_subs *const subs) {
	_ui_set_recver_btns(subs);
	_clear_list();

	CString str;

	cdm_frecver *recver = subs->parent();

	list->InsertItem(0, "time elapse");
	_ui_time_str(subs->up_time(), str);
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "time remains");
	_ui_remtime_str(subs->up_time(), subs->total_parts(), subs->done_parts(), str);
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "finished");
	_ui_percent_str(subs->total_parts(), subs->done_parts(), str);
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "status");
	_load_str(str, subs->ext_state());
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "state");
	_load_str(str, subs->state());
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "server port");
	list->SetItemText(0, 1, recver->addr_info()->port_str());

	list->InsertItem(0, "server ip");
	list->SetItemText(0, 1, recver->addr_info()->ip_str());

	list->InsertItem(0, "server host");
	list->SetItemText(0, 1, recver->addr_info()->host());

	list->InsertItem(0, "file size");
	_ui_size_to_str(subs->ifile()->sz(), str);
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "file path");
	list->SetItemText(0, 1, subs->ifile()->path());

	list->InsertItem(0, "file name");
	list->SetItemText(0, 1, subs->ifile()->name());

	list->InsertItem(0, "port");
	list->SetItemText(0, 1, subs->iaddr()->port_str());

	list->InsertItem(0, "ip");
	list->SetItemText(0, 1, subs->iaddr()->ip_str());

	list->InsertItem(0, "host");
	list->SetItemText(0, 1, subs->iaddr()->host());

	return 0;
}


int cdm_ui::_updt_recver_info(cdm_frecv_subs *const subs, const int ch_mask) {
	CString str;

	cdm_frecver *recver = subs->parent();

	if (0 != (FSUBS_CH_PROGRESS & ch_mask)) {
		// list->InsertItem(0, "time elapse");
		_ui_time_str(subs->up_time(), str);
		list->SetItemText(13, 1, str);
		// list->InsertItem(0, "time remains");
		_ui_remtime_str(subs->up_time(), subs->total_parts(), subs->done_parts(), str);
		list->SetItemText(12, 1, str);
		// list->InsertItem(0, "finished");
		_ui_percent_str(subs->total_parts(), subs->done_parts(), str);
		list->SetItemText(11, 1, str);
	}

	if (0 != (FSUBS_CH_STATE & ch_mask)) {
		//	list->InsertItem(0, "status");
		_load_str(str, subs->ext_state());
		list->SetItemText(10, 1, str);
		//list->InsertItem(0, "state");
		_load_str(str, subs->state());
		list->SetItemText(9, 1, str);

		_ui_set_recver_btns(subs);
	}

	if (0 != (FSUBS_CH_PARENT & ch_mask)) {
		// list->InsertItem(0, "server port");
		list->SetItemText(8, 1, recver->addr_info()->port_str());
		// list->InsertItem(0, "server ip");
		list->SetItemText(7, 1, recver->addr_info()->ip_str());
		// list->InsertItem(0, "server host");
		list->SetItemText(6, 1, recver->addr_info()->host());
	}

	if (0 != (FSUBS_CH_IFILE & ch_mask)) {
		// list->InsertItem(0, "file size");
		_ui_size_to_str(subs->ifile()->sz(), str);
		list->SetItemText(5, 1, str);
		// list->InsertItem(0, "file path");
		list->SetItemText(4, 1, subs->ifile()->path());
		// list->InsertItem(0, "file name");
		list->SetItemText(3, 1, subs->ifile()->name());
	}

	if (0 != (FSUBS_CH_IADDR & ch_mask)) {
		//list->InsertItem(0, "port");
		list->SetItemText(2, 1, subs->iaddr()->port_str());
		// list->InsertItem(0, "ip");
		list->SetItemText(1, 1, subs->iaddr()->ip_str());
		// list->InsertItem(0, "host");
		list->SetItemText(0, 1, subs->iaddr()->host());
	}

	return 0;
}


int cdm_ui::_show_senders_info(sdm_ti_data *const data) {
	_ui_set_sender_btns(NULL);
	_clear_list();

	return 0;
}


int cdm_ui::_show_sender_info(cdm_fsender *const sender) {
	_ui_set_sender_btns(sender);
	_clear_list();

	CString str;

	list->InsertItem(0, "time elapse");
	_ui_time_str(sender->up_time(), str);
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "time remains");
	_ui_remtime_str(sender->up_time(), sender->total_parts(), sender->done_parts(), str);
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "finished");
	_ui_percent_str(sender->total_parts(), sender->done_parts(), str);
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "status");
	_load_str(str, sender->ext_state());
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "state");
	_load_str(str, sender->state());
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "file size");
	_ui_size_to_str(sender->ifile()->sz(), str);
	list->SetItemText(0, 1, str);

	list->InsertItem(0, "file path");
	list->SetItemText(0, 1, sender->ifile()->path());

	list->InsertItem(0, "file name");
	list->SetItemText(0, 1, sender->ifile()->name());

	list->InsertItem(0, "port");
	list->SetItemText(0, 1, sender->addr_info()->port_str());

	list->InsertItem(0, "ip");
	list->SetItemText(0, 1, sender->addr_info()->ip_str());

	list->InsertItem(0, "host");
	list->SetItemText(0, 1, sender->addr_info()->host());

	return 0;
}


int cdm_ui::_updt_sender_info(cdm_fsender *const sender, const int ch_mask) {
	CString str;

	if (0 != (FSENDER_CH_PROGRESS & ch_mask)) {
		// list->InsertItem(0, "time elapse");
		_ui_time_str(sender->up_time(), str);
		list->SetItemText(10, 1, str);
		// list->InsertItem(0, "time remains");
		_ui_remtime_str(sender->up_time(), sender->total_parts(), sender->done_parts(), str);
		list->SetItemText(9, 1, str);
		// list->InsertItem(0, "finished");
		_ui_percent_str(sender->total_parts(), sender->done_parts(), str);
		list->SetItemText(8, 1, str);
	}

	if (0 != (FSENDER_CH_STATE & ch_mask)) {
		// list->InsertItem(0, "status");
		_load_str(str, sender->ext_state());
		list->SetItemText(7, 1, str);
		// list->InsertItem(0, "state");
		_load_str(str, sender->state());
		list->SetItemText(6, 1, str);

		_ui_set_sender_btns(sender);
	}

	if (0 != (FSENDER_CH_IFILE & ch_mask)) {
		// list->InsertItem(0, "file size");
		_ui_size_to_str(sender->ifile()->sz(), str);
		list->SetItemText(5, 1, str);
		// list->InsertItem(0, "file path");
		list->SetItemText(4, 1, sender->ifile()->path());
		// list->InsertItem(0, "file name");
		list->SetItemText(3, 1, sender->ifile()->name());
	}

	if (0 != (FSENDER_CH_IADDR & ch_mask)) {
		// list->InsertItem(0, "port");
		list->SetItemText(2, 1, sender->addr_info()->port_str());
		// list->InsertItem(0, "ip");
		list->SetItemText(1, 1, sender->addr_info()->ip_str());
		// list->InsertItem(0, "host");
		list->SetItemText(0, 1, sender->addr_info()->host());
	}

	return 0;
}


int cdm_ui::_tree_add_server(cdm_frecver *const recver) {
	CString cap;
	cap.Format("%s:%s", recver->addr_info()->host(), recver->addr_info()->port_str());
	HTREEITEM item = tree->InsertItem(cap, _tr_servers);
	recver->set_ui_data(item);

	sdm_ti_data *data = new sdm_ti_data;
	data->objt = OBJT_SERVER;
	data->obj = recver;
	tree->SetItemData(item, (DWORD_PTR)data);

	tree->Select(item, TVGN_FIRSTVISIBLE);
	tree->Select(item, TVGN_CARET);
	_ti_active = item;

	return 0;
}


int cdm_ui::_tree_add_recver(cdm_frecv_subs *const subs) {
	CString cap;
	cap.Format("%s:%s", subs->iaddr()->host(), subs->iaddr()->port_str());
	HTREEITEM item = tree->InsertItem(cap, _tr_recvers);
	subs->set_ui_data(item);

	sdm_ti_data *data = new sdm_ti_data;
	data->objt = OBJT_RECVER;
	data->obj = subs;
	tree->SetItemData(item, (DWORD_PTR)data);

	tree->Select(item, TVGN_FIRSTVISIBLE);
	tree->Select(item, TVGN_CARET);
	_ti_active = item;

	return 0;
}


int cdm_ui::_tree_add_sender(cdm_fsender *const sender) {
	CString cap;
	cap.Format("%s:%s", sender->addr_info()->host(), sender->addr_info()->port_str());
	HTREEITEM item = tree->InsertItem(cap, _tr_senders);
	sender->set_ui_data(item);

	sdm_ti_data *data = new sdm_ti_data;
	data->objt = OBJT_SENDER;
	data->obj = sender;
	tree->SetItemData(item, (DWORD_PTR)data);

	tree->Select(item, TVGN_FIRSTVISIBLE);
	tree->Select(item, TVGN_CARET);
	_ti_active = item;

	// tree->RedrawWindow();
	
	// _show_serv_info(frecver);

	return 0;
}


int cdm_ui::_run_cool_stuff() {
	if (NULL != _cool_stuff_thread_h) return -1;

	_cool_stuff_mtx = CreateMutex(NULL, FALSE, NULL);
	if (NULL == _cool_stuff_mtx) return -1;

	_cool_stuff_stop_flag = false;
	_cool_stuff_thread_h = CreateThread(NULL, 0,
		(LPTHREAD_START_ROUTINE)_cool_stuff, this, 0,
		&_cool_stuff_thread_id
	);
	if (NULL == _cool_stuff_thread_h) {
		CloseHandle(_cool_stuff_mtx);
		return -1;
	}
	

	return 0;
}


int cdm_ui::_stop_cool_stuff() {
	if (NULL == _cool_stuff_thread_h) return -1;

	_cool_stuff_stop_flag = true;
	DWORD rev = WaitForSingleObject(_cool_stuff_mtx, _cool_stuff_timeout);
	if (WAIT_TIMEOUT == rev) {
		TerminateThread(_cool_stuff_thread_h, -1);
		CloseHandle(_cool_stuff_mtx);
		return -1;
	}

	return 0;
}


DWORD cdm_ui::_cool_stuff(cdm_ui *mwnd) {
	int _wnd_x = 175, _wnd_y = 423;
	int _wnd_w = 287, _wnd_h = 49;

	int _point_x = 0;
	int _point_y = 0;

	DWORD rev = WaitForSingleObject(mwnd->_cool_stuff_mtx, _cool_stuff_timeout);
	if (WAIT_TIMEOUT == rev) return -1;

	CDC *mdc = mwnd->GetDC();
	HDC buf_dc = CreateCompatibleDC(mdc->GetSafeHdc());

	BITMAPINFO ibmp;
	ibmp.bmiHeader.biSize = sizeof(ibmp.bmiHeader);
	ibmp.bmiHeader.biWidth = _wnd_w;
	ibmp.bmiHeader.biHeight = _wnd_h;
	ibmp.bmiHeader.biPlanes = 1;
	ibmp.bmiHeader.biBitCount = 32;
	ibmp.bmiHeader.biCompression = BI_RGB;
	ibmp.bmiHeader.biSizeImage = 0;
	ibmp.bmiHeader.biXPelsPerMeter = 0;
	ibmp.bmiHeader.biYPelsPerMeter = 0;
	ibmp.bmiHeader.biClrUsed = 0;
	ibmp.bmiHeader.biClrImportant = 0;
	RGBQUAD *pixels;
	HBITMAP buf_bmp = CreateDIBSection(buf_dc, &ibmp,
		DIB_RGB_COLORS, (void **)&pixels, NULL, 0);
	HBITMAP old_bmp = (HBITMAP)SelectObject(buf_dc, buf_bmp);

	HPEN hpen = CreatePen(PS_SOLID, 1, RGB(0,0,0xFF));
	HBRUSH hbrush = CreateSolidBrush(RGB(0,0,0xFF));
	HFONT hfont = CreateFont(30, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, RUSSIAN_CHARSET,
		OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, "Courier New");
	SetBkColor(buf_dc, RGB(0, 0, 0));
	SetTextColor(buf_dc, RGB(0, 0, 0xFF));
	SelectObject(buf_dc, hpen);
	SelectObject(buf_dc, hbrush);
	SelectObject(buf_dc, hfont);

	POINT mp;
	int x = 0, y = 0;

	RGBQUAD *ts = (RGBQUAD *)malloc(_wnd_w*_wnd_h * sizeof(RGBQUAD));
	for (int i = 0; i < _wnd_w*_wnd_h; ++i) ((int *)pixels)[i] = 0;
	for (int i = 0; i < _wnd_w*_wnd_h; ++i) ((int *)ts)[i] = 0;

	while (!mwnd->_cool_stuff_stop_flag) {
		GetCursorPos(&mp);
		mwnd->ScreenToClient(&mp);
		mp.x -= _wnd_x; mp.y -= _wnd_y;
		if (mp.x > 0 && mp.x < _wnd_w && mp.y > 0 && mp.y < _wnd_h) {
			x = mp.x; y = mp.y;
			Ellipse(buf_dc, x-4, y-4, x+4, y+4);
		}

		for (int i = _wnd_w-2; i > 0; --i) {
			for (int j = _wnd_h-2; j > 0; --j) {
				ts[i + _wnd_w*j].rgbBlue = 
					pixels[i+0 + _wnd_w*(j+0)].rgbBlue * 6/256 +
					pixels[i+1 + _wnd_w*(j+0)].rgbBlue * 63/256 +
					pixels[i-1 + _wnd_w*(j+0)].rgbBlue * 63/256 +
					pixels[i+0 + _wnd_w*(j+1)].rgbBlue * 63/256 +
					pixels[i+0 + _wnd_w*(j-1)].rgbBlue * 63/256 ;
			}
		}

		for (int i = 0; i < _wnd_w*_wnd_h; ++i) {
			pixels[i].rgbBlue = (pixels[i].rgbBlue + ts[i].rgbBlue) / 2;
			pixels[i].rgbGreen = 0;
			pixels[i].rgbRed = 0;
		}


		if (_point_x >= _wnd_w) {
			_point_x = 0;
			char *str = "NetBeat";
			TextOut(buf_dc, 75, 10, str, (int)strlen(str));
		} else _point_x += 1;

		_point_y += (rand()-RAND_MAX/2)*mwnd->_core->speeed() % 10;
		
		int th = _wnd_h/2 + _point_y % _wnd_h/2;

		mwnd->_core->reset_speeed();
		Ellipse(buf_dc, _point_x-2, th-2, _point_x+2, th+2);
		th = -(th-_wnd_h/2) + _wnd_h/2;
		Ellipse(buf_dc, _point_x-2, th-2, _point_x+2, th+2);

		BitBlt(mdc->GetSafeHdc(), _wnd_x, _wnd_y, _wnd_w, _wnd_h, buf_dc, 0, 0, SRCCOPY);
		Sleep(50);
	}

	SelectObject(buf_dc, old_bmp);
	DeleteDC(buf_dc);
	DeleteObject(buf_bmp);
	mwnd->ReleaseDC(mdc);

	ReleaseMutex(mwnd->_cool_stuff_mtx);
	return 0;
}


int cdm_ui::_load_str(CString &str, const int rid) {
	int rev = str.LoadString( (rid >= 0)? rid: -rid ); 
	if (0 == rev) {
		str.Format("[rid %i failed]", rid);
		return -1;
	}

	return 0;
}


int cdm_ui::_get_os_error_str(CString &str, const int ercode) {
	char *os_msg;
	int rev = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|
				  FORMAT_MESSAGE_ALLOCATE_BUFFER|
				  FORMAT_MESSAGE_ARGUMENT_ARRAY,
				  NULL, ercode, 0, (LPSTR)&os_msg, 0, NULL);
	if (0 == rev) return -1;
	str.Format("%s", os_msg);
	LocalFree(os_msg);

	return 0;
}



}	// end of namespace "dm_ui"
Соседние файлы в папке main