dl-fldigi/src/dialogs/Viewer.cxx

426 wiersze
11 KiB
C++

// special test version of Viewer.cxx
#include <config.h>
#include "Viewer.h"
#include "main.h"
#include "viewpsk.h"
#include "configuration.h"
#include "status.h"
#include "waterfall.h"
#include "fl_digi.h"
#include "re.h"
#include "gettext.h"
#include "spot.h"
#include <FL/Enumerations.H>
#include <FL/Fl_Slider.H>
#include <FL/fl_ask.H>
#include <string>
using namespace std;
string bwsrfreq;
string bwsrline[MAXCHANNELS];
static int brwsFreq[MAXCHANNELS];
static int freq;
static double dfreq;
static long long rfc;
static bool usb;
string dkred;
string dkblue;
string dkgreen;
string bkselect;
string white;
string bkgnd[2];
int cols[] = {100, 0};
int cwidth;
int cheight;
int rfwidth;
int chwidth;
int sbarwidth = 16;
int border = 4;
re_t seek_re("", REG_EXTENDED | REG_ICASE | REG_NOSUB);
int re_eflags = REG_NOTBOL | REG_NOTEOL;
//unsigned int nchars = 80;
string freqformat(int i)
{
static char szLine[80];
string fline;
if (pskviewer) freq = pskviewer->get_freq(progdefaults.VIEWERchannels - 1 - i);
else freq = progdefaults.VIEWERstart + 100 * (progdefaults.VIEWERchannels - 1 - i);
brwsFreq[i] = freq;
if (rfc != 0) {
if (usb) dfreq = rfc + freq;
else dfreq = rfc - freq;
} else
dfreq = freq;
if (progdefaults.VIEWERshowfreq)
snprintf(szLine, sizeof(szLine), "%10.3f", dfreq / 1000.0);
else
snprintf(szLine, sizeof(szLine), "%3d", progdefaults.VIEWERchannels - i);
fline = "@f";
fline += bkselect.c_str();
fline += white.c_str();
fline += szLine;
fline += '\t';
fline += bkgnd[i % 2];
fline += "@f";
return fline;
}
void pskBrowser::resize(int x, int y, int w, int h) {
unsigned int nuchars = (w - cols[0] - (sbarwidth + border)) / cwidth;
string bline;
if (nuchars < progStatus.VIEWERnchars) {
Fl_Hold_Browser::clear();
for (int i = 0; i < progdefaults.VIEWERchannels; i++) {
size_t len = bwsrline[i].length();
if (len > nuchars)
bwsrline[i] = bwsrline[i].substr(len - nuchars);
bline = freqformat(i);
if (seek_re.match(bwsrline[i].c_str(), re_eflags))
bline.append(dkred);
else if (!progdefaults.myCall.empty() &&
strcasestr(bwsrline[i].c_str(), progdefaults.myCall.c_str()))
bline.append(dkgreen);
bline.append("@.").append(bwsrline[i]);
Fl_Hold_Browser::add(bline.c_str());
}
}
progStatus.VIEWERnchars = nuchars;
progStatus.VIEWERxpos = dlgViewer->x();
progStatus.VIEWERypos = dlgViewer->y();
Fl_Hold_Browser::resize(x,y,w,h);
}
Fl_Double_Window *dlgViewer = (Fl_Double_Window *)0;
Fl_Button *btnCloseViewer=(Fl_Button *)0;
Fl_Button *btnClearViewer=(Fl_Button *)0;
pskBrowser *brwsViewer=(pskBrowser *)0;
Fl_Input *inpSeek = (Fl_Input *)0;
Fl_Slider *sldrViewerSquelch = (Fl_Slider *)0;
//Fl_Light_Button *chkBeep = 0;
static void make_colors()
{
char tempstr[20];
snprintf(tempstr, sizeof(tempstr), "@b@C%d",
adjust_color(fl_color_cube(128 * (FL_NUM_RED - 1) / 255,
0 * (FL_NUM_GREEN - 1) / 255,
0 * (FL_NUM_BLUE - 1) / 255),
FL_BACKGROUND2_COLOR)); // dark red
dkred = tempstr;
snprintf(tempstr, sizeof(tempstr), "@b@C%d",
adjust_color(fl_color_cube(0 * (FL_NUM_RED - 1) / 255,
128 * (FL_NUM_GREEN - 1) / 255,
0 * (FL_NUM_BLUE - 1) / 255),
FL_BACKGROUND2_COLOR)); // dark green
dkgreen = tempstr;
snprintf(tempstr, sizeof(tempstr), "@b@C%d",
adjust_color(fl_color_cube(0 * (FL_NUM_RED - 1) / 255,
0 * (FL_NUM_GREEN - 1) / 255,
128 * (FL_NUM_BLUE - 1) / 255),
FL_BACKGROUND2_COLOR)); // dark blue
dkblue = tempstr;
snprintf(tempstr, sizeof(tempstr), "@C%d", FL_FOREGROUND_COLOR); // foreground
white = tempstr;
snprintf(tempstr, sizeof(tempstr), "@B%d",
adjust_color(FL_SELECTION_COLOR, FL_FOREGROUND_COLOR)); // default selection color bkgnd
bkselect = tempstr;
snprintf(tempstr, sizeof(tempstr), "@B%d", FL_BACKGROUND2_COLOR); // background for odd rows
bkgnd[0] = tempstr;
Fl_Color bg2 = fl_color_average(FL_BACKGROUND2_COLOR, FL_BLACK, .9);
if (bg2 == FL_BLACK)
bg2 = fl_color_average(FL_BACKGROUND2_COLOR, FL_WHITE, .9);
snprintf(tempstr, sizeof(tempstr), "@B%d", adjust_color(bg2, FL_FOREGROUND_COLOR)); // even rows
bkgnd[1] = tempstr;
}
static void evalcwidth()
{
fl_font(FL_COURIER, FL_NORMAL_SIZE);
cwidth = (int)fl_width("W");
cheight = fl_height();
rfwidth = 11 * cwidth;
chwidth = 4 * cwidth;
}
static void cb_btnCloseViewer(Fl_Button*, void*) {
progStatus.VIEWERxpos = dlgViewer->x();
progStatus.VIEWERypos = dlgViewer->y();
dlgViewer->hide();
}
void ClearViewer() {
brwsViewer->clear();
usb = wf->USB();
rfc = wf->rfcarrier();
string bline;
for (int i = 0; i < progdefaults.VIEWERchannels; i++) {
if (pskviewer) freq = pskviewer->get_freq(progdefaults.VIEWERchannels - 1 - i);
else freq = progdefaults.VIEWERstart + 100 * (progdefaults.VIEWERchannels - 1 - i);
bline = freqformat(i);
bwsrline[i].clear();
brwsViewer->add(bline.c_str());
}
if (progdefaults.VIEWERshowfreq)
cols[0] = rfwidth;
else
cols[0] = chwidth;
brwsViewer->column_widths(cols);
}
void initViewer()
{
if (!pskviewer) return;
if (!dlgViewer) return;
pskviewer->init();
ClearViewer();
dlgViewer->resize(dlgViewer->x(), dlgViewer->y(),
progStatus.VIEWERnchars * cwidth + cols[0] + (sbarwidth + border),
cheight * progdefaults.VIEWERchannels + 50 + border);
}
// i in [1, progdefaults.VIEWERchannels]
static void set_freq(int i, int freq)
{
string new_line;
if (freq == 0) // reset
freq = progdefaults.VIEWERstart + 100 * (progdefaults.VIEWERchannels - i);
pskviewer->set_freq(progdefaults.VIEWERchannels - i, freq);
new_line.append(freqformat(i - 1)).append("@.").append(bwsrline[i - 1]);
brwsViewer->replace(i, new_line.c_str());
}
static void cb_btnClearViewer(Fl_Button*, void*) {
if (Fl::event_button() == FL_LEFT_MOUSE)
ClearViewer();
else
for (int i = 1; i <= progdefaults.VIEWERchannels; i++)
set_freq(i, 0);
}
static void cb_brwsViewer(Fl_Hold_Browser*, void*) {
int sel = brwsViewer->value();
if (sel == 0 || sel > progdefaults.VIEWERchannels)
return;
switch (Fl::event_button()) {
case FL_LEFT_MOUSE:
ReceiveText->addchr('\n', FTextBase::ALTR);
ReceiveText->addstr(bwsrline[sel - 1].c_str(), FTextBase::ALTR);
active_modem->set_freq(brwsFreq[sel - 1]);
break;
case FL_MIDDLE_MOUSE: // copy from modem
set_freq(sel, active_modem->get_freq());
break;
case FL_RIGHT_MOUSE: // reset
set_freq(sel, 0);
break;
default:
break;
}
}
static void cb_Seek(Fl_Input *, void *)
{
static Fl_Color seek_color[2] = { FL_FOREGROUND_COLOR,
adjust_color(FL_RED, FL_BACKGROUND2_COLOR) }; // invalid RE
seek_re = *inpSeek->value() ? inpSeek->value() : "[invalid";
if (inpSeek->textcolor() != seek_color[!seek_re]) {
inpSeek->textcolor(seek_color[!seek_re]);
inpSeek->redraw();
}
}
static void cb_Squelch(Fl_Slider *, void *)
{
progdefaults.VIEWERsquelch = sldrViewerSquelch->value();
progdefaults.changed = true;
}
Fl_Double_Window* createViewer() {
Fl_Double_Window* w;
Fl_Pack *p;
make_colors();
evalcwidth();
if (progdefaults.VIEWERshowfreq)
cols[0] = rfwidth;
else
cols[0] = chwidth;
static int viewerwidth = (progStatus.VIEWERnchars * cwidth) + cols[0] + sbarwidth + border;
static int viewerheight = 50 + cheight * progdefaults.VIEWERchannels + border;
w = new Fl_Double_Window(progStatus.VIEWERxpos, progStatus.VIEWERypos, viewerwidth, viewerheight, _("Psk Viewer"));
w->xclass(PACKAGE_NAME);
p = new Fl_Pack(0,0,viewerwidth, viewerheight);
Fl_Pack *p1 = new Fl_Pack(0, 0, viewerwidth, 25);
p1->type(1);
Fl_Box *bx = new Fl_Box(0,0,50, 25);
inpSeek = new Fl_Input(50, 5, 200, 25, _("Find: "));
inpSeek->callback((Fl_Callback*)cb_Seek);
inpSeek->when(FL_WHEN_CHANGED);
inpSeek->textfont(FL_SCREEN);
inpSeek->value("CQ");
// chkBeep = new Fl_Light_Button(inpSeek->x() + border, inpSeek->y(), 60, inpSeek->h(), "Beep");
bx = new Fl_Box(250, 5, 200, 25);
p1->resizable(bx);
p1->end();
inpSeek->do_callback();
brwsViewer = new pskBrowser(2, 25, viewerwidth, viewerheight - 50);
brwsViewer->callback((Fl_Callback*)cb_brwsViewer);
brwsViewer->column_widths(cols);
Fl_Pack *p2 = new Fl_Pack(0, viewerheight - 25, viewerwidth, 25);
p2->type(1);
bx = new Fl_Box(0,viewerheight - 25, 10, 25);
btnClearViewer = new Fl_Button(10, viewerheight - 25, 65, 25, _("Clear"));
btnClearViewer->callback((Fl_Callback*)cb_btnClearViewer);
btnClearViewer->tooltip(_("Left click to clear text\nRight click to reset frequencies"));
bx = new Fl_Box(75, viewerheight - 25, 10, 25);
btnCloseViewer = new Fl_Button(85, viewerheight - 25, 65, 25, _("Close"));
btnCloseViewer->callback((Fl_Callback*)cb_btnCloseViewer);
bx = new Fl_Box(140, viewerheight - 25, 5, 25);
sldrViewerSquelch = new Fl_Slider(145, viewerheight - 25, 200, 25);
sldrViewerSquelch->tooltip(_("Set Viewer Squelch"));
sldrViewerSquelch->type(FL_HOR_NICE_SLIDER);
sldrViewerSquelch->range(0.0, 100.0);
sldrViewerSquelch->value(progdefaults.VIEWERsquelch);
sldrViewerSquelch->callback((Fl_Callback*)cb_Squelch);
bx = new Fl_Box(345, viewerheight - 25, 25, 25);
p2->resizable(bx);
p2->end();
p->resizable(brwsViewer);
p->end();
w->resizable(p);
w->end();
w->callback((Fl_Callback*)cb_btnCloseViewer);
return w;
}
void openViewer() {
if (!dlgViewer) {
dlgViewer = createViewer();
ClearViewer();
}
dlgViewer->show();
dlgViewer->redraw();
}
void viewer_redraw()
{
if (!dlgViewer) return;
usb = wf->USB();
rfc = wf->rfcarrier();
for (int i = 0; i < progdefaults.VIEWERchannels; i++)
brwsViewer->text(i + 1, freqformat(i).c_str() );
if (progdefaults.VIEWERshowfreq)
cols[0] = rfwidth;
else
cols[0] = chwidth;
brwsViewer->column_widths(cols);
}
void viewaddchr(int ch, int freq, char c) {
if (!dlgViewer) return;
if (progStatus.spot_recv)
spot_recv(c, ch, freq);
if (rfc != wf->rfcarrier() || usb != wf->USB()) viewer_redraw();
static string nuline;
string bline;
int index = progdefaults.VIEWERchannels - 1 - ch;
if (progdefaults.VIEWERmarquee) {
if (bwsrline[index].length() > progStatus.VIEWERnchars ) {
bwsrline[index].erase(0,1);
}
if (c >= ' ' && c <= '~') {
bwsrline[index] += c;
} else {
bwsrline[index] += ' ';
}
} else {
if (c >= ' ' && c <= '~') {
bwsrline[index] += c;
} else {
bwsrline[index] += ' ';
}
if (bwsrline[index].length() > progStatus.VIEWERnchars)
bwsrline[index].clear();
}
nuline = freqformat(index);
if (seek_re.match(bwsrline[index].c_str(), re_eflags)) {
nuline.append(dkred);
// if (chkBeep->value())
// fl_beep();
}
else if (!progdefaults.myCall.empty() &&
strcasestr(bwsrline[index].c_str(), progdefaults.myCall.c_str())) {
nuline.append(dkgreen);
// if (chkBeep->value())
// fl_beep();
}
nuline.append("@.").append(bwsrline[index]);
brwsViewer->text(1 + index, nuline.c_str());
brwsViewer->redraw();
}
void viewclearchannel(int ch)
{
int index = progdefaults.VIEWERchannels - 1 - ch;
string nuline = freqformat(index);
bwsrline[index] = "";
brwsViewer->text( 1 + index, nuline.c_str());
brwsViewer->redraw();
}
void viewer_paste_freq(int freq)
{
if (!dlgViewer)
return;
int sel = 1, n = brwsViewer->size();
for (int i = 0; i < n; i++) {
if (brwsViewer->selected(i)) {
brwsViewer->select(i, false);
sel = i;
break;
}
}
set_freq(sel, freq);
brwsViewer->select(WCLAMP(sel+1, 1, n));
}