ircDDBGateway/RemoteControl/RemoteControlRepeaterPanel.cpp
2018-05-09 19:23:17 +01:00

398 lines
12 KiB
C++

/*
* Copyright (C) 2011,2012,2013 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "RemoteControlRepeaterPanel.h"
#include "RemoteControlApp.h"
#include "DStarDefines.h"
#include "HostFile.h"
#include <wx/filename.h>
enum {
List_Reflectors = 7100,
Button_Refresh,
Button_Link,
Button_Unlink
};
BEGIN_EVENT_TABLE(CRemoteControlRepeaterPanel, wxPanel)
EVT_LIST_ITEM_SELECTED(List_Reflectors, CRemoteControlRepeaterPanel::onSelect)
EVT_BUTTON(Button_Refresh, CRemoteControlRepeaterPanel::onRefresh)
EVT_BUTTON(Button_Link, CRemoteControlRepeaterPanel::onLink)
EVT_BUTTON(Button_Unlink, CRemoteControlRepeaterPanel::onUnlink)
END_EVENT_TABLE()
#if defined(__WINDOWS__)
const unsigned int LIST_HEIGHT = 350U;
const unsigned int LIST_WIDTH = 350U;
const unsigned int CALLSIGN_WIDTH = 100U;
const unsigned int PROTOCOL_WIDTH = 55U;
const unsigned int DIRECTION_WIDTH = 55U;
const unsigned int TYPE_WIDTH = 65U;
const unsigned int STATE_WIDTH = 55U;
const unsigned int BUTTON_WIDTH = 75U;
const unsigned int REFLECTOR_WIDTH = 75U;
const unsigned int CHANNEL_WIDTH = 40U;
const unsigned int RECONNECT_WIDTH = 75U;
#else
const unsigned int LIST_HEIGHT = 350U;
const unsigned int LIST_WIDTH = 350U;
const unsigned int CALLSIGN_WIDTH = 100U;
const unsigned int PROTOCOL_WIDTH = 55U;
const unsigned int DIRECTION_WIDTH = 55U;
const unsigned int TYPE_WIDTH = 65U;
const unsigned int STATE_WIDTH = 55U;
const unsigned int BUTTON_WIDTH = 75U;
const unsigned int REFLECTOR_WIDTH = 90U;
const unsigned int CHANNEL_WIDTH = 50U;
const unsigned int RECONNECT_WIDTH = 100U;
#endif
const unsigned int BORDER_SIZE = 5U;
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);
}
CRemoteControlRepeaterPanel::~CRemoteControlRepeaterPanel()
{
}
void CRemoteControlRepeaterPanel::add(const CRemoteControlRepeaterData& data)
{
m_list->DeleteAllItems();
m_unlink->Disable();
m_reflectors.Clear();
m_protocols.Clear();
RECONNECT reconnect = data.getReconnect();
m_reconnect->SetSelection(int(reconnect));
wxString reflector = data.getReflector();
reflector.Append(wxT(" "));
reflector.Truncate(LONG_CALLSIGN_LENGTH);
bool res = m_channel->SetStringSelection(reflector.Right(1));
if (!res)
m_channel->SetSelection(0);
reflector.Truncate(LONG_CALLSIGN_LENGTH - 1U);
reflector.Append(wxT(" "));
res = m_reflector->SetStringSelection(reflector);
if (!res)
m_reflector->SetSelection(0);
unsigned int count = data.getLinkCount();
for (unsigned int i = 0U; i < count; i++) {
CRemoteControlLinkData& link = data.getLink(i);
wxString callsign = link.getCallsign();
PROTOCOL protocol = link.getProtocol();
bool isLinked = link.isLinked();
DIRECTION direction = link.getDirection();
bool isDongle = link.isDongle();
m_reflectors.Add(callsign);
m_protocols.Add(protocol);
m_list->InsertItem(0L, callsign);
// To allow for sorting
m_list->SetItemData(0L, long(protocol));
switch (protocol) {
case PROTO_DEXTRA:
m_list->SetItem(0L, 1, wxT("DExtra"));
break;
case PROTO_DPLUS:
m_list->SetItem(0L, 1, wxT("D-Plus"));
break;
case PROTO_DCS:
m_list->SetItem(0L, 1, wxT("DCS"));
break;
case PROTO_CCS:
m_list->SetItem(0L, 1, wxT("CCS"));
break;
default:
m_list->SetItem(0L, 1, wxT("?????"));
break;
}
switch (direction){
case DIR_INCOMING:
m_list->SetItem(0L, 2, _("IN"));
break;
case DIR_OUTGOING:
m_list->SetItem(0L, 2, _("OUT"));
break;
default:
m_list->SetItem(0L, 2, wxT("???"));
break;
}
if (isDongle)
m_list->SetItem(0L, 3, _("Dongle"));
else
m_list->SetItem(0L, 3, _("Repeater"));
if (isLinked)
m_list->SetItem(0L, 4, _("Linked"));
else
m_list->SetItem(0L, 4, _("Linking"));
}
}
void CRemoteControlRepeaterPanel::onRefresh(wxCommandEvent&)
{
::wxGetApp().repeaterRefresh(m_callsign);
}
void CRemoteControlRepeaterPanel::onLink(wxCommandEvent&)
{
int n = m_reconnect->GetCurrentSelection();
if (n == wxNOT_FOUND)
return;
RECONNECT reconnect = RECONNECT(n);
n = m_reflector->GetCurrentSelection();
if (n == wxNOT_FOUND)
return;
wxString reflector = wxEmptyString;
if (n > 0) {
n = m_channel->GetCurrentSelection();
if (n == wxNOT_FOUND)
return;
reflector = m_reflector->GetStringSelection();
if (reflector.IsEmpty())
return;
wxString channel = m_channel->GetStringSelection();
if (channel.IsEmpty())
return;
reflector.Append(wxT(" "));
reflector.Truncate(LONG_CALLSIGN_LENGTH - 1U);
reflector.Append(channel);
}
::wxGetApp().link(m_callsign, reconnect, reflector);
}
void CRemoteControlRepeaterPanel::onUnlink(wxCommandEvent&)
{
if (m_selected == -1)
return;
wxString reflector = m_reflectors.Item(m_selected);
PROTOCOL protocol = m_protocols.Item(m_selected);
m_selected = -1;
m_unlink->Disable();
::wxGetApp().unlink(m_callsign, protocol, reflector);
}
void CRemoteControlRepeaterPanel::onSelect(wxListEvent& event)
{
m_selected = event.GetSelection();
m_unlink->Enable();
}