Exemplo n.º 1
0
int main()
{
    g_type_init();

    Samoyed::Scheduler scheduler(2);

    char *pwd = g_get_current_dir();

    std::string fileName1(pwd);
    fileName1 += G_DIR_SEPARATOR_S "text-file-saver-test.GBK";
    char *uri1 = g_filename_to_uri(fileName1.c_str(), NULL, NULL);
    if (!uri1)
    {
        printf("File name to URI conversion error.\n");
        return -1;
    }
    boost::shared_ptr<char> textUtf8(g_strdup(TEXT_UTF8), g_free);
    boost::shared_ptr<Samoyed::TextFileSaver> saver1(
        new Samoyed::TextFileSaver(scheduler, 1, uri1, textUtf8, -1,
                                   "GBK"));
    saver1->addFinishedCallback(onDone);
    saver1->addCanceledCallback(onDone);
    g_free(uri1);

    std::string fileName2(pwd);
    fileName2 += G_DIR_SEPARATOR_S "text-file-saver-test.UTF-8";
    char *uri2 = g_filename_to_uri(fileName2.c_str(), NULL, NULL);
    if (!uri2)
    {
        printf("File name to URI conversion error.\n");
        return -1;
    }
    boost::shared_ptr<Samoyed::TextFileSaver> saver2(
        new Samoyed::TextFileSaver(scheduler, 1, uri2, textUtf8, -1,
                                   "UTF-8"));
    saver2->addFinishedCallback(onDone);
    saver2->addCanceledCallback(onDone);
    g_free(uri2);

    saver1->submit(saver1);
    saver2->submit(saver2);
    scheduler.wait();

    g_free(pwd);
    return 0;
}
CTimerControlRepeaterPanel::CTimerControlRepeaterPanel(wxWindow* parent, int id, const wxString& callsign) :
wxPanel(parent, id),
m_callsign(callsign),
m_list(NULL),
m_day(NULL),
m_hour(NULL),
m_minute(NULL),
m_reflector(NULL),
m_channel(NULL),
m_reconnect(NULL),
m_item(NULL),
m_n(0)
{
	wxBoxSizer* sizer1 = new wxBoxSizer(wxHORIZONTAL);

	m_list = new wxListCtrl(this, List_Select, wxDefaultPosition, wxSize(LIST_WIDTH, LIST_HEIGHT), wxLC_REPORT | wxLC_SINGLE_SEL);
	m_list->InsertColumn(0L, _("Day"));
	m_list->SetColumnWidth(0L, DAY_WIDTH);
	m_list->InsertColumn(1L, _("Time"));
	m_list->SetColumnWidth(1L, TIME_WIDTH);
	m_list->InsertColumn(2L, _("Type"));
	m_list->SetColumnWidth(2L, TYPE_WIDTH);
	m_list->InsertColumn(3L, _("Reflector"));
	m_list->SetColumnWidth(3L, REFLECTOR_WIDTH);
	sizer1->Add(m_list, 0, wxTOP | wxBOTTOM | wxLEFT | wxEXPAND, BORDER_SIZE);

	wxBoxSizer* sizer2 = new wxBoxSizer(wxVERTICAL);

	m_day = new wxChoice(this, -1, wxDefaultPosition, wxSize(DAY_WIDTH, -1));
	m_day->Append(_("Sunday"));
	m_day->Append(_("Monday"));
	m_day->Append(_("Tuesday"));
	m_day->Append(_("Wednesday"));
	m_day->Append(_("Thursday"));
	m_day->Append(_("Friday"));
	m_day->Append(_("Saturday"));
	m_day->Append(_("Every day"));
	m_day->Append(_("Mon-Fri"));
	m_day->Append(_("Sat-Sun"));
	sizer2->Add(m_day, 0, wxALL, BORDER_SIZE);
	m_day->SetSelection(0);

	wxBoxSizer* sizer2a = new wxBoxSizer(wxHORIZONTAL);

	m_hour = new wxChoice(this, -1, wxDefaultPosition, wxSize(HOUR_WIDTH, -1));
	m_hour->Append(wxT("00"));
	m_hour->Append(wxT("01"));
	m_hour->Append(wxT("02"));
	m_hour->Append(wxT("03"));
	m_hour->Append(wxT("04"));
	m_hour->Append(wxT("05"));
	m_hour->Append(wxT("06"));
	m_hour->Append(wxT("07"));
	m_hour->Append(wxT("08"));
	m_hour->Append(wxT("09"));
	m_hour->Append(wxT("10"));
	m_hour->Append(wxT("11"));
	m_hour->Append(wxT("12"));
	m_hour->Append(wxT("13"));
	m_hour->Append(wxT("14"));
	m_hour->Append(wxT("15"));
	m_hour->Append(wxT("16"));
	m_hour->Append(wxT("17"));
	m_hour->Append(wxT("18"));
	m_hour->Append(wxT("19"));
	m_hour->Append(wxT("20"));
	m_hour->Append(wxT("21"));
	m_hour->Append(wxT("22"));
	m_hour->Append(wxT("23"));
	sizer2a->Add(m_hour, 0, wxALL, BORDER_SIZE);
	m_hour->SetSelection(0);

	wxStaticText* dummy1Label = new wxStaticText(this, -1, wxT(":"));
	sizer2a->Add(dummy1Label, 0, wxALL, BORDER_SIZE);

	m_minute = new wxChoice(this, -1, wxDefaultPosition, wxSize(MINUTE_WIDTH, -1));
	m_minute->Append(wxT("00"));
	m_minute->Append(wxT("05"));
	m_minute->Append(wxT("10"));
	m_minute->Append(wxT("15"));
	m_minute->Append(wxT("20"));
	m_minute->Append(wxT("25"));
	m_minute->Append(wxT("30"));
	m_minute->Append(wxT("35"));
	m_minute->Append(wxT("40"));
	m_minute->Append(wxT("45"));
	m_minute->Append(wxT("50"));
	m_minute->Append(wxT("55"));
	sizer2a->Add(m_minute, 0, wxALL, BORDER_SIZE);
	m_minute->SetSelection(0);

	sizer2->Add(sizer2a);

	wxStaticText* dummy2Label = new wxStaticText(this, -1, wxEmptyString);
	sizer2->Add(dummy2Label, 0, wxALL, BORDER_SIZE);

	wxBoxSizer* sizer3 = new wxBoxSizer(wxHORIZONTAL);

	m_reflector = new wxChoice(this, -1, wxDefaultPosition, wxSize(REFLECTOR_WIDTH, -1));
	m_reflector->Append(_("None"));

	wxFileName fileName1(wxFileName::GetHomeDir(), DPLUS_HOSTS_FILE_NAME);
	if (fileName1.IsFileReadable()) {
		CHostFile file(fileName1.GetFullPath(), false);

		for (unsigned int i = 0U; i < file.getCount(); i++)
			m_reflector->Append(file.getName(i).Trim());
	}

#if defined(__WINDOWS__)
	wxFileName fileName4(::wxGetCwd(), DPLUS_HOSTS_FILE_NAME);
#else
	wxFileName fileName4(wxT(DATA_DIR), DPLUS_HOSTS_FILE_NAME);
#endif
	if (fileName4.IsFileReadable()) {
		CHostFile file(fileName4.GetFullPath(), false);

		for (unsigned int i = 0U; i < file.getCount(); i++) {
			wxString name = file.getName(i).Trim();
			if (m_reflector->FindString(name) == wxNOT_FOUND)
				m_reflector->Append(name);
		}
	}

	wxFileName fileName2(wxFileName::GetHomeDir(), DEXTRA_HOSTS_FILE_NAME);
	if (fileName2.IsFileReadable()) {
		CHostFile file(fileName2.GetFullPath(), false);

		for (unsigned int i = 0U; i < file.getCount(); i++)
			m_reflector->Append(file.getName(i).Trim());
	}

#if defined(__WINDOWS__)
	wxFileName fileName5(::wxGetCwd(), DEXTRA_HOSTS_FILE_NAME);
#else
	wxFileName fileName5(wxT(DATA_DIR), DEXTRA_HOSTS_FILE_NAME);
#endif
	if (fileName5.IsFileReadable()) {
		CHostFile file(fileName5.GetFullPath(), false);

		for (unsigned int i = 0U; i < file.getCount(); i++) {
			wxString name = file.getName(i).Trim();
			if (m_reflector->FindString(name) == wxNOT_FOUND)
				m_reflector->Append(name);
		}
	}

	wxFileName fileName3(wxFileName::GetHomeDir(), DCS_HOSTS_FILE_NAME);
	if (fileName3.IsFileReadable()) {
		CHostFile file(fileName3.GetFullPath(), false);

		for (unsigned int i = 0U; i < file.getCount(); i++)
			m_reflector->Append(file.getName(i).Trim());
	}

#if defined(__WINDOWS__)
	wxFileName fileName6(::wxGetCwd(), DCS_HOSTS_FILE_NAME);
#else
	wxFileName fileName6(wxT(DATA_DIR), DCS_HOSTS_FILE_NAME);
#endif
	if (fileName6.IsFileReadable()) {
		CHostFile file(fileName6.GetFullPath(), false);

		for (unsigned int i = 0U; i < file.getCount(); i++) {
			wxString name = file.getName(i).Trim();
			if (m_reflector->FindString(name) == wxNOT_FOUND)
				m_reflector->Append(name);
		}
	}

	sizer3->Add(m_reflector, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);
	m_reflector->SetSelection(0);

	m_channel = new wxChoice(this, -1, wxDefaultPosition, wxSize(CHANNEL_WIDTH, -1));
	m_channel->Append(wxT("A"));
	m_channel->Append(wxT("B"));
	m_channel->Append(wxT("C"));
	m_channel->Append(wxT("D"));
	m_channel->Append(wxT("E"));
	m_channel->Append(wxT("F"));
	m_channel->Append(wxT("G"));
	m_channel->Append(wxT("H"));
	m_channel->Append(wxT("I"));
	m_channel->Append(wxT("J"));
	m_channel->Append(wxT("K"));
	m_channel->Append(wxT("L"));
	m_channel->Append(wxT("M"));
	m_channel->Append(wxT("N"));
	m_channel->Append(wxT("O"));
	m_channel->Append(wxT("P"));
	m_channel->Append(wxT("Q"));
	m_channel->Append(wxT("R"));
	m_channel->Append(wxT("S"));
	m_channel->Append(wxT("T"));
	m_channel->Append(wxT("U"));
	m_channel->Append(wxT("V"));
	m_channel->Append(wxT("W"));
	m_channel->Append(wxT("X"));
	m_channel->Append(wxT("Y"));
	m_channel->Append(wxT("Z"));
	sizer3->Add(m_channel, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);
	m_channel->SetSelection(0);

	sizer2->Add(sizer3);

	m_reconnect = new wxChoice(this, -1, wxDefaultPosition, wxSize(RECONNECT_WIDTH, -1));
	m_reconnect->Append(_("Never"));
	m_reconnect->Append(_("Fixed"));
	m_reconnect->Append(_("5 minutes"));
	m_reconnect->Append(_("10 minutes"));
	m_reconnect->Append(_("15 minutes"));
	m_reconnect->Append(_("20 minutes"));
	m_reconnect->Append(_("25 minutes"));
	m_reconnect->Append(_("30 minutes"));
	m_reconnect->Append(_("60 minutes"));
	m_reconnect->Append(_("90 minutes"));
	m_reconnect->Append(_("120 minutes"));
	m_reconnect->Append(_("180 minutes"));
	sizer2->Add(m_reconnect, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);
	m_reconnect->SetSelection(0);

	wxStaticText* dummy3Label = new wxStaticText(this, -1, wxEmptyString);
	sizer2->Add(dummy3Label, 0, wxALL, BORDER_SIZE);

	wxButton* addButton = new wxButton(this, Button_Add, _("Add"), wxDefaultPosition, wxSize(BUTTON_WIDTH, -1));
	sizer2->Add(addButton, 0, wxALL, BORDER_SIZE);

	wxButton* modButton = new wxButton(this, Button_Modify, _("Modify"), wxDefaultPosition, wxSize(BUTTON_WIDTH, -1));
	sizer2->Add(modButton, 0, wxALL, BORDER_SIZE);

	wxButton* delButton = new wxButton(this, Button_Delete, _("Delete"), wxDefaultPosition, wxSize(BUTTON_WIDTH, -1));
	sizer2->Add(delButton, 0, wxALL, BORDER_SIZE);

	sizer1->Add(sizer2);

	SetAutoLayout(true);

	SetSizer(sizer1);
}
Exemplo n.º 3
0
void CIRCDDBGatewayThread::run()
{
	// Truncate the old Links.log file
	wxString fullName = LINKS_BASE_NAME;

	if (!m_name.IsEmpty()) {
		fullName.Append(wxT("_"));
		fullName.Append(m_name);
	}

	wxFileName fileName1(m_logDir, fullName, wxT("log"));
	wxLogMessage(wxT("Truncating %s"), fileName1.GetFullPath().c_str());

	wxFFile file;
	bool ret = file.Open(fileName1.GetFullPath(), wxT("wt"));
	if (ret)
		file.Close();

	// Truncate the old StarNet.log file
	fullName = STARNET_BASE_NAME;

	if (!m_name.IsEmpty()) {
		fullName.Append(wxT("_"));
		fullName.Append(m_name);
	}

	wxFileName fileName2(m_logDir, fullName, wxT("log"));
	wxLogMessage(wxT("Truncating %s"), fileName2.GetFullPath().c_str());

	ret = file.Open(fileName2.GetFullPath(), wxT("wt"));
	if (ret)
		file.Close();

	wxString dextraAddress = m_dextraEnabled ? m_gatewayAddress : LOOPBACK_ADDRESS;
	m_dextraPool = new CDExtraProtocolHandlerPool(MAX_OUTGOING + 1U, DEXTRA_PORT, dextraAddress);
	ret = m_dextraPool->open();
	if (!ret) {
		wxLogError(wxT("Could not open the DExtra protocol pool"));
		delete m_dextraPool;
		m_dextraPool = NULL;
	} else {
		// Allocate the incoming port
		CDExtraProtocolHandler* handler = m_dextraPool->getHandler(DEXTRA_PORT);
		CDExtraHandler::setDExtraProtocolIncoming(handler);
		CDExtraHandler::setDExtraProtocolHandlerPool(m_dextraPool);
	}

	wxString dplusAddress = m_dplusEnabled ? m_gatewayAddress : LOOPBACK_ADDRESS;
	m_dplusPool = new CDPlusProtocolHandlerPool(MAX_OUTGOING + 1U, DPLUS_PORT, dplusAddress);
	ret = m_dplusPool->open();
	if (!ret) {
		wxLogError(wxT("Could not open the D-Plus protocol pool"));
		delete m_dplusPool;
		m_dplusPool = NULL;
	} else {
		// Allocate the incoming port
		CDPlusProtocolHandler* handler = m_dplusPool->getHandler(DPLUS_PORT);
		CDPlusHandler::setDPlusProtocolIncoming(handler);
		CDPlusHandler::setDPlusProtocolHandlerPool(m_dplusPool);
	}

	wxString dcsAddress = m_dcsEnabled ? m_gatewayAddress : LOOPBACK_ADDRESS;
	m_dcsPool = new CDCSProtocolHandlerPool(MAX_OUTGOING + 1U, DCS_PORT, dcsAddress);
	ret = m_dcsPool->open();
	if (!ret) {
		wxLogError(wxT("Could not open the DCS protocol pool"));
		delete m_dcsPool;
		m_dcsPool = NULL;
	} else {
		// Allocate the incoming port
		CDCSProtocolHandler* handler = m_dcsPool->getHandler(DCS_PORT);
		CDCSHandler::setDCSProtocolIncoming(handler);
		CDCSHandler::setDCSProtocolHandlerPool(m_dcsPool);
	}

	m_g2Handler = new CG2ProtocolHandler(G2_DV_PORT, m_gatewayAddress);
	ret = m_g2Handler->open();
	if (!ret) {
		wxLogError(wxT("Could not open the G2 protocol handler"));
		delete m_g2Handler;
		m_g2Handler = NULL;
	}

	// Wait here until we have the essentials to run
	while (!m_killed && (m_dextraPool == NULL || m_dplusPool == NULL || m_dcsPool == NULL || m_g2Handler == NULL || (m_icomRepeaterHandler == NULL && m_hbRepeaterHandler == NULL && m_dummyRepeaterHandler == NULL) || m_gatewayCallsign.IsEmpty()))
		::wxMilliSleep(500UL);		// 1/2 sec

	if (m_killed)
		return;

	m_stopped = false;

	wxLogMessage(wxT("Starting the ircDDB Gateway thread"));

	CHeaderLogger* headerLogger = NULL;
	if (m_logEnabled) {
		m_statusTimer1.start();

		headerLogger = new CHeaderLogger(m_logDir, m_name);
		bool ret = headerLogger->open();
		if (!ret) {
			delete headerLogger;
			headerLogger = NULL;
		}
	}

	loadGateways();
	loadReflectors();

	CG2Handler::setG2ProtocolHandler(m_g2Handler);
	CG2Handler::setHeaderLogger(headerLogger);

	CDExtraHandler::setCallsign(m_gatewayCallsign);
	CDExtraHandler::setHeaderLogger(headerLogger);
	CDExtraHandler::setMaxDongles(m_dextraMaxDongles);

	CDPlusHandler::setCallsign(m_gatewayCallsign);
	CDPlusHandler::setDPlusLogin(m_dplusLogin);
	CDPlusHandler::setHeaderLogger(headerLogger);
	CDPlusHandler::setMaxDongles(m_dplusMaxDongles);
	if (m_dplusEnabled)
		CDPlusHandler::startAuthenticator(m_gatewayAddress, &m_cache);

	CDCSHandler::setGatewayType(m_gatewayType);
	CDCSHandler::setHeaderLogger(headerLogger);

	CRepeaterHandler::setLocalAddress(m_gatewayAddress);
	CRepeaterHandler::setG2Handler(m_g2Handler);

	if (m_irc != NULL)
		CRepeaterHandler::setIRC(m_irc);

	CRepeaterHandler::setCache(&m_cache);
	CRepeaterHandler::setGateway(m_gatewayCallsign);
	CRepeaterHandler::setLanguage(m_language);
	CRepeaterHandler::setDExtraEnabled(m_dextraEnabled);
	CRepeaterHandler::setDPlusEnabled(m_dplusEnabled);
	CRepeaterHandler::setDCSEnabled(m_dcsEnabled);
	CRepeaterHandler::setHeaderLogger(headerLogger);
	CRepeaterHandler::setAPRSWriter(m_aprsWriter);
	CRepeaterHandler::setInfoEnabled(m_infoEnabled);
	CRepeaterHandler::setEchoEnabled(m_echoEnabled);
	CRepeaterHandler::setDTMFEnabled(m_dtmfEnabled);
	if (m_whiteList != NULL) {
		CDExtraHandler::setWhiteList(m_whiteList);
		CDPlusHandler::setWhiteList(m_whiteList);
		CDCSHandler::setWhiteList(m_whiteList);
	}
	if (m_blackList != NULL) {
		CDExtraHandler::setBlackList(m_blackList);
		CDPlusHandler::setBlackList(m_blackList);
		CDCSHandler::setBlackList(m_blackList);
	}
	if (m_restrictList != NULL)
		CRepeaterHandler::setRestrictList(m_restrictList);

	CAudioUnit::setLanguage(m_language);

	CStarNetHandler::setCache(&m_cache);
	CStarNetHandler::setGateway(m_gatewayCallsign);
	CStarNetHandler::setG2Handler(m_g2Handler);

	if (m_irc != NULL)
		CStarNetHandler::setIRC(m_irc);

	CStarNetHandler::setLogging(m_logEnabled, m_logDir);
#if defined(DEXTRA_LINK) || defined(DCS_LINK)
	CStarNetHandler::link();
#endif

	if (m_ddModeEnabled) {
		CDDHandler::initialise(MAX_DD_ROUTES, m_name);
		CDDHandler::setLogging(m_logEnabled, m_logDir);
		CDDHandler::setHeaderLogger(headerLogger);

		if (m_irc != NULL)
			CDDHandler::setIRC(m_irc);
	}

	wxString ccsAddress = m_ccsEnabled ? m_gatewayAddress : LOOPBACK_ADDRESS;
	CCCSHandler::setLocalAddress(ccsAddress);
	CCCSHandler::setHeaderLogger(headerLogger);
	CCCSHandler::setHost(m_ccsHost);

	// If no ircDDB then APRS is started immediately
	if (m_aprsWriter != NULL && m_irc == NULL)
		m_aprsWriter->setEnabled(true);

	if (m_remoteEnabled && !m_remotePassword.IsEmpty() && m_remotePort > 0U) {
		m_remote = new CRemoteHandler(m_remotePassword, m_remotePort, m_gatewayAddress);
		bool res = m_remote->open();
		if (!res) {
			delete m_remote;
			m_remote = NULL;
		}
	}

	CRepeaterHandler::startup();

	m_statusFileTimer.start();

	CCallsignServer* server = NULL;
	if (m_dextraEnabled || m_dcsEnabled) {
		server = new CCallsignServer(m_gatewayCallsign, m_gatewayAddress, &m_cache);
		server->start();
	}

	wxStopWatch stopWatch;
	stopWatch.Start();

	m_statusTimer2.start();

	try {
		while (!m_killed) {
			if (m_icomRepeaterHandler != NULL)
				processRepeater(m_icomRepeaterHandler);

			if (m_hbRepeaterHandler != NULL)
				processRepeater(m_hbRepeaterHandler);

			if (m_dummyRepeaterHandler != NULL)
				processRepeater(m_dummyRepeaterHandler);

			if (m_irc != NULL)
				processIrcDDB();

			processDExtra();
			processDPlus();
			processDCS();
			processG2();
			CCCSHandler::process();

			if (m_ddModeEnabled)
				processDD();

			if (m_remote != NULL)
				m_remote->process();

			unsigned long ms = stopWatch.Time();
			stopWatch.Start();

			CRepeaterHandler::clock(ms);
			CG2Handler::clock(ms);
			CDExtraHandler::clock(ms);
			CDPlusHandler::clock(ms);
			CDCSHandler::clock(ms);
			CStarNetHandler::clock(ms);
			CDDHandler::clock(ms);
	 		CCCSHandler::clock(ms);

			m_statusTimer2.clock(ms);

			m_statusFileTimer.clock(ms);
			if (m_statusFileTimer.hasExpired()) {
				readStatusFiles();
				m_statusFileTimer.start();
			}

			if (m_aprsWriter != NULL)
				m_aprsWriter->clock(ms);

			if (m_logEnabled) {
				m_statusTimer1.clock(ms);
				if (m_statusTimer1.hasExpired()) {
					bool ret1 = CDExtraHandler::stateChange();
					bool ret2 = CDPlusHandler::stateChange();
					bool ret3 = CDCSHandler::stateChange();
					bool ret4 = CCCSHandler::stateChange();
					if (ret1 || ret2 || ret3 || ret4)
						writeStatus();
		
					m_statusTimer1.start();
				}
			}

			::wxMilliSleep(TIME_PER_TIC_MS);
		}
	}
	catch (std::exception& e) {
		wxString message(e.what(), wxConvLocal);
		wxLogError(wxT("Exception raised in the main thread - \"%s\""), message.c_str());
	}
	catch (...) {
		wxLogError(wxT("Unknown exception raised in the main thread"));
	}

	wxLogMessage(wxT("Stopping the ircDDB Gateway thread"));

	// Unlink from all reflectors
	CDExtraHandler::unlink();
	CDPlusHandler::unlink();
	CDCSHandler::unlink();
	CCCSHandler::disconnect();

	if (m_ddModeEnabled)
		CDDHandler::finalise();

	if (server != NULL)
		server->stop();

	m_dextraPool->close();
	delete m_dextraPool;

	m_dplusPool->close();
	delete m_dplusPool;

	m_dcsPool->close();
	delete m_dcsPool;

	m_g2Handler->close();
	delete m_g2Handler;

	if (m_irc != NULL) {
		m_irc->close();
		delete m_irc;
	}

	if (m_icomRepeaterHandler != NULL) {
		m_icomRepeaterHandler->close();
		delete m_icomRepeaterHandler;
	}

	if (m_hbRepeaterHandler != NULL) {
		m_hbRepeaterHandler->close();
		delete m_hbRepeaterHandler;
	}

	if (m_dummyRepeaterHandler != NULL) {
		m_dummyRepeaterHandler->close();
		delete m_dummyRepeaterHandler;
	}

	if (m_remote != NULL) {
		m_remote->close();
		delete m_remote;
	}

	if (headerLogger != NULL) {
		headerLogger->close();
		delete headerLogger;
	}
}
CRemoteControlRepeaterPanel::CRemoteControlRepeaterPanel(wxWindow* parent, int id, const wxString& callsign) :
wxPanel(parent, id),
m_callsign(callsign),
m_list(NULL),
m_reflector(NULL),
m_channel(NULL),
m_reconnect(NULL),
m_unlink(NULL),
m_selected(-1),
m_reflectors(),
m_protocols()
{
	wxBoxSizer* sizer1 = new wxBoxSizer(wxHORIZONTAL);

	m_list = new wxListCtrl(this, List_Reflectors, wxDefaultPosition, wxSize(LIST_WIDTH, LIST_HEIGHT), wxLC_REPORT | wxLC_SINGLE_SEL);
	m_list->InsertColumn(0L, _("Callsign"));
	m_list->SetColumnWidth(0L, CALLSIGN_WIDTH);
	m_list->InsertColumn(1L, _("Protocol"));
	m_list->SetColumnWidth(1L, PROTOCOL_WIDTH);
	m_list->InsertColumn(2L, _("Direction"));
	m_list->SetColumnWidth(2L, DIRECTION_WIDTH);
	m_list->InsertColumn(3L, _("Type"));
	m_list->SetColumnWidth(3L, TYPE_WIDTH);
	m_list->InsertColumn(4L, _("State"));
	m_list->SetColumnWidth(4L, STATE_WIDTH);
	sizer1->Add(m_list, 0, wxTOP | wxBOTTOM | wxLEFT | wxEXPAND, BORDER_SIZE);

	wxBoxSizer* sizer2 = new wxBoxSizer(wxVERTICAL);

	wxButton* refreshButton = new wxButton(this, Button_Refresh, _("Refresh"), wxDefaultPosition, wxSize(BUTTON_WIDTH, -1));
	sizer2->Add(refreshButton, 0, wxALL, BORDER_SIZE);

	wxStaticText* dummy1Label = new wxStaticText(this, -1, wxEmptyString);
	sizer2->Add(dummy1Label, 0, wxALL, BORDER_SIZE);

	wxStaticText* dummy2Label = new wxStaticText(this, -1, wxEmptyString);
	sizer2->Add(dummy2Label, 0, wxALL, BORDER_SIZE);

	wxBoxSizer* sizer3 = new wxBoxSizer(wxHORIZONTAL);

	m_reflector = new wxChoice(this, -1, wxDefaultPosition, wxSize(REFLECTOR_WIDTH, -1));
	m_reflector->Append(_("None"));

	wxFileName fileName1(wxFileName::GetHomeDir(), DPLUS_HOSTS_FILE_NAME);
	if (fileName1.IsFileReadable()) {
		CHostFile file(fileName1.GetFullPath(), false);

		for (unsigned int i = 0U; i < file.getCount(); i++)
			m_reflector->Append(file.getName(i).Trim());
	}

#if defined(__WINDOWS__)
	wxFileName fileName4(::wxGetCwd(), DPLUS_HOSTS_FILE_NAME);
#else
	wxFileName fileName4(wxT(DATA_DIR), DPLUS_HOSTS_FILE_NAME);
#endif
	if (fileName4.IsFileReadable()) {
		CHostFile file(fileName4.GetFullPath(), false);

		for (unsigned int i = 0U; i < file.getCount(); i++) {
			wxString name = file.getName(i).Trim();
			if (m_reflector->FindString(name) == wxNOT_FOUND)
				m_reflector->Append(name);
		}
	}

	wxFileName fileName2(wxFileName::GetHomeDir(), DEXTRA_HOSTS_FILE_NAME);
	if (fileName2.IsFileReadable()) {
		CHostFile file(fileName2.GetFullPath(), false);

		for (unsigned int i = 0U; i < file.getCount(); i++)
			m_reflector->Append(file.getName(i).Trim());
	}

#if defined(__WINDOWS__)
	wxFileName fileName5(::wxGetCwd(), DEXTRA_HOSTS_FILE_NAME);
#else
	wxFileName fileName5(wxT(DATA_DIR), DEXTRA_HOSTS_FILE_NAME);
#endif
	if (fileName5.IsFileReadable()) {
		CHostFile file(fileName5.GetFullPath(), false);

		for (unsigned int i = 0U; i < file.getCount(); i++) {
			wxString name = file.getName(i).Trim();
			if (m_reflector->FindString(name) == wxNOT_FOUND)
				m_reflector->Append(name);
		}
	}

	wxFileName fileName3(wxFileName::GetHomeDir(), DCS_HOSTS_FILE_NAME);
	if (fileName3.IsFileReadable()) {
		CHostFile file(fileName3.GetFullPath(), false);

		for (unsigned int i = 0U; i < file.getCount(); i++)
			m_reflector->Append(file.getName(i).Trim());
	}

#if defined(__WINDOWS__)
	wxFileName fileName6(::wxGetCwd(), DCS_HOSTS_FILE_NAME);
#else
	wxFileName fileName6(wxT(DATA_DIR), DCS_HOSTS_FILE_NAME);
#endif
	if (fileName6.IsFileReadable()) {
		CHostFile file(fileName6.GetFullPath(), false);

		for (unsigned int i = 0U; i < file.getCount(); i++) {
			wxString name = file.getName(i).Trim();
			if (m_reflector->FindString(name) == wxNOT_FOUND)
				m_reflector->Append(name);
		}
	}

	sizer3->Add(m_reflector, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);
	m_reflector->SetSelection(0);

	m_channel = new wxChoice(this, -1, wxDefaultPosition, wxSize(CHANNEL_WIDTH, -1));
	m_channel->Append(wxT("A"));
	m_channel->Append(wxT("B"));
	m_channel->Append(wxT("C"));
	m_channel->Append(wxT("D"));
	m_channel->Append(wxT("E"));
	m_channel->Append(wxT("F"));
	m_channel->Append(wxT("G"));
	m_channel->Append(wxT("H"));
	m_channel->Append(wxT("I"));
	m_channel->Append(wxT("J"));
	m_channel->Append(wxT("K"));
	m_channel->Append(wxT("L"));
	m_channel->Append(wxT("M"));
	m_channel->Append(wxT("N"));
	m_channel->Append(wxT("O"));
	m_channel->Append(wxT("P"));
	m_channel->Append(wxT("Q"));
	m_channel->Append(wxT("R"));
	m_channel->Append(wxT("S"));
	m_channel->Append(wxT("T"));
	m_channel->Append(wxT("U"));
	m_channel->Append(wxT("V"));
	m_channel->Append(wxT("W"));
	m_channel->Append(wxT("X"));
	m_channel->Append(wxT("Y"));
	m_channel->Append(wxT("Z"));
	sizer3->Add(m_channel, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);
	m_channel->SetSelection(0);

	sizer2->Add(sizer3);

	m_reconnect = new wxChoice(this, -1, wxDefaultPosition, wxSize(RECONNECT_WIDTH, -1));
	m_reconnect->Append(_("Never"));
	m_reconnect->Append(_("Fixed"));
	m_reconnect->Append(_("5 minutes"));
	m_reconnect->Append(_("10 minutes"));
	m_reconnect->Append(_("15 minutes"));
	m_reconnect->Append(_("20 minutes"));
	m_reconnect->Append(_("25 minutes"));
	m_reconnect->Append(_("30 minutes"));
	m_reconnect->Append(_("60 minutes"));
	m_reconnect->Append(_("90 minutes"));
	m_reconnect->Append(_("120 minutes"));
	m_reconnect->Append(_("180 minutes"));
	sizer2->Add(m_reconnect, 0, wxALL | wxALIGN_LEFT, BORDER_SIZE);
	m_reconnect->SetSelection(0);

	wxStaticText* dummy3Label = new wxStaticText(this, -1, wxEmptyString);
	sizer2->Add(dummy3Label, 0, wxALL, BORDER_SIZE);

	wxButton* linkButton = new wxButton(this, Button_Link, _("Link"), wxDefaultPosition, wxSize(BUTTON_WIDTH, -1));
	sizer2->Add(linkButton, 0, wxALL, BORDER_SIZE);

	m_unlink = new wxButton(this, Button_Unlink, _("Unlink"), wxDefaultPosition, wxSize(BUTTON_WIDTH, -1));
	sizer2->Add(m_unlink, 0, wxALL, BORDER_SIZE);
	m_unlink->Disable();

	sizer1->Add(sizer2);

	SetAutoLayout(true);

	SetSizer(sizer1);
}