📄 stationsdlg.cpp
字号:
/******************************************************************************\
* Technische Universitaet Darmstadt, Institut fuer Nachrichtentechnik
* Copyright (c) 2004
*
* Author(s):
* Volker Fischer, Stephane Fillod, Tomi Manninen
*
* 5/15/2005 Andrea Russo
* - added preview
* 5/25/2005 Andrea Russo
* - added "days" column in stations list view
*
******************************************************************************
*
* 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.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
\******************************************************************************/
#include "StationsDlg.h"
#if !defined(HAVE_RIG_PARSE_MODE) && defined(HAVE_LIBHAMLIB)
extern "C"
{
extern rmode_t parse_mode(const char *);
extern vfo_t parse_vfo(const char *);
extern setting_t parse_func(const char *);
extern setting_t parse_level(const char *);
extern setting_t parse_parm(const char *);
extern const char* strstatus(enum rig_status_e);
}
# define rig_parse_mode parse_mode
# define rig_parse_vfo parse_vfo
# define rig_parse_func parse_func
# define rig_parse_level parse_level
# define rig_parse_parm parse_parm
# define rig_strstatus strstatus
#endif
/* Implementation *************************************************************/
void CDRMSchedule::ReadStatTabFromFile(const ESchedMode eNewSchM)
{
const int iMaxLenName = 256;
char cName[iMaxLenName];
int iFileStat;
_BOOLEAN bReadOK = TRUE;
FILE* pFile;
/* Save new mode */
eSchedMode = eNewSchM;
/* Open file and init table for stations */
StationsTable.Init(0);
switch (eNewSchM)
{
case SM_DRM:
pFile = fopen(DRMSCHEDULE_INI_FILE_NAME, "r");
break;
case SM_ANALOG:
pFile = fopen(AMSCHEDULE_INI_FILE_NAME, "r");
break;
}
/* Check if opening of file was successful */
if (pFile == 0)
return;
fgets(cName, iMaxLenName, pFile); /* Remove "[DRMSchedule]" */
do
{
CStationsItem StationsItem;
/* Start stop time */
int iStartTime, iStopTime;
iFileStat = fscanf(pFile, "StartStopTimeUTC=%04d-%04d\n",
&iStartTime, &iStopTime);
if (iFileStat != 2)
bReadOK = FALSE;
else
{
StationsItem.SetStartTimeNum(iStartTime);
StationsItem.SetStopTimeNum(iStopTime);
}
/* Days */
/* Init days with the "irregular" marker in case no valid string could
be read */
string strNewDaysFlags = FLAG_STR_IRREGULAR_TRANSM;
iFileStat = fscanf(pFile, "Days[SMTWTFS]=%255[^\n|^\r]\n", cName);
if (iFileStat != 1)
fscanf(pFile, "\n");
else
{
/* Check for length of input string (must be 7) */
const string strTMP = cName;
if (strTMP.length() == 7)
strNewDaysFlags = strTMP;
}
/* Frequency */
iFileStat = fscanf(pFile, "Frequency=%d\n", &StationsItem.iFreq);
if (iFileStat != 1)
bReadOK = FALSE;
/* Target */
iFileStat = fscanf(pFile, "Target=%255[^\n|^\r]\n", cName);
if (iFileStat != 1)
fscanf(pFile, "\n");
else
StationsItem.strTarget = cName;
/* Power */
iFileStat = fscanf(pFile, "Power=%255[^\n|^\r]\n", cName);
if (iFileStat != 1)
fscanf(pFile, "\n");
else
StationsItem.rPower = QString(cName).toFloat();
/* Name of the station */
iFileStat = fscanf(pFile, "Programme=%255[^\n|^\r]\n", cName);
if (iFileStat != 1)
fscanf(pFile, "\n");
else
StationsItem.strName = cName;
/* Language */
iFileStat = fscanf(pFile, "Language=%255[^\n|^\r]\n", cName);
if (iFileStat != 1)
fscanf(pFile, "\n");
else
StationsItem.strLanguage = cName;
/* Site */
iFileStat = fscanf(pFile, "Site=%255[^\n|^\r]\n", cName);
if (iFileStat != 1)
fscanf(pFile, "\n");
else
StationsItem.strSite = cName;
/* Country */
iFileStat = fscanf(pFile, "Country=%255[^\n|^\r]\n", cName);
if (iFileStat != 1)
fscanf(pFile, "\n");
else
StationsItem.strCountry = cName;
iFileStat = fscanf(pFile, "\n");
/* Check for error before applying data */
if (bReadOK == TRUE)
{
/* Set "days flag string" and generate strings for displaying active
days */
StationsItem.SetDaysFlagString(strNewDaysFlags);
/* Add new item in table */
StationsTable.Add(StationsItem);
}
} while (!((iFileStat == EOF) || (bReadOK == FALSE)));
fclose(pFile);
}
CDRMSchedule::StationState CDRMSchedule::CheckState(const int iPos)
{
/* Get system time */
time_t ltime;
time(<ime);
if (IsActive(iPos, ltime) == TRUE)
return IS_ACTIVE;
else
{
/* Station is not active, check preview condition */
if (iSecondsPreview > 0)
{
if (IsActive(iPos, ltime + iSecondsPreview) == TRUE)
return IS_PREVIEW;
else
return IS_INACTIVE;
}
else
return IS_INACTIVE;
}
}
_BOOLEAN CDRMSchedule::IsActive(const int iPos, const time_t ltime)
{
/* Calculate time in UTC */
struct tm* gmtCur = gmtime(<ime);
const time_t lCurTime = mktime(gmtCur);
/* Get stop time */
struct tm* gmtStop = gmtime(<ime);
gmtStop->tm_hour = StationsTable[iPos].iStopHour;
gmtStop->tm_min = StationsTable[iPos].iStopMinute;
const time_t lStopTime = mktime(gmtStop);
/* Get start time */
struct tm* gmtStart = gmtime(<ime);
gmtStart->tm_hour = StationsTable[iPos].iStartHour;
gmtStart->tm_min = StationsTable[iPos].iStartMinute;
const time_t lStartTime = mktime(gmtStart);
/* Check, if stop time is on next day */
_BOOLEAN bSecondDay = FALSE;
if (lStopTime < lStartTime)
{
/* Check, if we are at the first or the second day right now */
if (lCurTime < lStopTime)
{
/* Second day. Increase day count */
gmtCur->tm_wday++;
/* Check that value is valid (range 0 - 6) */
if (gmtCur->tm_wday > 6)
gmtCur->tm_wday = 0;
/* Set flag */
bSecondDay = TRUE;
}
}
/* Check day
tm_wday: day of week (0 - 6; Sunday = 0). "strDaysFlags" are coded with
pseudo binary representation. A one signalls that day is active. The most
significant 1 is the sunday, then followed the monday and so on. */
if ((StationsTable[iPos].strDaysFlags[gmtCur->tm_wday] ==
CHR_ACTIVE_DAY_MARKER) ||
/* Check also for special case: days are 0000000. This is reserved for
DRM test transmissions or irregular transmissions. We define here
that these stations are transmitting every day */
(StationsTable[iPos].strDaysFlags == FLAG_STR_IRREGULAR_TRANSM))
{
/* Check time interval */
if (lStopTime > lStartTime)
{
if ((lCurTime >= lStartTime) && (lCurTime < lStopTime))
return TRUE;
}
else
{
if (bSecondDay == FALSE)
{
/* First day. Only check if we are after start time */
if (lCurTime >= lStartTime)
return TRUE;
}
else
{
/* Second day. Only check if we are before stop time */
if (lCurTime < lStopTime)
return TRUE;
}
}
}
return FALSE;
}
void CStationsItem::SetDaysFlagString(const string strNewDaysFlags)
{
/* Set internal "days flag" string and "show days" string */
strDaysFlags = strNewDaysFlags;
strDaysShow = "";
/* Init days string vector */
const QString strDayDef [] =
{
QObject::tr("Sun"),
QObject::tr("Mon"),
QObject::tr("Tue"),
QObject::tr("Wed"),
QObject::tr("Thu"),
QObject::tr("Fri"),
QObject::tr("Sat")
};
/* First test for day constellations which allow to apply special names */
if (strDaysFlags == FLAG_STR_IRREGULAR_TRANSM)
strDaysShow = QObject::tr("irregular").latin1();
else if (strDaysFlags == "1111111")
strDaysShow = QObject::tr("daily").latin1();
else if (strDaysFlags == "1111100")
strDaysShow = QObject::tr("from Sun to Thu").latin1();
else if (strDaysFlags == "1111110")
strDaysShow = QObject::tr("from Sun to Fri").latin1();
else if (strDaysFlags == "0111110")
strDaysShow = QObject::tr("from Mon to Fri").latin1();
else if (strDaysFlags == "0111111")
strDaysShow = QObject::tr("from Mon to Sat").latin1();
else
{
/* No special name could be applied, just list all active days */
for (int i = 0; i < 7; i++)
{
/* Check if day is active */
if (strDaysFlags[i] == CHR_ACTIVE_DAY_MARKER)
{
/* Set commas in between the days, to not set a comma at
the beginning */
if (strDaysShow != "")
strDaysShow += ",";
/* Add current day */
strDaysShow += strDayDef[i].latin1();
}
}
}
}
StationsDlg::StationsDlg(CDRMReceiver* pNDRMR, QWidget* parent,
const char* name, bool modal, WFlags f) : vecpListItems(0),
CStationsDlgBase(parent, name, modal, f), pDRMRec(pNDRMR)
{
/* Set help text for the controls */
AddWhatsThisHelp();
#ifdef _WIN32 /* This works only reliable under Windows :-( */
/* Get window geometry data from DRMReceiver module and apply it */
const QRect WinGeom(pDRMRec->GeomStationsDlg.iXPos,
pDRMRec->GeomStationsDlg.iYPos,
pDRMRec->GeomStationsDlg.iWSize,
pDRMRec->GeomStationsDlg.iHSize);
if (WinGeom.isValid() && !WinGeom.isEmpty() && !WinGeom.isNull())
setGeometry(WinGeom);
#else /* Under Linux only restore the size */
resize(pDRMRec->GeomStationsDlg.iWSize,
pDRMRec->GeomStationsDlg.iHSize);
#endif
/* Define size of the bitmaps */
const int iXSize = 13;
const int iYSize = 13;
/* Create bitmaps */
BitmCubeGreen.resize(iXSize, iYSize);
BitmCubeGreen.fill(QColor(0, 255, 0));
BitmCubeYellow.resize(iXSize, iYSize);
BitmCubeYellow.fill(QColor(255, 255, 0));
BitmCubeRed.resize(iXSize, iYSize);
BitmCubeRed.fill(QColor(255, 0, 0));
BitmCubeOrange.resize(iXSize, iYSize);
BitmCubeOrange.fill(QColor(255, 128, 0));
#ifdef HAVE_LIBHAMLIB
/* Init progress bar for input s-meter */
ProgrSigStrength->setRange(S_METER_THERMO_MIN, S_METER_THERMO_MAX);
ProgrSigStrength->setOrientation(QwtThermo::Horizontal, QwtThermo::Top);
ProgrSigStrength->setAlarmLevel(S_METER_THERMO_ALARM);
ProgrSigStrength->setAlarmColor(QColor(255, 0, 0));
ProgrSigStrength->setScale(S_METER_THERMO_MIN, S_METER_THERMO_MAX, 10.0);
EnableSMeter(FALSE); /* disable for initialization */
#else
/* s-meter only implemented for hamlib */
ProgrSigStrength->hide();
TextLabelSMeter->hide();
#endif
/* Clear list box for file names and set up columns */
ListViewStations->clear();
/* We assume that one column is already there */
ListViewStations->setColumnText(0, tr("Station Name"));
ListViewStations->addColumn(tr("Time [UTC]"));
ListViewStations->addColumn(tr("Frequency [kHz]"));
ListViewStations->addColumn(tr("Target"));
ListViewStations->addColumn(tr("Power [kW]"));
ListViewStations->addColumn(tr("Country"));
ListViewStations->addColumn(tr("Site"));
ListViewStations->addColumn(tr("Language"));
ListViewStations->addColumn(tr("Days"));
/* Load the current schedule from file and initialize list view */
LoadSchedule(CDRMSchedule::SM_DRM);
/* Set up frequency selector control (QWTCounter control) */
QwtCounterFrequency->setRange(0.0, 30000.0, 1.0);
QwtCounterFrequency->setNumButtons(3); /* Three buttons on each side */
QwtCounterFrequency->setIncSteps(QwtCounter::Button1, 1); /* Increment */
QwtCounterFrequency->setIncSteps(QwtCounter::Button2, 10);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -