From 39fe31b14730b0ba1fac82e4494849016bbe44cb Mon Sep 17 00:00:00 2001 From: David Freese Date: Sun, 14 Aug 2011 09:11:44 -0500 Subject: [PATCH 01/54] Wide Cursor Tracks * Added user configurable item for 2x track widths --- src/dialogs/confdialog.cxx | 84 +++++++++++++++++++++++++++---------- src/dialogs/confdialog.fl | 70 ++++++++++++++++++++----------- src/include/confdialog.h | 3 ++ src/include/configuration.h | 9 ++++ src/waterfall/waterfall.cxx | 38 ++++++++++++++--- 5 files changed, 152 insertions(+), 52 deletions(-) diff --git a/src/dialogs/confdialog.cxx b/src/dialogs/confdialog.cxx index 79c434f0..5a017493 100644 --- a/src/dialogs/confdialog.cxx +++ b/src/dialogs/confdialog.cxx @@ -857,6 +857,27 @@ progdefaults.changed = true; }; } +Fl_Check_Button *btnUseWideTracks=(Fl_Check_Button *)0; + +static void cb_btnUseWideTracks(Fl_Check_Button* o, void*) { + progdefaults.UseWideTracks = o->value(); +progdefaults.changed = true; +} + +Fl_Check_Button *btnUseWideCenter=(Fl_Check_Button *)0; + +static void cb_btnUseWideCenter(Fl_Check_Button* o, void*) { + progdefaults.UseWideCenter = o->value(); +progdefaults.changed = true; +} + +Fl_Check_Button *btnUseWideCursor=(Fl_Check_Button *)0; + +static void cb_btnUseWideCursor(Fl_Check_Button* o, void*) { + progdefaults.UseWideCursor = o->value(); +progdefaults.changed = true; +} + Fl_Check_Button *chkShowAudioScale=(Fl_Check_Button *)0; static void cb_chkShowAudioScale(Fl_Check_Button* o, void*) { @@ -3668,16 +3689,15 @@ ab and newline are automatically included.")); } // Fl_Tabs* tabsUI tabUI->end(); } // Fl_Group* tabUI - { tabWaterfall = new Fl_Group(0, 25, 500, 347, _("Waterfall")); - tabWaterfall->hide(); - { tabsWaterfall = new Fl_Tabs(0, 25, 500, 347); + { tabWaterfall = new Fl_Group(0, 25, 501, 347, _("Waterfall")); + { tabsWaterfall = new Fl_Tabs(0, 25, 501, 347); tabsWaterfall->color((Fl_Color)FL_LIGHT1); tabsWaterfall->selection_color((Fl_Color)FL_LIGHT1); - { Fl_Group* o = new Fl_Group(0, 50, 500, 320, _("Display")); - { Fl_Group* o = new Fl_Group(5, 60, 490, 162, _("Colors and cursors")); + { Fl_Group* o = new Fl_Group(0, 50, 501, 320, _("Display")); + { Fl_Group* o = new Fl_Group(5, 60, 496, 162, _("Colors and cursors")); o->box(FL_ENGRAVED_FRAME); o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); - { colorbox* o = WF_Palette = new colorbox(15, 98, 260, 24); + { colorbox* o = WF_Palette = new colorbox(15, 93, 260, 24, _("aa")); WF_Palette->box(FL_DOWN_BOX); WF_Palette->color((Fl_Color)FL_FOREGROUND_COLOR); WF_Palette->selection_color((Fl_Color)FL_BACKGROUND_COLOR); @@ -3691,89 +3711,107 @@ ab and newline are automatically included.")); o->label(progdefaults.PaletteName.c_str()); o->labelsize(FL_NORMAL_SIZE); } // colorbox* WF_Palette - { btnColor[0] = new Fl_Button(15, 128, 20, 24); + { btnColor[0] = new Fl_Button(15, 120, 20, 24); btnColor[0]->tooltip(_("Change color")); btnColor[0]->callback((Fl_Callback*)cb_btnColor); } // Fl_Button* btnColor[0] - { btnColor[1] = new Fl_Button(45, 128, 20, 24); + { btnColor[1] = new Fl_Button(45, 120, 20, 24); btnColor[1]->tooltip(_("Change color")); btnColor[1]->callback((Fl_Callback*)cb_btnColor1); } // Fl_Button* btnColor[1] - { btnColor[2] = new Fl_Button(75, 128, 20, 24); + { btnColor[2] = new Fl_Button(75, 120, 20, 24); btnColor[2]->tooltip(_("Change color")); btnColor[2]->callback((Fl_Callback*)cb_btnColor2); } // Fl_Button* btnColor[2] - { btnColor[3] = new Fl_Button(105, 128, 20, 24); + { btnColor[3] = new Fl_Button(105, 120, 20, 24); btnColor[3]->tooltip(_("Change color")); btnColor[3]->callback((Fl_Callback*)cb_btnColor3); } // Fl_Button* btnColor[3] - { btnColor[4] = new Fl_Button(135, 128, 20, 24); + { btnColor[4] = new Fl_Button(135, 120, 20, 24); btnColor[4]->tooltip(_("Change color")); btnColor[4]->callback((Fl_Callback*)cb_btnColor4); } // Fl_Button* btnColor[4] - { btnColor[5] = new Fl_Button(165, 128, 20, 24); + { btnColor[5] = new Fl_Button(165, 120, 20, 24); btnColor[5]->tooltip(_("Change color")); btnColor[5]->callback((Fl_Callback*)cb_btnColor5); } // Fl_Button* btnColor[5] - { btnColor[6] = new Fl_Button(195, 128, 20, 24); + { btnColor[6] = new Fl_Button(195, 120, 20, 24); btnColor[6]->tooltip(_("Change color")); btnColor[6]->callback((Fl_Callback*)cb_btnColor6); } // Fl_Button* btnColor[6] - { btnColor[7] = new Fl_Button(225, 128, 20, 24); + { btnColor[7] = new Fl_Button(225, 120, 20, 24); btnColor[7]->tooltip(_("Change color")); btnColor[7]->callback((Fl_Callback*)cb_btnColor7); } // Fl_Button* btnColor[7] - { btnColor[8] = new Fl_Button(256, 128, 20, 24); + { btnColor[8] = new Fl_Button(256, 120, 20, 24); btnColor[8]->tooltip(_("Change color")); btnColor[8]->callback((Fl_Callback*)cb_btnColor8); } // Fl_Button* btnColor[8] - { btnLoadPalette = new Fl_Button(314, 96, 70, 24, _("Load...")); + { btnLoadPalette = new Fl_Button(314, 93, 70, 24, _("Load...")); btnLoadPalette->tooltip(_("Load a new palette")); btnLoadPalette->callback((Fl_Callback*)cb_btnLoadPalette); } // Fl_Button* btnLoadPalette - { btnSavePalette = new Fl_Button(314, 128, 70, 24, _("Save...")); + { btnSavePalette = new Fl_Button(314, 120, 70, 24, _("Save...")); btnSavePalette->tooltip(_("Save this palette")); btnSavePalette->callback((Fl_Callback*)cb_btnSavePalette); } // Fl_Button* btnSavePalette - { Fl_Check_Button* o = btnUseCursorLines = new Fl_Check_Button(15, 161, 150, 20, _("Bandwidth cursor")); + { Fl_Check_Button* o = btnUseCursorLines = new Fl_Check_Button(15, 149, 150, 20, _("Bandwidth cursor")); btnUseCursorLines->tooltip(_("Show cursor with bandwidth lines")); btnUseCursorLines->down_box(FL_DOWN_BOX); btnUseCursorLines->callback((Fl_Callback*)cb_btnUseCursorLines); o->value(progdefaults.UseCursorLines); } // Fl_Check_Button* btnUseCursorLines - { Fl_Button* o = btnCursorBWcolor = new Fl_Button(15, 191, 20, 20, _("Cursor color")); + { Fl_Button* o = btnCursorBWcolor = new Fl_Button(15, 172, 20, 20, _("Cursor color")); btnCursorBWcolor->tooltip(_("Change color")); btnCursorBWcolor->color((Fl_Color)3); btnCursorBWcolor->callback((Fl_Callback*)cb_btnCursorBWcolor); btnCursorBWcolor->align(FL_ALIGN_RIGHT); o->color(fl_rgb_color(progdefaults.cursorLineRGBI.R,progdefaults.cursorLineRGBI.G,progdefaults.cursorLineRGBI.B)); } // Fl_Button* btnCursorBWcolor - { Fl_Check_Button* o = btnUseCursorCenterLine = new Fl_Check_Button(185, 161, 149, 20, _("Cursor center line")); + { Fl_Check_Button* o = btnUseCursorCenterLine = new Fl_Check_Button(185, 149, 149, 20, _("Cursor center line")); btnUseCursorCenterLine->tooltip(_("Show cursor with center line")); btnUseCursorCenterLine->down_box(FL_DOWN_BOX); btnUseCursorCenterLine->callback((Fl_Callback*)cb_btnUseCursorCenterLine); o->value(progdefaults.UseCursorCenterLine); } // Fl_Check_Button* btnUseCursorCenterLine - { Fl_Button* o = btnCursorCenterLineColor = new Fl_Button(185, 191, 20, 20, _("Center line color")); + { Fl_Button* o = btnCursorCenterLineColor = new Fl_Button(185, 172, 20, 20, _("Center line color")); btnCursorCenterLineColor->tooltip(_("Change color")); btnCursorCenterLineColor->color((Fl_Color)FL_BACKGROUND2_COLOR); btnCursorCenterLineColor->callback((Fl_Callback*)cb_btnCursorCenterLineColor); btnCursorCenterLineColor->align(FL_ALIGN_RIGHT); o->color(fl_rgb_color(progdefaults.cursorCenterRGBI.R,progdefaults.cursorCenterRGBI.G,progdefaults.cursorCenterRGBI.B)); } // Fl_Button* btnCursorCenterLineColor - { Fl_Check_Button* o = btnUseBWTracks = new Fl_Check_Button(346, 161, 145, 20, _("Bandwidth tracks")); + { Fl_Check_Button* o = btnUseBWTracks = new Fl_Check_Button(346, 149, 145, 20, _("Bandwidth tracks")); btnUseBWTracks->tooltip(_("Show bandwidth tracks on waterfall")); btnUseBWTracks->down_box(FL_DOWN_BOX); btnUseBWTracks->callback((Fl_Callback*)cb_btnUseBWTracks); o->value(progdefaults.UseBWTracks); } // Fl_Check_Button* btnUseBWTracks - { Fl_Button* o = btnBwTracksColor = new Fl_Button(346, 191, 20, 20, _("Tracks color")); + { Fl_Button* o = btnBwTracksColor = new Fl_Button(346, 172, 20, 20, _("Tracks color")); btnBwTracksColor->tooltip(_("Change color")); btnBwTracksColor->color((Fl_Color)1); btnBwTracksColor->callback((Fl_Callback*)cb_btnBwTracksColor); btnBwTracksColor->align(FL_ALIGN_RIGHT); o->color(fl_rgb_color(progdefaults.bwTrackRGBI.R,progdefaults.bwTrackRGBI.G,progdefaults.bwTrackRGBI.B)); } // Fl_Button* btnBwTracksColor + { Fl_Check_Button* o = btnUseWideTracks = new Fl_Check_Button(346, 196, 145, 20, _("Wide tracks")); + btnUseWideTracks->tooltip(_("Show bandwidth tracks on waterfall")); + btnUseWideTracks->down_box(FL_DOWN_BOX); + btnUseWideTracks->callback((Fl_Callback*)cb_btnUseWideTracks); + o->value(progdefaults.UseWideTracks); + } // Fl_Check_Button* btnUseWideTracks + { Fl_Check_Button* o = btnUseWideCenter = new Fl_Check_Button(185, 197, 145, 20, _("Wide center line")); + btnUseWideCenter->tooltip(_("Show bandwidth tracks on waterfall")); + btnUseWideCenter->down_box(FL_DOWN_BOX); + btnUseWideCenter->callback((Fl_Callback*)cb_btnUseWideCenter); + o->value(progdefaults.UseWideCenter); + } // Fl_Check_Button* btnUseWideCenter + { Fl_Check_Button* o = btnUseWideCursor = new Fl_Check_Button(15, 195, 145, 20, _("Wide cursor")); + btnUseWideCursor->tooltip(_("Show bandwidth tracks on waterfall")); + btnUseWideCursor->down_box(FL_DOWN_BOX); + btnUseWideCursor->callback((Fl_Callback*)cb_btnUseWideCursor); + o->value(progdefaults.UseWideCursor); + } // Fl_Check_Button* btnUseWideCursor o->end(); } // Fl_Group* o { Fl_Group* o = new Fl_Group(5, 222, 490, 62, _("Frequency scale")); diff --git a/src/dialogs/confdialog.fl b/src/dialogs/confdialog.fl index a14f9ebb..23e27c80 100644 --- a/src/dialogs/confdialog.fl +++ b/src/dialogs/confdialog.fl @@ -903,23 +903,24 @@ connect_to_log_server();} } } Fl_Group tabWaterfall { - label Waterfall - xywh {0 25 500 347} hide + label Waterfall open + xywh {0 25 501 347} } { Fl_Tabs tabsWaterfall {open - xywh {0 25 500 347} color 50 selection_color 50 + xywh {0 25 501 347} color 50 selection_color 50 } { Fl_Group {} { label Display open - xywh {0 50 500 320} + xywh {0 50 501 320} } { Fl_Group {} { label {Colors and cursors} open - xywh {5 60 490 162} box ENGRAVED_FRAME align 21 + xywh {5 60 496 162} box ENGRAVED_FRAME align 21 } { Fl_Button WF_Palette { + label aa callback {progdefaults.changed = true;} - xywh {15 98 260 24} box DOWN_BOX color 0 labelsize 12 align 5 + xywh {15 93 260 24} box DOWN_BOX color 0 labelsize 12 align 5 code0 {\#include "colorbox.h"} code1 {o->label(progdefaults.PaletteName.c_str());} code2 {o->labelsize(FL_NORMAL_SIZE);} @@ -928,59 +929,59 @@ connect_to_log_server();} Fl_Button {btnColor[0]} { callback {selectColor(0); progdefaults.changed = true;} - tooltip {Change color} xywh {15 128 20 24} + tooltip {Change color} xywh {15 120 20 24} } Fl_Button {btnColor[1]} { callback {selectColor(1); progdefaults.changed = true;} - tooltip {Change color} xywh {45 128 20 24} + tooltip {Change color} xywh {45 120 20 24} } Fl_Button {btnColor[2]} { callback {selectColor(2); progdefaults.changed = true;} - tooltip {Change color} xywh {75 128 20 24} + tooltip {Change color} xywh {75 120 20 24} } Fl_Button {btnColor[3]} { callback {selectColor(3); progdefaults.changed = true;} - tooltip {Change color} xywh {105 128 20 24} + tooltip {Change color} xywh {105 120 20 24} } Fl_Button {btnColor[4]} { callback {selectColor(4); progdefaults.changed = true;} - tooltip {Change color} xywh {135 128 20 24} + tooltip {Change color} xywh {135 120 20 24} } Fl_Button {btnColor[5]} { callback {selectColor(5); progdefaults.changed = true;} - tooltip {Change color} xywh {165 128 20 24} + tooltip {Change color} xywh {165 120 20 24} } Fl_Button {btnColor[6]} { callback {selectColor(6); progdefaults.changed = true;} - tooltip {Change color} xywh {195 128 20 24} + tooltip {Change color} xywh {195 120 20 24} } Fl_Button {btnColor[7]} { callback {selectColor(7); progdefaults.changed = true;} - tooltip {Change color} xywh {225 128 20 24} + tooltip {Change color} xywh {225 120 20 24} } Fl_Button {btnColor[8]} { callback {selectColor(8); progdefaults.changed = true;} - tooltip {Change color} xywh {256 128 20 24} + tooltip {Change color} xywh {256 120 20 24} } Fl_Button btnLoadPalette { label {Load...} callback {loadPalette(); progdefaults.changed = true;} - tooltip {Load a new palette} xywh {314 96 70 24} + tooltip {Load a new palette} xywh {314 93 70 24} code0 {\#include "colorbox.h"} } Fl_Button btnSavePalette { label {Save...} callback {savePalette();} - tooltip {Save this palette} xywh {314 128 70 24} + tooltip {Save this palette} xywh {314 120 70 24} code0 {\#include "colorbox.h"} } Fl_Check_Button btnUseCursorLines { @@ -991,7 +992,7 @@ if (o->value()) else btnCursorBWcolor->deactivate(); progdefaults.changed = true;} - tooltip {Show cursor with bandwidth lines} xywh {15 161 150 20} down_box DOWN_BOX + tooltip {Show cursor with bandwidth lines} xywh {15 149 150 20} down_box DOWN_BOX code0 {o->value(progdefaults.UseCursorLines);} } Fl_Button btnCursorBWcolor { @@ -1004,7 +1005,7 @@ o->color(fl_rgb_color(progdefaults.cursorLineRGBI.R,progdefaults.cursorLineRGBI. o->redraw(); progdefaults.changed = true; }} - tooltip {Change color} xywh {15 191 20 20} color 3 align 8 + tooltip {Change color} xywh {15 172 20 20} color 3 align 8 code0 {\#include } code1 {o->color(fl_rgb_color(progdefaults.cursorLineRGBI.R,progdefaults.cursorLineRGBI.G,progdefaults.cursorLineRGBI.B));} } @@ -1012,7 +1013,7 @@ progdefaults.changed = true; label {Cursor center line} callback {progdefaults.UseCursorCenterLine = o->value(); progdefaults.changed = true;} - tooltip {Show cursor with center line} xywh {185 161 149 20} down_box DOWN_BOX + tooltip {Show cursor with center line} xywh {185 149 149 20} down_box DOWN_BOX code0 {o->value(progdefaults.UseCursorCenterLine);} } Fl_Button btnCursorCenterLineColor { @@ -1025,14 +1026,14 @@ o->color(fl_rgb_color(progdefaults.cursorCenterRGBI.R,progdefaults.cursorCenterR o->redraw(); progdefaults.changed = true; }} - tooltip {Change color} xywh {185 191 20 20} color 7 align 8 + tooltip {Change color} xywh {185 172 20 20} color 7 align 8 code0 {o->color(fl_rgb_color(progdefaults.cursorCenterRGBI.R,progdefaults.cursorCenterRGBI.G,progdefaults.cursorCenterRGBI.B));} } Fl_Check_Button btnUseBWTracks { label {Bandwidth tracks} callback {progdefaults.UseBWTracks = o->value(); progdefaults.changed = true;} - tooltip {Show bandwidth tracks on waterfall} xywh {346 161 145 20} down_box DOWN_BOX + tooltip {Show bandwidth tracks on waterfall} xywh {346 149 145 20} down_box DOWN_BOX code0 {o->value(progdefaults.UseBWTracks);} } Fl_Button btnBwTracksColor { @@ -1046,9 +1047,30 @@ o->redraw(); wf->redraw_marker(); progdefaults.changed = true; }} - tooltip {Change color} xywh {346 191 20 20} color 1 align 8 + tooltip {Change color} xywh {346 172 20 20} color 1 align 8 code0 {o->color(fl_rgb_color(progdefaults.bwTrackRGBI.R,progdefaults.bwTrackRGBI.G,progdefaults.bwTrackRGBI.B));} } + Fl_Check_Button btnUseWideTracks { + label {Wide tracks} + callback {progdefaults.UseWideTracks = o->value(); +progdefaults.changed = true;} + tooltip {Show bandwidth tracks on waterfall} xywh {346 196 145 20} down_box DOWN_BOX + code0 {o->value(progdefaults.UseWideTracks);} + } + Fl_Check_Button btnUseWideCenter { + label {Wide center line} + callback {progdefaults.UseWideCenter = o->value(); +progdefaults.changed = true;} + tooltip {Show bandwidth tracks on waterfall} xywh {185 197 145 20} down_box DOWN_BOX + code0 {o->value(progdefaults.UseWideCenter);} + } + Fl_Check_Button btnUseWideCursor { + label {Wide cursor} + callback {progdefaults.UseWideCursor = o->value(); +progdefaults.changed = true;} selected + tooltip {Show bandwidth tracks on waterfall} xywh {15 195 145 20} down_box DOWN_BOX + code0 {o->value(progdefaults.UseWideCursor);} + } } Fl_Group {} { label {Frequency scale} open @@ -2143,7 +2165,7 @@ o->color(fl_rgb_color(progdefaults.rttymarkRGBI.R,progdefaults.rttymarkRGBI.G,pr o->redraw(); wf->redraw_marker(); progdefaults.changed = true; -}} selected +}} tooltip {Change color} xywh {403 208 18 18} color 2 align 8 code0 {o->color(fl_rgb_color(progdefaults.rttymarkRGBI.R,progdefaults.rttymarkRGBI.G,progdefaults.rttymarkRGBI.B));} } diff --git a/src/include/confdialog.h b/src/include/confdialog.h index d9178ec6..f8b692fc 100644 --- a/src/include/confdialog.h +++ b/src/include/confdialog.h @@ -126,6 +126,9 @@ extern Fl_Check_Button *btnUseCursorCenterLine; extern Fl_Button *btnCursorCenterLineColor; extern Fl_Check_Button *btnUseBWTracks; extern Fl_Button *btnBwTracksColor; +extern Fl_Check_Button *btnUseWideTracks; +extern Fl_Check_Button *btnUseWideCenter; +extern Fl_Check_Button *btnUseWideCursor; extern Fl_Check_Button *chkShowAudioScale; extern Fl_Button *btnWaterfallFont; extern Fl_Check_Button *btnViewXmtSignal; diff --git a/src/include/configuration.h b/src/include/configuration.h index a6dbc57d..1a57f6ea 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -520,6 +520,15 @@ ELEM_(bool, UseBWTracks, "USEBWTRACKS", \ "Draw bandwidth marker with vertical lines", \ true) \ + ELEM_(bool, UseWideTracks, "USEWIDETRACKS", \ + "Draw bandwidth marker with 3x vertical lines", \ + false) \ + ELEM_(bool, UseWideCursor, "USEWIDECURSOR", \ + "Draw cursor with 3x vertical lines", \ + false) \ + ELEM_(bool, UseWideCenter, "USEWIDECENTER", \ + "Draw center line marker with 3x vertical lines", \ + false) \ ELEM_(RGBI, cursorLineRGBI, "CLCOLORS", \ "Color of cursor lines (RGBI)", \ {255, 255, 0, 255}) \ diff --git a/src/waterfall/waterfall.cxx b/src/waterfall/waterfall.cxx index 7fd69cbf..142047b0 100644 --- a/src/waterfall/waterfall.cxx +++ b/src/waterfall/waterfall.cxx @@ -855,13 +855,25 @@ void WFdisp::update_waterfall() { if (active_modem->get_reverse()) { *pos1 = progdefaults.rttymarkRGBI; *pos2 = progdefaults.bwTrackRGBI; + if (progdefaults.UseWideTracks) { + *(pos1 + 1) = *pos1; + *(pos2 - 1) = *pos2; + } } else { *pos1 = progdefaults.bwTrackRGBI; *pos2 = progdefaults.rttymarkRGBI; + if (progdefaults.UseWideTracks) { + *(pos1 + 1) = *pos1; + *(pos2 - 1) = *pos2; + } } } else { *pos1 = progdefaults.bwTrackRGBI; *pos2 = progdefaults.bwTrackRGBI; + if (progdefaults.UseWideTracks) { + *(pos1 + 1) = *pos1; + *(pos2 - 1) = *pos2; + } } pos1 += disp_width; pos2 += disp_width; @@ -886,10 +898,16 @@ void WFdisp::drawcolorWF() { RGBI *pos2 = (fft_img + cursorpos + bw_hi/step); if (pos1 >= fft_img && pos2 < fft_img + disp_width) for (int y = 0; y < image_height; y ++) { - if (progdefaults.UseCursorLines) + if (progdefaults.UseCursorLines) { *pos1 = *pos2 = progdefaults.cursorLineRGBI; - if (progdefaults.UseCursorCenterLine) + if (progdefaults.UseWideCursor) + *(pos1 + 1) = *(pos2 - 1) = *pos1; + } + if (progdefaults.UseCursorCenterLine) { *pos0 = progdefaults.cursorCenterRGBI; + if (progdefaults.UseWideCenter) + *(pos0 - 1) = *(pos0 + 1) = *pos0; + } pos0 += disp_width; pos1 += disp_width; pos2 += disp_width; @@ -974,9 +992,14 @@ void WFdisp::drawspectrum() { if (progdefaults.UseBWTracks) { uchar *pos1 = pixmap + (carrierfreq - offset - bandwidth/2) / step; uchar *pos2 = pixmap + (carrierfreq - offset + bandwidth/2) / step; - if (pos1 >= pixmap && pos2 < pixmap + disp_width) + if (pos1 >= pixmap && + pos2 < pixmap + disp_width) for (int y = 0; y < image_height; y ++) { *pos1 = *pos2 = 255; + if (progdefaults.UseWideTracks) { + *(pos1 + 1) = 255; + *(pos2 - 1) = 255; + } pos1 += IMAGE_WIDTH/step; pos2 += IMAGE_WIDTH/step; } @@ -991,10 +1014,15 @@ void WFdisp::drawspectrum() { uchar *pos1 = (pixmap + cursorpos - bw_lo/step); uchar *pos2 = (pixmap + cursorpos + bw_hi/step); for (int y = 0; y < h1; y ++) { - if (progdefaults.UseCursorLines) + if (progdefaults.UseCursorLines) { *pos1 = *pos2 = 255; - if (progdefaults.UseCursorCenterLine) + if (progdefaults.UseWideCursor) + *(pos1 + 1) = *(pos2 - 1) = *pos1; + } + if (progdefaults.UseCursorCenterLine) { *pos0 = 255; + if (progdefaults.UseWideCenter) *(pos0-1) = *(pos0+1) = *(pos0); + } pos0 += IMAGE_WIDTH/step; pos1 += IMAGE_WIDTH/step; pos2 += IMAGE_WIDTH/step; From 5af9f3a824d4f47c646c94bcda1db72b3cb63a69 Mon Sep 17 00:00:00 2001 From: David Freese Date: Mon, 29 Aug 2011 19:50:24 -0500 Subject: [PATCH 02/54] DTMF encoder * Added DTMF encoder accessible as a macro tag - where string of chars can contain 0..9,space,-,comma,*,#,A..D - space, hyphen and comma insert a 50 msec silent period in the transmissions --- src/include/configuration.h | 1 + src/include/modem.h | 8 ++++ src/misc/macroedit.cxx | 1 + src/misc/macros.cxx | 9 ++++ src/trx/modem.cxx | 86 +++++++++++++++++++++++++++++++++++++ src/trx/trx.cxx | 2 + 6 files changed, 107 insertions(+) diff --git a/src/include/configuration.h b/src/include/configuration.h index 1a57f6ea..7b4b06f7 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -563,6 +563,7 @@ "Single tone at center of modem BW, carrier detect for amplifiers", \ 0.0) \ ELEM_(bool, macroCWid, "", "", false) \ + ELEM_(std::string, DTMFstr, "", "", "") \ ELEM_(int, videowidth, "VIDEOWIDTH", \ "Video ID text width (characters per row)", \ 1) \ diff --git a/src/include/modem.h b/src/include/modem.h index c8009241..30f7f461 100644 --- a/src/include/modem.h +++ b/src/include/modem.h @@ -65,6 +65,9 @@ protected: bool s2n_valid; unsigned cap; + static int DTMF_row[]; + static int DTMF_col[]; + public: modem(); virtual ~modem(){}; @@ -177,6 +180,11 @@ public: void cwid_sendtext (const std::string& s); void cwid(); +// for DTMF transmission + void DTMF_silence(int); + void DTMF_two_tones(int); + void DTMF_send(); + // for noise tests private: void add_noise(double *, int); diff --git a/src/misc/macroedit.cxx b/src/misc/macroedit.cxx index f2d2faf4..f96ddad2 100644 --- a/src/misc/macroedit.cxx +++ b/src/misc/macroedit.cxx @@ -158,6 +158,7 @@ void loadBrowser(Fl_Widget *widget) { w->add(_("\tvideo text")); w->add(_("\tTx RSID on,off,toggle")); w->add(_("\tRx RSID on,off,toggle")); + w->add(_("\tTx digits string")); w->add(LINE_SEP); w->add(_("\tCW QSK post-timing")); diff --git a/src/misc/macros.cxx b/src/misc/macros.cxx index 704ece84..9b1fd87b 100644 --- a/src/misc/macros.cxx +++ b/src/misc/macros.cxx @@ -141,6 +141,7 @@ void pAFC(string &, size_t &); void pLOCK(string &, size_t &); void pRX_RSID(string &, size_t &); void pTX_RSID(string &, size_t &); +void pDTMF(string &, size_t &); #ifdef __WIN32__ void pTALK(string &, size_t &); @@ -227,6 +228,7 @@ MTAGS mtags[] = { {"", pSRCHUP}, {"", pSRCHDN}, {"", pGOHOME}, @@ -627,6 +629,13 @@ void pCWID(string &s, size_t &i) s.replace( i, 6, ""); } +void pDTMF(string &s, size_t &i) +{ + size_t endbracket = s.find('>',i); + progdefaults.DTMFstr = s.substr(i + 6, endbracket - i - 6); + s.replace(i, endbracket - i + 1, ""); +} + void pRX(string &s, size_t &i) { s.replace (i, 4, "^r"); diff --git a/src/trx/modem.cxx b/src/trx/modem.cxx index 11cd8ddb..eda710e8 100644 --- a/src/trx/modem.cxx +++ b/src/trx/modem.cxx @@ -967,3 +967,89 @@ mfntchr idch2[] = { }; +//====================================================================== +// DTMF tone transmit +//====================================================================== +int modem::DTMF_row[] = { +941, 697, 697, 697, 770, 770, 770, 852, 852, 852, 941, 941, 697, 770, 852, 941}; +//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, *, #, A, B, C, D + +int modem::DTMF_col[] = { +1336, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1477, 1633, 1633, 1633, 1633}; +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, *, #, A, B, C, D + +//---------------------------------------------------------------------- +// transmit silence for specified time duration +//---------------------------------------------------------------------- + +void modem::DTMF_silence(int duration) +{ + double sr = active_modem->get_samplerate(); + int length = duration * sr / 1000; + memset(outbuf, 0, length * sizeof(*outbuf)); + active_modem->ModulateXmtr(outbuf, length); +} + +//---------------------------------------------------------------------- +// transmit DTMF tones for specific time interval +//---------------------------------------------------------------------- + +void modem::DTMF_two_tones(int rc) +{ + if (rc < 0 || rc > 15) return; + double sr = active_modem->get_samplerate(); + double phaseincr = 2.0 * M_PI * DTMF_row[rc] / sr; + double phase = 0; +printf("%d %d\n", DTMF_row[rc], DTMF_col[rc]); + int length = 50 * sr / 1000; + + for (int i = 0; i < length; i++) { + outbuf[i] = 0.5 * sin(phase); + phase += phaseincr; + } + + phaseincr = 2.0 * M_PI * DTMF_col[rc] / sr; + phase = 0; + for (int i = 0; i < length; i++) { + outbuf[i] += 0.5 * sin(phase); + phase += phaseincr; + } + for (int i = 0; i < RT; i++) { + outbuf[i] *= cwid_keyshape[i]; + outbuf[length - 1 - i] *= cwid_keyshape[i]; + } + + active_modem->ModulateXmtr(outbuf, length); + +} + +//---------------------------------------------------------------------- +// transmit the string contained in progdefaults.DTMFstr and output as +// dtmf valid characters, 0-9, *, #, A-D +// each pair of tones is separated by 50ms silence +// 500 msec silence for ' ', ',' or '-' +// 50 msec silence for invalid characters +//---------------------------------------------------------------------- + +void modem::DTMF_send() +{ + if (progdefaults.DTMFstr.empty()) return; + + int c = 0; + + RT = (int) (samplerate * 4 / 1000.0); // 4 msec rise/fall time + cwid_makeshape(); + + for(size_t i = 0; i < progdefaults.DTMFstr.length(); i++) { + c = progdefaults.DTMFstr[i]; + if (c == ' ' || c == ',' || c == '-') DTMF_silence(50); + else if (c >= '0' && c <= '9') DTMF_two_tones(c - '0'); + else if (c == '*') DTMF_two_tones(10); + else if (c == '#') DTMF_two_tones(11); + else if (c >= 'A' && c <= 'D') DTMF_two_tones(12 + c - 'A'); + else if (c >= 'a' && c <= 'd') DTMF_two_tones(12 + c - 'a'); + DTMF_silence(50); + } + progdefaults.DTMFstr.clear(); +} + diff --git a/src/trx/trx.cxx b/src/trx/trx.cxx index 5ccc821b..0d80b283 100644 --- a/src/trx/trx.cxx +++ b/src/trx/trx.cxx @@ -305,6 +305,8 @@ void trx_trx_transmit_loop() if (progdefaults.TransmitRSid) ReedSolomon->send(true); + active_modem->DTMF_send(); + while (trx_state == STATE_TX) { try { if (active_modem->tx_process() < 0) From 74364eed6844e3058f1da363dd2623ed7de1963a Mon Sep 17 00:00:00 2001 From: David Freese Date: Tue, 30 Aug 2011 14:09:00 -0500 Subject: [PATCH 03/54] DTMF class * Changed implementation to separate class, similar to RsID implementation * Added Delay and Tone Pulse Length parameters to - | | |_phone # - | |_250 msec pulse duration, 50 msec default - |_500 msec wait before first tone, 0 default * Decoder under development --- src/Makefile.am | 2 + src/dtmf/dtmf.cxx | 203 +++++++++++++++++++++++++++++++++++++++++ src/include/dtmf.h | 107 ++++++++++++++++++++++ src/include/modem.h | 7 -- src/misc/macroedit.cxx | 2 +- src/trx/modem.cxx | 88 ------------------ src/trx/trx.cxx | 8 +- 7 files changed, 320 insertions(+), 97 deletions(-) create mode 100644 src/dtmf/dtmf.cxx create mode 100644 src/include/dtmf.h diff --git a/src/Makefile.am b/src/Makefile.am index dd86ddf8..d0a3c9a4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -252,6 +252,7 @@ fldigi_SOURCES += \ dialogs/Viewer.cxx \ dialogs/htmlstrings.cxx \ dialogs/notifydialog.cxx \ + dtmf/dtmf.cxx \ thor/thor.cxx \ thor/thorvaricode.cxx \ dominoex/dominoex.cxx \ @@ -269,6 +270,7 @@ fldigi_SOURCES += \ include/htmlstrings.h \ include/arq_io.h \ include/confdialog.h \ + include/dtmf.h \ include/FTextView.h \ include/FTextRXTX.h \ include/fileselect.h \ diff --git a/src/dtmf/dtmf.cxx b/src/dtmf/dtmf.cxx new file mode 100644 index 00000000..0b5d405f --- /dev/null +++ b/src/dtmf/dtmf.cxx @@ -0,0 +1,203 @@ +// ---------------------------------------------------------------------------- +// +// DTMF.cxx +// +// Copyright (C) 2011 +// Dave Freese, W1HKJ +// +// This file is part of fldigi. +// +// Fldigi 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 3 of the License, or +// (at your option) any later version. +// +// Fldigi 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 fldigi. If not, see . +// ---------------------------------------------------------------------------- + +#include + +#include +#include +#include +#include + +#include "dtmf.h" +#include "filters.h" +#include "fft.h" +#include "misc.h" +#include "trx.h" +#include "waterfall.h" + +#include "fl_digi.h" +#include "configuration.h" +#include "confdialog.h" +#include "qrunner.h" +#include "notify.h" +#include "debug.h" + +#include "main.h" + +LOG_FILE_SOURCE(debug::LOG_MODEM); + +// tones in 4x4 array +// 697 770 842 941 1209 1336 1447 1633 + +int cDTMF::tones[] = {697, 770, 842, 941, 1209, 1336, 1477, 1633}; + +int cDTMF::row[] = { +941, 697, 697, 697, 770, 770, 770, 852, 852, 852, 941, 941, 697, 770, 852, 941}; +//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, *, #, A, B, C, D + +int cDTMF::col[] = { +1336, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1477, 1633, 1633, 1633, 1633}; +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, *, #, A, B, C, D + +cDTMF::PAIRS cDTMF::pairs[] = { +{0, 0, '1'}, {0, 1, '2'}, {0, 2, '3'}, {0, 3, 'A'}, +{1, 0, '4'}, {1, 1, '5'}, {1, 2, '6'}, {1, 3, 'B'}, +{2, 0, '7'}, {2, 1, '8'}, {2, 2, '9'}, {2, 3, 'C'}, +{3, 0, '*'}, {3, 1, '0'}, {3, 2, '#'}, {3, 3, 'D'} }; + +void cDTMF::makeshape() +{ + for (int i = 0; i < 128; i++) shape[i] = 1.0; + for (int i = 0; i < RT; i++) + shape[i] = 0.5 * (1.0 - cos (M_PI * i / RT)); +} + + +cDTMF::cDTMF() +{ +} + +//rx is a work in progress :>) + +void cDTMF::receive(const float* buf, size_t len) +{ + int binlo = 0, binhi = 0; + double val1 = 0, val2 = 0, avg = 1e-6; +//this doesn't work! + for (int i = 0; i < 8; i++) { + bins[i] = wf->powerDensity(tones[i], 4); + avg += bins[i] / 8; + } + for (int i = 0; i < 4; i++) { + if (bins[i] > val1) { val1 = bins[i]; binlo = i; } + if (bins[i+4] > val2) { val2 = bins[i+4]; binhi = i;} + } + if ((val1 / avg > 0.5) && (val2 / avg > 0.5)) { + for (int i = 0; i < 16; i++) { + if (pairs[i].lo == binlo && pairs[i].hi == binhi) { + printf("DTMF %c\n", pairs[i].ch); + break; + } + } + } +} + + +//====================================================================== +// DTMF tone transmit +//====================================================================== + +//---------------------------------------------------------------------- +// transmit silence for specified time duration in milliseconds +//---------------------------------------------------------------------- + +void cDTMF::silence(int len) +{ + double sr = active_modem->get_samplerate(); + int length = len * sr / 1000; + if (length > 16384) length = 16384; + memset(outbuf, 0, length * sizeof(*outbuf)); + active_modem->ModulateXmtr(outbuf, length); +} + +//---------------------------------------------------------------------- +// transmit DTMF tones for specific time interval +//---------------------------------------------------------------------- + +void cDTMF::two_tones(int rc) +{ + if (rc < 0 || rc > 15) return; + double sr = active_modem->get_samplerate(); + double phaseincr = 2.0 * M_PI * row[rc] / sr; + double phase = 0; + int length = duration * sr / 1000; + if (length > 16384) length = 16384; + + for (int i = 0; i < length; i++) { + outbuf[i] = 0.5 * sin(phase); + phase += phaseincr; + } + + phaseincr = 2.0 * M_PI * col[rc] / sr; + phase = 0; + for (int i = 0; i < length; i++) { + outbuf[i] += 0.5 * sin(phase); + phase += phaseincr; + } + for (int i = 0; i < RT; i++) { + outbuf[i] *= shape[i]; + outbuf[length - 1 - i] *= shape[i]; + } + + active_modem->ModulateXmtr(outbuf, length); +} + +//---------------------------------------------------------------------- +// transmit the string contained in progdefaults.DTMFstr and output as +// dtmf valid characters, 0-9, *, #, A-D +// each pair of tones is separated by 50ms silence +// 500 msec silence for ' ', ',' or '-' +// 50 msec silence for invalid characters +//---------------------------------------------------------------------- + +void cDTMF::send() +{ + if (progdefaults.DTMFstr.empty()) return; + + int c = 0, delay = 0; + duration = 50; + RT = (int)(active_modem->get_samplerate() * 4 / 1000.0); // 4 msec edge + makeshape(); + size_t colon = std::string::npos; + + size_t modifier = progdefaults.DTMFstr.find('D'); + if (modifier != std::string::npos) { + delay = atoi(&progdefaults.DTMFstr[modifier + 1]); + colon = progdefaults.DTMFstr.find(':', modifier); + progdefaults.DTMFstr.erase(modifier, colon - modifier + 1); + } + + modifier = progdefaults.DTMFstr.find('L'); + if (modifier != std::string::npos) { + duration = atoi(&progdefaults.DTMFstr[modifier + 1]); + colon = progdefaults.DTMFstr.find(':', modifier); + progdefaults.DTMFstr.erase(modifier, colon - modifier + 1); + } + + while (delay > 50) { silence(50); delay -= 50;} + if (delay) silence(delay); + + for(size_t i = 0; i < progdefaults.DTMFstr.length(); i++) { + c = progdefaults.DTMFstr[i]; + if (c == ' ' || c == ',' || c == '-') + silence(duration); + else if (c >= '0' && c <= '9') two_tones(c - '0'); + else if (c == '*') two_tones(10); + else if (c == '#') two_tones(11); + else if (c >= 'A' && c <= 'D') two_tones(12 + c - 'A'); + else if (c >= 'a' && c <= 'd') two_tones(12 + c - 'a'); + silence(duration); + } + progdefaults.DTMFstr.clear(); +} + diff --git a/src/include/dtmf.h b/src/include/dtmf.h new file mode 100644 index 00000000..795e7d96 --- /dev/null +++ b/src/include/dtmf.h @@ -0,0 +1,107 @@ +#include "filters.h" + +// #define X1 0 /* 350 dialtone */ +// #define X2 1 /* 440 ring, dialtone */ +// #define X3 2 /* 480 ring, busy */ +// #define X4 3 /* 620 busy */ + +// #define R1 4 /* 697, dtmf row 1 */ +// #define R2 5 /* 770, dtmf row 2 */ +// #define R3 6 /* 852, dtmf row 3 */ +// #define R4 8 /* 941, dtmf row 4 */ +// #define C1 10 /* 1209, dtmf col 1 */ +// #define C2 12 /* 1336, dtmf col 2 */ +// #define C3 13 /* 1477, dtmf col 3 */ +// #define C4 14 /* 1633, dtmf col 4 */ + +// #define B1 4 /* 700, blue box 1 */ +// #define B2 7 /* 900, bb 2 */ +// #define B3 9 /* 1100, bb 3 */ +// #define B4 11 /* 1300, bb4 */ +// #define B5 13 /* 1500, bb5 */ +// #define B6 15 /* 1700, bb6 */ +// #define B7 16 /* 2400, bb7 */ +// #define B8 17 /* 2600, bb8 */ + +// #define NUMTONES 18 + +/* values returned by detect + * 0-9 DTMF 0 through 9 or MF 0-9 + * 10-11 DTMF *, # + * 12-15 DTMF A,B,C,D + * 16-20 MF last column: C11, C12, KP1, KP2, ST + * 21 2400 + * 22 2600 + * 23 2400 + 2600 + * 24 DIALTONE + * 25 RING + * 26 BUSY + * 27 silence + * -1 invalid + */ +/* +#define D0 0 +#define D1 1 +#define D2 2 +#define D3 3 +#define D4 4 +#define D5 5 +#define D6 6 +#define D7 7 +#define D8 8 +#define D9 9 +#define DSTAR 10 +#define DPND 11 +#define DA 12 +#define DB 13 +#define DC 14 +#define DD 15 +#define DC11 16 +#define DC12 17 +#define DKP1 18 +#define DKP2 19 +#define DST 20 +#define D24 21 +#define D26 22 +#define D2426 23 +#define DDT 24 +#define DRING 25 +#define DBUSY 26 +#define DSIL 27 +*/ +/* translation of above codes into text */ +/* +char *dtran[] = { + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", + "*", "#", "A", "B", "C", "D", + "+C11 ", "+C12 ", " KP1+", " KP2+", "+ST ", + " 2400 ", " 2600 ", " 2400+2600 ", + " DIALTONE ", " RING ", " BUSY ","" }; +*/ +//#define RANGE 0.1 /* any thing higher than RANGE*peak is "on" */ +//#define THRESH 100.0 /* minimum level for the loudest tone */ +//#define FLUSH_TIME 100 /* 100 frames = 3 seconds */ + +class cDTMF { +struct PAIRS {int lo; int hi; char ch;}; +private: + static int row[]; + static int col[]; + static int tones[]; + static PAIRS pairs[]; + double bins[8]; + double outbuf[16384]; + double shape[128]; + int RT; + int duration; + +public: + cDTMF(); + ~cDTMF() {} + void receive(const float* buf, size_t len); + void makeshape(); + void silence(int); + void two_tones(int); + void send(); + +}; diff --git a/src/include/modem.h b/src/include/modem.h index 30f7f461..dde5cef1 100644 --- a/src/include/modem.h +++ b/src/include/modem.h @@ -65,8 +65,6 @@ protected: bool s2n_valid; unsigned cap; - static int DTMF_row[]; - static int DTMF_col[]; public: modem(); @@ -180,11 +178,6 @@ public: void cwid_sendtext (const std::string& s); void cwid(); -// for DTMF transmission - void DTMF_silence(int); - void DTMF_two_tones(int); - void DTMF_send(); - // for noise tests private: void add_noise(double *, int); diff --git a/src/misc/macroedit.cxx b/src/misc/macroedit.cxx index f96ddad2..e6a07ec2 100644 --- a/src/misc/macroedit.cxx +++ b/src/misc/macroedit.cxx @@ -158,7 +158,7 @@ void loadBrowser(Fl_Widget *widget) { w->add(_("\tvideo text")); w->add(_("\tTx RSID on,off,toggle")); w->add(_("\tRx RSID on,off,toggle")); - w->add(_("\tTx digits string")); + w->add(_("\t[Delay][Len](ms)")); w->add(LINE_SEP); w->add(_("\tCW QSK post-timing")); diff --git a/src/trx/modem.cxx b/src/trx/modem.cxx index eda710e8..26ec4cfd 100644 --- a/src/trx/modem.cxx +++ b/src/trx/modem.cxx @@ -965,91 +965,3 @@ mfntchr idch2[] = { {'}', { 0x00, 0x80, 0xC0, 0x40, 0x40, 0x40, 0x60, 0x60, 0x40, 0x40, 0x40, 0xC0, 0x80, 0x00 }, }, {'~', { 0x00, 0x98, 0xFC, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }; - - -//====================================================================== -// DTMF tone transmit -//====================================================================== -int modem::DTMF_row[] = { -941, 697, 697, 697, 770, 770, 770, 852, 852, 852, 941, 941, 697, 770, 852, 941}; -//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, *, #, A, B, C, D - -int modem::DTMF_col[] = { -1336, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1477, 1633, 1633, 1633, 1633}; -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, *, #, A, B, C, D - -//---------------------------------------------------------------------- -// transmit silence for specified time duration -//---------------------------------------------------------------------- - -void modem::DTMF_silence(int duration) -{ - double sr = active_modem->get_samplerate(); - int length = duration * sr / 1000; - memset(outbuf, 0, length * sizeof(*outbuf)); - active_modem->ModulateXmtr(outbuf, length); -} - -//---------------------------------------------------------------------- -// transmit DTMF tones for specific time interval -//---------------------------------------------------------------------- - -void modem::DTMF_two_tones(int rc) -{ - if (rc < 0 || rc > 15) return; - double sr = active_modem->get_samplerate(); - double phaseincr = 2.0 * M_PI * DTMF_row[rc] / sr; - double phase = 0; -printf("%d %d\n", DTMF_row[rc], DTMF_col[rc]); - int length = 50 * sr / 1000; - - for (int i = 0; i < length; i++) { - outbuf[i] = 0.5 * sin(phase); - phase += phaseincr; - } - - phaseincr = 2.0 * M_PI * DTMF_col[rc] / sr; - phase = 0; - for (int i = 0; i < length; i++) { - outbuf[i] += 0.5 * sin(phase); - phase += phaseincr; - } - for (int i = 0; i < RT; i++) { - outbuf[i] *= cwid_keyshape[i]; - outbuf[length - 1 - i] *= cwid_keyshape[i]; - } - - active_modem->ModulateXmtr(outbuf, length); - -} - -//---------------------------------------------------------------------- -// transmit the string contained in progdefaults.DTMFstr and output as -// dtmf valid characters, 0-9, *, #, A-D -// each pair of tones is separated by 50ms silence -// 500 msec silence for ' ', ',' or '-' -// 50 msec silence for invalid characters -//---------------------------------------------------------------------- - -void modem::DTMF_send() -{ - if (progdefaults.DTMFstr.empty()) return; - - int c = 0; - - RT = (int) (samplerate * 4 / 1000.0); // 4 msec rise/fall time - cwid_makeshape(); - - for(size_t i = 0; i < progdefaults.DTMFstr.length(); i++) { - c = progdefaults.DTMFstr[i]; - if (c == ' ' || c == ',' || c == '-') DTMF_silence(50); - else if (c >= '0' && c <= '9') DTMF_two_tones(c - '0'); - else if (c == '*') DTMF_two_tones(10); - else if (c == '#') DTMF_two_tones(11); - else if (c >= 'A' && c <= 'D') DTMF_two_tones(12 + c - 'A'); - else if (c >= 'a' && c <= 'd') DTMF_two_tones(12 + c - 'a'); - DTMF_silence(50); - } - progdefaults.DTMFstr.clear(); -} - diff --git a/src/trx/trx.cxx b/src/trx/trx.cxx index 0d80b283..cb8dc79a 100644 --- a/src/trx/trx.cxx +++ b/src/trx/trx.cxx @@ -37,6 +37,7 @@ #include "misc.h" #include "configuration.h" #include "status.h" +#include "dtmf.h" #include "soundconf.h" #include "ringbuffer.h" @@ -68,6 +69,7 @@ state_t trx_state; modem *active_modem = 0; cRsId *ReedSolomon = 0; +cDTMF *dtmf = 0; SoundBase *scard; static int _trx_tune; @@ -256,6 +258,7 @@ void trx_trx_receive_loop() active_modem->rx_process(rbvec[0].buf, numread); if (progdefaults.rsid) ReedSolomon->receive(fbuf, numread); +// dtmf->receive(fbuf, numread); } else { bool afc = progStatus.afconoff; @@ -305,7 +308,7 @@ void trx_trx_transmit_loop() if (progdefaults.TransmitRSid) ReedSolomon->send(true); - active_modem->DTMF_send(); + dtmf->send(); while (trx_state == STATE_TX) { try { @@ -526,6 +529,7 @@ void trx_start(void) if (scard) delete scard; if (ReedSolomon) delete ReedSolomon; + if (dtmf) delete dtmf; switch (progdefaults.btnAudioIOis) { @@ -552,6 +556,8 @@ void trx_start(void) } ReedSolomon = new cRsId; + dtmf = new cDTMF; + #endif // !BENCHMARK_MODE #if USE_NAMED_SEMAPHORES From ff185628bf2608e0559bcfc5e488d4ef86134ff7 Mon Sep 17 00:00:00 2001 From: Remi Chateauneu Date: Tue, 30 Aug 2011 18:32:41 -0500 Subject: [PATCH 04/54] Macros code cleanup * Removed useless extern definition. * Pass string index as value. * Calc closing bracket position once only. --- src/include/macros.h | 2 +- src/misc/macros.cxx | 476 +++++++++++++++++-------------------------- 2 files changed, 185 insertions(+), 293 deletions(-) diff --git a/src/include/macros.h b/src/include/macros.h index a5cd7e8f..3f863297 100644 --- a/src/include/macros.h +++ b/src/include/macros.h @@ -42,7 +42,7 @@ struct MACROTEXT { MACROTEXT(); private: std::string expanded; - void loadnewMACROS(std::string& s, size_t &i); + void loadnewMACROS(std::string& s, size_t &i, size_t endbracket); }; extern MACROTEXT macros; diff --git a/src/misc/macros.cxx b/src/misc/macros.cxx index 9b1fd87b..a9055592 100644 --- a/src/misc/macros.cxx +++ b/src/misc/macros.cxx @@ -66,187 +66,19 @@ MACROTEXT macros; CONTESTCNTR contest_count; static bool TransmitON = false; static bool ToggleTXRX = false; -int mNbr; +static int mNbr; std::string qso_time = ""; std::string qso_exchange = ""; -bool save_xchg; -size_t xbeg = 0, xend = 0; +static bool save_xchg; +static size_t xbeg = 0, xend = 0; string text2send = ""; string text2repeat = ""; string text2save = ""; + size_t repeatchar = 0; -struct MTAGS { const char *mTAG; void (*fp)(string &, size_t &);}; - -void pCALL(string &, size_t &); -void pFREQ(string &, size_t &); -void pLOC(string &, size_t &); -void pMODE(string &, size_t &); -void pNAME(string &, size_t &); -void pQTH(string &, size_t &); -void pRST(string &, size_t &); -void pMYCALL(string &, size_t &); -void pMYLOC(string &, size_t &); -void pMYNAME(string &, size_t &); -void pMYQTH(string &, size_t &); -void pMYRST(string &, size_t &); -void pQSOTIME(string &, size_t &); -void pLDT(string &, size_t &); -void pILDT(string &, size_t &); -void pZDT(string &, size_t &); -void pIZDT(string &, size_t &); -void pZT(string &, size_t &); -void pLT(string &, size_t &); -void pLD(string &, size_t &); -void pZD(string &, size_t &); -void pID(string &, size_t &); -void pTEXT(string &, size_t &); -void pCWID(string &, size_t &); -void pRX(string &, size_t &); -void pTX(string &, size_t &); -void pTXRX(string &, size_t &); -void pVER(string &, size_t &); -void pCNTR(string &, size_t &); -void pDECR(string &, size_t &); -void pINCR(string &, size_t &); -void pXIN(string &, size_t &); -void pXOUT(string &, size_t &); -void pSAVEXCHG(string &, size_t &); -void pXBEG(string &, size_t &); -void pXEND(string &, size_t &); -void pLOG(string &, size_t &); -void pLNW(string &, size_t &); -void pCLRLOG(string &, size_t &); -void pTIMER(string &, size_t &); -void pIDLE(string &, size_t &); -void pTUNE(string &, size_t &); -void pMODEM_compat(string &, size_t &); -void pMODEM(string &, size_t &); -void pEXEC(string &, size_t &); -void pSTOP(string &, size_t &); -void pCONT(string &, size_t &); -void pGET(string &, size_t &); -void pINFO1(string &, size_t &); -void pINFO2(string &, size_t &); -void pCLRRX(string &, size_t &); -void pCLRTX(string &, size_t &); -void pFILE(string &, size_t &); -void pWPM(string &, size_t &); -void pRISETIME(string &, size_t &); -void pPRE(string &, size_t &); -void pPOST(string &, size_t &); -void pAFC(string &, size_t &); -void pLOCK(string &, size_t &); -void pRX_RSID(string &, size_t &); -void pTX_RSID(string &, size_t &); -void pDTMF(string &, size_t &); - -#ifdef __WIN32__ -void pTALK(string &, size_t &); -#endif - -void pWAIT(string&, size_t &); -void pSRCHUP(string&, size_t&); -void pSRCHDN(string&, size_t&); -void pGOHOME(string&, size_t&); - -void pGOFREQ(string&, size_t&); -void pQSY(string&, size_t&); -void pQSYTO(string &, size_t&); -void pQSYFM(string &, size_t&); -void pRIGMODE(string&, size_t&); -void pFILWID(string&, size_t&); - -void pMAPIT(string&, size_t&); -void pREPEAT(string&, size_t&); - -//void pMACROS(string &, size_t &); - -MTAGS mtags[] = { -{"", pCALL}, -{"", pFREQ}, -{"", pLOC}, -{"", pMODE}, -{"", pNAME}, -{"", pQTH}, -{"", pRST}, -{"", pMYCALL}, -{"", pMYLOC}, -{"", pMYNAME}, -{"", pMYQTH}, -{"", pMYRST}, -{"", pQSOTIME}, -{"", pINFO1}, -{"", pINFO2}, -{"", pLDT}, -{"", pILDT}, -{"", pZDT}, -{"", pIZDT}, -{"", pLT}, -{"", pZT}, -{"", pLD}, -{"", pZD}, -{"", pID}, -{"", pTEXT}, -{"", pCWID}, -{"", pRX}, -{"", pTX}, -{"", pTXRX}, -{"", pVER}, -{"", pCNTR}, -{"", pDECR}, -{"", pINCR}, -{"", pXOUT}, -{"", pXIN}, -{"", pXOUT}, -{"", pXBEG}, -{"", pXEND}, -{"", pSAVEXCHG}, -{"", pLOG}, -{"", pLNW}, -{"", pCLRLOG}, -{"", pMODEM_compat}, -{"", pEXEC}, -{"", pSTOP}, -{"", pCONT}, -{"", pGET}, -{"", pCLRRX}, -{"", pCLRTX}, -{"", pSRCHUP}, -{"", pSRCHDN}, -{"", pGOHOME}, -{"", pQSYTO}, -{"", pQSYFM}, -{"", pMAPIT}, -{"", pREPEAT}, -#ifdef __WIN32__ -{"',i); string fname = s.substr(i+6, endbracket - i - 6); if (fname.length() > 0) { FILE *toadd = fopen(fname.c_str(), "r"); @@ -296,9 +127,8 @@ void pFILE(string &s, size_t &i) s.replace(i, endbracket - i + 1, ""); } -void pTIMER(string &s, size_t &i) +static void pTIMER(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); int number; string sTime = s.substr(i+7, endbracket - i - 7); if (sTime.length() > 0) { @@ -309,9 +139,8 @@ void pTIMER(string &s, size_t &i) s.replace(i, endbracket - i + 1, ""); } -void pREPEAT(string &s, size_t &i) +static void pREPEAT(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); progStatus.repeatMacro = mNbr; s.replace(i, endbracket - i + 1, ""); text2repeat = s; @@ -319,9 +148,8 @@ void pREPEAT(string &s, size_t &i) s.insert(i, "[REPEAT]"); } -void pWPM(string &s, size_t &i) +static void pWPM(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); int number; string sTime = s.substr(i+5, endbracket - i - 5); if (sTime.length() > 0) { @@ -334,9 +162,8 @@ void pWPM(string &s, size_t &i) s.replace(i, endbracket - i + 1, ""); } -void pRISETIME(string &s, size_t &i) +static void pRISETIME(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); float number; string sVal = s.substr(i+6, endbracket - i - 6); if (sVal.length() > 0) { @@ -349,9 +176,8 @@ void pRISETIME(string &s, size_t &i) s.replace(i, endbracket - i + 1, ""); } -void pPRE(string &s, size_t &i) +static void pPRE(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); float number; string sVal = s.substr(i+5, endbracket - i - 5); if (sVal.length() > 0) { @@ -364,9 +190,8 @@ void pPRE(string &s, size_t &i) s.replace(i, endbracket - i + 1, ""); } -void pPOST(string &s, size_t &i) +static void pPOST(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); float number; string sVal = s.substr(i+6, endbracket - i - 6); if (sVal.length() > 0) { @@ -380,11 +205,10 @@ void pPOST(string &s, size_t &i) } bool macro_idle_on = false; -float idleTime = 0; +static float idleTime = 0; -void pIDLE(string &s, size_t &i) +static void pIDLE(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); float number; string sTime = s.substr(i+6, endbracket - i - 6); if (sTime.length() > 0) { @@ -395,12 +219,11 @@ void pIDLE(string &s, size_t &i) s.replace(i, endbracket - i + 1, ""); } -bool useTune = false; -int tuneTime = 0; +static bool useTune = false; +static int tuneTime = 0; -void pTUNE(string &s, size_t &i) +static void pTUNE(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); int number; string sTime = s.substr(i+6, endbracket - i - 6); if (sTime.length() > 0) { @@ -411,12 +234,11 @@ void pTUNE(string &s, size_t &i) s.replace(i, endbracket - i + 1, ""); } -bool useWait = false; -int waitTime = 0; +static bool useWait = false; +static int waitTime = 0; -void pWAIT(string &s, size_t &i) +static void pWAIT(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); int number; string sTime = s.substr(i+6, endbracket - i - 6); if (sTime.length() > 0) { @@ -427,102 +249,101 @@ void pWAIT(string &s, size_t &i) s.replace(i, endbracket - i + 1, ""); } -void pINFO1(string &s, size_t &i) +static void pINFO1(string &s, size_t &i, size_t endbracket) { s.replace( i, 7, info1msg ); } -void pINFO2(string &s, size_t &i) +static void pINFO2(string &s, size_t &i, size_t endbracket) { s.replace( i, 7, info2msg ); } -void pCLRRX(string &s, size_t &i) +static void pCLRRX(string &s, size_t &i, size_t endbracket) { s.replace( i, 7, "" ); ReceiveText->clear(); } -void pCLRTX(string &s, size_t &i) +static void pCLRTX(string &s, size_t &i, size_t endbracket) { s.replace( i, 7, "" ); TransmitText->clear(); } -void pCALL(string &s, size_t &i) +static void pCALL(string &s, size_t &i, size_t endbracket) { s.replace( i, 6, inpCall->value() ); } -void pGET(string &s, size_t &i) +static void pGET(string &s, size_t &i, size_t endbracket) { s.erase( i, 9 ); GET = true; } -void pFREQ(string &s, size_t &i) +static void pFREQ(string &s, size_t &i, size_t endbracket) { s.replace( i, 6, inpFreq->value() ); } -void pLOC(string &s, size_t &i) +static void pLOC(string &s, size_t &i, size_t endbracket) { s.replace( i, 5, inpLoc->value() ); } -void pMODE(string &s, size_t &i) +static void pMODE(string &s, size_t &i, size_t endbracket) { s.replace( i, 6, active_modem->get_mode_name()); } -void pNAME(string &s, size_t &i) +static void pNAME(string &s, size_t &i, size_t endbracket) { s.replace( i, 6, inpName->value() ); } -void pQTH(string &s, size_t &i) +static void pQTH(string &s, size_t &i, size_t endbracket) { s.replace( i,5, inpQth->value() ); } -void pQSOTIME(string &s, size_t &i) +static void pQSOTIME(string &s, size_t &i, size_t endbracket) { qso_time = inpTimeOff->value(); s.replace( i, 9, qso_time.c_str() ); } -void pRST(string &s, size_t &i) +static void pRST(string &s, size_t &i, size_t endbracket) { s.replace( i, 5, cutstring(inpRstOut->value())); } - -void pMYCALL(string &s, size_t &i) +static void pMYCALL(string &s, size_t &i, size_t endbracket) { s.replace( i, 8, inpMyCallsign->value() ); } -void pMYLOC(string &s, size_t &i) +static void pMYLOC(string &s, size_t &i, size_t endbracket) { s.replace( i, 7, inpMyLocator->value() ); } -void pMYNAME(string &s, size_t &i) +static void pMYNAME(string &s, size_t &i, size_t endbracket) { s.replace( i, 8, inpMyName->value() ); } -void pMYQTH(string &s, size_t &i) +static void pMYQTH(string &s, size_t &i, size_t endbracket) { s.replace( i, 7, inpMyQth->value() ); } -void pMYRST(string &s, size_t &i) +static void pMYRST(string &s, size_t &i, size_t endbracket) { s.replace( i, 7, inpRstIn->value() ); } -void pLDT(string &s, size_t &i) +static void pLDT(string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -533,7 +354,7 @@ void pLDT(string &s, size_t &i) s.replace( i, 5, szDt); } -void pILDT(string &s, size_t &i) +static void pILDT(string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -544,7 +365,7 @@ void pILDT(string &s, size_t &i) s.replace( i, 6, szDt); } -void pZDT(string &s, size_t &i) +static void pZDT(string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -555,7 +376,7 @@ void pZDT(string &s, size_t &i) s.replace( i, 5, szDt); } -void pIZDT(string &s, size_t &i) +static void pIZDT(string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -566,7 +387,7 @@ void pIZDT(string &s, size_t &i) s.replace( i, 6, szDt); } -void pLT(string &s, size_t &i) +static void pLT(string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -577,7 +398,7 @@ void pLT(string &s, size_t &i) s.replace( i, 4, szDt); } -void pZT(string &s, size_t &i) +static void pZT(string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -588,7 +409,7 @@ void pZT(string &s, size_t &i) s.replace( i, 4, szDt); } -void pLD(string &s, size_t &i) +static void pLD(string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -599,7 +420,7 @@ void pLD(string &s, size_t &i) s.replace( i, 4, szDt); } -void pZD(string &s, size_t &i) +static void pZD(string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -610,51 +431,50 @@ void pZD(string &s, size_t &i) s.replace( i, 4, szDt); } -void pID(string &s, size_t &i) +static void pID(string &s, size_t &i, size_t endbracket) { progdefaults.macroid = true; s.replace( i, 4, ""); } -void pTEXT(string &s, size_t &i) +static void pTEXT(string &s, size_t &i, size_t endbracket) { progdefaults.macrotextid = true; s.replace( i, 6, ""); } -void pCWID(string &s, size_t &i) +static void pCWID(string &s, size_t &i, size_t endbracket) { progdefaults.macroCWid = true; s.replace( i, 6, ""); } -void pDTMF(string &s, size_t &i) +static void pDTMF(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); progdefaults.DTMFstr = s.substr(i + 6, endbracket - i - 6); s.replace(i, endbracket - i + 1, ""); } -void pRX(string &s, size_t &i) +static void pRX(string &s, size_t &i, size_t endbracket) { s.replace (i, 4, "^r"); } -void pTX(string &s, size_t &i) +static void pTX(string &s, size_t &i, size_t endbracket) { s.erase(i, 4); TransmitON = true; } -void pTXRX(string &s, size_t &i) +static void pTXRX(string &s, size_t &i, size_t endbracket) { s.erase(i, 7); ToggleTXRX = true; } -void pVER(string &s, size_t &i) +static void pVER(string &s, size_t &i, size_t endbracket) { string progname; progname = "Fldigi "; @@ -662,7 +482,7 @@ void pVER(string &s, size_t &i) s.replace( i, 5, progname ); } -void pCNTR(string &s, size_t &i) +static void pCNTR(string &s, size_t &i, size_t endbracket) { int contestval; contestval = contest_count.count; @@ -674,7 +494,7 @@ void pCNTR(string &s, size_t &i) s.replace (i, 6, ""); } -void pDECR(string &s, size_t &i) +static void pDECR(string &s, size_t &i, size_t endbracket) { int contestval; contest_count.count--; @@ -684,7 +504,7 @@ void pDECR(string &s, size_t &i) updateOutSerNo(); } -void pINCR(string &s, size_t &i) +static void pINCR(string &s, size_t &i, size_t endbracket) { int contestval; contest_count.count++; @@ -693,51 +513,51 @@ void pINCR(string &s, size_t &i) updateOutSerNo(); } -void pXIN(string &s, size_t &i) +static void pXIN(string &s, size_t &i, size_t endbracket) { s.replace( i, 5, inpXchgIn->value() ); } -void pXOUT(string &s, size_t &i) +static void pXOUT(string &s, size_t &i, size_t endbracket) { s.replace( i, 6, cutstring(progdefaults.myXchg.c_str())); } -void pXBEG(string &s, size_t &i) +static void pXBEG(string &s, size_t &i, size_t endbracket) { s.replace( i, 6, ""); xbeg = i; } -void pXEND(string &s, size_t &i) +static void pXEND(string &s, size_t &i, size_t endbracket) { s.replace( i, 6, ""); xend = i; } -void pSAVEXCHG(string &s, size_t &i) +static void pSAVEXCHG(string &s, size_t &i, size_t endbracket) { save_xchg = true; s.replace( i, 10, ""); } -void pLOG(string &s, size_t &i) +static void pLOG(string &s, size_t &i, size_t endbracket) { qsoSave_cb(0, 0); s.replace(i, 5, ""); } -void pLNW(string &s, size_t &i) +static void pLNW(string &s, size_t &i, size_t endbracket) { s.replace(i, 5, "^L"); } -void pCLRLOG(string &s, size_t &i) +static void pCLRLOG(string &s, size_t &i, size_t endbracket) { s.replace(i, 10, "^C"); } -void pMODEM_compat(string &s, size_t &i) +static void pMODEM_compat(string &s, size_t &i, size_t endbracket) { size_t j, k, len = s.length(); @@ -764,7 +584,7 @@ void pMODEM_compat(string &s, size_t &i) #include #include "re.h" -void pMODEM(string &s, size_t &i) +static void pMODEM(string &s, size_t &i, size_t endbracket) { static fre_t re("", REG_EXTENDED); @@ -843,9 +663,8 @@ void pMODEM(string &s, size_t &i) s.erase(i, o[0].rm_eo - i); } -void pAFC(string &s, size_t &i) +static void pAFC(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); string sVal = s.substr(i+5, endbracket - i - 5); if (sVal.length() > 0) { // sVal = on|off|t [ON, OFF or Toggle] @@ -861,9 +680,8 @@ void pAFC(string &s, size_t &i) s.replace(i, endbracket - i + 1, ""); } -void pLOCK(string &s, size_t &i) +static void pLOCK(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); string sVal = s.substr(i+6, endbracket - i - 6); if (sVal.length() > 0) { // sVal = on|off|t [ON, OFF or Toggle] @@ -880,9 +698,8 @@ void pLOCK(string &s, size_t &i) s.replace(i, endbracket - i + 1, ""); } -void pTX_RSID(string &s, size_t &i) +static void pTX_RSID(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); string sVal = s.substr(i+8, endbracket - i - 8); if (sVal.length() > 0) { // sVal = on|off|t [ON, OFF or Toggle] @@ -898,9 +715,8 @@ void pTX_RSID(string &s, size_t &i) s.replace(i, endbracket - i + 1, ""); } -void pRX_RSID(string &s, size_t &i) +static void pRX_RSID(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); string sVal = s.substr(i+8, endbracket - i - 8); if (sVal.length() > 0) { // sVal = on|off|t [ON, OFF or Toggle] @@ -917,9 +733,8 @@ void pRX_RSID(string &s, size_t &i) } #ifdef __WIN32__ -void pTALK(string &s, size_t &i) +static void pTALK(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); string sVal = s.substr(i+6, endbracket - i - 6); if (sVal.length() > 0) { // sVal = on|off [ON, OFF] @@ -934,7 +749,7 @@ void pTALK(string &s, size_t &i) } #endif -void pSRCHUP(string &s, size_t &i) +static void pSRCHUP(string &s, size_t &i, size_t endbracket) { s.replace( i, 8, ""); active_modem->searchUp(); @@ -942,7 +757,7 @@ void pSRCHUP(string &s, size_t &i) wf->insert_text(true); } -void pSRCHDN(string &s, size_t &i) +static void pSRCHDN(string &s, size_t &i, size_t endbracket) { s.replace( i, 8, ""); active_modem->searchDown(); @@ -950,7 +765,7 @@ void pSRCHDN(string &s, size_t &i) wf->insert_text(true); } -void pGOHOME(string &s, size_t &i) +static void pGOHOME(string &s, size_t &i, size_t endbracket) { s.replace( i, 8, ""); if (active_modem == cw_modem) @@ -961,9 +776,8 @@ void pGOHOME(string &s, size_t &i) active_modem->set_freq(progdefaults.PSKsweetspot); } -void pGOFREQ(string &s, size_t &i) +static void pGOFREQ(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); int number; string sGoFreq = s.substr(i+8, endbracket - i - 8); if (sGoFreq.length() > 0) { @@ -977,21 +791,20 @@ void pGOFREQ(string &s, size_t &i) s.replace(i, endbracket - i + 1, ""); } -void pQSYTO(string &s, size_t &i) +static void pQSYTO(string &s, size_t &i, size_t endbracket) { s.replace( i, 7, ""); do_qsy(true); } -void pQSYFM(string &s, size_t &i) +static void pQSYFM(string &s, size_t &i, size_t endbracket) { s.replace( i, 7, ""); do_qsy(false); } -void pQSY(string &s, size_t &i) +static void pQSY(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); int rf = 0; int audio = 0; float rfd = 0; @@ -1026,18 +839,16 @@ void pQSY(string &s, size_t &i) s.replace(i, endbracket - i + 1, ""); } -void pRIGMODE(string& s, size_t& i) +static void pRIGMODE(string& s, size_t& i, size_t endbracket) { - size_t endbracket = s.find('>',i); string sMode = s.substr(i+9, endbracket - i - 9); qso_opMODE->value(sMode.c_str()); cb_qso_opMODE(); s.replace(i, endbracket - i + 1, ""); } -void pFILWID(string& s, size_t& i) +static void pFILWID(string& s, size_t& i, size_t endbracket) { - size_t endbracket = s.find('>',i); string sWidth = s.substr(i+8, endbracket - i - 8); qso_opBW->value(sWidth.c_str()); cb_qso_opBW(); @@ -1154,7 +965,7 @@ void set_macro_env(void) } #ifndef __MINGW32__ -void pEXEC(string &s, size_t &i) +static void pEXEC(string &s, size_t &i, size_t endbracket) { size_t start, end; if ((start = s.find('>', i)) == string::npos || @@ -1218,7 +1029,8 @@ void pEXEC(string &s, size_t &i) // option 2: do nothing and allow it to be parsed for more macros } #else // !__MINGW32__ -void pEXEC(string& s, size_t& i) + +static void pEXEC(string& s, size_t& i, size_t endbracket) { size_t start, end; if ((start = s.find('>', i)) == string::npos || @@ -1244,7 +1056,7 @@ void pEXEC(string& s, size_t& i) } #endif // !__MINGW32__ -void MAPIT(int how) +static void MAPIT(int how) { float lat = 0, lon = 0; string sCALL = inpCall->value(); @@ -1290,9 +1102,8 @@ void MAPIT(int how) cb_mnuVisitURL(NULL, (void*)url.c_str()); } -void pMAPIT(string &s, size_t &i) +static void pMAPIT(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); string sVal = s.substr(i + 7, endbracket - i - 7); if (sVal.length() > 0) { if (sVal.compare(0,3,"adr") == 0) @@ -1309,18 +1120,103 @@ void pMAPIT(string &s, size_t &i) expand = false; } -void pSTOP(string &s, size_t &i) +static void pSTOP(string &s, size_t &i, size_t endbracket) { s.erase(i, s.find('>', i) + 1 - i); expand = false; } -void pCONT(string &s, size_t &i) +static void pCONT(string &s, size_t &i, size_t endbracket) { s.erase(i, s.find('>', i) + 1 - i); expand = true; } +struct MTAGS { const char *mTAG; void (*fp)(string &, size_t&, size_t );}; + +MTAGS mtags[] = { +{"", pCALL}, +{"", pFREQ}, +{"", pLOC}, +{"", pMODE}, +{"", pNAME}, +{"", pQTH}, +{"", pRST}, +{"", pMYCALL}, +{"", pMYLOC}, +{"", pMYNAME}, +{"", pMYQTH}, +{"", pMYRST}, +{"", pQSOTIME}, +{"", pINFO1}, +{"", pINFO2}, +{"", pLDT}, +{"", pILDT}, +{"", pZDT}, +{"", pIZDT}, +{"", pLT}, +{"", pZT}, +{"", pLD}, +{"", pZD}, +{"", pID}, +{"", pTEXT}, +{"", pCWID}, +{"", pRX}, +{"", pTX}, +{"", pTXRX}, +{"", pVER}, +{"", pCNTR}, +{"", pDECR}, +{"", pINCR}, +{"", pXOUT}, +{"", pXIN}, +{"", pXOUT}, +{"", pXBEG}, +{"", pXEND}, +{"", pSAVEXCHG}, +{"", pLOG}, +{"", pLNW}, +{"", pCLRLOG}, +{"", pMODEM_compat}, +{"", pEXEC}, +{"", pSTOP}, +{"", pCONT}, +{"", pGET}, +{"", pCLRRX}, +{"", pCLRTX}, +{"", pSRCHUP}, +{"", pSRCHDN}, +{"", pGOHOME}, +{"", pQSYTO}, +{"", pQSYFM}, +{"", pMAPIT}, +{"", pREPEAT}, +#ifdef __WIN32__ +{"label( name[i].c_str()); -// btnMacro[i]->redraw_label(); -// } -// return 0; } else { mFile.getline(szLine, 4095); @@ -1426,9 +1317,8 @@ void MACROTEXT::saveMacroFile() } } -void MACROTEXT::loadnewMACROS(string &s, size_t &i) +void MACROTEXT::loadnewMACROS(string &s, size_t &i, size_t endbracket) { - size_t endbracket = s.find('>',i); string fname = s.substr(i+8, endbracket - i - 8); if (fname.length() > 0) { loadMacros(fname); @@ -1457,14 +1347,15 @@ string MACROTEXT::expandMacro(int n) tuneTime = 0; while ((idx = expanded.find('<', idx)) != string::npos) { - if (expanded.find("',idx); + if (expanded.find("", idx) == idx) - pCONT(expanded, idx); + pCONT(expanded, idx, endbracket); if (!expand) { idx++; continue; @@ -1473,7 +1364,7 @@ string MACROTEXT::expandMacro(int n) pMtags = mtags; while (pMtags->mTAG != 0) { if (expanded.find(pMtags->mTAG,idx) == idx) { - pMtags->fp(expanded,idx); + pMtags->fp(expanded,idx, endbracket); break; } pMtags++; @@ -1615,7 +1506,7 @@ void MACROTEXT::execute(int n) void MACROTEXT::repeat(int n) { expandMacro(n); -printf("%s\n",text2repeat.c_str()); + LOG_INFO("%s",text2repeat.c_str()); macro_idle_on = false; if (idleTime) progStatus.repeatIdleTime = idleTime; } @@ -1632,9 +1523,9 @@ MACROTEXT::MACROTEXT() } -string mtext = +static string mtext = "//fldigi macro definition file extended\n\ -// This file defines the macro structe(s) for the digital modem program, fldigi\n\ +// This file defines the macro structure(s) for the digital modem program, fldigi\n\ // It also serves as a basis for any macros that are written by the user\n\ //\n\ // The top line of this file should always be the first line in every macro \n\ @@ -1662,3 +1553,4 @@ void MACROTEXT::saveMacros(const string& fname) { mfile.close(); changed = false; } + From 49e2dd288942d9fd6c383bd09004dbfeaa8b542b Mon Sep 17 00:00:00 2001 From: David Freese Date: Sat, 3 Sep 2011 10:48:33 -0500 Subject: [PATCH 05/54] CW Prosign defaults * Changed Morse table to comply with configuration.h defaults --- src/cw_rtty/morse.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cw_rtty/morse.cxx b/src/cw_rtty/morse.cxx index 19eb6018..78b9f3e4 100644 --- a/src/cw_rtty/morse.cxx +++ b/src/cw_rtty/morse.cxx @@ -51,13 +51,13 @@ static CW_TABLE cw_table[] = { /* Prosigns */ {'=', "", "-...-" }, // 0 {'~', "", ".-.-" }, // 1 - {'%', "", ".-..." }, // 2 - {'+', "", ".-.-." }, // 3 - {'>', "", "...-.-" }, // 4 - {'<', "", "-.--." }, // 5 + {'<', "", ".-..." }, // 2 + {'>', "", ".-.-." }, // 3 + {'%', "", "...-.-" }, // 4 + {'+', "", "-.--." }, // 5 {'&', "", "..-.-" }, // 6 - {'}', "", "....--" }, // 7 - {'{', "", "...-." }, // 8 + {'{', "", "....--" }, // 7 + {'}', "", "...-." }, // 8 /* ASCII 7bit letters */ {'A', "A", ".-" }, {'B', "B", "-..." }, From 166fe5931fe45cce838a15e72185938f3567fd3f Mon Sep 17 00:00:00 2001 From: David Freese Date: Sat, 3 Sep 2011 15:18:57 -0500 Subject: [PATCH 06/54] DTMF decoder * Added decoder to cDTMF * Changed Delay parameters to - | | |_phone # - | |_250 msec pulse length, 50 msec default - |_500 msec wait before first tone, 0 default --- src/dialogs/confdialog.cxx | 21 +++- src/dialogs/confdialog.fl | 21 +++- src/dialogs/fl_digi.cxx | 6 ++ src/dtmf/dtmf.cxx | 201 ++++++++++++++++++++++++------------ src/include/confdialog.h | 2 + src/include/configuration.h | 3 + src/include/dtmf.h | 133 ++++++++---------------- src/include/fl_digi.h | 1 + src/misc/macroedit.cxx | 2 +- src/soundcard/sound.cxx | 10 ++ src/trx/trx.cxx | 2 +- 11 files changed, 241 insertions(+), 161 deletions(-) diff --git a/src/dialogs/confdialog.cxx b/src/dialogs/confdialog.cxx index 5a017493..cc9ed41d 100644 --- a/src/dialogs/confdialog.cxx +++ b/src/dialogs/confdialog.cxx @@ -2865,6 +2865,14 @@ static void cb_chkRxStream(Fl_Check_Button* o, void*) { progdefaults.changed = true; } +Fl_Group *tabDTMF=(Fl_Group *)0; + +Fl_Check_Button *chkDTMFdecode=(Fl_Check_Button *)0; + +static void cb_chkDTMFdecode(Fl_Check_Button* o, void*) { + progdefaults.DTMFdecode = o->value(); +} + Fl_Group *tabQRZ=(Fl_Group *)0; Fl_Round_Button *btnQRZcdrom=(Fl_Round_Button *)0; @@ -2998,7 +3006,6 @@ static const char szProsigns[] = "~|%|&|+|=|{|}|<|>|[|]| "; tabOperator->tooltip(_("Operator information")); tabOperator->callback((Fl_Callback*)cb_tabOperator); tabOperator->when(FL_WHEN_CHANGED); - tabOperator->hide(); { Fl_Group* o = new Fl_Group(5, 35, 490, 165, _("Station")); o->box(FL_ENGRAVED_FRAME); o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); @@ -3690,6 +3697,7 @@ ab and newline are automatically included.")); tabUI->end(); } // Fl_Group* tabUI { tabWaterfall = new Fl_Group(0, 25, 501, 347, _("Waterfall")); + tabWaterfall->hide(); { tabsWaterfall = new Fl_Tabs(0, 25, 501, 347); tabsWaterfall->color((Fl_Color)FL_LIGHT1); tabsWaterfall->selection_color((Fl_Color)FL_LIGHT1); @@ -4022,6 +4030,7 @@ an merging")); tabWaterfall->end(); } // Fl_Group* tabWaterfall { tabModems = new Fl_Group(-4, 25, 521, 347, _("Modems")); + tabModems->hide(); { tabsModems = new Fl_Tabs(-4, 25, 521, 347); tabsModems->selection_color((Fl_Color)FL_LIGHT1); tabsModems->align(FL_ALIGN_TOP_RIGHT); @@ -6468,6 +6477,16 @@ d frequency")); } // Fl_Group* o tabText_IO->end(); } // Fl_Group* tabText_IO + { tabDTMF = new Fl_Group(0, 50, 500, 320, _("DTMF")); + tabDTMF->hide(); + { Fl_Check_Button* o = chkDTMFdecode = new Fl_Check_Button(175, 71, 175, 20, _("Decode DTMF tones")); + chkDTMFdecode->tooltip(_("Send rx text to file: textout.txt")); + chkDTMFdecode->down_box(FL_DOWN_BOX); + chkDTMFdecode->callback((Fl_Callback*)cb_chkDTMFdecode); + o->value(progdefaults.DTMFdecode); + } // Fl_Check_Button* chkDTMFdecode + tabDTMF->end(); + } // Fl_Group* tabDTMF tabsMisc->end(); } // Fl_Tabs* tabsMisc tabMisc->end(); diff --git a/src/dialogs/confdialog.fl b/src/dialogs/confdialog.fl index 23e27c80..505f0f11 100644 --- a/src/dialogs/confdialog.fl +++ b/src/dialogs/confdialog.fl @@ -105,8 +105,8 @@ static const char szProsigns[] = "~|%|&|+|=|{|}|<|>|[|]| ";} {} } { Fl_Group tabOperator { label Operator - callback {progdefaults.changed = true;} - tooltip {Operator information} xywh {0 25 500 345} when 1 hide + callback {progdefaults.changed = true;} selected + tooltip {Operator information} xywh {0 25 500 345} when 1 } { Fl_Group {} { label Station open @@ -904,7 +904,7 @@ connect_to_log_server();} } Fl_Group tabWaterfall { label Waterfall open - xywh {0 25 501 347} + xywh {0 25 501 347} hide } { Fl_Tabs tabsWaterfall {open xywh {0 25 501 347} color 50 selection_color 50 @@ -1067,7 +1067,7 @@ progdefaults.changed = true;} Fl_Check_Button btnUseWideCursor { label {Wide cursor} callback {progdefaults.UseWideCursor = o->value(); -progdefaults.changed = true;} selected +progdefaults.changed = true;} tooltip {Show bandwidth tracks on waterfall} xywh {15 195 145 20} down_box DOWN_BOX code0 {o->value(progdefaults.UseWideCursor);} } @@ -1239,7 +1239,7 @@ behaves inside the waterfall} xywh {15 196 150 22} down_box BORDER_BOX align 8 } Fl_Group tabModems { label Modems open - xywh {-4 25 521 347} + xywh {-4 25 521 347} hide } { Fl_Tabs tabsModems {open xywh {-4 25 521 347} selection_color 50 align 9 @@ -3641,6 +3641,17 @@ progdefaults.changed = true;} } } } + Fl_Group tabDTMF { + label DTMF open + xywh {0 50 500 320} hide + } { + Fl_Check_Button chkDTMFdecode { + label {Decode DTMF tones} + callback {progdefaults.DTMFdecode = o->value();} + tooltip {Send rx text to file: textout.txt} xywh {175 71 175 20} down_box DOWN_BOX + code0 {o->value(progdefaults.DTMFdecode);} + } + } } } Fl_Group tabQRZ { diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 65120551..63bead64 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -3536,6 +3536,12 @@ void showMacroSet() { set_macroLabels(); } +void showDTMF(const string s) { + string dtmfstr = "\n "; + dtmfstr.append(s); + ReceiveText->add(dtmfstr.c_str()); +} + void setwfrange() { wf->opmode(); } diff --git a/src/dtmf/dtmf.cxx b/src/dtmf/dtmf.cxx index 0b5d405f..d6934011 100644 --- a/src/dtmf/dtmf.cxx +++ b/src/dtmf/dtmf.cxx @@ -28,19 +28,16 @@ #include #include -#include "dtmf.h" -#include "filters.h" -#include "fft.h" -#include "misc.h" #include "trx.h" -#include "waterfall.h" + +#include "dtmf.h" +#include "misc.h" #include "fl_digi.h" #include "configuration.h" -#include "confdialog.h" #include "qrunner.h" -#include "notify.h" #include "debug.h" +#include "status.h" #include "main.h" @@ -49,21 +46,129 @@ LOG_FILE_SOURCE(debug::LOG_MODEM); // tones in 4x4 array // 697 770 842 941 1209 1336 1447 1633 -int cDTMF::tones[] = {697, 770, 842, 941, 1209, 1336, 1477, 1633}; +int cDTMF::row[] = {697, 770, 852, 941}; -int cDTMF::row[] = { -941, 697, 697, 697, 770, 770, 770, 852, 852, 852, 941, 941, 697, 770, 852, 941}; -//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, *, #, A, B, C, D +int cDTMF::col[] = {1209, 1336, 1477, 1633}; -int cDTMF::col[] = { -1336, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1477, 1633, 1633, 1633, 1633}; -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, *, #, A, B, C, D +const char cDTMF::rc[] = "123A456B789C*0#D"; -cDTMF::PAIRS cDTMF::pairs[] = { -{0, 0, '1'}, {0, 1, '2'}, {0, 2, '3'}, {0, 3, 'A'}, -{1, 0, '4'}, {1, 1, '5'}, {1, 2, '6'}, {1, 3, 'B'}, -{2, 0, '7'}, {2, 1, '8'}, {2, 2, '9'}, {2, 3, 'C'}, -{3, 0, '*'}, {3, 1, '0'}, {3, 2, '#'}, {3, 3, 'D'} }; +//====================================================================== +// DTMF tone receive +//====================================================================== +// tone #s and coefficients +// 8000 Hz sampling N == 240 +// 11025 Hz sampling N == 331 + +/* + * calculate the power of each tone using Goertzel filters + */ +void cDTMF::calc_power() +{ + double sr = active_modem->get_samplerate(); +// reset row freq filters + for (int i = 0; i < 4; i++) filt[i]->reset(240, row[i], sr); +// reset col freq filters + for (int i = 0; i < 4; i++) filt[i+4]->reset(240, col[i], sr); + + for (int i = 0; i < framesize; i++) + for (int j = 0; j < NUMTONES; j++) + filt[j]->run(data[i]); + + for (int i = 0; i < NUMTONES; i++) + power[i] = filt[i]->mag(); + + maxpower = 0; + minpower = 1e6; + for (int i = 0; i < NUMTONES;i++) { + if (power[i] > maxpower) + maxpower = power[i]; + if (power[i] < minpower) + minpower = power[i]; + } + if ( minpower == 0 ) minpower = 1e-3; +} + + +/* + * detect which signals are present. + * + */ + +int cDTMF::decode() +{ + calc_power(); + + if (maxpower < (10 * progStatus.sldrSquelchValue)) + return ' '; + + int r = -1, c = -1; + double pwr = 0; + for (int i = 0; i < 4; i++) + if (power[i] > pwr) { + pwr = power[i]; + r = i; + } + pwr = 0; + for (int i = 0; i < 4; i++) + if (power[i+4] > pwr) { + pwr = power[i+4]; + c = i; + } + if (r == -1 || c == -1) + return ' '; + return rc[r*4 + c]; +} + +/* + * read in frames, output the decoded + * results + */ +void cDTMF::receive(const float* buf, size_t len) +{ + int x; + static size_t dptr = 0; + size_t bufptr = 0; + + if (!progdefaults.DTMFdecode) return; + + framesize = (active_modem->get_samplerate() == 8000) ? 240 : 331; + + while (1) { + int i; + for ( i = dptr; i < framesize; i++) { + data[i] = buf[bufptr]; + bufptr++; + if (bufptr == len) break; + } + if (i < framesize) { + dptr = i + 1; + return; + } + dptr = 0; + + x = decode(); + if (x == ' ') { + silence_time++; + if (silence_time == 4 && !dtmfchars.empty()) dtmfchars += ' '; + if (silence_time == FLUSH_TIME) { + if (!dtmfchars.empty()) { + REQ(showDTMF, dtmfchars); + dtmfchars.clear(); + } + silence_time = 0; + } + } else { + silence_time = 0; + if (x != last && last == ' ') + dtmfchars += x; + } + last = x; + } +} + +//====================================================================== +// DTMF tone transmit +//====================================================================== void cDTMF::makeshape() { @@ -72,41 +177,6 @@ void cDTMF::makeshape() shape[i] = 0.5 * (1.0 - cos (M_PI * i / RT)); } - -cDTMF::cDTMF() -{ -} - -//rx is a work in progress :>) - -void cDTMF::receive(const float* buf, size_t len) -{ - int binlo = 0, binhi = 0; - double val1 = 0, val2 = 0, avg = 1e-6; -//this doesn't work! - for (int i = 0; i < 8; i++) { - bins[i] = wf->powerDensity(tones[i], 4); - avg += bins[i] / 8; - } - for (int i = 0; i < 4; i++) { - if (bins[i] > val1) { val1 = bins[i]; binlo = i; } - if (bins[i+4] > val2) { val2 = bins[i+4]; binhi = i;} - } - if ((val1 / avg > 0.5) && (val2 / avg > 0.5)) { - for (int i = 0; i < 16; i++) { - if (pairs[i].lo == binlo && pairs[i].hi == binhi) { - printf("DTMF %c\n", pairs[i].ch); - break; - } - } - } -} - - -//====================================================================== -// DTMF tone transmit -//====================================================================== - //---------------------------------------------------------------------- // transmit silence for specified time duration in milliseconds //---------------------------------------------------------------------- @@ -124,11 +194,14 @@ void cDTMF::silence(int len) // transmit DTMF tones for specific time interval //---------------------------------------------------------------------- -void cDTMF::two_tones(int rc) +void cDTMF::two_tones(int ch) { - if (rc < 0 || rc > 15) return; + if (!strchr(rc, ch)) return; + int pos = strchr(rc, ch) - rc; + int r = pos / 4; + int c = pos % 4; double sr = active_modem->get_samplerate(); - double phaseincr = 2.0 * M_PI * row[rc] / sr; + double phaseincr = 2.0 * M_PI * row[r] / sr; double phase = 0; int length = duration * sr / 1000; if (length > 16384) length = 16384; @@ -138,7 +211,7 @@ void cDTMF::two_tones(int rc) phase += phaseincr; } - phaseincr = 2.0 * M_PI * col[rc] / sr; + phaseincr = 2.0 * M_PI * col[c] / sr; phase = 0; for (int i = 0; i < length; i++) { outbuf[i] += 0.5 * sin(phase); @@ -170,7 +243,7 @@ void cDTMF::send() makeshape(); size_t colon = std::string::npos; - size_t modifier = progdefaults.DTMFstr.find('D'); + size_t modifier = progdefaults.DTMFstr.find("W"); if (modifier != std::string::npos) { delay = atoi(&progdefaults.DTMFstr[modifier + 1]); colon = progdefaults.DTMFstr.find(':', modifier); @@ -191,11 +264,11 @@ void cDTMF::send() c = progdefaults.DTMFstr[i]; if (c == ' ' || c == ',' || c == '-') silence(duration); - else if (c >= '0' && c <= '9') two_tones(c - '0'); - else if (c == '*') two_tones(10); - else if (c == '#') two_tones(11); - else if (c >= 'A' && c <= 'D') two_tones(12 + c - 'A'); - else if (c >= 'a' && c <= 'd') two_tones(12 + c - 'a'); + else if ( (c >= '0' && c <= '9') || + c == '*' || + c == '#' || + (c >= 'A' && c <= 'D') ) + two_tones(c); silence(duration); } progdefaults.DTMFstr.clear(); diff --git a/src/include/confdialog.h b/src/include/confdialog.h index f8b692fc..a98d8ba2 100644 --- a/src/include/confdialog.h +++ b/src/include/confdialog.h @@ -401,6 +401,8 @@ extern void close_talker(); extern Fl_Light_Button *btnConnectTalker; extern Fl_Check_Button *btn_auto_talk; extern Fl_Check_Button *chkRxStream; +extern Fl_Group *tabDTMF; +extern Fl_Check_Button *chkDTMFdecode; extern Fl_Group *tabQRZ; extern Fl_Round_Button *btnQRZcdrom; extern Fl_Input2 *txtQRZpathname; diff --git a/src/include/configuration.h b/src/include/configuration.h index 7b4b06f7..235a3662 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -564,6 +564,9 @@ 0.0) \ ELEM_(bool, macroCWid, "", "", false) \ ELEM_(std::string, DTMFstr, "", "", "") \ + ELEM_(bool, DTMFdecode, "DTMFDECODE", \ + "Decode received DTMF tones", \ + false) \ ELEM_(int, videowidth, "VIDEOWIDTH", \ "Video ID text width (characters per row)", \ 1) \ diff --git a/src/include/dtmf.h b/src/include/dtmf.h index 795e7d96..9fdbec6a 100644 --- a/src/include/dtmf.h +++ b/src/include/dtmf.h @@ -1,107 +1,62 @@ +#include + #include "filters.h" -// #define X1 0 /* 350 dialtone */ -// #define X2 1 /* 440 ring, dialtone */ -// #define X3 2 /* 480 ring, busy */ -// #define X4 3 /* 620 busy */ - -// #define R1 4 /* 697, dtmf row 1 */ -// #define R2 5 /* 770, dtmf row 2 */ -// #define R3 6 /* 852, dtmf row 3 */ -// #define R4 8 /* 941, dtmf row 4 */ -// #define C1 10 /* 1209, dtmf col 1 */ -// #define C2 12 /* 1336, dtmf col 2 */ -// #define C3 13 /* 1477, dtmf col 3 */ -// #define C4 14 /* 1633, dtmf col 4 */ - -// #define B1 4 /* 700, blue box 1 */ -// #define B2 7 /* 900, bb 2 */ -// #define B3 9 /* 1100, bb 3 */ -// #define B4 11 /* 1300, bb4 */ -// #define B5 13 /* 1500, bb5 */ -// #define B6 15 /* 1700, bb6 */ -// #define B7 16 /* 2400, bb7 */ -// #define B8 17 /* 2600, bb8 */ - -// #define NUMTONES 18 - -/* values returned by detect - * 0-9 DTMF 0 through 9 or MF 0-9 - * 10-11 DTMF *, # - * 12-15 DTMF A,B,C,D - * 16-20 MF last column: C11, C12, KP1, KP2, ST - * 21 2400 - * 22 2600 - * 23 2400 + 2600 - * 24 DIALTONE - * 25 RING - * 26 BUSY - * 27 silence - * -1 invalid - */ -/* -#define D0 0 -#define D1 1 -#define D2 2 -#define D3 3 -#define D4 4 -#define D5 5 -#define D6 6 -#define D7 7 -#define D8 8 -#define D9 9 -#define DSTAR 10 -#define DPND 11 -#define DA 12 -#define DB 13 -#define DC 14 -#define DD 15 -#define DC11 16 -#define DC12 17 -#define DKP1 18 -#define DKP2 19 -#define DST 20 -#define D24 21 -#define D26 22 -#define D2426 23 -#define DDT 24 -#define DRING 25 -#define DBUSY 26 -#define DSIL 27 -*/ -/* translation of above codes into text */ -/* -char *dtran[] = { - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", - "*", "#", "A", "B", "C", "D", - "+C11 ", "+C12 ", " KP1+", " KP2+", "+ST ", - " 2400 ", " 2600 ", " 2400+2600 ", - " DIALTONE ", " RING ", " BUSY ","" }; -*/ -//#define RANGE 0.1 /* any thing higher than RANGE*peak is "on" */ -//#define THRESH 100.0 /* minimum level for the loudest tone */ -//#define FLUSH_TIME 100 /* 100 frames = 3 seconds */ - class cDTMF { -struct PAIRS {int lo; int hi; char ch;}; +public: +#define N 240 // 30 msec interval at 8000 sps + +#define RANGE 0.5 /* any thing higher than RANGE*peak is "on" */ +#define THRESH 1000 /* 6 dB s/n for detection */ +#define FLUSH_TIME 10 /* 10 frames ~ 330 millisecond */ + +#define NUMTONES 8 + private: + double power[NUMTONES]; + double thresh; + double maxpower; + double minpower; + double data[350]; + + goertzel *filt[NUMTONES]; + + int framesize; + + static double coef[]; + static int k[]; + static const char *dtran[]; + static int row[]; static int col[]; - static int tones[]; - static PAIRS pairs[]; - double bins[8]; + static const char rc[]; + double outbuf[16384]; double shape[128]; int RT; int duration; + int silence_time; + int last; + std::string dtmfchars; public: - cDTMF(); - ~cDTMF() {} + cDTMF() { + for (int i = 0; i < 4; i++) filt[i] = new goertzel(240, row[i], 8000); + for (int i = 0; i < 4; i++) filt[i+4] = new goertzel(240, col[i], 8000); + for (int i = 0; i < N; i++) data[i] = 0; + dtmfchars.clear(); + framesize = 240; // 8000 sr default + silence_time = 0; + last = ' '; + } + ~cDTMF() {}; +// receive + void calc_power(); + int decode(); void receive(const float* buf, size_t len); +// transmit void makeshape(); void silence(int); void two_tones(int); void send(); - }; diff --git a/src/include/fl_digi.h b/src/include/fl_digi.h index 9ef6b7b1..9a7ed0e6 100644 --- a/src/include/fl_digi.h +++ b/src/include/fl_digi.h @@ -198,6 +198,7 @@ extern void show_bw(const std::string& sWidth); extern void show_spot(bool v); extern void showMacroSet(); extern void setwfrange(); +extern void showDTMF(const std::string s); extern void xmtrcv_selection_color(); extern void rev_selection_color(); diff --git a/src/misc/macroedit.cxx b/src/misc/macroedit.cxx index e6a07ec2..67349a10 100644 --- a/src/misc/macroedit.cxx +++ b/src/misc/macroedit.cxx @@ -158,7 +158,7 @@ void loadBrowser(Fl_Widget *widget) { w->add(_("\tvideo text")); w->add(_("\tTx RSID on,off,toggle")); w->add(_("\tRx RSID on,off,toggle")); - w->add(_("\t[Delay][Len](ms)")); + w->add(_("\t[Wait][Len](ms)")); w->add(LINE_SEP); w->add(_("\tCW QSK post-timing")); diff --git a/src/soundcard/sound.cxx b/src/soundcard/sound.cxx index 1e2f4146..92ad4177 100644 --- a/src/soundcard/sound.cxx +++ b/src/soundcard/sound.cxx @@ -264,11 +264,21 @@ sf_count_t SoundBase::read_file(SNDFILE* file, float* buf, size_t count) sf_count_t SoundBase::write_file(SNDFILE* file, float* buf, size_t count) { + FILE *dfile = fopen("dtmfdata.txt", "a"); + for (size_t i = 0; i < count; i++) + fprintf(dfile, "%f\n", buf[i]); + fclose(dfile); + WRITE_FILE(float, file, buf, count); } sf_count_t SoundBase::write_file(SNDFILE* file, double* buf, size_t count) { + FILE *dfile = fopen("dtmfdata.txt", "a"); + for (size_t i = 0; i < count; i++) + fprintf(dfile, "%f\n", (float)buf[i]); + fclose(dfile); + WRITE_FILE(double, file, buf, count); } diff --git a/src/trx/trx.cxx b/src/trx/trx.cxx index cb8dc79a..2476caaa 100644 --- a/src/trx/trx.cxx +++ b/src/trx/trx.cxx @@ -258,7 +258,7 @@ void trx_trx_receive_loop() active_modem->rx_process(rbvec[0].buf, numread); if (progdefaults.rsid) ReedSolomon->receive(fbuf, numread); -// dtmf->receive(fbuf, numread); + dtmf->receive(fbuf, numread); } else { bool afc = progStatus.afconoff; From a776fe86626180df14860fe4d4aebd8ca72d7440 Mon Sep 17 00:00:00 2001 From: David Freese Date: Sun, 4 Sep 2011 05:46:40 -0500 Subject: [PATCH 07/54] Version 3.21.14 Maintenance release --- ChangeLog | 19 +++++++++++++++++++ configure.ac | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index dce26382..ed71e79e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,26 @@ +=Version 3.21.14= + +2011-09-03 David Freese + + 166fe59: DTMF decoder + 49e2dd2: CW Prosign defaults + +2011-08-30 Remi Chateauneu + + ff18562: Macros code cleanup + +2011-08-30 David Freese + + 74364ee: DTMF class + 5af9f3a: DTMF encoder + 39fe31b: Wide Cursor Tracks + + =Version 3.21.13= + 2011-08-07 Pavel Milanes Costa 5f3c3da: Update to Spanish translation diff --git a/configure.ac b/configure.ac index 966aa928..97fd2ae9 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [3]) m4_define(FLDIGI_MINOR, [21]) -m4_define(FLDIGI_PATCH, [.13]) +m4_define(FLDIGI_PATCH, [.14]) m4_define(FLARQ_MAJOR, [4]) m4_define(FLARQ_MINOR, [3]) m4_define(FLARQ_PATCH, [.1]) From 261275ea95899ab64dde40d24f1aa77d55c3ea41 Mon Sep 17 00:00:00 2001 From: Remi Chateauneu Date: Sun, 4 Sep 2011 08:40:00 -0500 Subject: [PATCH 08/54] modem::display_metric now sets the member modem::m --- src/dialogs/fl_digi.cxx | 6 +++--- src/include/fl_digi.h | 2 +- src/include/modem.h | 9 +-------- src/trx/modem.cxx | 6 ++++++ 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 63bead64..92bda965 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -5224,7 +5224,7 @@ void put_Bandwidth(int bandwidth) wf->Bandwidth ((int)bandwidth); } -static void set_metric(double metric) +static void callback_set_metric(double metric) { pgrsSquelch->value(metric); if (!progStatus.sqlonoff) @@ -5236,10 +5236,10 @@ static void set_metric(double metric) btnSQL->redraw_label(); } -void display_metric(double metric) +void global_display_metric(double metric) { FL_LOCK_D(); - REQ_DROP(set_metric, metric); + REQ_DROP(callback_set_metric, metric); FL_UNLOCK_D(); FL_AWAKE_D(); } diff --git a/src/include/fl_digi.h b/src/include/fl_digi.h index 9a7ed0e6..22fff043 100644 --- a/src/include/fl_digi.h +++ b/src/include/fl_digi.h @@ -166,7 +166,7 @@ extern void cb_mnuVisitURL(Fl_Widget*, void* arg); extern void put_freq(double frequency); extern void put_Bandwidth(int bandwidth); -extern void display_metric(double metric); +extern void global_display_metric(double metric); extern void put_cwRcvWPM(double wpm); extern void set_scope_mode(Digiscope::scope_mode md); diff --git a/src/include/modem.h b/src/include/modem.h index dde5cef1..2d3941b3 100644 --- a/src/include/modem.h +++ b/src/include/modem.h @@ -85,17 +85,11 @@ public: virtual void searchDown() {}; virtual void searchUp() {}; -// void update_syncscope(); - void HistoryON(bool val) {historyON = val;} bool HistoryON() { return historyON;} -// void set_mode(trx_mode); trx_mode get_mode(); const char *get_mode_name() { return mode_info[get_mode()].sname;} -// void set_state(state_t); -// void set_state_wait(state_t); -// state_t get_state(); virtual void set_freq(double); int get_freq(); void init_freqlock(); @@ -105,6 +99,7 @@ public: double get_txfreq(); double get_txfreq_woffset(); void set_metric(double); + void display_metric(double); double get_metric(); void set_reverse(bool on); bool get_reverse() { return reverse; } @@ -153,8 +148,6 @@ private: void wfid_make_tones(int numchars); void wfid_send(int numchars); -// double peakval(int symbol, int mask); -// int findmask(int symbol); void wfid_sendchars(std::string s); diff --git a/src/trx/modem.cxx b/src/trx/modem.cxx index 26ec4cfd..704adc87 100644 --- a/src/trx/modem.cxx +++ b/src/trx/modem.cxx @@ -223,6 +223,12 @@ void modem::set_metric(double m) metric = m; } +void modem::display_metric(double m) +{ + set_metric(m); + ::global_display_metric(m); +} + double modem::get_metric(void) { return metric; From e0ee3a9735d89e641b78e921b1e0f293349f0f50 Mon Sep 17 00:00:00 2001 From: Remi Chateauneu Date: Sun, 4 Sep 2011 08:42:00 -0500 Subject: [PATCH 09/54] Added wefax::adjust_metric method. --- src/wefax/wefax.cxx | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/wefax/wefax.cxx b/src/wefax/wefax.cxx index d66d5dc9..ff359e99 100644 --- a/src/wefax/wefax.cxx +++ b/src/wefax/wefax.cxx @@ -681,6 +681,7 @@ private: void save_automatic(const char * extra_msg); + void adjust_metric(double snr); void decode_apt(int x, const fax_signal & the_signal ); void decode_phasing(int x, const fax_signal & the_signal ); bool decode_image(int x); @@ -808,6 +809,25 @@ void fax_implementation::decode(const int* buf, int nb_samples) } } +// Estimate a rough metric which must be between 0 and 1. +// 20 = 20.0 * log10(snr) is a reasonable value, i.e. snr=10 +void fax_implementation::adjust_metric(double snr) +{ + // Computes on the fly the max and min of snr, so we can clamp. + static double max_snr = 0.0, min_snr = 0.0 ; + if( snr > max_snr ) + max_snr = snr ; + else + if( snr < min_snr ) + min_snr = snr ; + + if( min_snr == max_snr ) return ; + + double metric = 100 * (snr - min_snr) / (max_snr - min_snr); + + m_ptr_wefax->display_metric(metric); +} + // The number of transitions between black and white is counted. After 1/2 // second, the frequency is calculated. If it matches the APT start frequency, // the state skips to the detection of phasing lines, if it matches the apt @@ -828,6 +848,7 @@ void fax_implementation::decode_apt(int x, const fax_signal & the_signal ) char snr_buffer[128]; snprintf(snr_buffer, sizeof(snr_buffer), "s/n %3.0f dB", 20.0 * log10(tmp_snr)); put_Status1(snr_buffer); + adjust_metric(tmp_snr); m_apt_count=m_apt_trans=0; From c565815d2944c370ff7a7c0b1140345a238ad680 Mon Sep 17 00:00:00 2001 From: David Freese Date: Mon, 12 Sep 2011 19:21:13 -0500 Subject: [PATCH 10/54] CW QSK * Discard all pre/post timing if QSK on right channel is disabled --- src/cw_rtty/cw.cxx | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/cw_rtty/cw.cxx b/src/cw_rtty/cw.cxx index 19748329..fe17c35b 100644 --- a/src/cw_rtty/cw.cxx +++ b/src/cw_rtty/cw.cxx @@ -661,18 +661,23 @@ void cw::send_symbol(int bits, int len) keydown = symlen + delta ; keyup = symlen - delta; - kpre = (int)(progdefaults.CWpre * 8); - if (kpre > symlen) kpre = symlen; + if (progdefaults.QSK) { + kpre = (int)(progdefaults.CWpre * 8); + if (kpre > symlen) kpre = symlen; - if (progdefaults.CWnarrow) { - if (keydown - 2*knum < 0) - kpost = knum + (int)(progdefaults.CWpost * 8); - else - kpost = keydown - knum + (int)(progdefaults.CWpost * 8); - } else - kpost = keydown + (int)(progdefaults.CWpost * 8); + if (progdefaults.CWnarrow) { + if (keydown - 2*knum < 0) + kpost = knum + (int)(progdefaults.CWpost * 8); + else + kpost = keydown - knum + (int)(progdefaults.CWpost * 8); + } else + kpost = keydown + (int)(progdefaults.CWpost * 8); - if (kpost < 0) kpost = 0; + if (kpost < 0) kpost = 0; + } else { + kpre = 0; + kpost = 0; + } if (firstelement) { firstelement = false; From 5a9607ae8ee607bc7c0a6a5614f77510bb02984d Mon Sep 17 00:00:00 2001 From: David Freese Date: Fri, 16 Sep 2011 18:16:44 -0500 Subject: [PATCH 11/54] Control-Z bug fix * Fix for seg fault when pressing ctrl-Z immediately after double Escape --- src/widgets/Fl_Text_Buffer_mod_1_1.cxx | 1 + src/widgets/Fl_Text_Buffer_mod_1_3.cxx | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/widgets/Fl_Text_Buffer_mod_1_1.cxx b/src/widgets/Fl_Text_Buffer_mod_1_1.cxx index 9fc64601..665409c7 100644 --- a/src/widgets/Fl_Text_Buffer_mod_1_1.cxx +++ b/src/widgets/Fl_Text_Buffer_mod_1_1.cxx @@ -273,6 +273,7 @@ void Fl_Text_Buffer_mod::replace( int start, int end, const char *s ) { // Range check... if (!s) return; if (start < 0) start = 0; + if (end < 0) end = 0; if (end > mLength) end = mLength; call_predelete_callbacks( start, end-start ); diff --git a/src/widgets/Fl_Text_Buffer_mod_1_3.cxx b/src/widgets/Fl_Text_Buffer_mod_1_3.cxx index 7a8d9960..bffbabac 100644 --- a/src/widgets/Fl_Text_Buffer_mod_1_3.cxx +++ b/src/widgets/Fl_Text_Buffer_mod_1_3.cxx @@ -335,6 +335,8 @@ void Fl_Text_Buffer_mod::replace(int start, int end, const char *text) return; if (start < 0) start = 0; + if (end < 0) + end = 0; if (end > mLength) end = mLength; From 405816e701f3102e4ddc75b14f2d4668a2408e3a Mon Sep 17 00:00:00 2001 From: David Freese Date: Thu, 8 Sep 2011 15:16:15 -0500 Subject: [PATCH 12/54] Log Server lookup * Added cty.dat search when connect to log server - cty.dat must be installed in the current fldigi files directory --- src/logbook/xmlrpc_log.cxx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/logbook/xmlrpc_log.cxx b/src/logbook/xmlrpc_log.cxx index c43a7b49..ef88b557 100644 --- a/src/logbook/xmlrpc_log.cxx +++ b/src/logbook/xmlrpc_log.cxx @@ -26,6 +26,8 @@ #include "util.h" #include "date.h" #include "logbook.h" +#include "logger.h" +#include "locator.h" #include "fl_digi.h" #include "adif_io.h" #include "modem.h" @@ -119,6 +121,19 @@ bool xml_get_record(const char *callsign) inpLoc->value(""); inpNotes->value(""); } + if (inpLoc->value()[0]) { + double lon1, lat1, lon2, lat2; + double azimuth, distance; + char szAZ[4]; + if ( locator2longlat(&lon1, &lat1, progdefaults.myLocator.c_str()) == RIG_OK && + locator2longlat(&lon2, &lat2, inpLoc->value()) == RIG_OK && + qrb(lon1, lat1, lon2, lat2, &distance, &azimuth) == RIG_OK ) { + snprintf(szAZ,sizeof(szAZ),"%0.f", azimuth); + inpAZ->value(szAZ); + } else + inpAZ->value(""); + } else + inpAZ->value(""); return true; } From ab472e0ce5d3291f95c0160a2b03d74e7095f705 Mon Sep 17 00:00:00 2001 From: David Freese Date: Sun, 18 Sep 2011 08:17:30 -0500 Subject: [PATCH 13/54] CW/RTTY init fault * Modified transmit code for rtty preamble * Added missing stopflag initialization in CW and RTTY modem class --- src/cw_rtty/cw.cxx | 1 + src/cw_rtty/rtty.cxx | 27 ++++++++++++++------------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/cw_rtty/cw.cxx b/src/cw_rtty/cw.cxx index fe17c35b..e14f3c35 100644 --- a/src/cw_rtty/cw.cxx +++ b/src/cw_rtty/cw.cxx @@ -95,6 +95,7 @@ void cw::init() rx_init(); use_paren = progdefaults.CW_use_paren; prosigns = progdefaults.CW_prosigns; + stopflag = false; } cw::~cw() { diff --git a/src/cw_rtty/rtty.cxx b/src/cw_rtty/rtty.cxx index 929bde96..a0a9da7b 100644 --- a/src/cw_rtty/rtty.cxx +++ b/src/cw_rtty/rtty.cxx @@ -121,6 +121,7 @@ void rtty::init() bool wfrev = wf->Reverse(); bool wfsb = wf->USB(); reverse = wfrev ^ !wfsb; + stopflag = false; if (progdefaults.StartAtSweetSpot) set_freq(progdefaults.RTTYsweetspot); @@ -730,9 +731,10 @@ void rtty::send_char(int c) void rtty::send_idle() { - if (nbits == 5) + if (nbits == 5) { send_char(LETTERS); - else + txmode = LETTERS; + } else send_char(0); } @@ -743,13 +745,13 @@ int rtty::tx_process() int c; if (preamble > 0) { - preamble--; - send_symbol(1); - if (preamble == 0 && nbits == 5) { + for (int i = 0; i < preamble; i++) + send_symbol(1); + if (nbits == 5) { send_char(LETTERS); txmode = LETTERS; } - return 0; + preamble = 0; } c = get_tx_char(); @@ -772,16 +774,15 @@ int rtty::tx_process() return -1; } -// if NOT Baudot - if (nbits != 5) { - send_char(c); - return 0; - } - // send idle character if c == -1 if (c == -1) { send_idle(); - txmode = LETTERS; + return 0; + } + +// if NOT Baudot + if (nbits != 5) { + send_char(c); return 0; } From d2c33e4889cb42a4d7016e7cb19b054c7b80dcfb Mon Sep 17 00:00:00 2001 From: David Freese Date: Mon, 19 Sep 2011 15:07:13 -0500 Subject: [PATCH 14/54] RTTY baud * Corrected Macro selection of RTTY:45.45 * Changed status display to show 45.45 vice 45.5 --- src/cw_rtty/rtty.cxx | 10 ++++++++-- src/misc/macros.cxx | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/cw_rtty/rtty.cxx b/src/cw_rtty/rtty.cxx index a0a9da7b..61991e32 100644 --- a/src/cw_rtty/rtty.cxx +++ b/src/cw_rtty/rtty.cxx @@ -135,7 +135,10 @@ void rtty::init() rx_init(); put_MODEstatus(mode); - snprintf(msg1, sizeof(msg1), "%-4.1f / %-4.0f", rtty_baud, rtty_shift); + if ((rtty_baud - (int)rtty_baud) == 0) + snprintf(msg1, sizeof(msg1), "%-3.0f / %-4.0f", rtty_baud, rtty_shift); + else + snprintf(msg1, sizeof(msg1), "%-4.2f / %-4.0f", rtty_baud, rtty_shift); put_Status1(msg1); if (progdefaults.PreferXhairScope) set_scope_mode(Digiscope::XHAIRS); @@ -213,7 +216,10 @@ void rtty::restart() metric = 0.0; - snprintf(msg1, sizeof(msg1), "%-4.1f / %-4.0f", rtty_baud, rtty_shift); + if ((rtty_baud - (int)rtty_baud) == 0) + snprintf(msg1, sizeof(msg1), "%-3.0f / %-4.0f", rtty_baud, rtty_shift); + else + snprintf(msg1, sizeof(msg1), "%-4.2f / %-4.0f", rtty_baud, rtty_shift); put_Status1(msg1); put_MODEstatus(mode); for (int i = 0; i < 1024; i++) QI[i].re = QI[i].im = 0.0; diff --git a/src/misc/macros.cxx b/src/misc/macros.cxx index a9055592..51fcf1ae 100644 --- a/src/misc/macros.cxx +++ b/src/misc/macros.cxx @@ -631,7 +631,7 @@ static void pMODEM(string &s, size_t &i, size_t endbracket) if (args.at(0) != DBL_MIN) set_rtty_shift((int)args[0]); if (args.at(1) != DBL_MIN) - set_rtty_baud((int)args[1]); + set_rtty_baud((float)args[1]); if (args.at(2) != DBL_MIN) set_rtty_bits((int)args[2]); break; From bb258cd1fc6448223ab2a434c5e40f1b7b69a197 Mon Sep 17 00:00:00 2001 From: David Freese Date: Wed, 21 Sep 2011 08:39:40 -0500 Subject: [PATCH 15/54] Inline macro tags * Created ability to delay execution of designated tags until the time of occurrence in the transmit character stream. These include: - where the date defaults to current date. --- src/Makefile.am | 2 + src/dialogs/fl_digi.cxx | 139 ++++++++++-- src/dtmf/dtmf.cxx | 2 - src/globals/globals.cxx | 2 + src/include/fl_digi.h | 11 + src/include/globals.h | 2 + src/include/macros.h | 12 +- src/include/modem.h | 2 + src/include/nullmodem.h | 48 ++++ src/include/trx.h | 5 +- src/misc/macroedit.cxx | 35 +-- src/misc/macros.cxx | 486 +++++++++++++++++++++++++++++++++++++--- src/mt63/mt63.cxx | 13 +- src/trx/modem.cxx | 1 + src/trx/nullmodem.cxx | 91 ++++++++ src/trx/trx.cxx | 29 ++- 16 files changed, 794 insertions(+), 86 deletions(-) create mode 100644 src/include/nullmodem.h create mode 100644 src/trx/nullmodem.cxx diff --git a/src/Makefile.am b/src/Makefile.am index d0a3c9a4..efe570fb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -368,6 +368,7 @@ fldigi_SOURCES += \ include/rsid.h \ include/rtty.h \ include/view_rtty.h \ + include/nullmodem.h \ include/rx_extract.h \ include/speak.h \ include/serial.h \ @@ -480,6 +481,7 @@ fldigi_SOURCES += \ ssb/ssb.cxx \ throb/throb.cxx \ trx/modem.cxx \ + trx/nullmodem.cxx \ trx/trx.cxx \ waterfall/colorbox.cxx \ waterfall/digiscope.cxx \ diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 92bda965..7672ac33 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -77,6 +77,7 @@ #endif #include "rigio.h" #include "rigMEM.h" +#include "nullmodem.h" #include "psk.h" #include "cw.h" #include "mfsk.h" @@ -970,6 +971,11 @@ void init_modem(trx_mode mode, int freq) mode = NUM_MODES - 1; return init_modem(mode, freq); + case MODE_NULL: + startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem : + *mode_info[mode].modem = new NULLMODEM, freq); + break; + case MODE_CW: startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem : *mode_info[mode].modem = new cw, freq); @@ -2220,6 +2226,7 @@ void stopMacroTimer() progStatus.timer = 0; progStatus.repeatMacro = -1; Fl::remove_timeout(macro_timer); + Fl::remove_timeout(macro_timed_execute); btnMacroTimer->label(0); btnMacroTimer->color(FL_BACKGROUND_COLOR); @@ -2240,6 +2247,32 @@ void macro_timer(void*) Fl::repeat_timeout(1.0, macro_timer); } +void macro_timed_execute(void *) +{ + if (exec_date == zdate() && exec_time == ztime()) { + macros.timed_execute(); + btnMacroTimer->label(0); + btnMacroTimer->color(FL_BACKGROUND_COLOR); + btnMacroTimer->set_output(); + } else { + Fl::repeat_timeout(1.0, macro_timed_execute); + } +} + +void startTimedExecute(std::string &title) +{ + ENSURE_THREAD(FLMAIN_TID); + Fl::add_timeout(0.0, macro_timed_execute); + string txt = "Macro '"; + txt.append(title).append("' scheduled at "); + txt.append(exec_time).append(", on ").append(exec_date).append("\n"); + btnMacroTimer->label("SKED"); + btnMacroTimer->color(fl_rgb_color(240, 240, 0)); + btnMacroTimer->redraw_label(); + ReceiveText->clear(); + ReceiveText->add(txt.c_str(), FTextBase::CTRL); +} + void cbMacroTimerButton(Fl_Widget*, void*) { stopMacroTimer(); @@ -3017,6 +3050,7 @@ Fl_Menu_Item menu_[] = { { mode_info[MODE_PSK250].name, 0, cb_init_mode, (void *)MODE_PSK250, 0, FL_NORMAL_LABEL, 0, 14, 0}, {0,0,0,0,0,0,0,0,0}, +{ mode_info[MODE_NULL].name, 0, cb_init_mode, (void *)MODE_NULL, 0, FL_NORMAL_LABEL, 0, 14, 0}, { mode_info[MODE_SSB].name, 0, cb_init_mode, (void *)MODE_SSB, 0, FL_NORMAL_LABEL, 0, 14, 0}, { mode_info[MODE_WWV].name, 0, cb_init_mode, (void *)MODE_WWV, 0, FL_NORMAL_LABEL, 0, 14, 0}, @@ -3631,7 +3665,7 @@ void create_fl_digi_main_primary() { int Hmacrobtn; int xpos; int ypos; - int wblank; + int wBLANK; int fnt = fl_font(); int fsize = fl_size(); @@ -4273,14 +4307,14 @@ void create_fl_digi_main_primary() { Fl_Group *btngroup2 = new Fl_Group(0, Y + 1, progStatus.mainW - Hmacros, Hmacros - 1); Wmacrobtn = (btngroup2->w()) / NUMMACKEYS; Hmacrobtn = btngroup2->h() - 1; - wblank = (btngroup2->w() - NUMMACKEYS * Wmacrobtn) / 2; + wBLANK = (btngroup2->w() - NUMMACKEYS * Wmacrobtn) / 2; xpos = 0; ypos = btngroup2->y(); for (int i = 0; i < NUMMACKEYS; i++) { if (i == 4 || i == 8) { - bx = new Fl_Box(xpos, ypos, wblank, Hmacrobtn); + bx = new Fl_Box(xpos, ypos, wBLANK, Hmacrobtn); bx->box(FL_FLAT_BOX); - xpos += wblank; + xpos += wBLANK; } btnMacro[NUMMACKEYS + i] = new Fl_Button(xpos, ypos, Wmacrobtn, Hmacrobtn, macros.name[NUMMACKEYS + i].c_str()); @@ -4452,14 +4486,14 @@ void create_fl_digi_main_primary() { Fl_Group *btngroup1 = new Fl_Group(0, Y+1, progStatus.mainW - Hmacros, Hmacros-1); Wmacrobtn = (btngroup1->w()) / NUMMACKEYS; Hmacrobtn = btngroup1->h() - 1; - wblank = (btngroup1->w() - NUMMACKEYS * Wmacrobtn) / 2; + wBLANK = (btngroup1->w() - NUMMACKEYS * Wmacrobtn) / 2; xpos = 0; ypos = btngroup1->y(); for (int i = 0; i < NUMMACKEYS; i++) { if (i == 4 || i == 8) { - bx = new Fl_Box(xpos, ypos, wblank, Hmacrobtn); + bx = new Fl_Box(xpos, ypos, wBLANK, Hmacrobtn); bx->box(FL_FLAT_BOX); - xpos += wblank; + xpos += wBLANK; } btnMacro[i] = new Fl_Button(xpos, ypos, Wmacrobtn, Hmacrobtn, macros.name[i].c_str()); @@ -4817,6 +4851,7 @@ Fl_Menu_Item alt_menu_[] = { { mode_info[MODE_PSK250].name, 0, cb_init_mode, (void *)MODE_PSK250, 0, FL_NORMAL_LABEL, 0, 14, 0}, {0,0,0,0,0,0,0,0,0}, +{ mode_info[MODE_NULL].name, 0, cb_init_mode, (void *)MODE_NULL, 0, FL_NORMAL_LABEL, 0, 14, 0}, { mode_info[MODE_SSB].name, 0, cb_init_mode, (void *)MODE_SSB, 0, FL_NORMAL_LABEL, 0, 14, 0}, { mode_info[MODE_WWV].name, 0, cb_init_mode, (void *)MODE_WWV, 0, FL_NORMAL_LABEL, 0, 14, 0}, @@ -5608,10 +5643,55 @@ void get_tx_char_idle(void *) progStatus.repeatIdleTime = 0; } +int Qwait_time = 0; +int Qidle_time = 0; + +static int que_timeout = 0; +bool que_ok = true; + +void post_queue_execute(void*) +{ + if (!que_timeout) { + LOG_ERROR("%s", "timed out"); + return; + } + while (!que_ok && trx_state != STATE_RX) { + que_timeout--; + Fl::repeat_timeout(0.05, post_queue_execute); + } + trx_transmit(); +} + +void queue_execute_after_rx(void*) +{ + if (!que_timeout) { + LOG_ERROR("%s", "timed out"); + return; + } + while (trx_state == STATE_TX) { + que_timeout--; + Fl::repeat_timeout(0.05, queue_execute_after_rx); + return; + } + que_ok = false; + que_timeout = 100; // 5 seconds + Fl::add_timeout(0.05, post_queue_execute); + queue_execute(); +} + char szTestChar[] = "E|I|S|T|M|O|A|V"; int get_tx_char(void) { - if (macro_idle_on) return -1; + int c; + static int pending = -1; + enum { STATE_CHAR, STATE_CTRL }; + static int state = STATE_CHAR; + + if (!que_ok) { return -1; } + if (Qwait_time) { return -1; } + if (Qidle_time) { return -1; } + if (macro_idle_on) { return -1; } + if (idling) { return -1; } if (arq_text_available) return arq_get_char(); @@ -5619,24 +5699,19 @@ int get_tx_char(void) if (active_modem == cw_modem && progdefaults.QSKadjust) return szTestChar[2 * progdefaults.TestChar]; - int c; - static int pending = -1; + if ( progStatus.repeatMacro && progStatus.repeatIdleTime > 0 && + !idling ) { + Fl::add_timeout(progStatus.repeatIdleTime, get_tx_char_idle); + idling = true; + return -1; + } + if (pending >= 0) { c = pending; pending = -1; return c; } - enum { STATE_CHAR, STATE_CTRL }; - static int state = STATE_CHAR; - - if ( progStatus.repeatMacro && progStatus.repeatIdleTime > 0 && - !idling ) { - Fl::add_timeout(progStatus.repeatIdleTime, get_tx_char_idle); - idling = true; - } - if (idling) return -1; - if (progStatus.repeatMacro > -1 && text2repeat.length()) { c = text2repeat[repeatchar]; repeatchar++; @@ -5648,12 +5723,15 @@ int get_tx_char(void) } c = TransmitText->nextChar(); + if (c == '^' && state == STATE_CHAR) { state = STATE_CTRL; c = TransmitText->nextChar(); } switch (c) { - case -1: break; // no character available + case -1: // no character available + queue_reset(); + break; case '\n': pending = '\n'; return '\r'; @@ -5663,6 +5741,8 @@ int get_tx_char(void) REQ_SYNC(&FTextTX::clear_sent, TransmitText); state = STATE_CHAR; c = 3; // ETX + if (progStatus.timer) + REQ(startMacroTimer); break; case 'R': if (state != STATE_CTRL) @@ -5671,6 +5751,8 @@ int get_tx_char(void) if (TransmitText->eot()) { REQ_SYNC(&FTextTX::clear_sent, TransmitText); c = 3; // ETX + if (progStatus.timer) + REQ(startMacroTimer); } else c = -1; break; @@ -5688,6 +5770,19 @@ int get_tx_char(void) c = -1; REQ(clearQSO); break; + case '!': + if (state != STATE_CTRL) + break; + state = STATE_CHAR; + if (queue_must_rx()) { + c = 3; + que_timeout = 400; // 20 seconds + Fl::add_timeout(0.0, queue_execute_after_rx); + } else { + c = -1; + queue_execute(); + } + break; case '^': state = STATE_CHAR; break; @@ -5870,7 +5965,6 @@ void start_tx() if (!(active_modem->get_cap() & modem::CAP_TX)) return; trx_transmit(); - REQ(&waterfall::set_XmtRcvBtn, wf, true); } void abort_tx() @@ -5881,6 +5975,7 @@ void abort_tx() return; } if (trx_state == STATE_TX) { + queue_reset(); trx_start_modem(active_modem); } } diff --git a/src/dtmf/dtmf.cxx b/src/dtmf/dtmf.cxx index d6934011..ae52b654 100644 --- a/src/dtmf/dtmf.cxx +++ b/src/dtmf/dtmf.cxx @@ -235,8 +235,6 @@ void cDTMF::two_tones(int ch) void cDTMF::send() { - if (progdefaults.DTMFstr.empty()) return; - int c = 0, delay = 0; duration = 50; RT = (int)(active_modem->get_samplerate() * 4 / 1000.0); // 4 msec edge diff --git a/src/globals/globals.cxx b/src/globals/globals.cxx index 5ce97e0d..1287b0b4 100644 --- a/src/globals/globals.cxx +++ b/src/globals/globals.cxx @@ -43,6 +43,8 @@ using namespace std; // ... doing so will break the Fl_menu_item table 'menu_'. -Kamal const struct mode_info_t mode_info[NUM_MODES] = { + { MODE_NULL, &null_modem, "NULL", "NULL", "", "NULL", "" }, + { MODE_CW, &cw_modem, "CW", "CW", "CW", "CW", "CW" }, { MODE_CONTESTIA, &contestia_modem, "CTSTIA", "Contestia", "", "CONTESTI", "CT" }, diff --git a/src/include/fl_digi.h b/src/include/fl_digi.h index 22fff043..ff07825a 100644 --- a/src/include/fl_digi.h +++ b/src/include/fl_digi.h @@ -148,6 +148,9 @@ extern Digiscope *digiscope; extern std::string main_window_title; +extern int Qwait_time; +extern int Qidle_time; + extern void toggleRSID(); extern void set_menus(); @@ -214,6 +217,10 @@ extern void put_WARNstatus(double); extern void qsoSave_cb(Fl_Widget *b, void *); +extern bool que_ok; +extern void post_queue_execute(void*); +extern void queue_execute_after_rx(void*); + extern void put_rx_data(int *data, int len); extern int get_tx_char(); extern int get_secondary_char(); @@ -259,6 +266,10 @@ extern void set_contestia_default_integ(); extern void startMacroTimer(); extern void stopMacroTimer(); +extern void macro_timer(void *); +extern void macro_timed_execute(void *); +extern void startTimedExecute(std::string &); + extern void cb_ResetSerNbr(); extern void updateOutSerNo(); diff --git a/src/include/globals.h b/src/include/globals.h index 3eb0267c..ff1e478d 100644 --- a/src/include/globals.h +++ b/src/include/globals.h @@ -49,6 +49,8 @@ enum { MODE_PREV = -2, MODE_NEXT, + MODE_NULL, + MODE_CW, MODE_CONTESTIA, diff --git a/src/include/macros.h b/src/include/macros.h index 3f863297..9f5ff90a 100644 --- a/src/include/macros.h +++ b/src/include/macros.h @@ -36,9 +36,10 @@ struct MACROTEXT { void openMacroFile(); void saveMacroFile(); void saveMacros(const std::string& fname); - std::string expandMacro(int n); + std::string expandMacro(std::string &s); void execute(int n); void repeat(int n); + void timed_execute(); MACROTEXT(); private: std::string expanded; @@ -53,6 +54,15 @@ extern std::string info2msg; extern std::string qso_time; extern std::string qso_exchange; +extern std::string exec_date; +extern std::string exec_time; +extern std::string exec_string; + void set_macro_env(void); +void queue_reset(); +void queue_execute(); +bool queue_must_rx(); +void idleTimer(void *); + #endif diff --git a/src/include/modem.h b/src/include/modem.h index 2d3941b3..ebbba513 100644 --- a/src/include/modem.h +++ b/src/include/modem.h @@ -181,6 +181,8 @@ protected: virtual void s2nreport(void); }; +extern modem *null_modem; + extern modem *cw_modem; extern modem *mfsk8_modem; diff --git a/src/include/nullmodem.h b/src/include/nullmodem.h new file mode 100644 index 00000000..599695e4 --- /dev/null +++ b/src/include/nullmodem.h @@ -0,0 +1,48 @@ +// ---------------------------------------------------------------------------- +// NULLMODEM.h -- BASIS FOR ALL MODEMS +// +// Copyright (C) 2006 +// Dave Freese, W1HKJ +// +// This file is part of fldigi. +// +// Fldigi 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 3 of the License, or +// (at your option) any later version. +// +// Fldigi 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 fldigi. If not, see . +// ---------------------------------------------------------------------------- + +#ifndef _NULLMODEM_H +#define _NULLMODEM_H + +#include "trx.h" +#include "modem.h" +#include "fft.h" +#include "filters.h" +#include "complex.h" + +#define NULLMODEMSampleRate 8000 + +class NULLMODEM : public modem { +protected: +public: + NULLMODEM(); + ~NULLMODEM(); + void init(); + void rx_init(); + void restart(); + void tx_init(SoundBase *sc); + int rx_process(const double *buf, int len); + int tx_process(); + +}; + +#endif diff --git a/src/include/trx.h b/src/include/trx.h index 39435629..2bd56113 100644 --- a/src/include/trx.h +++ b/src/include/trx.h @@ -43,11 +43,8 @@ extern void trx_tune(); extern void trx_receive(); extern void trx_reset(void); -extern void trx_start_macro_timer(); -extern void trx_wait_state(void); - -extern void macro_timer(void *); +extern void trx_wait_state(void); extern state_t trx_state; extern modem *active_modem; diff --git a/src/misc/macroedit.cxx b/src/misc/macroedit.cxx index 67349a10..349a5acd 100644 --- a/src/misc/macroedit.cxx +++ b/src/misc/macroedit.cxx @@ -52,12 +52,12 @@ using namespace std; Fl_Double_Window *MacroEditDialog = (Fl_Double_Window *)0; -Fl_Button *btnMacroEditOK = (Fl_Button *)0; -Fl_Button *btnMacroEditCancel = (Fl_Button *)0; +Fl_Button *btnMacroEditApply = (Fl_Button *)0; +Fl_Button *btnMacroEditClose = (Fl_Button *)0; Fl_Button *btnInsertMacro = (Fl_Button *)0; Fl_Input2 *macrotext = (Fl_Input2 *)0; Fl_Input2 *labeltext = (Fl_Input2 *)0; -static int widths[] = {130, 0}; +static int widths[] = {150, 0}; Fl_Hold_Browser *macroDefs=(Fl_Hold_Browser *)0; @@ -151,6 +151,7 @@ void loadBrowser(Fl_Widget *widget) { w->add(_("\ttune signal for NN sec")); w->add(_("\tdelay xmt for NN sec")); w->add(_("\trepeat macro continuously")); + w->add(_("\tschedule execution")); w->add(LINE_SEP); w->add(_("\tCW identifier")); @@ -240,8 +241,10 @@ void loadBrowser(Fl_Widget *widget) { void cbMacroEditOK(Fl_Widget *w, void *) { - if (w == btnMacroEditCancel) - goto ret; + if (w == btnMacroEditClose) { + MacroEditDialog->hide(); + return; + } if (iType == MACRO_EDIT_BUTTON) { macros.text[iMacro] = macrotext->value(); @@ -264,8 +267,6 @@ void cbMacroEditOK(Fl_Widget *w, void *) } else if (iType == MACRO_EDIT_INPUT) iInput->value(macrotext->value()); -ret: - MacroEditDialog->hide(); } void cbInsertMacro(Fl_Widget *, void *) @@ -315,30 +316,30 @@ void cbInsertMacro(Fl_Widget *, void *) Fl_Double_Window* make_macroeditor(void) { - Fl_Double_Window* w = new Fl_Double_Window(768, 190, ""); + Fl_Double_Window* w = new Fl_Double_Window(800, 190, ""); - macrotext = new Fl_Input2(2, 22, 450, 140, _("Text:")); + macrotext = new Fl_Input2(2, 22, 450, 140, _("Macro Text")); macrotext->type(FL_MULTILINE_INPUT); macrotext->textfont(FL_COURIER); - macrotext->align(FL_ALIGN_TOP_LEFT); + macrotext->align(FL_ALIGN_TOP); - btnInsertMacro = new Fl_Button(454, 86, 20, 20); + btnInsertMacro = new Fl_Button(434, 2, 40, 20); btnInsertMacro->image(new Fl_Pixmap(left_arrow_icon)); btnInsertMacro->callback(cbInsertMacro); - macroDefs = new Fl_Hold_Browser(476, 22, 290, 140, _("Select Tags:")); + macroDefs = new Fl_Hold_Browser(452, 22, 346, 140, _("Select Tag")); macroDefs->column_widths(widths); - macroDefs->align(FL_ALIGN_TOP_LEFT); + macroDefs->align(FL_ALIGN_TOP); loadBrowser(macroDefs); labeltext = new Fl_Input2(2 + 450 - 115, 164, 115, 24, _("Macro Button Label:")); labeltext->textfont(FL_COURIER); - btnMacroEditOK = new Fl_Button(476 + 145 - 80 - 1, 164, 80, 24, _("OK")); - btnMacroEditOK->callback(cbMacroEditOK); + btnMacroEditApply = new Fl_Button(452 + macroDefs->w()/2 - 80 - 1, 164, 80, 24, _("Apply")); + btnMacroEditApply->callback(cbMacroEditOK); - btnMacroEditCancel = new Fl_Button(476 + 145 + 1 , 164, 80, 24, _("Cancel")); - btnMacroEditCancel->callback(cbMacroEditOK); + btnMacroEditClose = new Fl_Button(452 + macroDefs->w()/2 + 1 , 164, 80, 24, _("Close")); + btnMacroEditClose->callback(cbMacroEditOK); w->end(); w->xclass(PACKAGE_NAME); diff --git a/src/misc/macros.cxx b/src/misc/macros.cxx index 51fcf1ae..251a49f8 100644 --- a/src/misc/macros.cxx +++ b/src/misc/macros.cxx @@ -55,6 +55,7 @@ #include #include #include +#include #ifdef __WIN32__ #include "speak.h" @@ -62,6 +63,17 @@ using namespace std; +struct CMDS { string cmd; void (*fp)(string); }; +queue cmds; + +// following used for debugging and development +//void pushcmd(CMDS cmd) +//{ +// LOG_INFO("%s, # = %d", cmd.cmd.c_str(), (int)cmds.size()); +// cmds.push(cmd); +//} +#define pushcmd(a) cmds.push((a)) + MACROTEXT macros; CONTESTCNTR contest_count; static bool TransmitON = false; @@ -70,20 +82,24 @@ static int mNbr; std::string qso_time = ""; std::string qso_exchange = ""; -static bool save_xchg; -static size_t xbeg = 0, xend = 0; -string text2send = ""; -string text2repeat = ""; -string text2save = ""; +std::string exec_date = ""; +std::string exec_time = ""; +std::string exec_string = ""; + +std::string text2send = ""; +std::string text2repeat = ""; +//std::string text2save = ""; +std::string info1msg = ""; +std::string info2msg = ""; size_t repeatchar = 0; +static size_t xbeg = 0, xend = 0; +static bool save_xchg; static bool expand; static bool GET = false; - -string info1msg = ""; -string info2msg = ""; +static bool timed_exec = false; static char cutnumbers[] = "T12345678N"; static string cutstr; @@ -204,6 +220,107 @@ static void pPOST(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, ""); } +static void setwpm(int d) +{ + sldrCWxmtWPM->value(d); + cntCW_WPM->value(d); +} + +static void doWPM(string s) +{ + int number; + string sTime = s.substr(6); + if (sTime.length() > 0) { + sscanf(sTime.c_str(), "%d", &number); + if (number < 5) number = 5; + if (number > 200) number = 200; + progdefaults.CWspeed = number; + REQ(setwpm, number); + } +} + +static void pQueWPM(string &s, size_t &i, size_t endbracket) +{ + struct CMDS cmd = { s.substr(i, endbracket - i + 1), doWPM }; + pushcmd(cmd); + s.replace(i, endbracket - i + 1, "^!"); +} + +static void setRISETIME(int d) +{ + cntCWrisetime->value(d); +} + +static void doRISETIME(string s) +{ + float number; + string sVal = s.substr(7, s.length() - 8); + if (sVal.length() > 0) { + sscanf(sVal.c_str(), "%f", &number); + if (number < 0) number = 0; + if (number > 20) number = 20; + progdefaults.CWrisetime = number; + REQ(setRISETIME, number); + } +} + +static void pQueRISETIME(string &s, size_t &i, size_t endbracket) +{ + struct CMDS cmd = { s.substr(i, endbracket - i + 1), doRISETIME }; + pushcmd(cmd); + s.replace(i, endbracket - i + 1, "^!"); +} + +static void setPRE(int d) +{ + cntPreTiming->value(d); +} + +static void doPRE(string s) +{ + float number; + string sVal = s.substr(6, s.length() - 7); + if (sVal.length() > 0) { + sscanf(sVal.c_str(), "%f", &number); + if (number < 0) number = 0; + if (number > 20) number = 20; + progdefaults.CWpre = number; + REQ(setPRE, number); + } +} + +static void pQuePRE(string &s, size_t &i, size_t endbracket) +{ + struct CMDS cmd = { s.substr(i, endbracket - i + 1), doPRE }; + pushcmd(cmd); + s.replace(i, endbracket - i + 1, "^!"); +} + +static void setPOST(int d) +{ + cntPostTiming->value(d); +} + +static void doPOST(string s) +{ + float number; + string sVal = s.substr(7, s.length() - 8); + if (sVal.length() > 0) { + sscanf(sVal.c_str(), "%f", &number); + if (number < -20) number = -20; + if (number > 20) number = 20; + progdefaults.CWpost = number; + REQ(setPOST, number); + } +} + +static void pQuePOST(string &s, size_t &i, size_t endbracket) +{ + struct CMDS cmd = { s.substr(i, endbracket - i + 1), doPOST }; + pushcmd(cmd); + s.replace(i, endbracket - i + 1, "^!"); +} + bool macro_idle_on = false; static float idleTime = 0; @@ -219,6 +336,31 @@ static void pIDLE(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, ""); } +static void doneIDLE(void *) +{ + Qidle_time = 0; +} + +static void doIDLE(string s) +{ + float number; + string sTime = s.substr(7, s.length() - 8); + if (sTime.length() > 0) { + sscanf(sTime.c_str(), "%f", &number); + Qidle_time = 1; + Fl::add_timeout(number, doneIDLE); + } else { + Qidle_time = 0; + } +} + +static void pQueIDLE(string &s, size_t &i, size_t endbracket) +{ + struct CMDS cmd = { s.substr(i, endbracket - i + 1), doIDLE }; + pushcmd(cmd); + s.replace(i, endbracket - i + 1, "^!"); +} + static bool useTune = false; static int tuneTime = 0; @@ -249,6 +391,33 @@ static void pWAIT(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, ""); } +static void doneWAIT(void *) +{ + Qwait_time = 0; + start_tx(); +} + +static void doWAIT(string s) +{ + int number; + string sTime = s.substr(7, s.length() - 8); + if (sTime.length() > 0) { + sscanf(sTime.c_str(), "%d", &number); + Qwait_time = number; + Fl::add_timeout (number * 1.0, doneWAIT); + } else + Qwait_time = 0; + que_ok = true; +} + +static void pQueWAIT(string &s, size_t &i, size_t endbracket) +{ + struct CMDS cmd = { s.substr(i, endbracket - i + 1), doWAIT }; + pushcmd(cmd); + s.replace(i, endbracket - i + 1, "^!"); +} + + static void pINFO1(string &s, size_t &i, size_t endbracket) { s.replace( i, 7, info1msg ); @@ -440,7 +609,6 @@ static void pID(string &s, size_t &i, size_t endbracket) static void pTEXT(string &s, size_t &i, size_t endbracket) { progdefaults.macrotextid = true; - s.replace( i, 6, ""); } @@ -450,10 +618,16 @@ static void pCWID(string &s, size_t &i, size_t endbracket) s.replace( i, 6, ""); } +static void doDTMF(string s) +{ + progdefaults.DTMFstr = s.substr(6, s.length() - 7); +} + static void pDTMF(string &s, size_t &i, size_t endbracket) { - progdefaults.DTMFstr = s.substr(i + 6, endbracket - i - 6); - s.replace(i, endbracket - i + 1, ""); + CMDS cmd = {s.substr(i, endbracket - i + 1), doDTMF}; + pushcmd(cmd); + s.replace(i, endbracket - i + 1, "^!"); } static void pRX(string &s, size_t &i, size_t endbracket) @@ -557,7 +731,7 @@ static void pCLRLOG(string &s, size_t &i, size_t endbracket) s.replace(i, 10, "^C"); } -static void pMODEM_compat(string &s, size_t &i, size_t endbracket) +static void pMODEM_compSKED(string &s, size_t &i, size_t endbracket) { size_t j, k, len = s.length(); @@ -584,6 +758,84 @@ static void pMODEM_compat(string &s, size_t &i, size_t endbracket) #include #include "re.h" +static void doMODEM(string s) +{ + static fre_t re("", REG_EXTENDED); + string tomatch = s; + + if (!re.match(tomatch.c_str())) { + que_ok = true; + return; + } + + const std::vector& o = re.suboff(); + string name = tomatch.substr(o[1].rm_so, o[1].rm_eo - o[1].rm_so); + trx_mode m; + for (m = 0; m < NUM_MODES; m++) + if (name == mode_info[m].sname) + break; + // do we have arguments and a valid modem? + if (o.size() == 2 || m == NUM_MODES) { + que_ok = true; + return; + } + + // parse arguments + vector args; + args.reserve(8); + char* end; + double d; + for (const char* p = s.c_str() + o[2].rm_so + 1; *p; p++) { + errno = 0; + d = strtod(p, &end); + if (!errno && p != end) { + args.push_back(d); + p = end; + } + else // push an invalid value + args.push_back(DBL_MIN); + } + + try { + switch (m) { + case MODE_RTTY: // carrier shift, baud rate, bits per char + if (args.at(0) != DBL_MIN) + set_rtty_shift((int)args[0]); + if (args.at(1) != DBL_MIN) + set_rtty_baud((float)args[1]); + if (args.at(2) != DBL_MIN) + set_rtty_bits((int)args[2]); + break; + case MODE_CONTESTIA: // bandwidth, tones + if (args.at(0) != DBL_MIN) + set_contestia_bw((int)args[0]); + if (args.at(1) != DBL_MIN) + set_contestia_tones((int)args[1]); + break; + case MODE_OLIVIA: // bandwidth, tones + if (args.at(0) != DBL_MIN) + set_olivia_bw((int)args[0]); + if (args.at(1) != DBL_MIN) + set_olivia_tones((int)args[1]); + break; + default: + break; + } + } + catch (const exception& e) { } + + if (active_modem->get_mode() != mode_info[m].mode) + init_modem_sync(mode_info[m].mode); + que_ok = true; +} + +static void pQueMODEM(string &s, size_t &i, size_t endbracket) +{ + struct CMDS cmd = { s.substr(i, endbracket - i + 1), doMODEM }; + pushcmd(cmd); + s.replace(i, endbracket - i + 1, "^!"); +} + static void pMODEM(string &s, size_t &i, size_t endbracket) { static fre_t re("", REG_EXTENDED); @@ -677,6 +929,8 @@ static void pAFC(string &s, size_t &i, size_t endbracket) btnAFC->do_callback(); } +//pushcmd(s.substr(i, endbracket - i + 1)); +//s.replace(i, endbracket - i + 1, "^!"); s.replace(i, endbracket - i + 1, ""); } @@ -695,6 +949,8 @@ static void pLOCK(string &s, size_t &i, size_t endbracket) wf->xmtlock->damage(); wf->xmtlock->do_callback(); } +//pushcmd(s.substr(i, endbracket - i + 1)); +//s.replace(i, endbracket - i + 1, "^!"); s.replace(i, endbracket - i + 1, ""); } @@ -712,6 +968,8 @@ static void pTX_RSID(string &s, size_t &i, size_t endbracket) btnTxRSID->do_callback(); } +//pushcmd(s.substr(i, endbracket - i + 1)); +//s.replace(i, endbracket - i + 1, "^!"); s.replace(i, endbracket - i + 1, ""); } @@ -776,6 +1034,24 @@ static void pGOHOME(string &s, size_t &i, size_t endbracket) active_modem->set_freq(progdefaults.PSKsweetspot); } +static void doGOHOME(string s) +{ + if (active_modem == cw_modem) + active_modem->set_freq(progdefaults.CWsweetspot); + else if (active_modem == rtty_modem) + active_modem->set_freq(progdefaults.RTTYsweetspot); + else + active_modem->set_freq(progdefaults.PSKsweetspot); + que_ok = true; +} + +static void pQueGOHOME(string &s, size_t &i, size_t endbracket) +{ + struct CMDS cmd = { s.substr(i, endbracket - i + 1), doGOHOME }; + pushcmd(cmd); + s.replace(i, endbracket - i + 1, "^!"); +} + static void pGOFREQ(string &s, size_t &i, size_t endbracket) { int number; @@ -791,6 +1067,28 @@ static void pGOFREQ(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, ""); } +static void doGOFREQ(string s) +{ + int number; + string sGoFreq = s.substr(9, s.length() - 10); + if (sGoFreq.length() > 0) { + sscanf(sGoFreq.c_str(), "%d", &number); + if (number < progdefaults.LowFreqCutoff) + number = progdefaults.LowFreqCutoff; + if (number > progdefaults.HighFreqCutoff) + number = progdefaults.HighFreqCutoff; + active_modem->set_freq(number); + } + que_ok = true; +} + +static void pQueGOFREQ(string &s, size_t &i, size_t endbracket) +{ + struct CMDS cmd = { s.substr(i, endbracket - i + 1), doGOFREQ }; + pushcmd(cmd); + s.replace(i, endbracket - i + 1, "^!"); +} + static void pQSYTO(string &s, size_t &i, size_t endbracket) { s.replace( i, 7, ""); @@ -830,7 +1128,6 @@ static void pQSY(string &s, size_t &i, size_t endbracket) if (audio > progdefaults.HighFreqCutoff) audio = progdefaults.HighFreqCutoff; } - if (rf && rf != wf->rfcarrier()) qsy(rf, audio); else @@ -839,6 +1136,48 @@ static void pQSY(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, ""); } +static void doQSY(string s) +{ + int rf = 0; + int audio = 0; + float rfd = 0; + string sGoFreq; + sGoFreq = s.substr(6, s.length() - 7); + // no frequency(s) specified + if (sGoFreq.length() == 0) { + que_ok = true; + return; + } + // rf first value + sscanf(sGoFreq.c_str(), "%f", &rfd); + if (rfd > 0) + rf = (int)(1000*rfd); + size_t pos; + if ((pos = sGoFreq.find(":")) != string::npos) { + // af second value + sGoFreq.erase(0, pos+1); + if (sGoFreq.length()) + sscanf(sGoFreq.c_str(), "%d", &audio); + if (audio < 0) audio = 0; + if (audio < progdefaults.LowFreqCutoff) + audio = progdefaults.LowFreqCutoff; + if (audio > progdefaults.HighFreqCutoff) + audio = progdefaults.HighFreqCutoff; + } + if (rf && rf != wf->rfcarrier()) + qsy(rf, audio); + else + active_modem->set_freq(audio); + que_ok = true; +} + +static void pQueQSY(string &s, size_t &i, size_t endbracket) +{ + struct CMDS cmd = { s.substr(i, endbracket - i + 1), doQSY }; + pushcmd(cmd); + s.replace(i, endbracket - i + 1, "^!"); +} + static void pRIGMODE(string& s, size_t& i, size_t endbracket) { string sMode = s.substr(i+9, endbracket - i - 9); @@ -859,7 +1198,7 @@ void set_macro_env(void) { enum { #ifndef __WOE32__ - PATH, FLDIGI_RX_IPC_KEY, FLDIGI_TX_IPC_KEY, + pSKEDH, FLDIGI_RX_IPC_KEY, FLDIGI_TX_IPC_KEY, #endif FLDIGI_XMLRPC_ADDRESS, FLDIGI_XMLRPC_PORT, FLDIGI_ARQ_ADDRESS, FLDIGI_ARQ_PORT, @@ -881,7 +1220,7 @@ void set_macro_env(void) const char* val; } env[] = { #ifndef __WOE32__ - { "PATH", "" }, + { "pSKEDH", "" }, { "FLDIGI_RX_IPC_KEY", "" }, { "FLDIGI_TX_IPC_KEY", "" }, #endif @@ -919,13 +1258,13 @@ void set_macro_env(void) }; #ifndef __WOE32__ - // PATH - static string path = ScriptsDir; - path.erase(path.length()-1,1); + // pSKEDH + static string pSKEDh = ScriptsDir; + pSKEDh.erase(pSKEDh.length()-1,1); const char* p; - if ((p = getenv("PATH"))) - path.append(":").append(p); - env[PATH].val = path.c_str(); + if ((p = getenv("pSKEDH"))) + pSKEDh.append(":").append(p); + env[pSKEDH].val = pSKEDh.c_str(); // IPC keys char key[2][8]; @@ -1132,6 +1471,65 @@ static void pCONT(string &s, size_t &i, size_t endbracket) expand = true; } +static void pSKED(string &s, size_t &i, size_t endbracket) +{ + string data = s.substr(i+6, endbracket - i - 6); + size_t p = data.find(":"); + if (p == std::string::npos) { + exec_date = zdate(); + exec_time = data; + if (exec_time.empty()) exec_time = ztime(); + } else { + exec_time = data.substr(0, p); + exec_date = data.substr(p+1); + } + timed_exec = true; + s.replace(i, endbracket - i + 1, ""); +} + +void queue_reset() +{ + if (!cmds.empty()) { + Fl::remove_timeout(post_queue_execute); + Fl::remove_timeout(queue_execute_after_rx); + Fl::remove_timeout(doneIDLE); + Fl::remove_timeout(doneWAIT); + while (!cmds.empty()) cmds.pop(); + } + Qwait_time = 0; + Qidle_time = 0; + que_ok = true; +} + +void postQueue(string s) +{ + ReceiveText->add(s.c_str(), FTextBase::CTRL); +} + +void queue_execute() +{ + if (cmds.empty()) { + Qwait_time = 0; + Qidle_time = 0; + que_ok = true; + return; + } + CMDS cmd = cmds.front(); + cmds.pop(); + cmd.fp(cmd.cmd); + LOG_INFO("%s", cmd.cmd.c_str()); + REQ(postQueue, cmd.cmd.append("\n")); + return; +} + +bool queue_must_rx() +{ +static string rxcmds = "", pMODEM_compat}, +{"", pMODEM_compSKED}, {"", pEXEC}, {"", pSTOP}, @@ -1211,9 +1609,20 @@ MTAGS mtags[] = { {"", pMAPIT}, {"", pREPEAT}, +{"", pQueGOHOME}, +{"do_callback(); } +void MACROTEXT::timed_execute() +{ + queue_reset(); + TransmitText->clear(); + text2send = expandMacro(exec_string); + TransmitText->add(text2send.c_str()); + exec_string.clear(); + active_modem->set_stopflag(false); + start_tx(); +} + void MACROTEXT::execute(int n) { - text2save = text2send = expandMacro(n); + mNbr = n; +// text2save = + text2send = expandMacro(text[n]); + + if (timed_exec) { + progStatus.repeatMacro = -1; + exec_string = text[n]; + timed_exec = false; + startTimedExecute(name[n]); + return; + } if (progStatus.repeatMacro == -1) TransmitText->add( text2send.c_str() ); @@ -1505,8 +1935,8 @@ void MACROTEXT::execute(int n) void MACROTEXT::repeat(int n) { - expandMacro(n); - LOG_INFO("%s",text2repeat.c_str()); + expandMacro(text[n]); + LOG_WARN("%s",text2repeat.c_str()); macro_idle_on = false; if (idleTime) progStatus.repeatIdleTime = idleTime; } diff --git a/src/mt63/mt63.cxx b/src/mt63/mt63.cxx index 58014beb..b944c8e9 100644 --- a/src/mt63/mt63.cxx +++ b/src/mt63/mt63.cxx @@ -79,13 +79,22 @@ int mt63::tx_process() if (c == 0x03) { stopflag = true; flush = Tx->DataInterleave; - c = 0; } if (c == -1 || stopflag == true) c = 0; - if (stopflag && flush-- == 0) { + if (stopflag) { stopflag = false; + while (--flush) { + Tx->SendChar(0); + for (int i = 0; i < Tx->Comb.Output.Len; i++) + if (fabs(Tx->Comb.Output.Data[i]) > maxval) + maxval = fabs(Tx->Comb.Output.Data[i]); + for (int i = 0; i < Tx->Comb.Output.Len; i++) { + Tx->Comb.Output.Data[i] /= maxval; + } + ModulateXmtr((Tx->Comb.Output.Data), Tx->Comb.Output.Len); + } Tx->SendJam(); for (int i = 0; i < Tx->Comb.Output.Len; i++) if (fabs(Tx->Comb.Output.Data[i]) > maxval) diff --git a/src/trx/modem.cxx b/src/trx/modem.cxx index 704adc87..a34ac0cc 100644 --- a/src/trx/modem.cxx +++ b/src/trx/modem.cxx @@ -42,6 +42,7 @@ using namespace std; +modem *null_modem = 0; modem *cw_modem = 0; modem *mfsk8_modem = 0; diff --git a/src/trx/nullmodem.cxx b/src/trx/nullmodem.cxx new file mode 100644 index 00000000..a97dab52 --- /dev/null +++ b/src/trx/nullmodem.cxx @@ -0,0 +1,91 @@ +// ---------------------------------------------------------------------------- +// NULLMODEM.cxx -- NULLMODEM modem +// +// Copyright (C) 2006 +// Dave Freese, W1HKJ +// +// This file is part of fldigi. Adapted from code contained in gMFSK source code +// distribution. +// gMFSK Copyright (C) 2001, 2002, 2003 +// Tomi Manninen (oh2bns@sral.fi) +// +// Fldigi 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 3 of the License, or +// (at your option) any later version. +// +// Fldigi 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 fldigi. If not, see . +// ---------------------------------------------------------------------------- + +#include + +#include +#include + +#include "nullmodem.h" +#include "fl_digi.h" +#include "ascii.h" + +#define null_bw 1 + +NULLMODEM:: NULLMODEM() : modem() +{ + mode = MODE_NULL; + samplerate = 8000; + restart(); +} + +NULLMODEM::~NULLMODEM() {}; + +void NULLMODEM::tx_init(SoundBase *sc) +{ + scard = sc; +} + +void NULLMODEM::rx_init() +{ + put_MODEstatus(mode); +} + +void NULLMODEM::init() +{ + modem::init(); + rx_init(); + digiscope->mode(Digiscope::SCOPE); +} + +void NULLMODEM::restart() +{ + set_bandwidth(null_bw); +} + + +//===================================================================== +// receive processing +//===================================================================== + +int NULLMODEM::rx_process(const double *buf, int len) +{ + return 0; +} + +//===================================================================== +// transmit processing +//===================================================================== + + +int NULLMODEM::tx_process() +{ + MilliSleep(10); + if ( get_tx_char() == 0x03 || stopflag) { + stopflag = false; + return -1; + } + return 0; +} diff --git a/src/trx/trx.cxx b/src/trx/trx.cxx index 2476caaa..68a69895 100644 --- a/src/trx/trx.cxx +++ b/src/trx/trx.cxx @@ -158,7 +158,6 @@ static void trx_xmit_wfall_end(int samplerate) void trx_xmit_wfall_queue(int samplerate, const double* buf, size_t len) { ENSURE_THREAD(TRX_TID); - ringbuffer::vector_type wv[2]; wv[0].buf = wv[1].buf = 0; @@ -302,15 +301,19 @@ void trx_trx_transmit_loop() return; } - push2talk->set(true); + if (active_modem != ssb_modem) { + push2talk->set(true); + REQ(&waterfall::set_XmtRcvBtn, wf, true); + } active_modem->tx_init(scard); - if (progdefaults.TransmitRSid) + if ((active_modem != null_modem && active_modem != ssb_modem) && + progdefaults.TransmitRSid) ReedSolomon->send(true); - dtmf->send(); - while (trx_state == STATE_TX) { + if (active_modem != ssb_modem && !progdefaults.DTMFstr.empty()) + dtmf->send(); try { if (active_modem->tx_process() < 0) trx_state = STATE_RX; @@ -326,9 +329,6 @@ void trx_trx_transmit_loop() trx_xmit_wfall_end(current_samplerate); -// if (progdefaults.TransmitRSid) -// ReedSolomon->send(false); - scard->flush(); if (scard->must_close(O_WRONLY)) scard->Close(O_WRONLY); @@ -407,6 +407,17 @@ void *trx_loop(void *args) trxrb.reset(); trx_signal_state(); } +/* +printf("trx state %s\n", +trx_state == STATE_ABORT ? "abort" : +trx_state == STATE_ENDED ? "ended" : +trx_state == STATE_RESTART ? "restart" : +trx_state == STATE_NEW_MODEM ? "new modem" : +trx_state == STATE_TX ? "tx" : +trx_state == STATE_TUNE ? "tune" : +trx_state == STATE_RX ? "rx" : +"unknown"); +*/ switch (trx_state) { case STATE_ABORT: delete scard; @@ -423,8 +434,6 @@ void *trx_loop(void *args) break; case STATE_TX: trx_trx_transmit_loop(); - if (progStatus.timer) - REQ(startMacroTimer); break; case STATE_TUNE: trx_tune_loop(); From 960e580caae30d04dfaf4bd0252af2f542a76a77 Mon Sep 17 00:00:00 2001 From: David Freese Date: Wed, 21 Sep 2011 10:29:24 -0500 Subject: [PATCH 16/54] WWV xmt mode * Added sound card time tick transmit --- src/include/wwv.h | 11 ++++++++- src/trx/trx.cxx | 5 ++-- src/wwv/wwv.cxx | 61 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/include/wwv.h b/src/include/wwv.h index e129f24b..214cbb3e 100644 --- a/src/include/wwv.h +++ b/src/include/wwv.h @@ -69,6 +69,15 @@ protected: bool calc; bool zoom; + double keyshape[32]; // 4 msec rise and fall time for pulse + double audio[400]; + double quiet[400]; + double play[400]; + + double nco(double freq); + void makeshape(); + void makeaudio(); + public: wwv(); ~wwv(); @@ -77,7 +86,7 @@ public: void tx_init(SoundBase *sc); void restart() {}; int rx_process(const double *buf, int len); - int tx_process() {return -1;} + int tx_process(); void update_syncscope(); void set1(int x, int y); void set2(int x, int y); diff --git a/src/trx/trx.cxx b/src/trx/trx.cxx index 68a69895..59c7b6e7 100644 --- a/src/trx/trx.cxx +++ b/src/trx/trx.cxx @@ -288,7 +288,6 @@ void trx_trx_transmit_loop() MilliSleep(10); return; } - if (active_modem) { try { current_samplerate = active_modem->get_samplerate(); @@ -307,7 +306,9 @@ void trx_trx_transmit_loop() } active_modem->tx_init(scard); - if ((active_modem != null_modem && active_modem != ssb_modem) && + if ((active_modem != null_modem && + active_modem != ssb_modem && + active_modem != wwv_modem ) && progdefaults.TransmitRSid) ReedSolomon->send(true); diff --git a/src/wwv/wwv.cxx b/src/wwv/wwv.cxx index 641a9332..284b736a 100644 --- a/src/wwv/wwv.cxx +++ b/src/wwv/wwv.cxx @@ -46,8 +46,6 @@ void wwv::rx_init() phaseacc = 0.0; smpl_ctr = 0; // sample counter for timing wwv rx agc = 0.0; // threshold for tick detection -// sync = 0; -// sync0 = 0; ticks = 0; calc = false; zoom = false; @@ -87,8 +85,8 @@ wwv::wwv() : modem() lpfilter->init_lowpass (FIRLEN_1, DEC_1, lp); vidfilter = new Cmovavg(16); - - cap &= ~CAP_TX; + + makeaudio(); } @@ -165,3 +163,58 @@ void wwv::set2(int x, int y) zoom = !zoom; } +//====================================================================== +// transmit time tick +//====================================================================== + +void wwv::makeshape() +{ + for (int i = 0; i < 32; i++) + keyshape[i] = 0.5 * (1.0 - cos (M_PI * i / 32)); +} + +double wwv::nco(double freq) +{ + phaseacc += 2.0 * M_PI * freq / samplerate; + + if (phaseacc > M_PI) + phaseacc -= 2.0 * M_PI; + + return sin(phaseacc); +} + +void wwv::makeaudio() +{ + phaseacc = 0.0; + makeshape(); + for (int i = 0; i < 400; i++) { + audio[i] = (i < 200 ? nco(1000) : 0); + quiet[i] = 0; + } + for (int i = 0; i < 32; i++) { + audio[i] *= keyshape[i]; + audio[199 - i] *= keyshape[i]; + } +} + +int wwv::tx_process() +{ + static int cycle = 4; + int c = get_tx_char(); + + if (c == 0x03 || stopflag) { + stopflag = false; + return -1; + } + if (--cycle == 0) { + memcpy(play, audio, 400 * sizeof(double)); + ModulateXmtr(play, 400); + cycle = 4; + } else + ModulateXmtr(quiet, 400); + ModulateXmtr(quiet, 400); + ModulateXmtr(quiet, 400); + ModulateXmtr(quiet, 400); + ModulateXmtr(quiet, 400); + return 0; +} From cebc29297a979aefa0304d9c663f4f9fe6c1ba47 Mon Sep 17 00:00:00 2001 From: David Freese Date: Fri, 23 Sep 2011 09:26:22 -0500 Subject: [PATCH 17/54] Macro Editor * Changed to be resizable. Edit and Browser controls change in size proportionally. * Added Tile object to resizable group. Allows the text - picklist intersection to be dragged for resize. --- src/include/macroedit.h | 4 ++++ src/misc/macroedit.cxx | 52 +++++++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/include/macroedit.h b/src/include/macroedit.h index 4d9dc066..13050955 100644 --- a/src/include/macroedit.h +++ b/src/include/macroedit.h @@ -5,6 +5,10 @@ #include #include #include +#include +#include +#include + #include "flinput2.h" extern void loadBrowser(Fl_Widget *widget); diff --git a/src/misc/macroedit.cxx b/src/misc/macroedit.cxx index 349a5acd..932f52e5 100644 --- a/src/misc/macroedit.cxx +++ b/src/misc/macroedit.cxx @@ -34,8 +34,6 @@ #include #include -#include - #include "macros.h" #include "macroedit.h" #include "globals.h" @@ -314,35 +312,65 @@ void cbInsertMacro(Fl_Widget *, void *) macrotext->take_focus(); } +#include + Fl_Double_Window* make_macroeditor(void) { Fl_Double_Window* w = new Fl_Double_Window(800, 190, ""); - macrotext = new Fl_Input2(2, 22, 450, 140, _("Macro Text")); + Fl_Group *grpA = new Fl_Group(0, 0, 800, 22); + Fl_Group *grpB = new Fl_Group(450, 0, 350, 22); + btnInsertMacro = new Fl_Button(450, 2, 40, 20); + btnInsertMacro->image(new Fl_Pixmap(left_arrow_icon)); + btnInsertMacro->callback(cbInsertMacro); + grpB->end(); + grpA->end(); + + Fl_Group *grpC = new Fl_Group(0, 22, 800, 140); + Fl_Tile *tile = new Fl_Tile(0,22,800,140); + macrotext = new Fl_Input2(0, 22, 450, 140, _("Macro Text")); macrotext->type(FL_MULTILINE_INPUT); macrotext->textfont(FL_COURIER); macrotext->align(FL_ALIGN_TOP); - btnInsertMacro = new Fl_Button(434, 2, 40, 20); - btnInsertMacro->image(new Fl_Pixmap(left_arrow_icon)); - btnInsertMacro->callback(cbInsertMacro); - - macroDefs = new Fl_Hold_Browser(452, 22, 346, 140, _("Select Tag")); + macroDefs = new Fl_Hold_Browser(450, 22, 350, 140, _("Select Tag")); macroDefs->column_widths(widths); macroDefs->align(FL_ALIGN_TOP); - loadBrowser(macroDefs); - labeltext = new Fl_Input2(2 + 450 - 115, 164, 115, 24, _("Macro Button Label:")); + Fl_Box *minbox = new Fl_Box(200, 22, 400, 140); + minbox->hide(); + tile->end(); + tile->resizable(minbox); + grpC->end(); + + Fl_Group *grpD = new Fl_Group(0, 164, 452, 24); + Fl_Box *box3a = new Fl_Box(0, 164, 327, 24, ""); + labeltext = new Fl_Input2(337, 164, 115, 24, _("Macro Button Label")); labeltext->textfont(FL_COURIER); + grpD->end(); + grpD->resizable(box3a); - btnMacroEditApply = new Fl_Button(452 + macroDefs->w()/2 - 80 - 1, 164, 80, 24, _("Apply")); + Fl_Group *grpE = new Fl_Group(452, 164, 348, 24); + Fl_Box *box4a = new Fl_Box(452, 164, 92, 24, ""); + + btnMacroEditApply = new Fl_Button(544, 164, 80, 24, _("Apply")); btnMacroEditApply->callback(cbMacroEditOK); - btnMacroEditClose = new Fl_Button(452 + macroDefs->w()/2 + 1 , 164, 80, 24, _("Close")); + btnMacroEditClose = new Fl_Button(626 , 164, 80, 24, _("Close")); btnMacroEditClose->callback(cbMacroEditOK); + grpE->end(); + grpE->resizable(box4a); w->end(); + + w->resizable(grpC); + + w->size_range( 600, 120); + w->xclass(PACKAGE_NAME); + + loadBrowser(macroDefs); + return w; } From d0e1c5f71307c3d3e38f39671980b2784a5af39a Mon Sep 17 00:00:00 2001 From: David Freese Date: Sun, 25 Sep 2011 09:33:49 -0500 Subject: [PATCH 18/54] Log Menu Items * Moved menu items in list to prevent careless selection of "New" * Added confirmation dialog to create a new logbook --- src/dialogs/fl_digi.cxx | 11 ++++++----- src/logbook/logsupport.cxx | 3 +++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 7672ac33..47ec6ca9 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -3102,23 +3102,24 @@ Fl_Menu_Item menu_[] = { {0,0,0,0,0,0,0,0,0}, {_("&Logbook"), 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0}, -{ LOG_CONNECT_SERVER, 0, cb_log_server, 0, FL_MENU_TOGGLE | FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0}, { make_icon_label(_("View")), 'l', (Fl_Callback*)cb_mnuShowLogbook, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL, 0, 14, 0}, -{ make_icon_label(_("New")), 0, (Fl_Callback*)cb_mnuNewLogbook, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, -{ make_icon_label(_("Open...")), 0, (Fl_Callback*)cb_mnuOpenLogbook, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, -{ make_icon_label(_("Save")), 0, (Fl_Callback*)cb_mnuSaveLogbook, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL, 0, 14, 0}, {"ADIF", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0}, { make_icon_label(_("Merge...")), 0, (Fl_Callback*)cb_mnuMergeADIF_log, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, { make_icon_label(_("Export...")), 0, (Fl_Callback*)cb_mnuExportADIF_log, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, {0,0,0,0,0,0,0,0,0}, -{"Reports", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0}, +{"Reports", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0}, { make_icon_label(_("Text...")), 0, (Fl_Callback*)cb_mnuExportTEXT_log, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, { make_icon_label(_("CSV...")), 0, (Fl_Callback*)cb_mnuExportCSV_log, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, { make_icon_label(_("Cabrillo...")), 0, (Fl_Callback*)cb_Export_Cabrillo, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, {0,0,0,0,0,0,0,0,0}, +{ make_icon_label(_("New")), 0, (Fl_Callback*)cb_mnuNewLogbook, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, +{ make_icon_label(_("Open...")), 0, (Fl_Callback*)cb_mnuOpenLogbook, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, +{ make_icon_label(_("Save")), 0, (Fl_Callback*)cb_mnuSaveLogbook, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL, 0, 14, 0}, + +{ LOG_CONNECT_SERVER, 0, cb_log_server, 0, FL_MENU_TOGGLE, FL_NORMAL_LABEL, 0, 14, 0}, {0,0,0,0,0,0,0,0,0}, {" ", 0, 0, 0, FL_MENU_INACTIVE, FL_NORMAL_LABEL, 0, 14, 0}, diff --git a/src/logbook/logsupport.cxx b/src/logbook/logsupport.cxx index 8a95bbae..538a3441 100644 --- a/src/logbook/logsupport.cxx +++ b/src/logbook/logsupport.cxx @@ -165,6 +165,9 @@ static void dxcc_entity_cache_rm(cQsoRec* r); static void dxcc_entity_cache_add(cQsoDb& db); void cb_mnuNewLogbook(Fl_Menu_* m, void* d){ + if (!fl_choice2(_("Create New Logbook?"), _("No"), _("Yes"), NULL)) + return; + saveLogbook(); logbook_filename = LogsDir; From 48e5670216058fbfef4f7ae76847ebc8a54f7655 Mon Sep 17 00:00:00 2001 From: David Freese Date: Sun, 25 Sep 2011 09:36:04 -0500 Subject: [PATCH 19/54] Version 3.21.15 Maintenance release --- ChangeLog | 21 +++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ed71e79e..7ba760fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,28 @@ +=Version 3.21.15= + +2011-09-25 David Freese + + d0e1c5f: Log Menu Items + cebc292: Macro Editor + 960e580: WWV xmt mode + bb258cd: Inline macro tags + d2c33e4: RTTY baud + ab472e0: CW/RTTY init fault + 5a9607a: Control-Z bug fix + c565815: CW QSK + 405816e: Log Server lookup + +2011-09-04 Remi Chateauneu + + e0ee3a9: Added wefax::adjust_metric method. + 261275e: modem::display_metric now sets the member modem::m + + =Version 3.21.14= + 2011-09-03 David Freese 166fe59: DTMF decoder diff --git a/configure.ac b/configure.ac index 97fd2ae9..019c2242 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [3]) m4_define(FLDIGI_MINOR, [21]) -m4_define(FLDIGI_PATCH, [.14]) +m4_define(FLDIGI_PATCH, [.15]) m4_define(FLARQ_MAJOR, [4]) m4_define(FLARQ_MINOR, [3]) m4_define(FLARQ_PATCH, [.1]) From 8ac0558a38aad48df5b3aea43ca4d724aa8f0904 Mon Sep 17 00:00:00 2001 From: David Freese Date: Tue, 4 Oct 2011 15:31:42 -0500 Subject: [PATCH 20/54] Timer delay * Moved timer restart from Tx string parser to tx_transmit loop --- src/dialogs/fl_digi.cxx | 8 ++++---- src/trx/trx.cxx | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 47ec6ca9..2ed38f5a 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -5742,8 +5742,8 @@ int get_tx_char(void) REQ_SYNC(&FTextTX::clear_sent, TransmitText); state = STATE_CHAR; c = 3; // ETX - if (progStatus.timer) - REQ(startMacroTimer); +// if (progStatus.timer) +// REQ(startMacroTimer); break; case 'R': if (state != STATE_CTRL) @@ -5752,8 +5752,8 @@ int get_tx_char(void) if (TransmitText->eot()) { REQ_SYNC(&FTextTX::clear_sent, TransmitText); c = 3; // ETX - if (progStatus.timer) - REQ(startMacroTimer); +// if (progStatus.timer) +// REQ(startMacroTimer); } else c = -1; break; diff --git a/src/trx/trx.cxx b/src/trx/trx.cxx index 59c7b6e7..5282e051 100644 --- a/src/trx/trx.cxx +++ b/src/trx/trx.cxx @@ -339,6 +339,8 @@ void trx_trx_transmit_loop() push2talk->set(false); REQ(&waterfall::set_XmtRcvBtn, wf, false); + if (progStatus.timer) + REQ(startMacroTimer); } //============================================================================= From 3e554f81510a186177cffa6453c1ca17e0e85bde Mon Sep 17 00:00:00 2001 From: David Freese Date: Tue, 4 Oct 2011 15:35:20 -0500 Subject: [PATCH 21/54] !Queue reset * Added queue_reset call to pCLRTX, execution of macro tag . Causes any pending ^! tags to be cleared. --- src/misc/macros.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/misc/macros.cxx b/src/misc/macros.cxx index 251a49f8..861b35d3 100644 --- a/src/misc/macros.cxx +++ b/src/misc/macros.cxx @@ -437,6 +437,7 @@ static void pCLRRX(string &s, size_t &i, size_t endbracket) static void pCLRTX(string &s, size_t &i, size_t endbracket) { s.replace( i, 7, "" ); + queue_reset(); TransmitText->clear(); } From a66d31c458dbc9d8b1c853d2cd4220e7760cb7bb Mon Sep 17 00:00:00 2001 From: David Freese Date: Tue, 4 Oct 2011 17:19:22 -0500 Subject: [PATCH 22/54] Version 3.21.16 Maintenance release --- ChangeLog | 10 ++++++++-- configure.ac | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7ba760fb..948e929b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,15 @@ +=Version 3.21.16= + +2011-10-04 David Freese + + 3e554f8: !Queue reset + 8ac0558: Timer delay + + =Version 3.21.15= -2011-09-25 David Freese - d0e1c5f: Log Menu Items cebc292: Macro Editor 960e580: WWV xmt mode diff --git a/configure.ac b/configure.ac index 019c2242..45210977 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [3]) m4_define(FLDIGI_MINOR, [21]) -m4_define(FLDIGI_PATCH, [.15]) +m4_define(FLDIGI_PATCH, [.16]) m4_define(FLARQ_MAJOR, [4]) m4_define(FLARQ_MINOR, [3]) m4_define(FLARQ_PATCH, [.1]) From 4d13cb4a6e3367296c0c88f8aba4b4481829e961 Mon Sep 17 00:00:00 2001 From: David Freese Date: Wed, 5 Oct 2011 12:22:06 -0500 Subject: [PATCH 23/54] ... * Added limited tag expansion within ... tag pair. Following tags are expanded to their value. All other's are suppressed. Parser also suppresses nested ... pairs. - - - - - - - - - - - - - - - - - - - - - - - - --- src/misc/macros.cxx | 270 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 264 insertions(+), 6 deletions(-) diff --git a/src/misc/macros.cxx b/src/misc/macros.cxx index 861b35d3..3956a952 100644 --- a/src/misc/macros.cxx +++ b/src/misc/macros.cxx @@ -100,6 +100,7 @@ static bool save_xchg; static bool expand; static bool GET = false; static bool timed_exec = false; +static bool within_exec = false; static char cutnumbers[] = "T12345678N"; static string cutstr; @@ -124,7 +125,7 @@ static size_t mystrftime( char *s, size_t max, const char *fmt, const struct tm static void pFILE(string &s, size_t &i, size_t endbracket) { string fname = s.substr(i+6, endbracket - i - 6); - if (fname.length() > 0) { + if (fname.length() > 0 && !within_exec) { FILE *toadd = fopen(fname.c_str(), "r"); if (toadd) { string buffer; @@ -147,7 +148,7 @@ static void pTIMER(string &s, size_t &i, size_t endbracket) { int number; string sTime = s.substr(i+7, endbracket - i - 7); - if (sTime.length() > 0) { + if (sTime.length() > 0 && !within_exec) { sscanf(sTime.c_str(), "%d", &number); progStatus.timer = number; progStatus.timerMacro = mNbr; @@ -157,6 +158,10 @@ static void pTIMER(string &s, size_t &i, size_t endbracket) static void pREPEAT(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } progStatus.repeatMacro = mNbr; s.replace(i, endbracket - i + 1, ""); text2repeat = s; @@ -166,6 +171,10 @@ static void pREPEAT(string &s, size_t &i, size_t endbracket) static void pWPM(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } int number; string sTime = s.substr(i+5, endbracket - i - 5); if (sTime.length() > 0) { @@ -180,6 +189,10 @@ static void pWPM(string &s, size_t &i, size_t endbracket) static void pRISETIME(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } float number; string sVal = s.substr(i+6, endbracket - i - 6); if (sVal.length() > 0) { @@ -194,6 +207,10 @@ static void pRISETIME(string &s, size_t &i, size_t endbracket) static void pPRE(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } float number; string sVal = s.substr(i+5, endbracket - i - 5); if (sVal.length() > 0) { @@ -208,6 +225,10 @@ static void pPRE(string &s, size_t &i, size_t endbracket) static void pPOST(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } float number; string sVal = s.substr(i+6, endbracket - i - 6); if (sVal.length() > 0) { @@ -241,6 +262,10 @@ static void doWPM(string s) static void pQueWPM(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } struct CMDS cmd = { s.substr(i, endbracket - i + 1), doWPM }; pushcmd(cmd); s.replace(i, endbracket - i + 1, "^!"); @@ -266,6 +291,10 @@ static void doRISETIME(string s) static void pQueRISETIME(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } struct CMDS cmd = { s.substr(i, endbracket - i + 1), doRISETIME }; pushcmd(cmd); s.replace(i, endbracket - i + 1, "^!"); @@ -291,6 +320,10 @@ static void doPRE(string s) static void pQuePRE(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } struct CMDS cmd = { s.substr(i, endbracket - i + 1), doPRE }; pushcmd(cmd); s.replace(i, endbracket - i + 1, "^!"); @@ -316,6 +349,10 @@ static void doPOST(string s) static void pQuePOST(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } struct CMDS cmd = { s.substr(i, endbracket - i + 1), doPOST }; pushcmd(cmd); s.replace(i, endbracket - i + 1, "^!"); @@ -326,6 +363,10 @@ static float idleTime = 0; static void pIDLE(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } float number; string sTime = s.substr(i+6, endbracket - i - 6); if (sTime.length() > 0) { @@ -356,6 +397,10 @@ static void doIDLE(string s) static void pQueIDLE(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } struct CMDS cmd = { s.substr(i, endbracket - i + 1), doIDLE }; pushcmd(cmd); s.replace(i, endbracket - i + 1, "^!"); @@ -366,6 +411,10 @@ static int tuneTime = 0; static void pTUNE(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } int number; string sTime = s.substr(i+6, endbracket - i - 6); if (sTime.length() > 0) { @@ -381,6 +430,10 @@ static int waitTime = 0; static void pWAIT(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } int number; string sTime = s.substr(i+6, endbracket - i - 6); if (sTime.length() > 0) { @@ -412,6 +465,10 @@ static void doWAIT(string s) static void pQueWAIT(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } struct CMDS cmd = { s.substr(i, endbracket - i + 1), doWAIT }; pushcmd(cmd); s.replace(i, endbracket - i + 1, "^!"); @@ -430,12 +487,20 @@ static void pINFO2(string &s, size_t &i, size_t endbracket) static void pCLRRX(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.replace( i, 7, "" ); ReceiveText->clear(); } static void pCLRTX(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.replace( i, 7, "" ); queue_reset(); TransmitText->clear(); @@ -603,18 +668,30 @@ static void pZD(string &s, size_t &i, size_t endbracket) static void pID(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } progdefaults.macroid = true; s.replace( i, 4, ""); } static void pTEXT(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } progdefaults.macrotextid = true; s.replace( i, 6, ""); } static void pCWID(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } progdefaults.macroCWid = true; s.replace( i, 6, ""); } @@ -626,6 +703,10 @@ static void doDTMF(string s) static void pDTMF(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } CMDS cmd = {s.substr(i, endbracket - i + 1), doDTMF}; pushcmd(cmd); s.replace(i, endbracket - i + 1, "^!"); @@ -633,17 +714,29 @@ static void pDTMF(string &s, size_t &i, size_t endbracket) static void pRX(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.replace (i, 4, "^r"); } static void pTX(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.erase(i, 4); TransmitON = true; } static void pTXRX(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.erase(i, 7); ToggleTXRX = true; } @@ -659,6 +752,10 @@ static void pVER(string &s, size_t &i, size_t endbracket) static void pCNTR(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } int contestval; contestval = contest_count.count; if (contestval) { @@ -671,6 +768,10 @@ static void pCNTR(string &s, size_t &i, size_t endbracket) static void pDECR(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } int contestval; contest_count.count--; if (contest_count.count < 0) contest_count.count = 0; @@ -681,6 +782,10 @@ static void pDECR(string &s, size_t &i, size_t endbracket) static void pINCR(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } int contestval; contest_count.count++; contestval = contest_count.count; @@ -700,40 +805,68 @@ static void pXOUT(string &s, size_t &i, size_t endbracket) static void pXBEG(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.replace( i, 6, ""); xbeg = i; } static void pXEND(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.replace( i, 6, ""); xend = i; } static void pSAVEXCHG(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } save_xchg = true; s.replace( i, 10, ""); } static void pLOG(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } qsoSave_cb(0, 0); s.replace(i, 5, ""); } static void pLNW(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.replace(i, 5, "^L"); } static void pCLRLOG(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.replace(i, 10, "^C"); } static void pMODEM_compSKED(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } size_t j, k, len = s.length(); string name; @@ -832,6 +965,10 @@ static void doMODEM(string s) static void pQueMODEM(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } struct CMDS cmd = { s.substr(i, endbracket - i + 1), doMODEM }; pushcmd(cmd); s.replace(i, endbracket - i + 1, "^!"); @@ -839,6 +976,10 @@ static void pQueMODEM(string &s, size_t &i, size_t endbracket) static void pMODEM(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } static fre_t re("", REG_EXTENDED); if (!re.match(s.c_str() + i)) { @@ -918,6 +1059,10 @@ static void pMODEM(string &s, size_t &i, size_t endbracket) static void pAFC(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } string sVal = s.substr(i+5, endbracket - i - 5); if (sVal.length() > 0) { // sVal = on|off|t [ON, OFF or Toggle] @@ -937,6 +1082,10 @@ static void pAFC(string &s, size_t &i, size_t endbracket) static void pLOCK(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } string sVal = s.substr(i+6, endbracket - i - 6); if (sVal.length() > 0) { // sVal = on|off|t [ON, OFF or Toggle] @@ -957,6 +1106,10 @@ static void pLOCK(string &s, size_t &i, size_t endbracket) static void pTX_RSID(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } string sVal = s.substr(i+8, endbracket - i - 8); if (sVal.length() > 0) { // sVal = on|off|t [ON, OFF or Toggle] @@ -976,6 +1129,10 @@ static void pTX_RSID(string &s, size_t &i, size_t endbracket) static void pRX_RSID(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } string sVal = s.substr(i+8, endbracket - i - 8); if (sVal.length() > 0) { // sVal = on|off|t [ON, OFF or Toggle] @@ -994,6 +1151,10 @@ static void pRX_RSID(string &s, size_t &i, size_t endbracket) #ifdef __WIN32__ static void pTALK(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } string sVal = s.substr(i+6, endbracket - i - 6); if (sVal.length() > 0) { // sVal = on|off [ON, OFF] @@ -1010,6 +1171,10 @@ static void pTALK(string &s, size_t &i, size_t endbracket) static void pSRCHUP(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.replace( i, 8, ""); active_modem->searchUp(); if (progdefaults.WaterfallClickInsert) @@ -1018,6 +1183,10 @@ static void pSRCHUP(string &s, size_t &i, size_t endbracket) static void pSRCHDN(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.replace( i, 8, ""); active_modem->searchDown(); if (progdefaults.WaterfallClickInsert) @@ -1026,6 +1195,10 @@ static void pSRCHDN(string &s, size_t &i, size_t endbracket) static void pGOHOME(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.replace( i, 8, ""); if (active_modem == cw_modem) active_modem->set_freq(progdefaults.CWsweetspot); @@ -1048,6 +1221,10 @@ static void doGOHOME(string s) static void pQueGOHOME(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } struct CMDS cmd = { s.substr(i, endbracket - i + 1), doGOHOME }; pushcmd(cmd); s.replace(i, endbracket - i + 1, "^!"); @@ -1055,6 +1232,10 @@ static void pQueGOHOME(string &s, size_t &i, size_t endbracket) static void pGOFREQ(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } int number; string sGoFreq = s.substr(i+8, endbracket - i - 8); if (sGoFreq.length() > 0) { @@ -1085,6 +1266,10 @@ static void doGOFREQ(string s) static void pQueGOFREQ(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } struct CMDS cmd = { s.substr(i, endbracket - i + 1), doGOFREQ }; pushcmd(cmd); s.replace(i, endbracket - i + 1, "^!"); @@ -1092,18 +1277,30 @@ static void pQueGOFREQ(string &s, size_t &i, size_t endbracket) static void pQSYTO(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.replace( i, 7, ""); do_qsy(true); } static void pQSYFM(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.replace( i, 7, ""); do_qsy(false); } static void pQSY(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } int rf = 0; int audio = 0; float rfd = 0; @@ -1174,6 +1371,10 @@ static void doQSY(string s) static void pQueQSY(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } struct CMDS cmd = { s.substr(i, endbracket - i + 1), doQSY }; pushcmd(cmd); s.replace(i, endbracket - i + 1, "^!"); @@ -1181,6 +1382,10 @@ static void pQueQSY(string &s, size_t &i, size_t endbracket) static void pRIGMODE(string& s, size_t& i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } string sMode = s.substr(i+9, endbracket - i - 9); qso_opMODE->value(sMode.c_str()); cb_qso_opMODE(); @@ -1189,6 +1394,10 @@ static void pRIGMODE(string& s, size_t& i, size_t endbracket) static void pFILWID(string& s, size_t& i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } string sWidth = s.substr(i+8, endbracket - i - 8); qso_opBW->value(sWidth.c_str()); cb_qso_opBW(); @@ -1304,18 +1513,39 @@ void set_macro_env(void) setenv(env[j].var, env[j].val, 1); } +// this is only for the case where the user tries to nest ... +// as in +// ... ... +// which is not permitted +static void pEND_EXEC(string &s, size_t &i, size_t endbracket) +{ + s.replace(i, endbracket - i + 1, ""); + return; +} + #ifndef __MINGW32__ static void pEXEC(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } + size_t start, end; if ((start = s.find('>', i)) == string::npos || - (end = s.find("", start)) == string::npos) { + (end = s.rfind("")) == string::npos) { i++; return; } start++; i++; + string execstr = s.substr(start, end-start); + within_exec = true; + MACROTEXT m; + execstr = m.expandMacro(execstr); + within_exec = false; + int pfd[2]; if (pipe(pfd) == -1) { LOG_PERROR("pipe"); @@ -1334,7 +1564,7 @@ static void pEXEC(string &s, size_t &i, size_t endbracket) } close(pfd[1]); set_macro_env(); - execl("/bin/sh", "sh", "-c", s.substr(start, end-start).c_str(), (char *)NULL); + execl("/bin/sh", "sh", "-c", execstr.c_str(), (char *)NULL); perror("execl"); exit(EXIT_FAILURE); } @@ -1372,15 +1602,26 @@ static void pEXEC(string &s, size_t &i, size_t endbracket) static void pEXEC(string& s, size_t& i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } size_t start, end; if ((start = s.find('>', i)) == string::npos || - (end = s.find("", start)) == string::npos) { + (end = s.rfind("")) == string::npos) { i++; return; } start++; - char* cmd = strdup(s.substr(start, end-start).c_str()); + string execstr = s.substr(start, end-start); + within_exec = true; + MACROTEXT m; + execstr = m.expandMacro(execstr); + within_exec = false; + + char* cmd = strdup(execstr.c_str()); + STARTUPINFO si; PROCESS_INFORMATION pi; memset(&si, 0, sizeof(si)); @@ -1444,6 +1685,10 @@ static void MAPIT(int how) static void pMAPIT(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } string sVal = s.substr(i + 7, endbracket - i - 7); if (sVal.length() > 0) { if (sVal.compare(0,3,"adr") == 0) @@ -1462,18 +1707,30 @@ static void pMAPIT(string &s, size_t &i, size_t endbracket) static void pSTOP(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.erase(i, s.find('>', i) + 1 - i); expand = false; } static void pCONT(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } s.erase(i, s.find('>', i) + 1 - i); expand = true; } static void pSKED(string &s, size_t &i, size_t endbracket) { + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } string data = s.substr(i+6, endbracket - i - 6); size_t p = data.find(":"); if (p == std::string::npos) { @@ -1583,6 +1840,7 @@ MTAGS mtags[] = { {"", pMODEM_compSKED}, {"", pEXEC}, +{"", pEND_EXEC}, {"", pSTOP}, {"", pCONT}, {"", pGET}, From 07baee2de23a8516c28e66828e361c3bfa08ad30 Mon Sep 17 00:00:00 2001 From: David Freese Date: Thu, 6 Oct 2011 13:27:09 -0500 Subject: [PATCH 24/54] MACRO code cleanup * General code cleanup in files associated with macro.cxx --- src/dialogs/fl_digi.cxx | 4 - src/include/macros.h | 6 +- src/misc/macros.cxx | 430 ++++++++++++++++++++-------------------- 3 files changed, 216 insertions(+), 224 deletions(-) diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 2ed38f5a..d1307acf 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -5632,10 +5632,6 @@ void put_rx_data(int *data, int len) FHdisp->data(data, len); } -extern bool macro_idle_on; -extern string text2repeat; -extern size_t repeatchar; - bool idling = false; void get_tx_char_idle(void *) diff --git a/src/include/macros.h b/src/include/macros.h index 9f5ff90a..2be7a5ad 100644 --- a/src/include/macros.h +++ b/src/include/macros.h @@ -53,10 +53,14 @@ extern std::string info1msg; extern std::string info2msg; extern std::string qso_time; extern std::string qso_exchange; - extern std::string exec_date; extern std::string exec_time; extern std::string exec_string; +extern std::string text2repeat; + +extern bool macro_idle_on; +extern size_t repeatchar; + void set_macro_env(void); diff --git a/src/misc/macros.cxx b/src/misc/macros.cxx index 3956a952..e8b4bc0c 100644 --- a/src/misc/macros.cxx +++ b/src/misc/macros.cxx @@ -61,10 +61,10 @@ #include "speak.h" #endif -using namespace std; +//using namespace std; -struct CMDS { string cmd; void (*fp)(string); }; -queue cmds; +struct CMDS { std::string cmd; void (*fp)(std::string); }; +static queue cmds; // following used for debugging and development //void pushcmd(CMDS cmd) @@ -74,26 +74,30 @@ queue cmds; //} #define pushcmd(a) cmds.push((a)) +// these variables are referenced outside of this file MACROTEXT macros; CONTESTCNTR contest_count; + +std::string qso_time = ""; +std::string qso_exchange = ""; +std::string exec_date = ""; +std::string exec_time = ""; +std::string exec_string = ""; +std::string info1msg = ""; +std::string info2msg = ""; +std::string text2repeat = ""; + +size_t repeatchar = 0; + +bool macro_idle_on = false; + +static float idleTime = 0; static bool TransmitON = false; static bool ToggleTXRX = false; static int mNbr; -std::string qso_time = ""; -std::string qso_exchange = ""; +static std::string text2send = ""; -std::string exec_date = ""; -std::string exec_time = ""; -std::string exec_string = ""; - -std::string text2send = ""; -std::string text2repeat = ""; -//std::string text2save = ""; -std::string info1msg = ""; -std::string info2msg = ""; - -size_t repeatchar = 0; static size_t xbeg = 0, xend = 0; static bool save_xchg; @@ -102,10 +106,10 @@ static bool GET = false; static bool timed_exec = false; static bool within_exec = false; -static char cutnumbers[] = "T12345678N"; -static string cutstr; +static const char cutnumbers[] = "T12345678N"; +static std::string cutstr; -static string cutstring(const char *s) +static std::string cut_string(const char *s) { cutstr = s; if (!progdefaults.cutnbrs || active_modem != cw_modem) @@ -122,13 +126,13 @@ static size_t mystrftime( char *s, size_t max, const char *fmt, const struct tm return strftime(s, max, fmt, tm); } -static void pFILE(string &s, size_t &i, size_t endbracket) +static void pFILE(std::string &s, size_t &i, size_t endbracket) { - string fname = s.substr(i+6, endbracket - i - 6); + std::string fname = s.substr(i+6, endbracket - i - 6); if (fname.length() > 0 && !within_exec) { FILE *toadd = fopen(fname.c_str(), "r"); if (toadd) { - string buffer; + std::string buffer; char c = getc(toadd); while (c && !feof(toadd)) { if (c != '\r') buffer += c; // damn MSDOS txt files @@ -144,10 +148,10 @@ static void pFILE(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, ""); } -static void pTIMER(string &s, size_t &i, size_t endbracket) +static void pTIMER(std::string &s, size_t &i, size_t endbracket) { int number; - string sTime = s.substr(i+7, endbracket - i - 7); + std::string sTime = s.substr(i+7, endbracket - i - 7); if (sTime.length() > 0 && !within_exec) { sscanf(sTime.c_str(), "%d", &number); progStatus.timer = number; @@ -156,7 +160,7 @@ static void pTIMER(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, ""); } -static void pREPEAT(string &s, size_t &i, size_t endbracket) +static void pREPEAT(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -169,14 +173,14 @@ static void pREPEAT(string &s, size_t &i, size_t endbracket) s.insert(i, "[REPEAT]"); } -static void pWPM(string &s, size_t &i, size_t endbracket) +static void pWPM(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } int number; - string sTime = s.substr(i+5, endbracket - i - 5); + std::string sTime = s.substr(i+5, endbracket - i - 5); if (sTime.length() > 0) { sscanf(sTime.c_str(), "%d", &number); if (number < 5) number = 5; @@ -187,14 +191,14 @@ static void pWPM(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, ""); } -static void pRISETIME(string &s, size_t &i, size_t endbracket) +static void pRISETIME(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } float number; - string sVal = s.substr(i+6, endbracket - i - 6); + std::string sVal = s.substr(i+6, endbracket - i - 6); if (sVal.length() > 0) { sscanf(sVal.c_str(), "%f", &number); if (number < 0) number = 0; @@ -205,14 +209,14 @@ static void pRISETIME(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, ""); } -static void pPRE(string &s, size_t &i, size_t endbracket) +static void pPRE(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } float number; - string sVal = s.substr(i+5, endbracket - i - 5); + std::string sVal = s.substr(i+5, endbracket - i - 5); if (sVal.length() > 0) { sscanf(sVal.c_str(), "%f", &number); if (number < 0) number = 0; @@ -223,14 +227,14 @@ static void pPRE(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, ""); } -static void pPOST(string &s, size_t &i, size_t endbracket) +static void pPOST(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } float number; - string sVal = s.substr(i+6, endbracket - i - 6); + std::string sVal = s.substr(i+6, endbracket - i - 6); if (sVal.length() > 0) { sscanf(sVal.c_str(), "%f", &number); if (number < -20) number = -20; @@ -247,10 +251,10 @@ static void setwpm(int d) cntCW_WPM->value(d); } -static void doWPM(string s) +static void doWPM(std::string s) { int number; - string sTime = s.substr(6); + std::string sTime = s.substr(6); if (sTime.length() > 0) { sscanf(sTime.c_str(), "%d", &number); if (number < 5) number = 5; @@ -260,7 +264,7 @@ static void doWPM(string s) } } -static void pQueWPM(string &s, size_t &i, size_t endbracket) +static void pQueWPM(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -276,10 +280,10 @@ static void setRISETIME(int d) cntCWrisetime->value(d); } -static void doRISETIME(string s) +static void doRISETIME(std::string s) { float number; - string sVal = s.substr(7, s.length() - 8); + std::string sVal = s.substr(7, s.length() - 8); if (sVal.length() > 0) { sscanf(sVal.c_str(), "%f", &number); if (number < 0) number = 0; @@ -289,7 +293,7 @@ static void doRISETIME(string s) } } -static void pQueRISETIME(string &s, size_t &i, size_t endbracket) +static void pQueRISETIME(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -305,10 +309,10 @@ static void setPRE(int d) cntPreTiming->value(d); } -static void doPRE(string s) +static void doPRE(std::string s) { float number; - string sVal = s.substr(6, s.length() - 7); + std::string sVal = s.substr(6, s.length() - 7); if (sVal.length() > 0) { sscanf(sVal.c_str(), "%f", &number); if (number < 0) number = 0; @@ -318,7 +322,7 @@ static void doPRE(string s) } } -static void pQuePRE(string &s, size_t &i, size_t endbracket) +static void pQuePRE(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -334,10 +338,10 @@ static void setPOST(int d) cntPostTiming->value(d); } -static void doPOST(string s) +static void doPOST(std::string s) { float number; - string sVal = s.substr(7, s.length() - 8); + std::string sVal = s.substr(7, s.length() - 8); if (sVal.length() > 0) { sscanf(sVal.c_str(), "%f", &number); if (number < -20) number = -20; @@ -347,7 +351,7 @@ static void doPOST(string s) } } -static void pQuePOST(string &s, size_t &i, size_t endbracket) +static void pQuePOST(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -358,17 +362,14 @@ static void pQuePOST(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, "^!"); } -bool macro_idle_on = false; -static float idleTime = 0; - -static void pIDLE(string &s, size_t &i, size_t endbracket) +static void pIDLE(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } float number; - string sTime = s.substr(i+6, endbracket - i - 6); + std::string sTime = s.substr(i+6, endbracket - i - 6); if (sTime.length() > 0) { sscanf(sTime.c_str(), "%f", &number); macro_idle_on = true; @@ -382,10 +383,10 @@ static void doneIDLE(void *) Qidle_time = 0; } -static void doIDLE(string s) +static void doIDLE(std::string s) { float number; - string sTime = s.substr(7, s.length() - 8); + std::string sTime = s.substr(7, s.length() - 8); if (sTime.length() > 0) { sscanf(sTime.c_str(), "%f", &number); Qidle_time = 1; @@ -395,7 +396,7 @@ static void doIDLE(string s) } } -static void pQueIDLE(string &s, size_t &i, size_t endbracket) +static void pQueIDLE(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -409,14 +410,14 @@ static void pQueIDLE(string &s, size_t &i, size_t endbracket) static bool useTune = false; static int tuneTime = 0; -static void pTUNE(string &s, size_t &i, size_t endbracket) +static void pTUNE(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } int number; - string sTime = s.substr(i+6, endbracket - i - 6); + std::string sTime = s.substr(i+6, endbracket - i - 6); if (sTime.length() > 0) { sscanf(sTime.c_str(), "%d", &number); useTune = true; @@ -428,14 +429,14 @@ static void pTUNE(string &s, size_t &i, size_t endbracket) static bool useWait = false; static int waitTime = 0; -static void pWAIT(string &s, size_t &i, size_t endbracket) +static void pWAIT(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } int number; - string sTime = s.substr(i+6, endbracket - i - 6); + std::string sTime = s.substr(i+6, endbracket - i - 6); if (sTime.length() > 0) { sscanf(sTime.c_str(), "%d", &number); useWait = true; @@ -450,10 +451,10 @@ static void doneWAIT(void *) start_tx(); } -static void doWAIT(string s) +static void doWAIT(std::string s) { int number; - string sTime = s.substr(7, s.length() - 8); + std::string sTime = s.substr(7, s.length() - 8); if (sTime.length() > 0) { sscanf(sTime.c_str(), "%d", &number); Qwait_time = number; @@ -463,7 +464,7 @@ static void doWAIT(string s) que_ok = true; } -static void pQueWAIT(string &s, size_t &i, size_t endbracket) +static void pQueWAIT(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -475,17 +476,17 @@ static void pQueWAIT(string &s, size_t &i, size_t endbracket) } -static void pINFO1(string &s, size_t &i, size_t endbracket) +static void pINFO1(std::string &s, size_t &i, size_t endbracket) { s.replace( i, 7, info1msg ); } -static void pINFO2(string &s, size_t &i, size_t endbracket) +static void pINFO2(std::string &s, size_t &i, size_t endbracket) { s.replace( i, 7, info2msg ); } -static void pCLRRX(string &s, size_t &i, size_t endbracket) +static void pCLRRX(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -495,7 +496,7 @@ static void pCLRRX(string &s, size_t &i, size_t endbracket) ReceiveText->clear(); } -static void pCLRTX(string &s, size_t &i, size_t endbracket) +static void pCLRTX(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -506,79 +507,79 @@ static void pCLRTX(string &s, size_t &i, size_t endbracket) TransmitText->clear(); } -static void pCALL(string &s, size_t &i, size_t endbracket) +static void pCALL(std::string &s, size_t &i, size_t endbracket) { s.replace( i, 6, inpCall->value() ); } -static void pGET(string &s, size_t &i, size_t endbracket) +static void pGET(std::string &s, size_t &i, size_t endbracket) { s.erase( i, 9 ); GET = true; } -static void pFREQ(string &s, size_t &i, size_t endbracket) +static void pFREQ(std::string &s, size_t &i, size_t endbracket) { s.replace( i, 6, inpFreq->value() ); } -static void pLOC(string &s, size_t &i, size_t endbracket) +static void pLOC(std::string &s, size_t &i, size_t endbracket) { s.replace( i, 5, inpLoc->value() ); } -static void pMODE(string &s, size_t &i, size_t endbracket) +static void pMODE(std::string &s, size_t &i, size_t endbracket) { s.replace( i, 6, active_modem->get_mode_name()); } -static void pNAME(string &s, size_t &i, size_t endbracket) +static void pNAME(std::string &s, size_t &i, size_t endbracket) { s.replace( i, 6, inpName->value() ); } -static void pQTH(string &s, size_t &i, size_t endbracket) +static void pQTH(std::string &s, size_t &i, size_t endbracket) { s.replace( i,5, inpQth->value() ); } -static void pQSOTIME(string &s, size_t &i, size_t endbracket) +static void pQSOTIME(std::string &s, size_t &i, size_t endbracket) { qso_time = inpTimeOff->value(); s.replace( i, 9, qso_time.c_str() ); } -static void pRST(string &s, size_t &i, size_t endbracket) +static void pRST(std::string &s, size_t &i, size_t endbracket) { - s.replace( i, 5, cutstring(inpRstOut->value())); + s.replace( i, 5, cut_string(inpRstOut->value())); } -static void pMYCALL(string &s, size_t &i, size_t endbracket) +static void pMYCALL(std::string &s, size_t &i, size_t endbracket) { s.replace( i, 8, inpMyCallsign->value() ); } -static void pMYLOC(string &s, size_t &i, size_t endbracket) +static void pMYLOC(std::string &s, size_t &i, size_t endbracket) { s.replace( i, 7, inpMyLocator->value() ); } -static void pMYNAME(string &s, size_t &i, size_t endbracket) +static void pMYNAME(std::string &s, size_t &i, size_t endbracket) { s.replace( i, 8, inpMyName->value() ); } -static void pMYQTH(string &s, size_t &i, size_t endbracket) +static void pMYQTH(std::string &s, size_t &i, size_t endbracket) { s.replace( i, 7, inpMyQth->value() ); } -static void pMYRST(string &s, size_t &i, size_t endbracket) +static void pMYRST(std::string &s, size_t &i, size_t endbracket) { s.replace( i, 7, inpRstIn->value() ); } -static void pLDT(string &s, size_t &i, size_t endbracket) +static void pLDT(std::string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -589,7 +590,7 @@ static void pLDT(string &s, size_t &i, size_t endbracket) s.replace( i, 5, szDt); } -static void pILDT(string &s, size_t &i, size_t endbracket) +static void pILDT(std::string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -600,7 +601,7 @@ static void pILDT(string &s, size_t &i, size_t endbracket) s.replace( i, 6, szDt); } -static void pZDT(string &s, size_t &i, size_t endbracket) +static void pZDT(std::string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -611,7 +612,7 @@ static void pZDT(string &s, size_t &i, size_t endbracket) s.replace( i, 5, szDt); } -static void pIZDT(string &s, size_t &i, size_t endbracket) +static void pIZDT(std::string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -622,7 +623,7 @@ static void pIZDT(string &s, size_t &i, size_t endbracket) s.replace( i, 6, szDt); } -static void pLT(string &s, size_t &i, size_t endbracket) +static void pLT(std::string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -633,7 +634,7 @@ static void pLT(string &s, size_t &i, size_t endbracket) s.replace( i, 4, szDt); } -static void pZT(string &s, size_t &i, size_t endbracket) +static void pZT(std::string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -644,7 +645,7 @@ static void pZT(string &s, size_t &i, size_t endbracket) s.replace( i, 4, szDt); } -static void pLD(string &s, size_t &i, size_t endbracket) +static void pLD(std::string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -655,7 +656,7 @@ static void pLD(string &s, size_t &i, size_t endbracket) s.replace( i, 4, szDt); } -static void pZD(string &s, size_t &i, size_t endbracket) +static void pZD(std::string &s, size_t &i, size_t endbracket) { char szDt[80]; time_t tmptr; @@ -666,7 +667,7 @@ static void pZD(string &s, size_t &i, size_t endbracket) s.replace( i, 4, szDt); } -static void pID(string &s, size_t &i, size_t endbracket) +static void pID(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -676,7 +677,7 @@ static void pID(string &s, size_t &i, size_t endbracket) s.replace( i, 4, ""); } -static void pTEXT(string &s, size_t &i, size_t endbracket) +static void pTEXT(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -686,7 +687,7 @@ static void pTEXT(string &s, size_t &i, size_t endbracket) s.replace( i, 6, ""); } -static void pCWID(string &s, size_t &i, size_t endbracket) +static void pCWID(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -696,12 +697,12 @@ static void pCWID(string &s, size_t &i, size_t endbracket) s.replace( i, 6, ""); } -static void doDTMF(string s) +static void doDTMF(std::string s) { progdefaults.DTMFstr = s.substr(6, s.length() - 7); } -static void pDTMF(string &s, size_t &i, size_t endbracket) +static void pDTMF(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -712,7 +713,7 @@ static void pDTMF(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, "^!"); } -static void pRX(string &s, size_t &i, size_t endbracket) +static void pRX(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -721,7 +722,7 @@ static void pRX(string &s, size_t &i, size_t endbracket) s.replace (i, 4, "^r"); } -static void pTX(string &s, size_t &i, size_t endbracket) +static void pTX(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -731,7 +732,7 @@ static void pTX(string &s, size_t &i, size_t endbracket) TransmitON = true; } -static void pTXRX(string &s, size_t &i, size_t endbracket) +static void pTXRX(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -742,15 +743,15 @@ static void pTXRX(string &s, size_t &i, size_t endbracket) } -static void pVER(string &s, size_t &i, size_t endbracket) +static void pVER(std::string &s, size_t &i, size_t endbracket) { - string progname; + std::string progname; progname = "Fldigi "; progname.append(PACKAGE_VERSION); s.replace( i, 5, progname ); } -static void pCNTR(string &s, size_t &i, size_t endbracket) +static void pCNTR(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -761,12 +762,12 @@ static void pCNTR(string &s, size_t &i, size_t endbracket) if (contestval) { contest_count.Format(progdefaults.ContestDigits, progdefaults.UseLeadingZeros); snprintf(contest_count.szCount, sizeof(contest_count.szCount), contest_count.fmt.c_str(), contestval); - s.replace (i, 6, cutstring(contest_count.szCount)); + s.replace (i, 6, cut_string(contest_count.szCount)); } else s.replace (i, 6, ""); } -static void pDECR(string &s, size_t &i, size_t endbracket) +static void pDECR(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -780,7 +781,7 @@ static void pDECR(string &s, size_t &i, size_t endbracket) updateOutSerNo(); } -static void pINCR(string &s, size_t &i, size_t endbracket) +static void pINCR(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -793,17 +794,17 @@ static void pINCR(string &s, size_t &i, size_t endbracket) updateOutSerNo(); } -static void pXIN(string &s, size_t &i, size_t endbracket) +static void pXIN(std::string &s, size_t &i, size_t endbracket) { s.replace( i, 5, inpXchgIn->value() ); } -static void pXOUT(string &s, size_t &i, size_t endbracket) +static void pXOUT(std::string &s, size_t &i, size_t endbracket) { - s.replace( i, 6, cutstring(progdefaults.myXchg.c_str())); + s.replace( i, 6, cut_string(progdefaults.myXchg.c_str())); } -static void pXBEG(string &s, size_t &i, size_t endbracket) +static void pXBEG(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -813,7 +814,7 @@ static void pXBEG(string &s, size_t &i, size_t endbracket) xbeg = i; } -static void pXEND(string &s, size_t &i, size_t endbracket) +static void pXEND(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -823,7 +824,7 @@ static void pXEND(string &s, size_t &i, size_t endbracket) xend = i; } -static void pSAVEXCHG(string &s, size_t &i, size_t endbracket) +static void pSAVEXCHG(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -833,7 +834,7 @@ static void pSAVEXCHG(string &s, size_t &i, size_t endbracket) s.replace( i, 10, ""); } -static void pLOG(string &s, size_t &i, size_t endbracket) +static void pLOG(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -843,7 +844,7 @@ static void pLOG(string &s, size_t &i, size_t endbracket) s.replace(i, 5, ""); } -static void pLNW(string &s, size_t &i, size_t endbracket) +static void pLNW(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -852,7 +853,7 @@ static void pLNW(string &s, size_t &i, size_t endbracket) s.replace(i, 5, "^L"); } -static void pCLRLOG(string &s, size_t &i, size_t endbracket) +static void pCLRLOG(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -861,7 +862,7 @@ static void pCLRLOG(string &s, size_t &i, size_t endbracket) s.replace(i, 10, "^C"); } -static void pMODEM_compSKED(string &s, size_t &i, size_t endbracket) +static void pMODEM_compSKED(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -869,9 +870,9 @@ static void pMODEM_compSKED(string &s, size_t &i, size_t endbracket) } size_t j, k, len = s.length(); - string name; + std::string name; - if ((j = s.find('>', i)) == string::npos) + if ((j = s.find('>', i)) == std::string::npos) return; while (++j < len) if (!isspace(s[j])) break; @@ -892,10 +893,10 @@ static void pMODEM_compSKED(string &s, size_t &i, size_t endbracket) #include #include "re.h" -static void doMODEM(string s) +static void doMODEM(std::string s) { static fre_t re("", REG_EXTENDED); - string tomatch = s; + std::string tomatch = s; if (!re.match(tomatch.c_str())) { que_ok = true; @@ -903,7 +904,7 @@ static void doMODEM(string s) } const std::vector& o = re.suboff(); - string name = tomatch.substr(o[1].rm_so, o[1].rm_eo - o[1].rm_so); + std::string name = tomatch.substr(o[1].rm_so, o[1].rm_eo - o[1].rm_so); trx_mode m; for (m = 0; m < NUM_MODES; m++) if (name == mode_info[m].sname) @@ -963,7 +964,7 @@ static void doMODEM(string s) que_ok = true; } -static void pQueMODEM(string &s, size_t &i, size_t endbracket) +static void pQueMODEM(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -974,7 +975,7 @@ static void pQueMODEM(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, "^!"); } -static void pMODEM(string &s, size_t &i, size_t endbracket) +static void pMODEM(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -984,13 +985,13 @@ static void pMODEM(string &s, size_t &i, size_t endbracket) if (!re.match(s.c_str() + i)) { size_t end = s.find('>', i); - if (end != string::npos) + if (end != std::string::npos) s.erase(i, end - i); return; } const std::vector& o = re.suboff(); - string name = s.substr(o[1].rm_so, o[1].rm_eo - o[1].rm_so); + std::string name = s.substr(o[1].rm_so, o[1].rm_eo - o[1].rm_so); trx_mode m; for (m = 0; m < NUM_MODES; m++) if (name == mode_info[m].sname) @@ -1054,18 +1055,18 @@ static void pMODEM(string &s, size_t &i, size_t endbracket) MilliSleep(10); } - s.erase(i, o[0].rm_eo - i); + s.replace(i, endbracket - i + 1, ""); } -static void pAFC(string &s, size_t &i, size_t endbracket) +static void pAFC(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } - string sVal = s.substr(i+5, endbracket - i - 5); + std::string sVal = s.substr(i+5, endbracket - i - 5); if (sVal.length() > 0) { - // sVal = on|off|t [ON, OFF or Toggle] +// sVal = on|off|t [ON, OFF or Toggle] if (sVal.compare(0,2,"on") == 0) btnAFC->value(1); else if (sVal.compare(0,3,"off") == 0) @@ -1075,20 +1076,18 @@ static void pAFC(string &s, size_t &i, size_t endbracket) btnAFC->do_callback(); } -//pushcmd(s.substr(i, endbracket - i + 1)); -//s.replace(i, endbracket - i + 1, "^!"); s.replace(i, endbracket - i + 1, ""); } -static void pLOCK(string &s, size_t &i, size_t endbracket) +static void pLOCK(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } - string sVal = s.substr(i+6, endbracket - i - 6); + std::string sVal = s.substr(i+6, endbracket - i - 6); if (sVal.length() > 0) { - // sVal = on|off|t [ON, OFF or Toggle] +// sVal = on|off|t [ON, OFF or Toggle] if (sVal.compare(0,2,"on") == 0) wf->xmtlock->value(1); else if (sVal.compare(0,3,"off") == 0) @@ -1099,18 +1098,16 @@ static void pLOCK(string &s, size_t &i, size_t endbracket) wf->xmtlock->damage(); wf->xmtlock->do_callback(); } -//pushcmd(s.substr(i, endbracket - i + 1)); -//s.replace(i, endbracket - i + 1, "^!"); s.replace(i, endbracket - i + 1, ""); } -static void pTX_RSID(string &s, size_t &i, size_t endbracket) +static void pTX_RSID(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } - string sVal = s.substr(i+8, endbracket - i - 8); + std::string sVal = s.substr(i+8, endbracket - i - 8); if (sVal.length() > 0) { // sVal = on|off|t [ON, OFF or Toggle] if (sVal.compare(0,2,"on") == 0) @@ -1122,18 +1119,16 @@ static void pTX_RSID(string &s, size_t &i, size_t endbracket) btnTxRSID->do_callback(); } -//pushcmd(s.substr(i, endbracket - i + 1)); -//s.replace(i, endbracket - i + 1, "^!"); s.replace(i, endbracket - i + 1, ""); } -static void pRX_RSID(string &s, size_t &i, size_t endbracket) +static void pRX_RSID(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } - string sVal = s.substr(i+8, endbracket - i - 8); + std::string sVal = s.substr(i+8, endbracket - i - 8); if (sVal.length() > 0) { // sVal = on|off|t [ON, OFF or Toggle] if (sVal.compare(0,2,"on") == 0) @@ -1149,13 +1144,13 @@ static void pRX_RSID(string &s, size_t &i, size_t endbracket) } #ifdef __WIN32__ -static void pTALK(string &s, size_t &i, size_t endbracket) +static void pTALK(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } - string sVal = s.substr(i+6, endbracket - i - 6); + std::string sVal = s.substr(i+6, endbracket - i - 6); if (sVal.length() > 0) { // sVal = on|off [ON, OFF] if (sVal.compare(0,2,"on") == 0) @@ -1169,7 +1164,7 @@ static void pTALK(string &s, size_t &i, size_t endbracket) } #endif -static void pSRCHUP(string &s, size_t &i, size_t endbracket) +static void pSRCHUP(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -1181,7 +1176,7 @@ static void pSRCHUP(string &s, size_t &i, size_t endbracket) wf->insert_text(true); } -static void pSRCHDN(string &s, size_t &i, size_t endbracket) +static void pSRCHDN(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -1193,7 +1188,7 @@ static void pSRCHDN(string &s, size_t &i, size_t endbracket) wf->insert_text(true); } -static void pGOHOME(string &s, size_t &i, size_t endbracket) +static void pGOHOME(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -1208,7 +1203,7 @@ static void pGOHOME(string &s, size_t &i, size_t endbracket) active_modem->set_freq(progdefaults.PSKsweetspot); } -static void doGOHOME(string s) +static void doGOHOME(std::string s) { if (active_modem == cw_modem) active_modem->set_freq(progdefaults.CWsweetspot); @@ -1219,7 +1214,7 @@ static void doGOHOME(string s) que_ok = true; } -static void pQueGOHOME(string &s, size_t &i, size_t endbracket) +static void pQueGOHOME(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -1230,14 +1225,14 @@ static void pQueGOHOME(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, "^!"); } -static void pGOFREQ(string &s, size_t &i, size_t endbracket) +static void pGOFREQ(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } int number; - string sGoFreq = s.substr(i+8, endbracket - i - 8); + std::string sGoFreq = s.substr(i+8, endbracket - i - 8); if (sGoFreq.length() > 0) { sscanf(sGoFreq.c_str(), "%d", &number); if (number < progdefaults.LowFreqCutoff) @@ -1249,10 +1244,10 @@ static void pGOFREQ(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, ""); } -static void doGOFREQ(string s) +static void doGOFREQ(std::string s) { int number; - string sGoFreq = s.substr(9, s.length() - 10); + std::string sGoFreq = s.substr(9, s.length() - 10); if (sGoFreq.length() > 0) { sscanf(sGoFreq.c_str(), "%d", &number); if (number < progdefaults.LowFreqCutoff) @@ -1264,7 +1259,7 @@ static void doGOFREQ(string s) que_ok = true; } -static void pQueGOFREQ(string &s, size_t &i, size_t endbracket) +static void pQueGOFREQ(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -1275,7 +1270,7 @@ static void pQueGOFREQ(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, "^!"); } -static void pQSYTO(string &s, size_t &i, size_t endbracket) +static void pQSYTO(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -1285,7 +1280,7 @@ static void pQSYTO(string &s, size_t &i, size_t endbracket) do_qsy(true); } -static void pQSYFM(string &s, size_t &i, size_t endbracket) +static void pQSYFM(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -1295,7 +1290,7 @@ static void pQSYFM(string &s, size_t &i, size_t endbracket) do_qsy(false); } -static void pQSY(string &s, size_t &i, size_t endbracket) +static void pQSY(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -1304,7 +1299,7 @@ static void pQSY(string &s, size_t &i, size_t endbracket) int rf = 0; int audio = 0; float rfd = 0; - string sGoFreq = s.substr(i+5, endbracket - i - 5); + std::string sGoFreq = s.substr(i+5, endbracket - i - 5); // no frequency(s) specified if (sGoFreq.length() == 0) { s.replace(i, endbracket-i+1, ""); @@ -1315,7 +1310,7 @@ static void pQSY(string &s, size_t &i, size_t endbracket) if (rfd > 0) rf = (int)(1000*rfd); size_t pos; - if ((pos = sGoFreq.find(":")) != string::npos) { + if ((pos = sGoFreq.find(":")) != std::string::npos) { // af second value sGoFreq.erase(0, pos+1); if (sGoFreq.length()) @@ -1334,12 +1329,12 @@ static void pQSY(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, ""); } -static void doQSY(string s) +static void doQSY(std::string s) { int rf = 0; int audio = 0; float rfd = 0; - string sGoFreq; + std::string sGoFreq; sGoFreq = s.substr(6, s.length() - 7); // no frequency(s) specified if (sGoFreq.length() == 0) { @@ -1351,7 +1346,7 @@ static void doQSY(string s) if (rfd > 0) rf = (int)(1000*rfd); size_t pos; - if ((pos = sGoFreq.find(":")) != string::npos) { + if ((pos = sGoFreq.find(":")) != std::string::npos) { // af second value sGoFreq.erase(0, pos+1); if (sGoFreq.length()) @@ -1369,7 +1364,7 @@ static void doQSY(string s) que_ok = true; } -static void pQueQSY(string &s, size_t &i, size_t endbracket) +static void pQueQSY(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -1380,25 +1375,25 @@ static void pQueQSY(string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, "^!"); } -static void pRIGMODE(string& s, size_t& i, size_t endbracket) +static void pRIGMODE(std::string& s, size_t& i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } - string sMode = s.substr(i+9, endbracket - i - 9); + std::string sMode = s.substr(i+9, endbracket - i - 9); qso_opMODE->value(sMode.c_str()); cb_qso_opMODE(); s.replace(i, endbracket - i + 1, ""); } -static void pFILWID(string& s, size_t& i, size_t endbracket) +static void pFILWID(std::string& s, size_t& i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } - string sWidth = s.substr(i+8, endbracket - i - 8); + std::string sWidth = s.substr(i+8, endbracket - i - 8); qso_opBW->value(sWidth.c_str()); cb_qso_opBW(); s.replace(i, endbracket - i + 1, ""); @@ -1469,7 +1464,7 @@ void set_macro_env(void) #ifndef __WOE32__ // pSKEDH - static string pSKEDh = ScriptsDir; + static std::string pSKEDh = ScriptsDir; pSKEDh.erase(pSKEDh.length()-1,1); const char* p; if ((p = getenv("pSKEDH"))) @@ -1517,14 +1512,14 @@ void set_macro_env(void) // as in // ... ... // which is not permitted -static void pEND_EXEC(string &s, size_t &i, size_t endbracket) +static void pEND_EXEC(std::string &s, size_t &i, size_t endbracket) { s.replace(i, endbracket - i + 1, ""); return; } #ifndef __MINGW32__ -static void pEXEC(string &s, size_t &i, size_t endbracket) +static void pEXEC(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -1532,15 +1527,15 @@ static void pEXEC(string &s, size_t &i, size_t endbracket) } size_t start, end; - if ((start = s.find('>', i)) == string::npos || - (end = s.rfind("")) == string::npos) { + if ((start = s.find('>', i)) == std::string::npos || + (end = s.rfind("")) == std::string::npos) { i++; return; } start++; i++; - string execstr = s.substr(start, end-start); + std::string execstr = s.substr(start, end-start); within_exec = true; MACROTEXT m; execstr = m.expandMacro(execstr); @@ -1600,21 +1595,21 @@ static void pEXEC(string &s, size_t &i, size_t endbracket) } #else // !__MINGW32__ -static void pEXEC(string& s, size_t& i, size_t endbracket) +static void pEXEC(std::string& s, size_t& i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } size_t start, end; - if ((start = s.find('>', i)) == string::npos || - (end = s.rfind("")) == string::npos) { + if ((start = s.find('>', i)) == std::string::npos || + (end = s.rfind("")) == std::string::npos) { i++; return; } start++; - string execstr = s.substr(start, end-start); + std::string execstr = s.substr(start, end-start); within_exec = true; MACROTEXT m; execstr = m.expandMacro(execstr); @@ -1640,13 +1635,11 @@ static void pEXEC(string& s, size_t& i, size_t endbracket) static void MAPIT(int how) { float lat = 0, lon = 0; - string sCALL = inpCall->value(); - string sLOC = inpLoc->value(); + std::string sCALL = inpCall->value(); + std::string sLOC = inpLoc->value(); - string url = "http://maps.google.com/maps?q="; + std::string url = "http://maps.google.com/maps?q="; -// if (lookup_addr1.empty() && lookup_addr2.empty() && -// lookup_state.empty() && lookup_country.empty()) { if (how > 1 && !lookup_country.empty()) { url.append(lookup_addr1).append(",").append(lookup_addr2).append(","); url.append(lookup_state).append(",").append(lookup_country); @@ -1683,13 +1676,13 @@ static void MAPIT(int how) cb_mnuVisitURL(NULL, (void*)url.c_str()); } -static void pMAPIT(string &s, size_t &i, size_t endbracket) +static void pMAPIT(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } - string sVal = s.substr(i + 7, endbracket - i - 7); + std::string sVal = s.substr(i + 7, endbracket - i - 7); if (sVal.length() > 0) { if (sVal.compare(0,3,"adr") == 0) REQ(MAPIT,2); @@ -1705,7 +1698,7 @@ static void pMAPIT(string &s, size_t &i, size_t endbracket) expand = false; } -static void pSTOP(string &s, size_t &i, size_t endbracket) +static void pSTOP(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -1715,7 +1708,7 @@ static void pSTOP(string &s, size_t &i, size_t endbracket) expand = false; } -static void pCONT(string &s, size_t &i, size_t endbracket) +static void pCONT(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); @@ -1725,13 +1718,13 @@ static void pCONT(string &s, size_t &i, size_t endbracket) expand = true; } -static void pSKED(string &s, size_t &i, size_t endbracket) +static void pSKED(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { s.replace(i, endbracket - i + 1, ""); return; } - string data = s.substr(i+6, endbracket - i - 6); + std::string data = s.substr(i+6, endbracket - i - 6); size_t p = data.find(":"); if (p == std::string::npos) { exec_date = zdate(); @@ -1759,7 +1752,7 @@ void queue_reset() que_ok = true; } -void postQueue(string s) +static void postQueue(std::string s) { ReceiveText->add(s.c_str(), FTextBase::CTRL); } @@ -1782,15 +1775,15 @@ void queue_execute() bool queue_must_rx() { -static string rxcmds = "", pCALL}, {"", pFREQ}, {"", pLOC}, @@ -1885,11 +1878,11 @@ MTAGS mtags[] = { {0, 0} }; -int MACROTEXT::loadMacros(const string& filename) +int MACROTEXT::loadMacros(const std::string& filename) { - string mLine; - string mName; - string mDef; + std::string mLine; + std::string mName; + std::string mDef; bool inMacro = false; int mNumber = 0; unsigned long int crlf; // 64 bit cpu's @@ -1908,7 +1901,7 @@ int MACROTEXT::loadMacros(const string& filename) mFile.close(); return -2; } - if (mLine.find("extended") == string::npos) { + if (mLine.find("extended") == std::string::npos) { convert = true; changed = true; } @@ -1932,7 +1925,7 @@ int MACROTEXT::loadMacros(const string& filename) name[mNumber] = mLine.substr(idx+1); continue; } - while ((crlf = mLine.find("\\n")) != string::npos) { + while ((crlf = mLine.find("\\n")) != std::string::npos) { mLine.erase(crlf, 2); mLine.append("\n"); } @@ -1947,7 +1940,7 @@ int MACROTEXT::loadMacros(const string& filename) void MACROTEXT::loadDefault() { int erc; - string Filename = MacrosDir; + std::string Filename = MacrosDir; if (progdefaults.UseLastMacro == true) Filename.append(progStatus.LastMacroFile); else { @@ -1964,7 +1957,7 @@ void MACROTEXT::loadDefault() void MACROTEXT::openMacroFile() { - string deffilename = MacrosDir; + std::string deffilename = MacrosDir; deffilename.append(progStatus.LastMacroFile); const char *p = FSEL::select(_("Open macro file"), _("Fldigi macro definition file\t*.mdf"), deffilename.c_str()); if (p) { @@ -1976,7 +1969,7 @@ void MACROTEXT::openMacroFile() void MACROTEXT::saveMacroFile() { - string deffilename = MacrosDir; + std::string deffilename = MacrosDir; deffilename.append(progStatus.LastMacroFile); const char *p = FSEL::saveas(_("Save macro file"), _("Fldigi macro definition file\t*.mdf"), deffilename.c_str()); if (p) { @@ -1985,9 +1978,9 @@ void MACROTEXT::saveMacroFile() } } -void MACROTEXT::loadnewMACROS(string &s, size_t &i, size_t endbracket) +void MACROTEXT::loadnewMACROS(std::string &s, size_t &i, size_t endbracket) { - string fname = s.substr(i+8, endbracket - i - 8); + std::string fname = s.substr(i+8, endbracket - i - 8); if (fname.length() > 0) { loadMacros(fname); progStatus.LastMacroFile = fl_filename_name(fname.c_str()); @@ -1996,7 +1989,7 @@ void MACROTEXT::loadnewMACROS(string &s, size_t &i, size_t endbracket) showMacroSet(); } -string MACROTEXT::expandMacro(std::string &s) +std::string MACROTEXT::expandMacro(std::string &s) { size_t idx = 0; expand = true; @@ -2004,7 +1997,7 @@ string MACROTEXT::expandMacro(std::string &s) ToggleTXRX = false; // mNbr = n; expanded = s;//text[n]; - MTAGS *pMtags; + const MTAGS *pMtags; xbeg = xend = -1; save_xchg = false; @@ -2014,7 +2007,7 @@ string MACROTEXT::expandMacro(std::string &s) waitTime = 0; tuneTime = 0; - while ((idx = expanded.find('<', idx)) != string::npos) { + while ((idx = expanded.find('<', idx)) != std::string::npos) { size_t endbracket = expanded.find('>',idx); if (expanded.find("value(expanded.substr(pos1, pos2 - pos1).c_str()); } - if (pos2 != string::npos) { + if (pos2 != std::string::npos) { pos2 += 4; inpQth->value(expanded.substr(pos2, pos3 - pos2).c_str()); } - if (pos3 != string::npos) { + if (pos3 != std::string::npos) { pos3 += 4; inpLoc->value(expanded.substr(pos3).c_str()); } @@ -2060,15 +2053,15 @@ string MACROTEXT::expandMacro(std::string &s) return ""; } - if (xbeg != string::npos && xend != string::npos && xend > xbeg) { + if (xbeg != std::string::npos && xend != std::string::npos && xend > xbeg) { qso_exchange = expanded.substr(xbeg, xend - xbeg); } else if (save_xchg) { qso_exchange = expanded; save_xchg = false; } -// force "^r" to be last tag in the expanded string - if ((idx = expanded.find("^r")) != string::npos) { +// force "^r" to be last tag in the expanded std::string + if ((idx = expanded.find("^r")) != std::string::npos) { expanded.erase(idx, 2); expanded.append("^r"); } @@ -2081,7 +2074,7 @@ void idleTimer(void *) macro_idle_on = false; } -void continueMacro(void *) +static void continueMacro(void *) { if ( TransmitON ) { active_modem->set_stopflag(false); @@ -2093,14 +2086,14 @@ void continueMacro(void *) text2send.clear(); } -void finishTune(void *) +static void finishTune(void *) { trx_receive(); // delay to allow tx/rx loop to change state Fl::add_timeout(0.5, continueMacro); } -void finishWait(void *) +static void finishWait(void *) { if (useTune && tuneTime > 0) { trx_tune(); @@ -2137,7 +2130,6 @@ void MACROTEXT::timed_execute() void MACROTEXT::execute(int n) { mNbr = n; -// text2save = text2send = expandMacro(text[n]); if (timed_exec) { @@ -2151,11 +2143,11 @@ void MACROTEXT::execute(int n) if (progStatus.repeatMacro == -1) TransmitText->add( text2send.c_str() ); else { - size_t p = string::npos; + size_t p = std::string::npos; text2send = text[n]; - while ((p = text2send.find('<')) != string::npos) + while ((p = text2send.find('<')) != std::string::npos) text2send[p] = '['; - while ((p = text2send.find('>')) != string::npos) + while ((p = text2send.find('>')) != std::string::npos) text2send[p] = ']'; TransmitText->add( text2send.c_str() ); } @@ -2212,7 +2204,7 @@ MACROTEXT::MACROTEXT() } -static string mtext = +static std::string mtext = "//fldigi macro definition file extended\n\ // This file defines the macro structure(s) for the digital modem program, fldigi\n\ // It also serves as a basis for any macros that are written by the user\n\ @@ -2222,8 +2214,8 @@ static string mtext = //\n\ "; -void MACROTEXT::saveMacros(const string& fname) { - string work; +void MACROTEXT::saveMacros(const std::string& fname) { + std::string work; ofstream mfile(fname.c_str()); mfile << mtext; for (int i = 0; i < MAXMACROS; i++) { @@ -2232,7 +2224,7 @@ void MACROTEXT::saveMacros(const string& fname) { work = macros.text[i]; size_t pos; pos = work.find('\n'); - while (pos != string::npos) { + while (pos != std::string::npos) { work.insert(pos, "\\n"); pos = work.find('\n', pos + 3); } From 4ac5f6b3ff48dcf2d0262e201a38abdfd97791b2 Mon Sep 17 00:00:00 2001 From: David Freese Date: Mon, 10 Oct 2011 06:48:57 -0500 Subject: [PATCH 25/54] MFSK soft decode * Corrected viterbi puncture value to 128 which represents neither a 0 nor a 1 --- src/mfsk/mfsk.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mfsk/mfsk.cxx b/src/mfsk/mfsk.cxx index 83608624..41e9763c 100644 --- a/src/mfsk/mfsk.cxx +++ b/src/mfsk/mfsk.cxx @@ -517,7 +517,7 @@ void mfsk::softdecode(complex *bins) // shift to range 0...255 for (i = 0; i < symbits; i++) if (staticburst) - symbols[i] = 0; // puncturing + symbols[i] = 128; // puncturing 128 is neither 0 nor a 1 else symbols[i] = (unsigned char)clamp(128.0 + (b[i] / sum * 128.0), 0, 255); From 6beb6c474f344850e56e58fc4b8ad37e5fa1ec6d Mon Sep 17 00:00:00 2001 From: David Freese Date: Fri, 14 Oct 2011 07:42:07 -0500 Subject: [PATCH 26/54] Version 3.21.17 Maintenance release --- ChangeLog | 7 +++++-- configure.ac | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 948e929b..61d99c43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,12 @@ +2011-10-10 David Freese + + 4ac5f6b: MFSK soft decode + 07baee2: MACRO code cleanup + 4d13cb4: ... =Version 3.21.16= -2011-10-04 David Freese - 3e554f8: !Queue reset 8ac0558: Timer delay diff --git a/configure.ac b/configure.ac index 45210977..42cfc823 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [3]) m4_define(FLDIGI_MINOR, [21]) -m4_define(FLDIGI_PATCH, [.16]) +m4_define(FLDIGI_PATCH, [.17]) m4_define(FLARQ_MAJOR, [4]) m4_define(FLARQ_MINOR, [3]) m4_define(FLARQ_PATCH, [.1]) From ea31ce6fad4e5ce87c6e412f5e009ac2a93e40db Mon Sep 17 00:00:00 2001 From: David Freese Date: Sat, 15 Oct 2011 06:15:48 -0500 Subject: [PATCH 27/54] Version lookup * Changed PACKAGE_DL definition in configure.ac pointed to wrong url --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 42cfc823..a667d36d 100644 --- a/configure.ac +++ b/configure.ac @@ -57,7 +57,7 @@ AC_CONFIG_MACRO_DIR([m4]) FLDIGI_AUTHORS="Dave Freese, Stelios Bounanos, Leigh Klotz, Remi Chateauneu, and others" FLARQ_AUTHORS="Dave Freese" PACKAGE_HOME="http://www.w1hkj.com/Fldigi.html" -PACKAGE_DL="http://www.w1hkj.com/Downloads.html" +PACKAGE_DL="http://www.w1hkj.com/download.html" PACKAGE_PROJ="http://developer.berlios.de/project/showfiles.php?group_id=9149" PACKAGE_NEWBUG="https://fedorahosted.org/fldigi/newticket" PACKAGE_DOCS="http://www.w1hkj.com/FldigiHelp/index.html" From 9c13f6fcbe18a25b8abc43d1cb8f6779c99f58cb Mon Sep 17 00:00:00 2001 From: David Freese Date: Sun, 16 Oct 2011 08:06:26 -0500 Subject: [PATCH 28/54] RTTY bandwidth * Added bandwidth specifier to set modem RTTY tag Specifiers may be unspecified, i.e. * Altered RTTY startup bandwidth behavior to accept current bandwidth setting if not less than minimum required for acceptable decoding. --- src/cw_rtty/rtty.cxx | 5 +++-- src/dialogs/fl_digi.cxx | 6 ++++++ src/include/configuration.h | 10 +++++----- src/include/fl_digi.h | 1 + src/misc/macroedit.cxx | 2 +- src/misc/macros.cxx | 4 ++++ 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/cw_rtty/rtty.cxx b/src/cw_rtty/rtty.cxx index 61991e32..b83e81ce 100644 --- a/src/cw_rtty/rtty.cxx +++ b/src/cw_rtty/rtty.cxx @@ -181,8 +181,9 @@ void rtty::restart() symbollen = (int) (samplerate / rtty_baud + 0.5); set_bandwidth(shift); - rtty_BW = 1.5 * rtty_baud; - progdefaults.RTTY_BW = rtty_BW; + if (progdefaults.RTTY_BW < rtty_baud) + progdefaults.RTTY_BW = rtty_baud; + rtty_BW = progdefaults.RTTY_BW; sldrRTTYbandwidth->value(rtty_BW); wf->redraw_marker(); diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index d1307acf..15a0a722 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -6214,4 +6214,10 @@ void set_rtty_bits(int bits) } } +void set_rtty_bw(float bw) +{ + sldrRTTYbandwidth->value(bw); + sldrRTTYbandwidth->do_callback(); +} + diff --git a/src/include/configuration.h b/src/include/configuration.h index 235a3662..944b69f5 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -239,9 +239,12 @@ ELEM_(int, rtty_custom_shift, "RTTYCUSTOMSHIFT", \ "Custom shift (Hz)", \ 450) \ + ELEM_(double, RTTY_BW, "RTTYBW", \ + "Receive filter bandwidth (Hz)", \ + 68.0) \ ELEM_(int, rtty_baud, "RTTYBAUD", \ "Carrier baud rate. Values are as follows:\n" \ - " 0: 45; 1: 45.45; 2: 50; 3: 56; 4: 75; 5: 100; 6: 110; 7: 150; \n" \ + " 1: 45; 1: 45.45; 2: 50; 3: 56; 4: 75; 5: 100; 6: 110; 7: 150; \n" \ " 8: 200; 9: 300", \ 0) /* 45 */ \ ELEM_(int, rtty_bits, "RTTYBITS", \ @@ -293,13 +296,10 @@ true) \ ELEM_(bool, useMARKfreq, "USEMARKFREQ", \ "Use MARK frequency for logging", \ - true) \ + true) \ ELEM_(bool, Xagc, "XAGC", \ "This setting is currently unused", \ false) \ - ELEM_(double, RTTY_BW, "RTTYBW", \ - "Receive filter bandwidth (Hz)", \ - 400.0) \ /* CW */ \ ELEM_(bool, useCWkeylineRTS, "", "", false) \ ELEM_(bool, useCWkeylineDTR, "", "", false) \ diff --git a/src/include/fl_digi.h b/src/include/fl_digi.h index ff07825a..b212064c 100644 --- a/src/include/fl_digi.h +++ b/src/include/fl_digi.h @@ -300,6 +300,7 @@ void set_contestia_tones(int tones); void set_rtty_shift(int shift); void set_rtty_baud(float baud); void set_rtty_bits(int bits); +void set_rtty_bw(float bw); void sync_cw_parameters(); diff --git a/src/misc/macroedit.cxx b/src/misc/macroedit.cxx index 932f52e5..7ee80f2c 100644 --- a/src/misc/macroedit.cxx +++ b/src/misc/macroedit.cxx @@ -201,7 +201,7 @@ void loadBrowser(Fl_Widget *widget) { w->add(s); } // add some RTTY macros - const char* rtty[] = { "170:45.45:5", "170:50:5", "850:75:5" }; + const char* rtty[] = { "170:45.45:5:90", "170:50:5:100", "850:75:5:150" }; for (size_t i = 0; i < sizeof(rtty)/sizeof(*rtty); i++) { snprintf(s, sizeof(s), "", mode_info[MODE_RTTY].sname, rtty[i]); w->add(s); diff --git a/src/misc/macros.cxx b/src/misc/macros.cxx index e8b4bc0c..5b146997 100644 --- a/src/misc/macros.cxx +++ b/src/misc/macros.cxx @@ -940,6 +940,8 @@ static void doMODEM(std::string s) set_rtty_baud((float)args[1]); if (args.at(2) != DBL_MIN) set_rtty_bits((int)args[2]); + if (args.at(3) != DBL_MIN) + set_rtty_bw((float)args[3]); break; case MODE_CONTESTIA: // bandwidth, tones if (args.at(0) != DBL_MIN) @@ -1029,6 +1031,8 @@ static void pMODEM(std::string &s, size_t &i, size_t endbracket) set_rtty_baud((float)args[1]); if (args.at(2) != DBL_MIN) set_rtty_bits((int)args[2]); + if (args.at(3) != DBL_MIN) + set_rtty_bw((float)args[3]); break; case MODE_CONTESTIA: // bandwidth, tones if (args.at(0) != DBL_MIN) From 12474884a5755e60d635ce0f454d93b8eaf47802 Mon Sep 17 00:00:00 2001 From: David Freese Date: Sun, 16 Oct 2011 15:22:56 -0500 Subject: [PATCH 29/54] REV macro tag * Added macro tag --- src/misc/macroedit.cxx | 1 + src/misc/macros.cxx | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/misc/macroedit.cxx b/src/misc/macroedit.cxx index 7ee80f2c..f84cbd74 100644 --- a/src/misc/macroedit.cxx +++ b/src/misc/macroedit.cxx @@ -168,6 +168,7 @@ void loadBrowser(Fl_Widget *widget) { w->add(LINE_SEP); w->add(_("\tAFC on,off,toggle")); w->add(_("\tLOCK on,off,toggle")); + w->add(_("\tRev on,off,toggle")); w->add(LINE_SEP); w->add(_("\tchange macro defs file")); diff --git a/src/misc/macros.cxx b/src/misc/macros.cxx index 5b146997..e16cd248 100644 --- a/src/misc/macros.cxx +++ b/src/misc/macros.cxx @@ -1083,6 +1083,27 @@ static void pAFC(std::string &s, size_t &i, size_t endbracket) s.replace(i, endbracket - i + 1, ""); } +static void pREV(std::string &s, size_t &i, size_t endbracket) +{ + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } + std::string sVal = s.substr(i+5, endbracket - i - 5); + if (sVal.length() > 0) { +// sVal = on|off|t [ON, OFF or Toggle] + if (sVal.compare(0,2,"on") == 0) + wf->btnRev->value(1); + else if (sVal.compare(0,3,"off") == 0) + wf->btnRev->value(0); + else if (sVal.compare(0,1,"t") == 0) + wf->btnRev->value(!wf->btnRev->value()); + + wf->btnRev->do_callback(); + } + s.replace(i, endbracket - i + 1, ""); +} + static void pLOCK(std::string &s, size_t &i, size_t endbracket) { if (within_exec) { @@ -1850,6 +1871,7 @@ static const MTAGS mtags[] = { {" Date: Sun, 16 Oct 2011 08:50:12 -0500 Subject: [PATCH 30/54] Version 3.21.18 Maintenance release --- ChangeLog | 7 ++++++- configure.ac | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 61d99c43..4d39c835 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ -2011-10-10 David Freese +2011-10-16 David Freese + + 9c13f6f: RTTY bandwidth + + +=Version 3.21.17= 4ac5f6b: MFSK soft decode 07baee2: MACRO code cleanup diff --git a/configure.ac b/configure.ac index a667d36d..96f4db91 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [3]) m4_define(FLDIGI_MINOR, [21]) -m4_define(FLDIGI_PATCH, [.17]) +m4_define(FLDIGI_PATCH, [.18]) m4_define(FLARQ_MAJOR, [4]) m4_define(FLARQ_MINOR, [3]) m4_define(FLARQ_PATCH, [.1]) From 7046d49f98e77106fc72e7ed1ab81527adf81fb5 Mon Sep 17 00:00:00 2001 From: David Freese Date: Wed, 19 Oct 2011 09:34:42 -0500 Subject: [PATCH 31/54] HamQTH lookup * Added HamQTH to callsign queries --- src/dialogs/confdialog.cxx | 40 +++++--- src/dialogs/confdialog.fl | 47 ++++++---- src/include/confdialog.h | 1 + src/include/lookupcall.h | 2 +- src/misc/configuration.cxx | 3 + src/misc/lookupcall.cxx | 187 +++++++++++++++++++++++++++++++++---- src/misc/network.cxx | 1 + 7 files changed, 230 insertions(+), 51 deletions(-) diff --git a/src/dialogs/confdialog.cxx b/src/dialogs/confdialog.cxx index cc9ed41d..d21129fe 100644 --- a/src/dialogs/confdialog.cxx +++ b/src/dialogs/confdialog.cxx @@ -29,7 +29,7 @@ Mode_Browser* mode_browser; void set_qrz_buttons(Fl_Button* b) { Fl_Button* qrzb[] = { btnQRZnotavailable, btnQRZcdrom, btnQRZonline, btnQRZsub, btnHamcall, btnHAMCALLonline, - btnCALLOOK}; + btnCALLOOK, btnHamQTH}; for (size_t i = 0; i < sizeof(qrzb)/sizeof(*qrzb); i++) qrzb[i]->value(b == qrzb[i]); @@ -2929,6 +2929,14 @@ inpQRZuserpassword->redraw(); o->label((inpQRZuserpassword->type() & FL_SECRET_INPUT) ? "Show" : "Hide"); } +Fl_Round_Button *btnHamQTH=(Fl_Round_Button *)0; + +static void cb_btnHamQTH(Fl_Round_Button* o, void*) { + set_qrz_buttons(o); +progdefaults.QRZ = HAMQTH; +progdefaults.changed = true; +} + Fl_Round_Button *btnQRZnotavailable=(Fl_Round_Button *)0; static void cb_btnQRZnotavailable(Fl_Round_Button* o, void*) { @@ -6494,16 +6502,16 @@ d frequency")); { tabQRZ = new Fl_Group(0, 25, 500, 345, _("Callsign DB")); tabQRZ->tooltip(_("Callsign database")); tabQRZ->hide(); - { Fl_Group* o = new Fl_Group(5, 180, 490, 75, _("CDROM")); + { Fl_Group* o = new Fl_Group(5, 176, 490, 55, _("CDROM")); o->box(FL_ENGRAVED_FRAME); o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); - { Fl_Round_Button* o = btnQRZcdrom = new Fl_Round_Button(25, 215, 70, 20, _("QRZ")); + { Fl_Round_Button* o = btnQRZcdrom = new Fl_Round_Button(25, 196, 70, 20, _("QRZ")); btnQRZcdrom->tooltip(_("Use CD or hard drive CD image")); btnQRZcdrom->down_box(FL_DOWN_BOX); btnQRZcdrom->callback((Fl_Callback*)cb_btnQRZcdrom); o->value(progdefaults.QRZ == QRZCD); } // Fl_Round_Button* btnQRZcdrom - { Fl_Input2* o = txtQRZpathname = new Fl_Input2(104, 215, 300, 20, _("at:")); + { Fl_Input2* o = txtQRZpathname = new Fl_Input2(104, 196, 300, 20, _("at:")); txtQRZpathname->tooltip(_("ie: /home/dave/CALLBK/ or C:/CALLBK/\nLeave blank to search for database")); txtQRZpathname->box(FL_DOWN_BOX); txtQRZpathname->color((Fl_Color)FL_BACKGROUND2_COLOR); @@ -6520,22 +6528,22 @@ d frequency")); } // Fl_Input2* txtQRZpathname o->end(); } // Fl_Group* o - { Fl_Group* o = new Fl_Group(5, 260, 490, 95, _("Paid online subscription")); + { Fl_Group* o = new Fl_Group(5, 232, 490, 134, _("Subscriber data")); o->box(FL_ENGRAVED_FRAME); o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); - { Fl_Round_Button* o = btnQRZsub = new Fl_Round_Button(25, 291, 90, 20, _("QRZ.com")); + { Fl_Round_Button* o = btnQRZsub = new Fl_Round_Button(25, 263, 90, 20, _("QRZ.com")); btnQRZsub->tooltip(_("You need a paid QRZ online\nsubscription to access")); btnQRZsub->down_box(FL_DOWN_BOX); btnQRZsub->callback((Fl_Callback*)cb_btnQRZsub); o->value(progdefaults.QRZ == QRZNET); } // Fl_Round_Button* btnQRZsub - { Fl_Round_Button* o = btnHamcall = new Fl_Round_Button(25, 321, 105, 20, _("Hamcall.net")); + { Fl_Round_Button* o = btnHamcall = new Fl_Round_Button(25, 297, 105, 20, _("Hamcall.net")); btnHamcall->tooltip(_("You need a paid Hamcall online\nsubscription to access")); btnHamcall->down_box(FL_DOWN_BOX); btnHamcall->callback((Fl_Callback*)cb_btnHamcall); o->value(progdefaults.QRZ == HAMCALLNET); } // Fl_Round_Button* btnHamcall - { Fl_Input2* o = inpQRZusername = new Fl_Input2(235, 291, 90, 20, _("User name")); + { Fl_Input2* o = inpQRZusername = new Fl_Input2(235, 263, 150, 20, _("User name")); inpQRZusername->tooltip(_("Your login name")); inpQRZusername->box(FL_DOWN_BOX); inpQRZusername->color((Fl_Color)FL_BACKGROUND2_COLOR); @@ -6550,7 +6558,7 @@ d frequency")); o->value(progdefaults.QRZusername.c_str()); inpQRZusername->labelsize(FL_NORMAL_SIZE); } // Fl_Input2* inpQRZusername - { Fl_Input2* o = inpQRZuserpassword = new Fl_Input2(236, 321, 90, 20, _("Password")); + { Fl_Input2* o = inpQRZuserpassword = new Fl_Input2(235, 297, 150, 20, _("Password")); inpQRZuserpassword->tooltip(_("Your login password")); inpQRZuserpassword->box(FL_DOWN_BOX); inpQRZuserpassword->color((Fl_Color)FL_BACKGROUND2_COLOR); @@ -6566,10 +6574,16 @@ d frequency")); o->type(FL_SECRET_INPUT); inpQRZuserpassword->labelsize(FL_NORMAL_SIZE); } // Fl_Input2* inpQRZuserpassword - { btnQRZpasswordShow = new Fl_Button(336, 321, 70, 20, _("Show")); + { btnQRZpasswordShow = new Fl_Button(395, 297, 70, 20, _("Show")); btnQRZpasswordShow->tooltip(_("Show password in plain text")); btnQRZpasswordShow->callback((Fl_Callback*)cb_btnQRZpasswordShow); } // Fl_Button* btnQRZpasswordShow + { Fl_Round_Button* o = btnHamQTH = new Fl_Round_Button(26, 332, 121, 20, _("HamQTH.com")); + btnHamQTH->tooltip(_("You need a paid Hamcall online\nsubscription to access")); + btnHamQTH->down_box(FL_DOWN_BOX); + btnHamQTH->callback((Fl_Callback*)cb_btnHamQTH); + o->value(progdefaults.QRZ == HAMQTH); + } // Fl_Round_Button* btnHamQTH o->end(); } // Fl_Group* o { Fl_Group* o = new Fl_Group(5, 35, 490, 140); @@ -6582,19 +6596,19 @@ d frequency")); btnQRZnotavailable->callback((Fl_Callback*)cb_btnQRZnotavailable); o->value(progdefaults.QRZ == QRZNONE); } // Fl_Round_Button* btnQRZnotavailable - { Fl_Round_Button* o = btnQRZonline = new Fl_Round_Button(25, 75, 337, 20, _("QRZ online via default Internet Browser")); + { Fl_Round_Button* o = btnQRZonline = new Fl_Round_Button(25, 76, 337, 20, _("QRZ online via default Internet Browser")); btnQRZonline->tooltip(_("Visit QRZ web site")); btnQRZonline->down_box(FL_DOWN_BOX); btnQRZonline->callback((Fl_Callback*)cb_btnQRZonline); o->value(progdefaults.QRZ == QRZHTML); } // Fl_Round_Button* btnQRZonline - { Fl_Round_Button* o = btnHAMCALLonline = new Fl_Round_Button(25, 106, 337, 20, _("HamCall online via default Internet Browser")); + { Fl_Round_Button* o = btnHAMCALLonline = new Fl_Round_Button(25, 107, 337, 20, _("HamCall online via default Internet Browser")); btnHAMCALLonline->tooltip(_("Visit Hamcall web site")); btnHAMCALLonline->down_box(FL_DOWN_BOX); btnHAMCALLonline->callback((Fl_Callback*)cb_btnHAMCALLonline); o->value(progdefaults.QRZ == HAMCALLHTML); } // Fl_Round_Button* btnHAMCALLonline - { Fl_Round_Button* o = btnCALLOOK = new Fl_Round_Button(25, 137, 337, 20, _("Callook.info lookup (US callsigns only)")); + { Fl_Round_Button* o = btnCALLOOK = new Fl_Round_Button(25, 139, 337, 20, _("Callook.info lookup (US callsigns only)")); btnCALLOOK->tooltip(_("Visit Hamcall web site")); btnCALLOOK->down_box(FL_DOWN_BOX); btnCALLOOK->callback((Fl_Callback*)cb_btnCALLOOK); diff --git a/src/dialogs/confdialog.fl b/src/dialogs/confdialog.fl index 505f0f11..0202ae26 100644 --- a/src/dialogs/confdialog.fl +++ b/src/dialogs/confdialog.fl @@ -77,7 +77,7 @@ Function {set_qrz_buttons(Fl_Button* b)} {open return_type void } { code {Fl_Button* qrzb[] = { btnQRZnotavailable, btnQRZcdrom, btnQRZonline, btnQRZsub, btnHamcall, btnHAMCALLonline, - btnCALLOOK}; + btnCALLOOK, btnHamQTH}; for (size_t i = 0; i < sizeof(qrzb)/sizeof(*qrzb); i++) qrzb[i]->value(b == qrzb[i]);} {} @@ -185,7 +185,7 @@ progdefaults.changed = true;} } } Fl_Group tabUI { - label UI open + label UI xywh {0 25 502 346} hide } { Fl_Tabs tabsUI {open @@ -903,7 +903,7 @@ connect_to_log_server();} } } Fl_Group tabWaterfall { - label Waterfall open + label Waterfall xywh {0 25 501 347} hide } { Fl_Tabs tabsWaterfall {open @@ -1238,7 +1238,7 @@ behaves inside the waterfall} xywh {15 196 150 22} down_box BORDER_BOX align 8 } } Fl_Group tabModems { - label Modems open + label Modems xywh {-4 25 521 347} hide } { Fl_Tabs tabsModems {open @@ -3323,7 +3323,7 @@ progdefaults.changed = true;} } } Fl_Group tabMisc { - label Misc open + label Misc xywh {0 25 500 345} hide } { Fl_Tabs tabsMisc {open @@ -3655,19 +3655,19 @@ progdefaults.changed = true;} } } Fl_Group tabQRZ { - label {Callsign DB} + label {Callsign DB} open tooltip {Callsign database} xywh {0 25 500 345} hide } { Fl_Group {} { label CDROM open - xywh {5 180 490 75} box ENGRAVED_FRAME align 21 + xywh {5 176 490 55} box ENGRAVED_FRAME align 21 } { Fl_Round_Button btnQRZcdrom { label QRZ callback {set_qrz_buttons(o); progdefaults.QRZ = QRZCD; progdefaults.changed = true;} - tooltip {Use CD or hard drive CD image} xywh {25 215 70 20} down_box DOWN_BOX + tooltip {Use CD or hard drive CD image} xywh {25 196 70 20} down_box DOWN_BOX code0 {o->value(progdefaults.QRZ == QRZCD);} } Fl_Input txtQRZpathname { @@ -3676,15 +3676,15 @@ progdefaults.changed = true;} progdefaults.QRZchanged = true; progdefaults.changed = true;} tooltip {ie: /home/dave/CALLBK/ or C:/CALLBK/ -Leave blank to search for database} xywh {104 215 300 20} +Leave blank to search for database} xywh {104 196 300 20} code0 {o->value(progdefaults.QRZpathname.c_str());} code1 {txtQRZpathname->labelsize(FL_NORMAL_SIZE);} class Fl_Input2 } } Fl_Group {} { - label {Paid online subscription} open - xywh {5 260 490 95} box ENGRAVED_FRAME align 21 + label {Subscriber data} open + xywh {5 232 490 134} box ENGRAVED_FRAME align 21 } { Fl_Round_Button btnQRZsub { label {QRZ.com} @@ -3692,7 +3692,7 @@ Leave blank to search for database} xywh {104 215 300 20} progdefaults.QRZ = QRZNET; progdefaults.changed = true;} tooltip {You need a paid QRZ online -subscription to access} xywh {25 291 90 20} down_box DOWN_BOX +subscription to access} xywh {25 263 90 20} down_box DOWN_BOX code0 {o->value(progdefaults.QRZ == QRZNET);} } Fl_Round_Button btnHamcall { @@ -3701,14 +3701,14 @@ subscription to access} xywh {25 291 90 20} down_box DOWN_BOX progdefaults.QRZ = HAMCALLNET; progdefaults.changed = true;} tooltip {You need a paid Hamcall online -subscription to access} xywh {25 321 105 20} down_box DOWN_BOX +subscription to access} xywh {25 297 105 20} down_box DOWN_BOX code0 {o->value(progdefaults.QRZ == HAMCALLNET);} } Fl_Input inpQRZusername { label {User name} callback {progdefaults.QRZusername = o->value(); progdefaults.changed = true;} - tooltip {Your login name} xywh {235 291 90 20} + tooltip {Your login name} xywh {235 263 150 20} code0 {o->value(progdefaults.QRZusername.c_str());} code1 {inpQRZusername->labelsize(FL_NORMAL_SIZE);} class Fl_Input2 @@ -3717,7 +3717,7 @@ progdefaults.changed = true;} label Password callback {progdefaults.QRZuserpassword = o->value(); progdefaults.changed = true;} - tooltip {Your login password} xywh {236 321 90 20} + tooltip {Your login password} xywh {235 297 150 20} code0 {o->value(progdefaults.QRZuserpassword.c_str());} code1 {o->type(FL_SECRET_INPUT);} code2 {inpQRZuserpassword->labelsize(FL_NORMAL_SIZE);} @@ -3728,7 +3728,16 @@ progdefaults.changed = true;} callback {inpQRZuserpassword->type(inpQRZuserpassword->type() ^ FL_SECRET_INPUT); inpQRZuserpassword->redraw(); o->label((inpQRZuserpassword->type() & FL_SECRET_INPUT) ? "Show" : "Hide");} - tooltip {Show password in plain text} xywh {336 321 70 20} + tooltip {Show password in plain text} xywh {395 297 70 20} + } + Fl_Round_Button btnHamQTH { + label {HamQTH.com} + callback {set_qrz_buttons(o); +progdefaults.QRZ = HAMQTH; +progdefaults.changed = true;} + tooltip {You need a paid Hamcall online +subscription to access} xywh {26 332 121 20} down_box DOWN_BOX + code0 {o->value(progdefaults.QRZ == HAMQTH);} } } Fl_Group {} {open @@ -3747,7 +3756,7 @@ progdefaults.changed = true;} callback {set_qrz_buttons(o); progdefaults.QRZ = QRZHTML; progdefaults.changed = true;} - tooltip {Visit QRZ web site} xywh {25 75 337 20} down_box DOWN_BOX + tooltip {Visit QRZ web site} xywh {25 76 337 20} down_box DOWN_BOX code0 {o->value(progdefaults.QRZ == QRZHTML);} } Fl_Round_Button btnHAMCALLonline { @@ -3755,7 +3764,7 @@ progdefaults.changed = true;} callback {set_qrz_buttons(o); progdefaults.QRZ = HAMCALLHTML; progdefaults.changed = true;} - tooltip {Visit Hamcall web site} xywh {25 106 337 20} down_box DOWN_BOX + tooltip {Visit Hamcall web site} xywh {25 107 337 20} down_box DOWN_BOX code0 {o->value(progdefaults.QRZ == HAMCALLHTML);} } Fl_Round_Button btnCALLOOK { @@ -3763,7 +3772,7 @@ progdefaults.changed = true;} callback {set_qrz_buttons(o); progdefaults.QRZ = CALLOOK; progdefaults.changed = true;} - tooltip {Visit Hamcall web site} xywh {25 137 337 20} down_box DOWN_BOX + tooltip {Visit Hamcall web site} xywh {25 139 337 20} down_box DOWN_BOX code0 {o->value(progdefaults.QRZ == CALLOOK);} } } diff --git a/src/include/confdialog.h b/src/include/confdialog.h index a98d8ba2..6c4196f7 100644 --- a/src/include/confdialog.h +++ b/src/include/confdialog.h @@ -411,6 +411,7 @@ extern Fl_Round_Button *btnHamcall; extern Fl_Input2 *inpQRZusername; extern Fl_Input2 *inpQRZuserpassword; extern Fl_Button *btnQRZpasswordShow; +extern Fl_Round_Button *btnHamQTH; extern Fl_Round_Button *btnQRZnotavailable; extern Fl_Round_Button *btnQRZonline; extern Fl_Round_Button *btnHAMCALLonline; diff --git a/src/include/lookupcall.h b/src/include/lookupcall.h index 2da9b832..0a746a97 100644 --- a/src/include/lookupcall.h +++ b/src/include/lookupcall.h @@ -16,6 +16,6 @@ extern std::string lookup_country; extern void clear_Lookup(); extern void CALLSIGNquery(); -enum qrz_query_t { QRZ_EXIT = -1, QRZNONE, QRZNET, QRZCD, HAMCALLNET, QRZHTML, HAMCALLHTML, CALLOOK }; +enum qrz_query_t { QRZ_EXIT = -1, QRZNONE, QRZNET, QRZCD, HAMCALLNET, QRZHTML, HAMCALLHTML, CALLOOK, HAMQTH }; #endif diff --git a/src/misc/configuration.cxx b/src/misc/configuration.cxx index 17955927..8c009f44 100644 --- a/src/misc/configuration.cxx +++ b/src/misc/configuration.cxx @@ -654,6 +654,9 @@ int configuration::setDefaults() case CALLOOK: qrzb = btnCALLOOK; break; + case HAMQTH: + qrzb = btnHamQTH; + break; default : break; } diff --git a/src/misc/lookupcall.cxx b/src/misc/lookupcall.cxx index a8b748b7..0c10ae97 100644 --- a/src/misc/lookupcall.cxx +++ b/src/misc/lookupcall.cxx @@ -150,7 +150,7 @@ bool parseSessionKey(const string& sessionpage) { case EXN_TEXT: case EXN_CDATA: - switch (tag) + switch (tag) { default: break; @@ -188,7 +188,7 @@ bool parseSessionKey(const string& sessionpage) } delete xml; return true; -} +} bool parse_xml(const string& xmlpage) @@ -196,7 +196,7 @@ bool parse_xml(const string& xmlpage) //printf("%s\n", xmlpage.c_str()); IrrXMLReader* xml = createIrrXMLReader(new IIrrXMLStringReader(xmlpage)); -// If we got any result back, clear the session key so that it will be +// If we got any result back, clear the session key so that it will be // refreshed by this response, or if not present, will be removed and we'll // know to log in next time. if (xml) { @@ -207,7 +207,7 @@ bool parse_xml(const string& xmlpage) } TAG tag = QRZ_IGNORE; - + // parse the file until end reached while(xml && xml->read()) { switch(xml->getNodeType()) { @@ -269,12 +269,12 @@ bool parse_xml(const string& xmlpage) break; } break; - + case EXN_ELEMENT_END: tag=QRZ_IGNORE; break; - case EXN_ELEMENT: + case EXN_ELEMENT: { const char *nodeName = xml->getNodeName(); if (!strcmp("call", nodeName)) tag = QRZ_CALL; @@ -390,11 +390,11 @@ void QRZ_disp_result() } inpQth->value(lookup_qth.c_str()); - + inpState->value(lookup_state.c_str()); inpVEprov->value(lookup_province.c_str()); - + inpLoc->value(lookup_grid.c_str()); if (!lookup_country.empty()) @@ -419,7 +419,7 @@ void QRZ_CD_query() char srch[20]; size_t snip; - + memset( srch, 0, sizeof(srch) ); strncpy( srch, callsign.c_str(), 6 ); for (size_t i = 0; i < strlen(srch); i ++ ) @@ -652,36 +652,36 @@ void CALLOOKquery() void parse_html(const string& htmlpage) { size_t p; - + clear_Lookup(); - + if ((p = htmlpage.find(HAMCALL_FIRST)) != string::npos) { p++; while ((uchar)htmlpage[p] < 128 && p < htmlpage.length() ) lookup_fname += htmlpage[p++]; camel_case(lookup_fname); } - if ((p = htmlpage.find(HAMCALL_CITY)) != string::npos) { + if ((p = htmlpage.find(HAMCALL_CITY)) != string::npos) { p++; while ((uchar)htmlpage[p] < 128 && p < htmlpage.length()) lookup_qth += htmlpage[p++]; } - if ((p = htmlpage.find(HAMCALL_STATE)) != string::npos) { + if ((p = htmlpage.find(HAMCALL_STATE)) != string::npos) { p++; while ((uchar)htmlpage[p] < 128 && p < htmlpage.length()) lookup_state += htmlpage[p++]; } - if ((p = htmlpage.find(HAMCALL_GRID)) != string::npos) { + if ((p = htmlpage.find(HAMCALL_GRID)) != string::npos) { p++; while ((uchar)htmlpage[p] < 128 && p < htmlpage.length()) lookup_grid += htmlpage[p++]; } - if ((p = htmlpage.find(HAMCALL_DOB)) != string::npos) { + if ((p = htmlpage.find(HAMCALL_DOB)) != string::npos) { p++; lookup_notes = "DOB: "; while ((uchar)htmlpage[p] < 128 && p < htmlpage.length()) lookup_notes += htmlpage[p++]; - } + } } bool HAMCALLget(string& htmlpage) @@ -713,11 +713,156 @@ void HAMCALLquery() REQ(QRZ_disp_result); } +// --------------------------------------------------------------------- +// Hamcall specific functions +// --------------------------------------------------------------------- + +static string HAMQTH_session_id = ""; +static string HAMQTH_reply = ""; + +bool HAMQTH_get_session_id() +{ + string url = ""; + string retstr = ""; + size_t p1 = string::npos; + size_t p2 = string::npos; + + url.append("http://www.hamqth.com/xml.php?u=").append(progdefaults.QRZusername); + url.append("&p=").append(progdefaults.QRZuserpassword); + + HAMQTH_session_id.clear(); + if (!fetch_http(url, retstr, 5.0)) { + return false; + } + if ((p1 = retstr.find("")) != string::npos) { + p2 = retstr.find(""); + lookup_notes = retstr.substr(p1 + 7, p2 - p1 - 7); + return false; + } + if ((p1 = retstr.find("")) == string::npos) { + lookup_notes = "HamQTH not available"; + return false; + } + p2 = retstr.find(""); + HAMQTH_session_id = retstr.substr(p1 + 12, p2 - p1 - 12); +//printf("session id = %s\n", HAMQTH_session_id.c_str()); + return true; +} + +void parse_HAMQTH_html(const string& htmlpage) +{ + size_t p = string::npos; + size_t p1 = string::npos; + + clear_Lookup(); + + if ((p = htmlpage.find("")) != string::npos) { + p += 6; + p1 = htmlpage.find("", p); + if (p1 != string::npos) { + lookup_fname = htmlpage.substr(p, p1 - p); + camel_case(lookup_fname); + } + } + if ((p = htmlpage.find("")) != string::npos) { + p += 10; + p1 = htmlpage.find("", p); + if (p1 != string::npos) + lookup_qth = htmlpage.substr(p, p1 - p); + } + if ((p = htmlpage.find("")) != string::npos) { + p += 10; + p1 = htmlpage.find(""); + if (p1 != string::npos) + lookup_state = htmlpage.substr(p, p1 - p); + } + if ((p = htmlpage.find("")) != string::npos) { + p += 6; + p1 = htmlpage.find(""); + if (p1 != string::npos) + lookup_grid = htmlpage.substr(p, p1 - p); + } + if ((p = htmlpage.find("")) != string::npos) { + p += 10; + p1 = htmlpage.find(""); + if (p1 != string::npos) + lookup_notes = htmlpage.substr(p, p1 - p).append("\n"); + } + if ((p = htmlpage.find("")) != string::npos) { + p += 13; + p1 = htmlpage.find(""); + if (p1 != string::npos) + lookup_notes.append(htmlpage.substr(p, p1 - p)).append("\n"); + } + if ((p = htmlpage.find("")) != string::npos) { + p += 10; + p1 = htmlpage.find(""); + if (p1 != string::npos) + lookup_notes.append(htmlpage.substr(p, p1 - p)).append(", ").append(lookup_state); + } + if ((p = htmlpage.find("")) != string::npos) { + p += 9; + p1 = htmlpage.find(""); + if (p1 != string::npos) + lookup_notes.append(" ").append(htmlpage.substr(p, p1 - p)); + } + if ((p = htmlpage.find("")) != string::npos) { + p += 13; + p1 = htmlpage.find(""); + if (p1 != string::npos) + lookup_notes.append(" ").append(htmlpage.substr(p, p1 - p)); + } + if ((p == htmlpage.find("")) != string::npos) { + p += 9; + p1 = htmlpage.find(""); + if (p1 != string::npos) + lookup_notes.append("\nQSL via: ").append(htmlpage.substr(p, p1 - p)); + } +} + +bool HAMQTHget(string& htmlpage) +{ + string url = ""; + bool ret; + if (HAMQTH_session_id.empty()) { + if (!HAMQTH_get_session_id()) return false; + } + url.append("http://www.hamqth.com/xml.php?id=").append(HAMQTH_session_id); + url.append("&callsign=").append(callsign); + url.append("&prg=fldigi-").append(VERSION); + + ret = fetch_http(url, htmlpage, 5.0); +//printf("%s\n", htmlpage.c_str()); + if (htmlpage.find("") != string::npos) { + htmlpage.clear(); + if (!HAMQTH_get_session_id()) + return false; + ret = fetch_http(url, htmlpage, 5.0); +//printf("%s\n", htmlpage.c_str()); + } + return ret; +} + +void HAMQTHquery() +{ + ENSURE_THREAD(QRZ_TID); + + string htmlpage; + + if (!HAMQTHget(htmlpage)) return; + + parse_HAMQTH_html(htmlpage); + REQ(QRZ_disp_result); + +} + +// ---------------------------------------------------------------------------- + void QRZ_DETAILS_query() { string qrzurl = "http://www.qrz.com/callsign.html?callsign="; qrzurl.append(callsign); - + cb_mnuVisitURL(0, (void*)qrzurl.c_str()); } @@ -725,7 +870,7 @@ void HAMCALL_DETAILS_query() { string hamcallurl = "http://www.hamcall.net/call?callsign="; hamcallurl.append(callsign); - + cb_mnuVisitURL(0, (void*)hamcallurl.c_str()); } @@ -762,6 +907,9 @@ static void *LOOKUP_loop(void *args) case CALLOOK: CALLOOKquery(); break; + case HAMQTH: + HAMQTHquery(); + break; case QRZ_EXIT: return NULL; default: @@ -815,6 +963,9 @@ void CALLSIGNquery() case CALLOOK: inpNotes->value("Request sent to\nhttp://callook.info..."); break; + case HAMQTH: + inpNotes->value("Request sent to \nhttp://hamqth.com..."); + break; default: LOG_ERROR("Bad query type %d", DB_query); return; diff --git a/src/misc/network.cxx b/src/misc/network.cxx index 3c0db43e..4b094d23 100644 --- a/src/misc/network.cxx +++ b/src/misc/network.cxx @@ -21,6 +21,7 @@ // ---------------------------------------------------------------------------- #include +#include #include #include From ca79f8c10e20e51cf1c8bbdf6cd42b4d6a7d0d14 Mon Sep 17 00:00:00 2001 From: David Freese Date: Wed, 19 Oct 2011 12:43:32 -0500 Subject: [PATCH 32/54] Version 3.21.19 Maintenance release --- ChangeLog | 12 +++++++++++- configure.ac | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4d39c835..a61455e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ -2011-10-16 David Freese + +=Version 3.21.19= + +2011-10-19 David Freese + + 7046d49: HamQTH lookup + + +=Version 3.21.18= + + 1247488: REV macro tag 9c13f6f: RTTY bandwidth diff --git a/configure.ac b/configure.ac index 96f4db91..ddcec791 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [3]) m4_define(FLDIGI_MINOR, [21]) -m4_define(FLDIGI_PATCH, [.18]) +m4_define(FLDIGI_PATCH, [.19]) m4_define(FLARQ_MAJOR, [4]) m4_define(FLARQ_MINOR, [3]) m4_define(FLARQ_PATCH, [.1]) From c32fa639d0142505a7f7654de72d3f4076305f5d Mon Sep 17 00:00:00 2001 From: David Freese Date: Sun, 23 Oct 2011 07:54:17 -0500 Subject: [PATCH 33/54] DTMF debug * removed DTMF debug code from sound.cxx --- src/soundcard/sound.cxx | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/soundcard/sound.cxx b/src/soundcard/sound.cxx index 92ad4177..1e2f4146 100644 --- a/src/soundcard/sound.cxx +++ b/src/soundcard/sound.cxx @@ -264,21 +264,11 @@ sf_count_t SoundBase::read_file(SNDFILE* file, float* buf, size_t count) sf_count_t SoundBase::write_file(SNDFILE* file, float* buf, size_t count) { - FILE *dfile = fopen("dtmfdata.txt", "a"); - for (size_t i = 0; i < count; i++) - fprintf(dfile, "%f\n", buf[i]); - fclose(dfile); - WRITE_FILE(float, file, buf, count); } sf_count_t SoundBase::write_file(SNDFILE* file, double* buf, size_t count) { - FILE *dfile = fopen("dtmfdata.txt", "a"); - for (size_t i = 0; i < count; i++) - fprintf(dfile, "%f\n", (float)buf[i]); - fclose(dfile); - WRITE_FILE(double, file, buf, count); } From fba599cdd29f6146ef55a9765e9060b5189d45cf Mon Sep 17 00:00:00 2001 From: David Freese Date: Mon, 24 Oct 2011 13:06:05 -0500 Subject: [PATCH 34/54] RSID limit fault * Set upper and lower bounds to RSID limited search --- src/rsid/rsid.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rsid/rsid.cxx b/src/rsid/rsid.cxx index 3aed601a..1365ac10 100644 --- a/src/rsid/rsid.cxx +++ b/src/rsid/rsid.cxx @@ -435,7 +435,9 @@ void cRsId::search(void) else { double centerfreq = active_modem->get_freq(); nBinLow = (int)((centerfreq - 100.0 * RSID_RESOL) * 2048.0 / RSID_SAMPLE_RATE); + if (nBinLow < RSID_RESOL + 1) nBinLow = RSID_RESOL + 1; nBinHigh = (int)((centerfreq + 100.0 * RSID_RESOL) * 2048.0 / RSID_SAMPLE_RATE); + if (nBinHigh > RSID_FFT_SIZE -32) nBinHigh = RSID_FFT_SIZE; } bool bReverse = !(wf->Reverse() ^ wf->USB()); From 4572895c8a6a358057b0868cc442d26f9943dcbd Mon Sep 17 00:00:00 2001 From: David Freese Date: Mon, 24 Oct 2011 13:13:59 -0500 Subject: [PATCH 35/54] Version 3.21.20 Maintenance release --- ChangeLog | 10 ++++++++-- configure.ac | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index a61455e5..6a8cae7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,15 @@ +=Version 3.21.20= + +2011-10-24 David Freese + + fba599c: RSID limit fault + c32fa63: DTMF debug + + =Version 3.21.19= -2011-10-19 David Freese - 7046d49: HamQTH lookup diff --git a/configure.ac b/configure.ac index ddcec791..2d2013c0 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [3]) m4_define(FLDIGI_MINOR, [21]) -m4_define(FLDIGI_PATCH, [.19]) +m4_define(FLDIGI_PATCH, [.20]) m4_define(FLARQ_MAJOR, [4]) m4_define(FLARQ_MINOR, [3]) m4_define(FLARQ_PATCH, [.1]) From 3163fd295a233607c0c0e6ad4d21efb43072f901 Mon Sep 17 00:00:00 2001 From: David Freese Date: Tue, 25 Oct 2011 05:17:54 -0500 Subject: [PATCH 36/54] Resize fault * Fixed resize fault - required changing min height of hidden resizable control in main text panel. --- src/dialogs/fl_digi.cxx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 15a0a722..f3b6e1a9 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -4331,6 +4331,7 @@ void create_fl_digi_main_primary() { btnAltMacros2->tooltip(_("Shift-key macro set")); macroFrame2->resizable(btngroup2); macroFrame2->end(); + Y += Hmacros; int Htext = progStatus.mainH - Hwfall - Hmenu - Hstatus - Hmacros*NUMKEYROWS - Hqsoframe - 4; int Hrcvtxt = Htext / 2; @@ -4369,7 +4370,6 @@ void create_fl_digi_main_primary() { text_panel->x(), text_panel->y(), text_panel->w()/2, Htext, ""); -// mainViewer = new pskBrowser(mvgroup->x(), mvgroup->y(), mvgroup->w(), Htext-22, ""); mainViewer = new pskBrowser(mvgroup->x(), mvgroup->y(), mvgroup->w(), Htext-42, ""); mainViewer->box(FL_DOWN_BOX); mainViewer->has_scrollbar(Fl_Browser_::VERTICAL); @@ -4381,9 +4381,6 @@ void create_fl_digi_main_primary() { Fl_Group* gseek = new Fl_Group(mvgroup->x(), mvgroup->y() + Htext - 42, mvgroup->w(), 20); // search field -// const char* label = _("Find: "); -// fl_font(FL_HELVETICA, FL_NORMAL_SIZE); -// int label_w = static_cast(fl_width(label)); int seek_x = mvgroup->x() + 2; int seek_y = mvgroup->y() + Htext - 42; int seek_w = mvgroup->w() - 4; @@ -4471,8 +4468,8 @@ void create_fl_digi_main_primary() { TransmitText->align(FL_ALIGN_CLIP); Fl_Box *minbox = new Fl_Box( - text_panel->x(), text_panel->y() + 66, - text_panel->w() - 100, text_panel->h() - 66 - 80); + text_panel->x(), text_panel->y() + 66, // fixed by Raster min height + text_panel->w() - 100, text_panel->h() - 66 - 60); // fixed by HMIN & Hwfall max minbox->hide(); text_panel->resizable(minbox); From 3a37ced69551052e254a1f45ee00e50bdc85560f Mon Sep 17 00:00:00 2001 From: David Freese Date: Tue, 25 Oct 2011 14:33:05 -0500 Subject: [PATCH 37/54] Version 3.21.21 Maintenance release --- ChangeLog | 9 +++++++-- configure.ac | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6a8cae7b..497444dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,14 @@ +=Version 3.21.21= + +2011-10-25 David Freese + + 3163fd2: Resize fault + + =Version 3.21.20= -2011-10-24 David Freese - fba599c: RSID limit fault c32fa63: DTMF debug diff --git a/configure.ac b/configure.ac index 2d2013c0..dbea734d 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [3]) m4_define(FLDIGI_MINOR, [21]) -m4_define(FLDIGI_PATCH, [.20]) +m4_define(FLDIGI_PATCH, [.21]) m4_define(FLARQ_MAJOR, [4]) m4_define(FLARQ_MINOR, [3]) m4_define(FLARQ_PATCH, [.1]) From 1b3e852fa8e7ef93eb476b183c002e2c271a1bd6 Mon Sep 17 00:00:00 2001 From: David Freese Date: Tue, 25 Oct 2011 19:41:47 -0500 Subject: [PATCH 38/54] NBEMS-FLMSG Directories * Allow user specification of FLMSG directory as a command line argument --flmsg-dir "full-pathname-directory" * Defaults - Linux / OS-X $HOME/.nbems - XP C:\Documents and Settings\\NBEMS.files - Vista/Win7 C:\Users\\NBEMS.files --- src/dialogs/fl_digi.cxx | 14 ++++++++++ src/include/main.h | 9 +++++++ src/logger/rx_extract.cxx | 6 ++--- src/main.cxx | 54 +++++++++++++++++++++++++++++++++++++++ src/misc/arq_io.cxx | 2 +- 5 files changed, 81 insertions(+), 4 deletions(-) diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index f3b6e1a9..078ab5d9 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -1749,6 +1749,19 @@ void cb_ShowNBEMS(Fl_Widget*, void*) cb_mnuVisitURL(0, (void*)NBEMS_dir.c_str()); } +void cb_ShowFLMSG(Fl_Widget*, void*) +{ + DIR *flmsg_dir; + flmsg_dir = opendir(FLMSG_dir.c_str()); + if (!flmsg_dir) { + int ans = fl_choice2(_("Do not exist, create?"), _("No"), _("Yes"), 0); + if (!ans) return; + check_nbems_dirs(); + } + closedir(flmsg_dir); + cb_mnuVisitURL(0, (void*)FLMSG_dir.c_str()); +} + void cbTune(Fl_Widget *w, void *) { Fl_Button *b = (Fl_Button *)w; if (!(active_modem->get_cap() & modem::CAP_TX)) { @@ -2901,6 +2914,7 @@ Fl_Menu_Item menu_[] = { { make_icon_label(_("Folders")), 0, 0, 0, FL_SUBMENU, _FL_MULTI_LABEL, 0, 14, 0}, { make_icon_label(_("Fldigi config..."), folder_open_icon), 0, cb_ShowConfig, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, +{ make_icon_label(_("FLMSG files..."), folder_open_icon), 0, cb_ShowFLMSG, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, { make_icon_label(_("NBEMS files..."), folder_open_icon), 0, cb_ShowNBEMS, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, {0,0,0,0,0,0,0,0,0}, diff --git a/src/include/main.h b/src/include/main.h index dd5b7278..8446f5a5 100644 --- a/src/include/main.h +++ b/src/include/main.h @@ -38,6 +38,15 @@ extern std::string ICS_dir; extern std::string ICS_msg_dir; extern std::string ICS_tmp_dir; +extern std::string FLMSG_dir; +extern std::string FLMSG_WRAP_dir; +extern std::string FLMSG_WRAP_recv_dir; +extern std::string FLMSG_WRAP_send_dir; +extern std::string FLMSG_WRAP_auto_dir; +extern std::string FLMSG_ICS_dir; +extern std::string FLMSG_ICS_msg_dir; +extern std::string FLMSG_ICS_tmp_dir; + extern std::string xmlfname; extern std::string scDevice[2]; diff --git a/src/logger/rx_extract.cxx b/src/logger/rx_extract.cxx index 829b50a9..738b0560 100644 --- a/src/logger/rx_extract.cxx +++ b/src/logger/rx_extract.cxx @@ -104,7 +104,7 @@ void rx_extract_add(int c) gmtime_r(&t, &tim); strftime(dttm, sizeof(dttm), "%Y%m%d-%H%M%S", &tim); - string outfilename = WRAP_recv_dir; + string outfilename = FLMSG_WRAP_recv_dir; outfilename.append("extract-"); outfilename.append(dttm); outfilename.append(".wrap"); @@ -114,11 +114,11 @@ void rx_extract_add(int c) extractstream.close(); } rx_extract_msg = "File saved in "; - rx_extract_msg.append(WRAP_recv_dir); + rx_extract_msg.append(FLMSG_WRAP_recv_dir); put_status(rx_extract_msg.c_str(), 20, STATUS_CLEAR); if (progdefaults.open_nbems_folder) - open_recv_folder(WRAP_recv_dir.c_str()); + open_recv_folder(FLMSG_WRAP_recv_dir.c_str()); if ((progdefaults.open_flmsg || progdefaults.open_flmsg_print) && (rx_buff.find(flmsg) != string::npos) && diff --git a/src/main.cxx b/src/main.cxx index 643553a2..8df7525f 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -129,6 +129,7 @@ string WrapDir; string TalkDir; string TempDir; string PskMailDir; + string NBEMS_dir; string ARQ_dir; string ARQ_files_dir; @@ -142,6 +143,16 @@ string ICS_dir; string ICS_msg_dir; string ICS_tmp_dir; +string FLMSG_dir; +string FLMSG_dir_default; +string FLMSG_WRAP_dir; +string FLMSG_WRAP_recv_dir; +string FLMSG_WRAP_send_dir; +string FLMSG_WRAP_auto_dir; +string FLMSG_ICS_dir; +string FLMSG_ICS_msg_dir; +string FLMSG_ICS_tmp_dir; + string PskMailFile; string ArqFilename; string xmlfname; @@ -219,6 +230,7 @@ int main(int argc, char ** argv) NBEMS_dir = dirbuf; fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$USERPROFILE/"); PskMailDir = dirbuf; + FLMSG_dir_default = "$USERPROFILE/NBEMS.files/"; #else fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$HOME/.fldigi/"); HomeDir = dirbuf; @@ -226,6 +238,7 @@ int main(int argc, char ** argv) NBEMS_dir = dirbuf; fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$HOME/"); PskMailDir = dirbuf; + FLMSG_dir_default = "$HOME/.nbems/"; #endif } @@ -239,6 +252,13 @@ int main(int argc, char ** argv) if (main_window_title.empty()) main_window_title = PACKAGE_TARNAME; + { + char dirbuf[FL_PATH_MAX + 1]; + if (FLMSG_dir_default[FLMSG_dir_default.length()-1] != '/') + FLMSG_dir_default += '/'; + fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, FLMSG_dir_default.c_str()); + FLMSG_dir = dirbuf; + } checkdirectories(); check_nbems_dirs(); @@ -458,6 +478,9 @@ void generate_option_help(void) { << " --arq-server-port PORT\n" << " Set the ARQ TCP server port\n" << " The default is: " << progdefaults.arq_port << "\n\n" + << " --flmsg-dir DIRECTORY\n" + << " Look for flmsg files in DIRECTORY\n" + << " The default is " << FLMSG_dir_default << "\n\n" #if USE_XMLRPC << " --xmlrpc-server-address HOSTNAME\n" @@ -607,6 +630,7 @@ int parse_args(int argc, char **argv, int& idx) OPT_CONFIG_DIR, OPT_ARQ_ADDRESS, OPT_ARQ_PORT, OPT_SHOW_CPU_CHECK, + OPT_FLMSG_DIR, #if USE_XMLRPC OPT_CONFIG_XMLRPC_ADDRESS, OPT_CONFIG_XMLRPC_PORT, @@ -638,6 +662,7 @@ int parse_args(int argc, char **argv, int& idx) { "arq-server-address", 1, 0, OPT_ARQ_ADDRESS }, { "arq-server-port", 1, 0, OPT_ARQ_PORT }, + { "flmsg-dir", 1, 0, OPT_FLMSG_DIR }, { "cpu-speed-test", 0, 0, OPT_SHOW_CPU_CHECK }, @@ -726,6 +751,10 @@ int parse_args(int argc, char **argv, int& idx) progdefaults.arq_port = optarg; break; + case OPT_FLMSG_DIR: + FLMSG_dir_default = optarg; + break; + #if USE_XMLRPC case OPT_CONFIG_XMLRPC_ADDRESS: progdefaults.xmlrpc_address = optarg; @@ -1146,6 +1175,31 @@ void check_nbems_dirs(void) else if (r == 0 && NBEMS_dirs[i].new_dir_func) NBEMS_dirs[i].new_dir_func(); } + + DIRS FLMSG_dirs[] = { + { FLMSG_dir, 0, 0 }, + { FLMSG_WRAP_dir, "WRAP", 0 }, + { FLMSG_WRAP_recv_dir, "WRAP/recv", 0 }, + { FLMSG_WRAP_send_dir, "WRAP/send", 0 }, + { FLMSG_WRAP_auto_dir, "WRAP/auto", 0 }, + { FLMSG_ICS_dir, "ICS", 0 }, + { FLMSG_ICS_msg_dir, "ICS/messages", 0 }, + { FLMSG_ICS_tmp_dir, "ICS/templates", 0 }, + }; + + for (size_t i = 0; i < sizeof(FLMSG_dirs)/sizeof(*FLMSG_dirs); i++) { + if (FLMSG_dirs[i].suffix) + FLMSG_dirs[i].dir.assign(FLMSG_dir).append(FLMSG_dirs[i].suffix).append("/"); + + if ((r = mkdir(FLMSG_dirs[i].dir.c_str(), 0777)) == -1 && errno != EEXIST) { + cerr << _("Could not make directory") << ' ' << FLMSG_dirs[i].dir + << ": " << strerror(errno) << '\n'; + exit(EXIT_FAILURE); + } + else if (r == 0 && FLMSG_dirs[i].new_dir_func) + FLMSG_dirs[i].new_dir_func(); + } + nbems_dirs_checked = true; } diff --git a/src/misc/arq_io.cxx b/src/misc/arq_io.cxx index 9c08f534..a1a8a30e 100644 --- a/src/misc/arq_io.cxx +++ b/src/misc/arq_io.cxx @@ -380,7 +380,7 @@ bool WRAP_auto_arqRx() { time_t start_time, prog_time; static char mailline[1000]; - string sAutoFile = WRAP_auto_dir; + string sAutoFile = FLMSG_WRAP_auto_dir; sAutoFile += "wrap_auto_file"; ifstream autofile(sAutoFile.c_str()); From 269ae3a824e0fca7aaeac0b7b5c7c3b75f110f60 Mon Sep 17 00:00:00 2001 From: David Freese Date: Fri, 28 Oct 2011 17:24:38 -0500 Subject: [PATCH 39/54] RSID defaults * Changed RSID new installation defaults per request from NBEMS trainers. --- src/include/configuration.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/include/configuration.h b/src/include/configuration.h index 944b69f5..f57b0a4e 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -70,7 +70,7 @@ +20.0) \ ELEM_(bool, rsidWideSearch, "RSIDWIDESEARCH", \ "RSID detector searches the entire passband", \ - true) \ + false) \ ELEM_(int, rsid_squelch, "RSIDSQUELCH", \ "RSID detection opens squelch for nn seconds", \ 5) \ @@ -88,8 +88,8 @@ "Trigger RSID notifications but do not change modem and frequency", \ false) \ ELEM_(bool, rsid_auto_disable, "RSIDAUTODISABLE", \ - "Disable RSID detection when changing modem and/or frequency", \ - true) \ + "Disable RSID detection when RsID signal is detected", \ + false) \ ELEM_(bool, rsid_post, "RSIDPOST", \ "Transmit an RSID signal when modem data is concluded", \ false) \ From b66a4d748950369b799763a0007990c849d359b9 Mon Sep 17 00:00:00 2001 From: Pavel Milanes Costa Date: Fri, 28 Oct 2011 17:26:31 -0500 Subject: [PATCH 40/54] es.po update * update to Spanish translation files --- po/es.po | 2359 +++++++++++++++++++++++++++++------------------------- 1 file changed, 1279 insertions(+), 1080 deletions(-) diff --git a/po/es.po b/po/es.po index 48bbcf2d..32691ae6 100644 --- a/po/es.po +++ b/po/es.po @@ -6,25 +6,25 @@ # msgid "" msgstr "" -"Project-Id-Version: fldigi 3.21.9\n" +"Project-Id-Version: fldigi 3.22.0 ALPHA series\n" "Report-Msgid-Bugs-To: w1hkj AT w1hkj DOT com\n" -"POT-Creation-Date: 2011-06-27 07:53-0500\n" -"PO-Revision-Date: 2011-06-27 11:07-0500\n" +"POT-Creation-Date: 2011-10-26 14:12-0500\n" +"PO-Revision-Date: 2011-10-28 16:46-0500\n" "Last-Translator: Pavel Milanes Costa \n" -"Language-Team: Spanish (Pavel Milanes Costa) \n" -"Language: \n" +"Language-Team: Spanish (Pavel Milanes Costa) \n" +"Language: Spanish\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Spanish\n" "X-Poedit-Country: CUBA\n" -#: src/main.cxx:248 +#: src/main.cxx:268 #, c-format msgid "%s log started on %s" msgstr "%s log iniciado a %s" -#: src/main.cxx:889 +#: src/main.cxx:918 msgid "" "License GPLv3+: GNU GPL version 3 or later \n" "This is free software: you are free to change and redistribute it.\n" @@ -34,155 +34,155 @@ msgstr "" "Esto es un Software Libre: tu eres libre de cambiarlo y redistribuirlo.\n" "No hay GARANTIA, execpto la permitida por la ley.\n" -#: src/main.cxx:1100 -#: src/main.cxx:1142 +#: src/main.cxx:1129 +#: src/main.cxx:1171 +#: src/main.cxx:1195 msgid "Could not make directory" msgstr "No pude crear el directorio" -#: src/dialogs/fl_digi.cxx:147 +#: src/dialogs/fl_digi.cxx:148 msgid "Log all RX/TX text" msgstr "Guardar todo el texto de TX/RX" -#: src/dialogs/fl_digi.cxx:148 +#: src/dialogs/fl_digi.cxx:149 #: src/misc/debug.cxx:81 msgid "Rig control" msgstr "Control del radio" -#: src/dialogs/fl_digi.cxx:149 -#: src/dialogs/fl_digi.cxx:4697 +#: src/dialogs/fl_digi.cxx:150 +#: src/dialogs/fl_digi.cxx:4749 msgid "Op &Mode" msgstr "&Modo de Operación" -#: src/dialogs/fl_digi.cxx:150 +#: src/dialogs/fl_digi.cxx:151 msgid "Show fewer modes" msgstr "Mostrar menos modos" -#: src/dialogs/fl_digi.cxx:151 +#: src/dialogs/fl_digi.cxx:152 msgid "Show all modes" msgstr "Mostrar todos los modos" -#: src/dialogs/fl_digi.cxx:155 +#: src/dialogs/fl_digi.cxx:156 msgid "&View" msgstr "&Visita" -#: src/dialogs/fl_digi.cxx:156 +#: src/dialogs/fl_digi.cxx:157 msgid "&MFSK Image" msgstr "Imagen &MFSK" -#: src/dialogs/fl_digi.cxx:157 +#: src/dialogs/fl_digi.cxx:158 msgid "&Weather Fax Image" msgstr "&Imagen de Fax meteorológico" -#: src/dialogs/fl_digi.cxx:158 -#: src/dialogs/confdialog.cxx:3377 +#: src/dialogs/fl_digi.cxx:159 +#: src/dialogs/confdialog.cxx:3435 msgid "Contest" msgstr "Concurso" -#: src/dialogs/fl_digi.cxx:159 +#: src/dialogs/fl_digi.cxx:160 msgid "&Contest fields" msgstr "&Campos de concurso" -#: src/dialogs/fl_digi.cxx:160 +#: src/dialogs/fl_digi.cxx:161 msgid "C&ountries" msgstr "Paises" -#: src/dialogs/fl_digi.cxx:161 +#: src/dialogs/fl_digi.cxx:162 msgid "&UI" msgstr "I&U" -#: src/dialogs/fl_digi.cxx:162 +#: src/dialogs/fl_digi.cxx:163 msgid "Full" msgstr "Completo" -#: src/dialogs/fl_digi.cxx:163 -#: src/waterfall/waterfall.cxx:2025 -#: src/dialogs/confdialog.cxx:3249 +#: src/dialogs/fl_digi.cxx:164 +#: src/waterfall/waterfall.cxx:2080 +#: src/dialogs/confdialog.cxx:3307 msgid "None" msgstr "Ninguno" -#: src/dialogs/fl_digi.cxx:164 +#: src/dialogs/fl_digi.cxx:165 msgid "Rig control and logging" msgstr "Controles del radio y log" -#: src/dialogs/fl_digi.cxx:165 +#: src/dialogs/fl_digi.cxx:166 msgid "Rig control and contest" msgstr "Controles del radio y concursos" -#: src/dialogs/fl_digi.cxx:166 +#: src/dialogs/fl_digi.cxx:167 msgid "Docked scope" msgstr "Osciloscopio empotrado" -#: src/dialogs/fl_digi.cxx:167 +#: src/dialogs/fl_digi.cxx:168 msgid "Minimal controls" msgstr "Controles mínimos" -#: src/dialogs/fl_digi.cxx:168 +#: src/dialogs/fl_digi.cxx:169 msgid "Show channels" msgstr "Mostrar canales" -#: src/dialogs/fl_digi.cxx:170 +#: src/dialogs/fl_digi.cxx:171 msgid "Connect to server" msgstr "Conectar con el Servidor" -#: src/dialogs/fl_digi.cxx:537 -#: src/dialogs/fl_digi.cxx:551 -#: src/dialogs/fl_digi.cxx:560 -#: src/dialogs/fl_digi.cxx:2907 +#: src/dialogs/fl_digi.cxx:538 +#: src/dialogs/fl_digi.cxx:552 +#: src/dialogs/fl_digi.cxx:561 #: src/dialogs/fl_digi.cxx:2954 -#: src/dialogs/fl_digi.cxx:2985 -#: src/dialogs/fl_digi.cxx:4711 -#: src/dialogs/fl_digi.cxx:4748 -#: src/dialogs/fl_digi.cxx:4779 +#: src/dialogs/fl_digi.cxx:3001 +#: src/dialogs/fl_digi.cxx:3032 +#: src/dialogs/fl_digi.cxx:4763 +#: src/dialogs/fl_digi.cxx:4800 +#: src/dialogs/fl_digi.cxx:4831 msgid "Custom..." msgstr "Personalizar..." -#: src/dialogs/fl_digi.cxx:899 +#: src/dialogs/fl_digi.cxx:900 msgid "Save changed macros?" msgstr "Salvar macros modificadas?" -#: src/dialogs/fl_digi.cxx:899 -#: src/dialogs/fl_digi.cxx:2105 -#: src/dialogs/fl_digi.cxx:2157 -#: src/dialogs/fl_digi.cxx:2330 -#: src/dialogs/fl_digi.cxx:2342 -#: src/dialogs/fl_digi.cxx:2354 -#: src/dialogs/fl_digi.cxx:3393 +#: src/dialogs/fl_digi.cxx:900 +#: src/dialogs/fl_digi.cxx:2124 +#: src/dialogs/fl_digi.cxx:2176 +#: src/dialogs/fl_digi.cxx:2376 +#: src/dialogs/fl_digi.cxx:2388 +#: src/dialogs/fl_digi.cxx:2400 +#: src/dialogs/fl_digi.cxx:3442 #: src/dialogs/font_browser.cxx:140 #: src/fileselector/FL/Fl_Native_File_Chooser_FLTK.H:60 -#: src/logbook/logsupport.cxx:282 -#: src/misc/configuration.cxx:713 -#: src/misc/macroedit.cxx:335 +#: src/logbook/logsupport.cxx:285 +#: src/misc/configuration.cxx:716 #: src/soundcard/soundconf.cxx:527 #: src/logbook/lgbook.cxx:389 #: src/logbook/lgbook.cxx:988 msgid "Cancel" msgstr "Cancelar" -#: src/dialogs/fl_digi.cxx:899 -#: src/dialogs/fl_digi.cxx:2330 -#: src/dialogs/fl_digi.cxx:2342 -#: src/dialogs/fl_digi.cxx:2354 -#: src/dialogs/fl_digi.cxx:3075 -#: src/dialogs/fl_digi.cxx:3866 -#: src/dialogs/fl_digi.cxx:4064 -#: src/dialogs/fl_digi.cxx:4169 -#: src/logbook/logsupport.cxx:281 -#: src/dialogs/confdialog.cxx:6513 +#: src/dialogs/fl_digi.cxx:900 +#: src/dialogs/fl_digi.cxx:2376 +#: src/dialogs/fl_digi.cxx:2388 +#: src/dialogs/fl_digi.cxx:2400 +#: src/dialogs/fl_digi.cxx:3134 +#: src/dialogs/fl_digi.cxx:3921 +#: src/dialogs/fl_digi.cxx:4119 +#: src/dialogs/fl_digi.cxx:4224 +#: src/logbook/logsupport.cxx:284 +#: src/dialogs/confdialog.cxx:6623 msgid "Save" msgstr "Salvar" -#: src/dialogs/fl_digi.cxx:899 -#: src/dialogs/fl_digi.cxx:2330 -#: src/dialogs/fl_digi.cxx:2342 -#: src/dialogs/fl_digi.cxx:2354 +#: src/dialogs/fl_digi.cxx:900 +#: src/dialogs/fl_digi.cxx:2376 +#: src/dialogs/fl_digi.cxx:2388 +#: src/dialogs/fl_digi.cxx:2400 msgid "Don't save" msgstr "No salvar" -#: src/dialogs/fl_digi.cxx:1467 +#: src/dialogs/fl_digi.cxx:1473 msgid "Spotting disabled" msgstr "Spotting deshabilitado" -#: src/dialogs/fl_digi.cxx:1513 +#: src/dialogs/fl_digi.cxx:1519 #, c-format msgid "" "Could not run a web browser:\n" @@ -197,7 +197,7 @@ msgstr "" "Abre esta URL manualmente:\n" "%s" -#: src/dialogs/fl_digi.cxx:1526 +#: src/dialogs/fl_digi.cxx:1532 #, c-format msgid "" "Could not open url:\n" @@ -206,11 +206,11 @@ msgstr "" "No pude abrir la URL:\n" "%s\n" -#: src/dialogs/fl_digi.cxx:1577 +#: src/dialogs/fl_digi.cxx:1583 msgid "Checking for updates..." msgstr "Chequeando si hay actualizaciones..." -#: src/dialogs/fl_digi.cxx:1592 +#: src/dialogs/fl_digi.cxx:1598 #, c-format msgid "" "Could not check for updates:\n" @@ -219,7 +219,7 @@ msgstr "" "No se puede chequear si hay actualizaciones:\n" "%s" -#: src/dialogs/fl_digi.cxx:1596 +#: src/dialogs/fl_digi.cxx:1602 #, c-format msgid "" "Version %s is available at\n" @@ -234,430 +234,439 @@ msgstr "" "\n" "Que desea hacer?" -#: src/dialogs/fl_digi.cxx:1597 +#: src/dialogs/fl_digi.cxx:1603 #: src/dialogs/Viewer.cxx:266 #: src/misc/debug.cxx:278 +#: src/misc/macroedit.cxx:360 #: src/mfsk/mfsk-pic.cxx:376 #: src/spot/notify.cxx:512 #: src/spot/notify.cxx:516 #: src/dialogs/colorsfonts.cxx:776 -#: src/dialogs/confdialog.cxx:6516 +#: src/dialogs/confdialog.cxx:6626 msgid "Close" msgstr "Cerrar" -#: src/dialogs/fl_digi.cxx:1597 +#: src/dialogs/fl_digi.cxx:1603 msgid "Visit URL" msgstr "Visitar la URL" -#: src/dialogs/fl_digi.cxx:1597 +#: src/dialogs/fl_digi.cxx:1603 msgid "Copy URL" msgstr "Copiar la URL" -#: src/dialogs/fl_digi.cxx:1609 +#: src/dialogs/fl_digi.cxx:1615 msgid "You are running the latest version" msgstr "Estas utilizando la última version" -#: src/dialogs/fl_digi.cxx:1675 +#: src/dialogs/fl_digi.cxx:1681 msgid "Sunspot creation underway!" msgstr "Creación de un sunspot en proceso!" -#: src/dialogs/fl_digi.cxx:1682 +#: src/dialogs/fl_digi.cxx:1688 msgid "Audio device information is only available for the PortAudio backend" msgstr "La información del dispositivo de audio está solo dispodible cuando se usa PortAudio como método de comunicación con el dispositivo" -#: src/dialogs/fl_digi.cxx:1691 +#: src/dialogs/fl_digi.cxx:1697 msgid "Capture device" msgstr "Dispositivo de captura" -#: src/dialogs/fl_digi.cxx:1692 +#: src/dialogs/fl_digi.cxx:1698 msgid "Playback device" msgstr "Dispositivo de reproducción" -#: src/dialogs/fl_digi.cxx:1696 +#: src/dialogs/fl_digi.cxx:1702 msgid "Capture and playback devices" msgstr "Dispositivo de captura y reproducción" -#: src/dialogs/fl_digi.cxx:1738 +#: src/dialogs/fl_digi.cxx:1744 +#: src/dialogs/fl_digi.cxx:1757 msgid "Do not exist, create?" msgstr "No existe, lo creo?" -#: src/dialogs/fl_digi.cxx:1738 +#: src/dialogs/fl_digi.cxx:1744 +#: src/dialogs/fl_digi.cxx:1757 #: src/logbook/logsupport.cxx:148 -#: src/logbook/logsupport.cxx:692 -#: src/misc/configuration.cxx:715 +#: src/logbook/logsupport.cxx:168 +#: src/logbook/logsupport.cxx:695 +#: src/misc/configuration.cxx:718 msgid "No" msgstr "No" -#: src/dialogs/fl_digi.cxx:1738 +#: src/dialogs/fl_digi.cxx:1744 +#: src/dialogs/fl_digi.cxx:1757 #: src/logbook/logsupport.cxx:148 -#: src/logbook/logsupport.cxx:692 -#: src/misc/configuration.cxx:715 +#: src/logbook/logsupport.cxx:168 +#: src/logbook/logsupport.cxx:695 +#: src/misc/configuration.cxx:718 msgid "Yes" msgstr "Si" -#: src/dialogs/fl_digi.cxx:2105 +#: src/dialogs/fl_digi.cxx:2124 msgid "Clear log fields?" msgstr "Salvar campos del log?" -#: src/dialogs/fl_digi.cxx:2105 +#: src/dialogs/fl_digi.cxx:2124 #: src/fileselector/FL/Fl_Native_File_Chooser_FLTK.H:60 -#: src/misc/configuration.cxx:713 -#: src/misc/macroedit.cxx:332 +#: src/misc/configuration.cxx:716 #: src/soundcard/soundconf.cxx:527 #: src/logbook/lgbook.cxx:386 #: src/logbook/lgbook.cxx:985 msgid "OK" msgstr "OK" -#: src/dialogs/fl_digi.cxx:2118 +#: src/dialogs/fl_digi.cxx:2137 msgid "Enter a CALL !" msgstr "Entre un Indicativo!" -#: src/dialogs/fl_digi.cxx:2157 -#: src/dialogs/fl_digi.cxx:3393 +#: src/dialogs/fl_digi.cxx:2176 +#: src/dialogs/fl_digi.cxx:3442 msgid "Confirm" msgstr "Confirmar" -#: src/dialogs/fl_digi.cxx:2329 +#: src/dialogs/fl_digi.cxx:2375 msgid "Save changed configuration before exiting?" msgstr "Salvar los cambios en la configuración antes de salir?" -#: src/dialogs/fl_digi.cxx:2341 +#: src/dialogs/fl_digi.cxx:2387 msgid "Save log before exiting?" msgstr "Salvar libro de contactos antes de salir?" -#: src/dialogs/fl_digi.cxx:2353 +#: src/dialogs/fl_digi.cxx:2399 msgid "Save changed macros before exiting?" msgstr "Salvar macros modificadas antes de salir?" -#: src/dialogs/fl_digi.cxx:2867 -#: src/dialogs/fl_digi.cxx:4693 +#: src/dialogs/fl_digi.cxx:2913 +#: src/dialogs/fl_digi.cxx:4745 msgid "&File" msgstr "Archivos" -#: src/dialogs/fl_digi.cxx:2869 +#: src/dialogs/fl_digi.cxx:2915 msgid "Folders" msgstr "Carpetas" -#: src/dialogs/fl_digi.cxx:2870 +#: src/dialogs/fl_digi.cxx:2916 msgid "Fldigi config..." msgstr "Configuración de Fldigi..." -#: src/dialogs/fl_digi.cxx:2871 +#: src/dialogs/fl_digi.cxx:2917 +msgid "FLMSG files..." +msgstr "Ficheros FLMSG..." + +#: src/dialogs/fl_digi.cxx:2918 msgid "NBEMS files..." msgstr "Ficheros NBEMS..." -#: src/dialogs/fl_digi.cxx:2874 -#: src/dialogs/confdialog.cxx:3302 +#: src/dialogs/fl_digi.cxx:2921 +#: src/dialogs/confdialog.cxx:3360 msgid "Macros" msgstr "Macros" -#: src/dialogs/fl_digi.cxx:2875 +#: src/dialogs/fl_digi.cxx:2922 msgid "Open ..." msgstr "Abrir..." -#: src/dialogs/fl_digi.cxx:2876 +#: src/dialogs/fl_digi.cxx:2923 msgid "Save ..." msgstr "Salvar..." -#: src/dialogs/fl_digi.cxx:2879 -#: src/dialogs/confdialog.cxx:3169 +#: src/dialogs/fl_digi.cxx:2926 +#: src/dialogs/confdialog.cxx:3227 msgid "Text Capture" msgstr "Captura de Texto" -#: src/dialogs/fl_digi.cxx:2884 +#: src/dialogs/fl_digi.cxx:2931 #: src/misc/debug.cxx:79 -#: src/dialogs/confdialog.cxx:5607 +#: src/dialogs/confdialog.cxx:5701 msgid "Audio" msgstr "Audio" -#: src/dialogs/fl_digi.cxx:2885 +#: src/dialogs/fl_digi.cxx:2932 msgid "RX capture" msgstr "Capturar RX" -#: src/dialogs/fl_digi.cxx:2886 +#: src/dialogs/fl_digi.cxx:2933 msgid "TX generate" msgstr "Generar TX" -#: src/dialogs/fl_digi.cxx:2887 -#: src/dialogs/confdialog.cxx:5700 +#: src/dialogs/fl_digi.cxx:2934 +#: src/dialogs/confdialog.cxx:5794 msgid "Playback" msgstr "Reproducir" -#: src/dialogs/fl_digi.cxx:2891 -#: src/dialogs/fl_digi.cxx:4694 +#: src/dialogs/fl_digi.cxx:2938 +#: src/dialogs/fl_digi.cxx:4746 msgid "Exit" msgstr "Salir" -#: src/dialogs/fl_digi.cxx:3028 -#: src/dialogs/fl_digi.cxx:4821 +#: src/dialogs/fl_digi.cxx:3076 +#: src/dialogs/fl_digi.cxx:4874 msgid "&Configure" msgstr "&Configuración" -#: src/dialogs/fl_digi.cxx:3029 -#: src/dialogs/confdialog.cxx:2955 +#: src/dialogs/fl_digi.cxx:3077 +#: src/dialogs/confdialog.cxx:3013 msgid "Operator" msgstr "Operador" -#: src/dialogs/fl_digi.cxx:3030 +#: src/dialogs/fl_digi.cxx:3078 msgid "Colors && Fonts" msgstr "Colores y tipografía" -#: src/dialogs/fl_digi.cxx:3031 +#: src/dialogs/fl_digi.cxx:3079 msgid "User Interface" msgstr "Interfaz de Usuario" -#: src/dialogs/fl_digi.cxx:3032 -#: src/dialogs/fl_digi.cxx:3063 -#: src/dialogs/fl_digi.cxx:4822 -#: src/dialogs/confdialog.cxx:3649 +#: src/dialogs/fl_digi.cxx:3080 +#: src/dialogs/fl_digi.cxx:3111 +#: src/dialogs/fl_digi.cxx:4875 +#: src/dialogs/confdialog.cxx:3707 msgid "Waterfall" msgstr "Cascada" -#: src/dialogs/fl_digi.cxx:3033 +#: src/dialogs/fl_digi.cxx:3081 msgid "Waterfall controls" msgstr "Controles de la cascada" -#: src/dialogs/fl_digi.cxx:3034 -#: src/dialogs/fl_digi.cxx:4825 -#: src/dialogs/confdialog.cxx:3964 +#: src/dialogs/fl_digi.cxx:3082 +#: src/dialogs/fl_digi.cxx:4878 +#: src/dialogs/confdialog.cxx:4040 msgid "Modems" msgstr "Modems" -#: src/dialogs/fl_digi.cxx:3036 -#: src/dialogs/fl_digi.cxx:4824 +#: src/dialogs/fl_digi.cxx:3084 +#: src/dialogs/fl_digi.cxx:4877 msgid "Sound Card" msgstr "Dispositivo de sonido" -#: src/dialogs/fl_digi.cxx:3037 -#: src/dialogs/fl_digi.cxx:4826 +#: src/dialogs/fl_digi.cxx:3085 +#: src/dialogs/fl_digi.cxx:4879 msgid "IDs" msgstr "IDs" -#: src/dialogs/fl_digi.cxx:3038 -#: src/dialogs/confdialog.cxx:6032 +#: src/dialogs/fl_digi.cxx:3086 +#: src/dialogs/confdialog.cxx:6126 msgid "Misc" msgstr "Misc." -#: src/dialogs/fl_digi.cxx:3039 -#: src/dialogs/fl_digi.cxx:4827 +#: src/dialogs/fl_digi.cxx:3087 +#: src/dialogs/fl_digi.cxx:4880 #: src/dialogs/notifydialog.cxx:104 msgid "Notifications" msgstr "Notificaciones" -#: src/dialogs/fl_digi.cxx:3041 -#: src/dialogs/fl_digi.cxx:3852 -#: src/dialogs/fl_digi.cxx:4050 -#: src/dialogs/confdialog.cxx:6404 +#: src/dialogs/fl_digi.cxx:3089 +#: src/dialogs/fl_digi.cxx:3907 +#: src/dialogs/fl_digi.cxx:4105 +#: src/dialogs/confdialog.cxx:6508 msgid "QRZ" msgstr "QRZ" -#: src/dialogs/fl_digi.cxx:3042 -#: src/dialogs/fl_digi.cxx:4828 +#: src/dialogs/fl_digi.cxx:3090 +#: src/dialogs/fl_digi.cxx:4881 msgid "Save Config" msgstr "Salvar configuración" -#: src/dialogs/fl_digi.cxx:3047 +#: src/dialogs/fl_digi.cxx:3095 msgid "View/Hide Channels" msgstr "Ver/Ocultar Canales" -#: src/dialogs/fl_digi.cxx:3049 +#: src/dialogs/fl_digi.cxx:3097 msgid "Floating scope" msgstr "Osciloscopio flotante" -#: src/dialogs/fl_digi.cxx:3052 +#: src/dialogs/fl_digi.cxx:3100 msgid "Signal browser" msgstr "Navegador de señal" -#: src/dialogs/fl_digi.cxx:3055 +#: src/dialogs/fl_digi.cxx:3103 msgid "Controls" msgstr "Controles" -#: src/dialogs/fl_digi.cxx:3070 +#: src/dialogs/fl_digi.cxx:3118 msgid "&Logbook" msgstr "&Libro de guardia" -#: src/dialogs/fl_digi.cxx:3072 +#: src/dialogs/fl_digi.cxx:3119 msgid "View" msgstr "&Visita" -#: src/dialogs/fl_digi.cxx:3073 -#: src/logbook/logsupport.cxx:290 +#: src/dialogs/fl_digi.cxx:3122 +msgid "Merge..." +msgstr "Mezclar ADIF..." + +#: src/dialogs/fl_digi.cxx:3123 +msgid "Export..." +msgstr "Exportar..." + +#: src/dialogs/fl_digi.cxx:3127 +msgid "Text..." +msgstr "Texto..." + +#: src/dialogs/fl_digi.cxx:3128 +msgid "CSV..." +msgstr "CSV..." + +#: src/dialogs/fl_digi.cxx:3129 +msgid "Cabrillo..." +msgstr "Cabrillo..." + +#: src/dialogs/fl_digi.cxx:3132 +#: src/logbook/logsupport.cxx:293 #: src/logbook/lgbook.cxx:820 msgid "New" msgstr "Nuevo" -#: src/dialogs/fl_digi.cxx:3074 -#: src/dialogs/confdialog.cxx:5196 +#: src/dialogs/fl_digi.cxx:3133 +#: src/dialogs/confdialog.cxx:5290 msgid "Open..." msgstr "Abrir..." -#: src/dialogs/fl_digi.cxx:3078 -msgid "Merge..." -msgstr "Mezclar ADIF..." - -#: src/dialogs/fl_digi.cxx:3079 -msgid "Export..." -msgstr "Exportar..." - -#: src/dialogs/fl_digi.cxx:3083 -msgid "Text..." -msgstr "Texto..." - -#: src/dialogs/fl_digi.cxx:3084 -msgid "CSV..." -msgstr "CSV..." - -#: src/dialogs/fl_digi.cxx:3085 -msgid "Cabrillo..." -msgstr "Cabrillo..." - -#: src/dialogs/fl_digi.cxx:3091 +#: src/dialogs/fl_digi.cxx:3140 msgid "&Help" msgstr "A&yuda" -#: src/dialogs/fl_digi.cxx:3094 +#: src/dialogs/fl_digi.cxx:3143 msgid "Create sunspots" msgstr "Crear un sunspot" -#: src/dialogs/fl_digi.cxx:3096 +#: src/dialogs/fl_digi.cxx:3145 msgid "Beginners' Guide" msgstr "Guía del principiante" -#: src/dialogs/fl_digi.cxx:3097 +#: src/dialogs/fl_digi.cxx:3146 msgid "Online documentation..." msgstr "Documentación en internet..." -#: src/dialogs/fl_digi.cxx:3098 +#: src/dialogs/fl_digi.cxx:3147 msgid "Fldigi web site..." msgstr "Sitio web de Fldigi..." -#: src/dialogs/fl_digi.cxx:3099 +#: src/dialogs/fl_digi.cxx:3148 msgid "Reception reports..." msgstr "Reportes de recepción..." -#: src/dialogs/fl_digi.cxx:3100 +#: src/dialogs/fl_digi.cxx:3149 msgid "Command line options" msgstr "Opciones de linea de comandos" -#: src/dialogs/fl_digi.cxx:3101 +#: src/dialogs/fl_digi.cxx:3150 msgid "Audio device info" msgstr "Información de los dispositivos de audio" -#: src/dialogs/fl_digi.cxx:3102 +#: src/dialogs/fl_digi.cxx:3151 msgid "Build info" msgstr "Información de compilación" -#: src/dialogs/fl_digi.cxx:3103 +#: src/dialogs/fl_digi.cxx:3152 #: src/misc/debug.cxx:115 msgid "Event log" msgstr "Log de eventos" -#: src/dialogs/fl_digi.cxx:3104 +#: src/dialogs/fl_digi.cxx:3153 msgid "Check for updates..." msgstr "Comprobar si existen actualizaciones" -#: src/dialogs/fl_digi.cxx:3105 +#: src/dialogs/fl_digi.cxx:3154 msgid "&About" msgstr "&Acerca de" -#: src/dialogs/fl_digi.cxx:3335 +#: src/dialogs/fl_digi.cxx:3384 msgid "waterfall-only mode" msgstr "Modo de solo cascada" -#: src/dialogs/fl_digi.cxx:3337 +#: src/dialogs/fl_digi.cxx:3386 msgid "NO CALLSIGN SET" msgstr "NO SE HA DEFINIDO UN INDICATIVO" -#: src/dialogs/fl_digi.cxx:3352 +#: src/dialogs/fl_digi.cxx:3401 msgid "Close List" msgstr "Cerrar lista" -#: src/dialogs/fl_digi.cxx:3362 -#: src/dialogs/fl_digi.cxx:3717 -#: src/dialogs/fl_digi.cxx:4043 -#: src/dialogs/fl_digi.cxx:4155 +#: src/dialogs/fl_digi.cxx:3411 +#: src/dialogs/fl_digi.cxx:3772 +#: src/dialogs/fl_digi.cxx:4098 +#: src/dialogs/fl_digi.cxx:4210 msgid "Open List" msgstr "Lista abierta" -#: src/dialogs/fl_digi.cxx:3393 +#: src/dialogs/fl_digi.cxx:3442 msgid "Clear list?" msgstr "Limpiar la lista?" -#: src/dialogs/fl_digi.cxx:3426 +#: src/dialogs/fl_digi.cxx:3475 msgid "report" msgstr "reporte" -#: src/dialogs/fl_digi.cxx:3426 +#: src/dialogs/fl_digi.cxx:3475 msgid "reports" msgstr "reportes" -#: src/dialogs/fl_digi.cxx:3436 +#: src/dialogs/fl_digi.cxx:3485 msgid "Recent activity for grid" msgstr "Actividad reciente para el localizador" -#: src/dialogs/fl_digi.cxx:3711 +#: src/dialogs/fl_digi.cxx:3766 msgid "No rig specified" msgstr "No se ha especificado un radio" -#: src/dialogs/fl_digi.cxx:3791 +#: src/dialogs/fl_digi.cxx:3846 #: src/spot/notify.cxx:208 msgid "Select" msgstr "Selecciona" -#: src/dialogs/fl_digi.cxx:3798 +#: src/dialogs/fl_digi.cxx:3853 msgid "Add current frequency" msgstr "Añadir la frecuencia actual" -#: src/dialogs/fl_digi.cxx:3805 +#: src/dialogs/fl_digi.cxx:3860 msgid "Clear list" msgstr "Limpiar lista" -#: src/dialogs/fl_digi.cxx:3812 +#: src/dialogs/fl_digi.cxx:3867 msgid "Delete from list" msgstr "Eliminar de la lista" -#: src/dialogs/fl_digi.cxx:3832 +#: src/dialogs/fl_digi.cxx:3887 msgid "Select operating parameters" msgstr "Seleccionar los parámetros de configuración" -#: src/dialogs/fl_digi.cxx:3859 -#: src/dialogs/fl_digi.cxx:4057 -#: src/dialogs/fl_digi.cxx:4162 -#: src/dialogs/fl_digi.cxx:4380 +#: src/dialogs/fl_digi.cxx:3914 +#: src/dialogs/fl_digi.cxx:4112 +#: src/dialogs/fl_digi.cxx:4217 +#: src/dialogs/fl_digi.cxx:4432 #: src/dialogs/Viewer.cxx:274 #: src/widgets/FTextView.cxx:476 #: src/widgets/FTextView.cxx:642 #: src/widgets/flinput2.cxx:47 -#: src/dialogs/confdialog.cxx:4811 +#: src/dialogs/confdialog.cxx:4888 msgid "Clear" msgstr "Limpiar" -#: src/dialogs/fl_digi.cxx:3878 +#: src/dialogs/fl_digi.cxx:3933 msgid "QSO Freq" msgstr "Frec QSO" -#: src/dialogs/fl_digi.cxx:3888 -#: src/dialogs/fl_digi.cxx:4066 -#: src/dialogs/fl_digi.cxx:4172 +#: src/dialogs/fl_digi.cxx:3943 +#: src/dialogs/fl_digi.cxx:4121 +#: src/dialogs/fl_digi.cxx:4227 msgid "On" msgstr "Inic." -#: src/dialogs/fl_digi.cxx:3890 -#: src/dialogs/fl_digi.cxx:4070 -#: src/dialogs/fl_digi.cxx:4229 +#: src/dialogs/fl_digi.cxx:3945 +#: src/dialogs/fl_digi.cxx:4125 +#: src/dialogs/fl_digi.cxx:4284 msgid "Press to update" msgstr "Presione para actualizar" -#: src/dialogs/fl_digi.cxx:3894 -#: src/dialogs/fl_digi.cxx:4079 -#: src/dialogs/fl_digi.cxx:4173 +#: src/dialogs/fl_digi.cxx:3949 +#: src/dialogs/fl_digi.cxx:4134 +#: src/dialogs/fl_digi.cxx:4228 msgid "Off" msgstr "Fin" -#: src/dialogs/fl_digi.cxx:3899 -#: src/dialogs/fl_digi.cxx:4088 -#: src/dialogs/fl_digi.cxx:4174 +#: src/dialogs/fl_digi.cxx:3954 +#: src/dialogs/fl_digi.cxx:4143 +#: src/dialogs/fl_digi.cxx:4229 #: src/widgets/FTextRXTX.cxx:106 #: src/logbook/lgbook.cxx:401 #: src/logbook/lgbook.cxx:565 @@ -665,7 +674,7 @@ msgstr "Fin" msgid "Call" msgstr "Indicativo" -#: src/dialogs/fl_digi.cxx:3903 +#: src/dialogs/fl_digi.cxx:3958 #: src/widgets/FTextRXTX.cxx:107 #: src/logbook/lgbook.cxx:405 #: src/logbook/lgbook.cxx:577 @@ -673,50 +682,50 @@ msgstr "Indicativo" msgid "Name" msgstr "Nombre" -#: src/dialogs/fl_digi.cxx:3907 -#: src/dialogs/fl_digi.cxx:4096 +#: src/dialogs/fl_digi.cxx:3962 +#: src/dialogs/fl_digi.cxx:4151 #: src/logbook/lgbook.cxx:613 msgid "In" msgstr "Rec." -#: src/dialogs/fl_digi.cxx:3911 -#: src/dialogs/fl_digi.cxx:4104 +#: src/dialogs/fl_digi.cxx:3966 +#: src/dialogs/fl_digi.cxx:4159 #: src/logbook/lgbook.cxx:625 msgid "Out" msgstr "Env." -#: src/dialogs/fl_digi.cxx:3916 +#: src/dialogs/fl_digi.cxx:3971 #: src/widgets/FTextRXTX.cxx:108 msgid "QTH" msgstr "QTH" -#: src/dialogs/fl_digi.cxx:3919 +#: src/dialogs/fl_digi.cxx:3974 msgid "City" msgstr "Ciudad" -#: src/dialogs/fl_digi.cxx:3922 +#: src/dialogs/fl_digi.cxx:3977 #: src/logbook/lgbook.cxx:687 msgid "St" msgstr "Es" -#: src/dialogs/fl_digi.cxx:3925 +#: src/dialogs/fl_digi.cxx:3980 msgid "US State" msgstr "Estado de USA" -#: src/dialogs/fl_digi.cxx:3928 +#: src/dialogs/fl_digi.cxx:3983 #: src/logbook/lgbook.cxx:699 msgid "Pr" msgstr "Pr" -#: src/dialogs/fl_digi.cxx:3931 +#: src/dialogs/fl_digi.cxx:3986 msgid "Can. Province" msgstr "Provincia Can." -#: src/dialogs/fl_digi.cxx:3934 +#: src/dialogs/fl_digi.cxx:3989 msgid "Cnty" msgstr "País" -#: src/dialogs/fl_digi.cxx:3937 +#: src/dialogs/fl_digi.cxx:3992 #: src/spot/notify.cxx:562 #: src/widgets/FTextRXTX.cxx:111 #: src/logbook/lgbook.cxx:460 @@ -724,93 +733,93 @@ msgstr "País" msgid "Country" msgstr "País" -#: src/dialogs/fl_digi.cxx:3940 +#: src/dialogs/fl_digi.cxx:3995 #: src/logbook/lgbook.cxx:723 msgid "Loc" msgstr "Loc" -#: src/dialogs/fl_digi.cxx:3946 +#: src/dialogs/fl_digi.cxx:4001 msgid "Az" msgstr "Az" -#: src/dialogs/fl_digi.cxx:3960 +#: src/dialogs/fl_digi.cxx:4015 msgid "#Out" msgstr "#Env." -#: src/dialogs/fl_digi.cxx:3966 -#: src/dialogs/fl_digi.cxx:4223 +#: src/dialogs/fl_digi.cxx:4021 +#: src/dialogs/fl_digi.cxx:4278 msgid "Sent serial number (read only)" msgstr "Número de serie enviado (solo lectura)" -#: src/dialogs/fl_digi.cxx:3971 +#: src/dialogs/fl_digi.cxx:4026 msgid "#In" msgstr "#Recv." -#: src/dialogs/fl_digi.cxx:3977 -#: src/dialogs/fl_digi.cxx:4214 +#: src/dialogs/fl_digi.cxx:4032 +#: src/dialogs/fl_digi.cxx:4269 msgid "Received serial number" msgstr "Número de serie recibido" -#: src/dialogs/fl_digi.cxx:3981 +#: src/dialogs/fl_digi.cxx:4036 msgid "Xchg" msgstr "Xchg" -#: src/dialogs/fl_digi.cxx:3987 -#: src/dialogs/fl_digi.cxx:4205 +#: src/dialogs/fl_digi.cxx:4042 +#: src/dialogs/fl_digi.cxx:4260 msgid "Contest exchange in" msgstr "Intercambio de concurso recibido" -#: src/dialogs/fl_digi.cxx:4001 +#: src/dialogs/fl_digi.cxx:4056 #: src/logbook/lgbook.cxx:463 #: src/logbook/lgbook.cxx:807 msgid "Notes" msgstr "Notas" -#: src/dialogs/fl_digi.cxx:4076 -#: src/dialogs/fl_digi.cxx:4235 +#: src/dialogs/fl_digi.cxx:4131 +#: src/dialogs/fl_digi.cxx:4290 msgid "Time On" msgstr "Tiempo de comienzo" -#: src/dialogs/fl_digi.cxx:4085 -#: src/dialogs/fl_digi.cxx:4243 +#: src/dialogs/fl_digi.cxx:4140 +#: src/dialogs/fl_digi.cxx:4298 msgid "Time Off" msgstr "Tiempo de final" -#: src/dialogs/fl_digi.cxx:4094 -#: src/dialogs/fl_digi.cxx:4190 -#: src/dialogs/fl_digi.cxx:4543 +#: src/dialogs/fl_digi.cxx:4149 +#: src/dialogs/fl_digi.cxx:4245 +#: src/dialogs/fl_digi.cxx:4595 msgid "Other call" msgstr "Indicativo del otro" -#: src/dialogs/fl_digi.cxx:4102 +#: src/dialogs/fl_digi.cxx:4157 msgid "Received RST" msgstr "RST recib." -#: src/dialogs/fl_digi.cxx:4110 +#: src/dialogs/fl_digi.cxx:4165 msgid "Sent RST" msgstr "RST enviado" -#: src/dialogs/fl_digi.cxx:4112 +#: src/dialogs/fl_digi.cxx:4167 msgid "Nm" msgstr "Nm" -#: src/dialogs/fl_digi.cxx:4119 +#: src/dialogs/fl_digi.cxx:4174 msgid "Other name" msgstr "Nombre del otro" -#: src/dialogs/fl_digi.cxx:4175 +#: src/dialogs/fl_digi.cxx:4230 msgid "# S" msgstr "# S" -#: src/dialogs/fl_digi.cxx:4176 +#: src/dialogs/fl_digi.cxx:4231 msgid "# R" msgstr "# R" -#: src/dialogs/fl_digi.cxx:4177 +#: src/dialogs/fl_digi.cxx:4232 msgid "Ex" msgstr "Ex" -#: src/dialogs/fl_digi.cxx:4283 +#: src/dialogs/fl_digi.cxx:4338 msgid "" "Left Click - execute\n" "Shift-Fkey - execute\n" @@ -819,11 +828,11 @@ msgstr "" "Clic izquierdo - ejecutar\n" "Clic derecho - editar" -#: src/dialogs/fl_digi.cxx:4290 +#: src/dialogs/fl_digi.cxx:4345 msgid "Shift-key macro set" msgstr "Conjunto de macros con shift-tecla de función" -#: src/dialogs/fl_digi.cxx:4337 +#: src/dialogs/fl_digi.cxx:4392 msgid "" "Left click - select\n" "Right click - clear line" @@ -831,16 +840,16 @@ msgstr "" "Clic izquierdo - ejecutar\n" "Clic derecho - editar" -#: src/dialogs/fl_digi.cxx:4355 +#: src/dialogs/fl_digi.cxx:4407 msgid "seek - regular expression" msgstr "Expresión regular de búsqueda" -#: src/dialogs/fl_digi.cxx:4376 +#: src/dialogs/fl_digi.cxx:4428 #: src/dialogs/Viewer.cxx:284 msgid "Set Viewer Squelch" msgstr "Establecer el nivel de silenciado (SQL) del visor" -#: src/dialogs/fl_digi.cxx:4461 +#: src/dialogs/fl_digi.cxx:4513 msgid "" "Left Click - execute\n" "Fkey - execute\n" @@ -850,23 +859,23 @@ msgstr "" "Tecla de función - ejecutar\n" "Clic derecho - editar" -#: src/dialogs/fl_digi.cxx:4468 +#: src/dialogs/fl_digi.cxx:4520 msgid "Primary macro set" msgstr "Conjunto primario de macros" -#: src/dialogs/fl_digi.cxx:4485 -#: src/dialogs/fl_digi.cxx:5050 +#: src/dialogs/fl_digi.cxx:4537 +#: src/dialogs/fl_digi.cxx:5103 msgid "Detected signal level" msgstr "Nivel de señal detectado" -#: src/dialogs/fl_digi.cxx:4496 -#: src/dialogs/fl_digi.cxx:5062 -#: src/waterfall/waterfall.cxx:2026 +#: src/dialogs/fl_digi.cxx:4548 +#: src/dialogs/fl_digi.cxx:5115 +#: src/waterfall/waterfall.cxx:2081 msgid "Squelch level" msgstr "Nivel de silencio (SQL)" -#: src/dialogs/fl_digi.cxx:4510 -#: src/dialogs/fl_digi.cxx:5076 +#: src/dialogs/fl_digi.cxx:4562 +#: src/dialogs/fl_digi.cxx:5129 msgid "" "Left click: change mode\n" "Right click: configure" @@ -874,32 +883,32 @@ msgstr "" "Clic izquierdo: cambiar modo\n" "Clic derecho: configurar" -#: src/dialogs/fl_digi.cxx:4520 -#: src/dialogs/fl_digi.cxx:5083 +#: src/dialogs/fl_digi.cxx:4572 +#: src/dialogs/fl_digi.cxx:5136 msgid "CW transmit WPM" msgstr "WPM en TX de CW" -#: src/dialogs/fl_digi.cxx:4526 -#: src/dialogs/fl_digi.cxx:5090 +#: src/dialogs/fl_digi.cxx:4578 +#: src/dialogs/fl_digi.cxx:5143 msgid "Default WPM" msgstr "WPM predefinido" -#: src/dialogs/fl_digi.cxx:4579 -#: src/dialogs/fl_digi.cxx:5135 +#: src/dialogs/fl_digi.cxx:4631 +#: src/dialogs/fl_digi.cxx:5188 msgid "Automatic Frequency Control" msgstr "Control Automático de Frecuencia" -#: src/dialogs/fl_digi.cxx:4582 -#: src/dialogs/fl_digi.cxx:5138 +#: src/dialogs/fl_digi.cxx:4634 +#: src/dialogs/fl_digi.cxx:5191 msgid "Squelch" msgstr "Silenciado (SQL)" -#: src/dialogs/fl_digi.cxx:4625 -#: src/dialogs/fl_digi.cxx:4959 +#: src/dialogs/fl_digi.cxx:4677 +#: src/dialogs/fl_digi.cxx:5012 msgid "Scope" msgstr "Osciloscopio" -#: src/dialogs/fl_digi.cxx:4836 +#: src/dialogs/fl_digi.cxx:4889 #: src/dialogs/Viewer.cxx:241 msgid "Signal Browser" msgstr "Navegador de señal" @@ -978,31 +987,35 @@ msgstr "Exportar a fichero ADIF" msgid "Save changed Logbook?" msgstr "Salvar el libro de log cambiado?" -#: src/logbook/logsupport.cxx:183 +#: src/logbook/logsupport.cxx:168 +msgid "Create New Logbook?" +msgstr "Crear un nuevo libro de log?" + +#: src/logbook/logsupport.cxx:186 msgid "Open logbook file" msgstr "Abrir un libro de log" -#: src/logbook/logsupport.cxx:204 +#: src/logbook/logsupport.cxx:207 msgid "Save logbook file" msgstr "Salvar el libro de log" -#: src/logbook/logsupport.cxx:223 +#: src/logbook/logsupport.cxx:226 msgid "Merge ADIF file" msgstr "Mezclar fichero ADIF" -#: src/logbook/logsupport.cxx:291 +#: src/logbook/logsupport.cxx:294 #: src/spot/notify.cxx:196 #: src/spot/notify.cxx:510 #: src/logbook/lgbook.cxx:826 msgid "Update" msgstr "Actualizar" -#: src/logbook/logsupport.cxx:691 +#: src/logbook/logsupport.cxx:694 #, c-format msgid "Really delete record for \"%s\"?" msgstr "Ralmente borro la entrada par \"%s\"?" -#: src/logbook/logsupport.cxx:1076 +#: src/logbook/logsupport.cxx:1079 msgid "Create cabrillo report" msgstr "Crear un reporte Cabrillo" @@ -1034,7 +1047,7 @@ msgstr "No se puede iniciar flmsg" #: src/logger/rx_extract.cxx:189 #: src/logger/rx_extract.cxx:192 -#: src/dialogs/confdialog.cxx:6093 +#: src/dialogs/confdialog.cxx:6187 msgid "Locate flmsg executable" msgstr "Localización del ejecutable de flmsg" @@ -1070,7 +1083,7 @@ msgstr "Siempre LSB" msgid "Always USB" msgstr "Siempre USB" -#: src/misc/configuration.cxx:710 +#: src/misc/configuration.cxx:713 msgid "" "Reset all options to their default values?\n" "\n" @@ -1084,7 +1097,7 @@ msgstr "" "Se eliminaran los ficheros siguientes:\n" "fldigi_def.xml and fldigi.prefs\n" -#: src/misc/configuration.cxx:715 +#: src/misc/configuration.cxx:718 msgid "Confirm RESET" msgstr "Confirmar RESET" @@ -1117,7 +1130,7 @@ msgid "ARQ control" msgstr "Control ARQ" #: src/misc/debug.cxx:80 -#: src/waterfall/waterfall.cxx:2027 +#: src/waterfall/waterfall.cxx:2082 msgid "Modem" msgstr "Modem" @@ -1149,146 +1162,154 @@ msgstr "Ver log" msgid "A message was logged" msgstr "Un mensaje se añadió al log" -#: src/misc/macroedit.cxx:73 +#: src/misc/macroedit.cxx:71 msgid "\tmy frequency" msgstr "\tmi frecuencia" -#: src/misc/macroedit.cxx:74 +#: src/misc/macroedit.cxx:72 msgid "\tmode" msgstr "\tmodo" -#: src/misc/macroedit.cxx:75 +#: src/misc/macroedit.cxx:73 msgid "\tmy call" msgstr "\tmi indicativo" -#: src/misc/macroedit.cxx:76 +#: src/misc/macroedit.cxx:74 msgid "\tmy locator" msgstr "\tmi localizador" -#: src/misc/macroedit.cxx:77 +#: src/misc/macroedit.cxx:75 msgid "\tmy name" msgstr "\tmi nombre" -#: src/misc/macroedit.cxx:78 +#: src/misc/macroedit.cxx:76 msgid "\tmy QTH" msgstr "\tmi QTH" -#: src/misc/macroedit.cxx:79 +#: src/misc/macroedit.cxx:77 msgid "\tmy RST" msgstr "\tmi RST" -#: src/misc/macroedit.cxx:80 +#: src/misc/macroedit.cxx:78 msgid "\tFldigi version" msgstr "\tversion de Fldigi" -#: src/misc/macroedit.cxx:83 +#: src/misc/macroedit.cxx:81 msgid "\tother call" msgstr "\tindicativo del otro" -#: src/misc/macroedit.cxx:84 +#: src/misc/macroedit.cxx:82 msgid "\tS/N etc." msgstr "\tS/N etc." -#: src/misc/macroedit.cxx:85 +#: src/misc/macroedit.cxx:83 msgid "\tIMD etc." msgstr "\tIMD etc." -#: src/misc/macroedit.cxx:86 +#: src/misc/macroedit.cxx:84 msgid "\tother locator" msgstr "\tlocalizador del otro" -#: src/misc/macroedit.cxx:87 +#: src/misc/macroedit.cxx:85 msgid "\tother name" msgstr "\tnombre del otro" -#: src/misc/macroedit.cxx:88 +#: src/misc/macroedit.cxx:86 msgid "\tother QTH" msgstr "\tQTH del otro" -#: src/misc/macroedit.cxx:89 +#: src/misc/macroedit.cxx:87 msgid "\tother RST" msgstr "\tRST del otro" -#: src/misc/macroedit.cxx:90 +#: src/misc/macroedit.cxx:88 msgid "\tmap on google" msgstr "\tmapearlo en google" -#: src/misc/macroedit.cxx:91 +#: src/misc/macroedit.cxx:89 msgid "\tmap by value" msgstr "\tmapearlo por su valor" -#: src/misc/macroedit.cxx:94 +#: src/misc/macroedit.cxx:92 msgid "\tclear RX pane" msgstr "\tlimpiar el panel de RX" -#: src/misc/macroedit.cxx:97 +#: src/misc/macroedit.cxx:93 +msgid "\tclear TX pane" +msgstr "\tlimpiar el panel de TX" + +#: src/misc/macroedit.cxx:96 msgid "\ttext to NAME/QTH" msgstr "\ttexto a NOMBRE/QTH" -#: src/misc/macroedit.cxx:101 +#: src/misc/macroedit.cxx:100 msgid "\tDigitalk On, Off, Toggle" msgstr "\tDigitalk Encendido, apagado, invirtiendo" -#: src/misc/macroedit.cxx:105 +#: src/misc/macroedit.cxx:104 msgid "\tsave QSO data" msgstr "\tsalvar datos del QSO" -#: src/misc/macroedit.cxx:106 +#: src/misc/macroedit.cxx:105 msgid "\tlog at xmt time" msgstr "\tsalvar al tiempo que transmite" -#: src/misc/macroedit.cxx:107 +#: src/misc/macroedit.cxx:106 msgid "\tclear log fields" msgstr "\tlimpiar los campos del log" -#: src/misc/macroedit.cxx:110 +#: src/misc/macroedit.cxx:109 msgid "\tQSO time (HHMM))" msgstr "\tHora del QSO (HHMM)" -#: src/misc/macroedit.cxx:111 +#: src/misc/macroedit.cxx:110 msgid "\tLDT in iso-8601 format" msgstr "\tLDT en formato iso-8601" -#: src/misc/macroedit.cxx:112 +#: src/misc/macroedit.cxx:111 msgid "\tLocal datetime" msgstr "\tfecha y hora en tiempo local" -#: src/misc/macroedit.cxx:113 +#: src/misc/macroedit.cxx:112 msgid "\tZDT in iso-8601 format" msgstr "\tZDT en formato iso-8601" -#: src/misc/macroedit.cxx:114 +#: src/misc/macroedit.cxx:113 msgid "\tUTC datetime" msgstr "\tfecha y hora UTC" -#: src/misc/macroedit.cxx:115 +#: src/misc/macroedit.cxx:114 msgid "\tlocal time HHMM" msgstr "\thora local (HHMM)" -#: src/misc/macroedit.cxx:116 +#: src/misc/macroedit.cxx:115 msgid "\tzulu time HHMMZ" msgstr "\thora zulu HHMMZ" -#: src/misc/macroedit.cxx:117 +#: src/misc/macroedit.cxx:116 msgid "\tlocal date YYYY-MM-DD" msgstr "\tfecha local AAAA-MM-DD" -#: src/misc/macroedit.cxx:118 +#: src/misc/macroedit.cxx:117 msgid "\tzulu date YYYY-MM-DD Z" msgstr "\tfecha zulu AAAA-MM-DD Z" -#: src/misc/macroedit.cxx:121 +#: src/misc/macroedit.cxx:120 msgid "\tcontest counter" msgstr "\tcontador de concurso" -#: src/misc/macroedit.cxx:122 +#: src/misc/macroedit.cxx:121 msgid "\tdecrement counter" msgstr "\tdecrementar el contador" -#: src/misc/macroedit.cxx:123 +#: src/misc/macroedit.cxx:122 msgid "\tincrement counter" msgstr "\tincrementar el contador" +#: src/misc/macroedit.cxx:123 +msgid "\texchange in" +msgstr "\tintercambio entrante" + #: src/misc/macroedit.cxx:124 msgid "\texchange out" msgstr "\tintercambio enviado" @@ -1333,136 +1354,160 @@ msgstr "\tretornar a la frecuencia inicial en la cascada" msgid "\tmove to freq NNNN Hz" msgstr "\tmoverte a la frecuencia NNNN" -#: src/misc/macroedit.cxx:139 +#: src/misc/macroedit.cxx:137 +msgid "\tleft-clk QSY button" +msgstr "\tclick-izquierdo QSY a la frecuencia preferida de este modo" + +#: src/misc/macroedit.cxx:138 +msgid "\tright-clk QSY button" +msgstr "\tclick-derecho QSY a la frecuencia anterior" + +#: src/misc/macroedit.cxx:141 msgid "\tqsy to kHz, Hz" msgstr "\tqsy a kHz, Hz" -#: src/misc/macroedit.cxx:140 +#: src/misc/macroedit.cxx:142 msgid "\tvalid xcvr mode" msgstr "\tmodo válido para el trx" -#: src/misc/macroedit.cxx:141 +#: src/misc/macroedit.cxx:143 msgid "\tvalid xcvr filter width" msgstr "\tancho del filtro válido para el trx" -#: src/misc/macroedit.cxx:144 +#: src/misc/macroedit.cxx:146 msgid "\tinsert text file" msgstr "\tinsertar fichero de texto" -#: src/misc/macroedit.cxx:145 +#: src/misc/macroedit.cxx:147 msgid "\tidle signal for NN.nn sec" msgstr "\tesperar NN.nn segundos por la señal" -#: src/misc/macroedit.cxx:146 +#: src/misc/macroedit.cxx:148 msgid "\trepeat every NN sec" msgstr "\trepetir cada NN segundos" -#: src/misc/macroedit.cxx:147 +#: src/misc/macroedit.cxx:149 msgid "\ttune signal for NN sec" msgstr "\tsintonizar la señal por NN segundos" -#: src/misc/macroedit.cxx:148 +#: src/misc/macroedit.cxx:150 msgid "\tdelay xmt for NN sec" msgstr "\tretrasar la transmisión por NN segundos" -#: src/misc/macroedit.cxx:149 +#: src/misc/macroedit.cxx:151 msgid "\trepeat macro continuously" msgstr "\trepetir la macro continuamente" #: src/misc/macroedit.cxx:152 +msgid "\tschedule execution" +msgstr "\tplanificar ejecución" + +#: src/misc/macroedit.cxx:155 msgid "\tCW identifier" msgstr "\tidentificador de CW" -#: src/misc/macroedit.cxx:153 +#: src/misc/macroedit.cxx:156 msgid "\tsend mode ID in video text" msgstr "\tenviar el ID del modo como video texto" -#: src/misc/macroedit.cxx:154 +#: src/misc/macroedit.cxx:157 msgid "\tvideo text" msgstr "\tvideo texto" -#: src/misc/macroedit.cxx:155 +#: src/misc/macroedit.cxx:158 msgid "\tTx RSID on,off,toggle" msgstr "\tTx RSID encendido, apagado, invirtiendo" -#: src/misc/macroedit.cxx:156 +#: src/misc/macroedit.cxx:159 msgid "\tRx RSID on,off,toggle" msgstr "\tRx RSID encendido, apagado, invirtiendo" -#: src/misc/macroedit.cxx:159 +#: src/misc/macroedit.cxx:160 +msgid "\t[Wait][Len](ms)" +msgstr "\t[Wait][Len](ms)" + +#: src/misc/macroedit.cxx:163 msgid "\tCW QSK post-timing" msgstr "\tCW QSK al final" -#: src/misc/macroedit.cxx:160 +#: src/misc/macroedit.cxx:164 msgid "\tCW QSK pre-timing" msgstr "\tCW QSK al inicio" -#: src/misc/macroedit.cxx:161 +#: src/misc/macroedit.cxx:165 msgid "\tCW rise time" msgstr "\ttiempo de subida de CW" -#: src/misc/macroedit.cxx:162 +#: src/misc/macroedit.cxx:166 msgid "\tCW WPM" msgstr "\tCW WPM" -#: src/misc/macroedit.cxx:165 +#: src/misc/macroedit.cxx:169 msgid "\tAFC on,off,toggle" msgstr "\tAFC encendido, apagado, invirtiendo" -#: src/misc/macroedit.cxx:166 +#: src/misc/macroedit.cxx:170 msgid "\tLOCK on,off,toggle" msgstr "\tbloqueo (LOCK) encendido, apagado invirtiendo" -#: src/misc/macroedit.cxx:169 +#: src/misc/macroedit.cxx:171 +msgid "\tRev on,off,toggle" +msgstr "\tRev encendido, apagado, invirtiendo" + +#: src/misc/macroedit.cxx:174 msgid "\tchange macro defs file" msgstr "\tcambiar el fichero de definición de macros" -#: src/misc/macroedit.cxx:279 +#: src/misc/macroedit.cxx:284 msgid "Text file to insert" msgstr "Fichero de texto a insertar" -#: src/misc/macroedit.cxx:287 +#: src/misc/macroedit.cxx:292 msgid "Change to Macro file" msgstr "Cambiar a fichero de macro" -#: src/misc/macroedit.cxx:297 +#: src/misc/macroedit.cxx:302 msgid "Executable file to insert" msgstr "Fichero ejecutable a insertar" -#: src/misc/macroedit.cxx:315 -msgid "Text:" -msgstr "Texto:" +#: src/misc/macroedit.cxx:332 +msgid "Macro Text" +msgstr "Editor de macros - " -#: src/misc/macroedit.cxx:324 -msgid "Select Tags:" +#: src/misc/macroedit.cxx:337 +msgid "Select Tag" msgstr "Selecciona etiquetas" -#: src/misc/macroedit.cxx:329 -msgid "Macro Button Label:" +#: src/misc/macroedit.cxx:349 +msgid "Macro Button Label" msgstr "Etiqueta del botón de macro" -#: src/misc/macroedit.cxx:349 +#: src/misc/macroedit.cxx:357 +msgid "Apply" +msgstr "Aplicar" + +#: src/misc/macroedit.cxx:384 msgid "Macro editor - " msgstr "Editor de macros - " -#: src/misc/macros.cxx:1370 +#: src/misc/macros.cxx:1988 msgid "Open macro file" msgstr "Abrir fichero de macro" -#: src/misc/macros.cxx:1370 -#: src/misc/macros.cxx:1382 +#: src/misc/macros.cxx:1988 +#: src/misc/macros.cxx:2000 msgid "Fldigi macro definition file\t*.mdf" msgstr "Fichero de definición de macro para Fldigi\t*.mdf" -#: src/misc/macros.cxx:1382 +#: src/misc/macros.cxx:2000 msgid "Save macro file" msgstr "Salvar fichero macro" -#: src/misc/network.cxx:143 +#: src/misc/network.cxx:144 msgid "Aborted" msgstr "Abortado" -#: src/misc/network.cxx:143 +#: src/misc/network.cxx:144 msgid "Timed out" msgstr "Se ha demorado demasiado" @@ -1471,7 +1516,7 @@ msgid "Save image as:" msgstr "Guardar imagen como..." #: src/mfsk/mfsk-pic.cxx:93 -#: src/dialogs/confdialog.cxx:3712 +#: src/dialogs/confdialog.cxx:3770 msgid "Save..." msgstr "Salvar..." @@ -1515,43 +1560,43 @@ msgstr "Velocidad de transferencia, X1-normal" msgid "Load" msgstr "Cargar" -#: src/waterfall/waterfall.cxx:1489 +#: src/waterfall/waterfall.cxx:1544 msgid "Waterfall / FFT / Scope" msgstr "Cascada / FFT / Osciloscopio" -#: src/waterfall/waterfall.cxx:1499 +#: src/waterfall/waterfall.cxx:1554 msgid "Upper signal level (dB)" msgstr "Nivel superior de la señal (dB)" -#: src/waterfall/waterfall.cxx:1510 +#: src/waterfall/waterfall.cxx:1565 msgid "Signal range (dB)" msgstr "Rango de señal (dB)" -#: src/waterfall/waterfall.cxx:1516 +#: src/waterfall/waterfall.cxx:1571 msgid "Change waterfall scale" msgstr "Cambiar escala de la cascada" -#: src/waterfall/waterfall.cxx:1521 +#: src/waterfall/waterfall.cxx:1576 msgid "Slew display lower in frequency" msgstr "Correr la cascada hacia frecuencias más bajas" -#: src/waterfall/waterfall.cxx:1526 +#: src/waterfall/waterfall.cxx:1581 msgid "Center display on signal" msgstr "Centrar la señal" -#: src/waterfall/waterfall.cxx:1531 +#: src/waterfall/waterfall.cxx:1586 msgid "Slew display higher in frequency" msgstr "Correr la cascada hacia frecuencias más altas" -#: src/waterfall/waterfall.cxx:1536 +#: src/waterfall/waterfall.cxx:1591 msgid "Waterfall drop speed" msgstr "Velocidad de caida de la cascada" -#: src/waterfall/waterfall.cxx:1546 +#: src/waterfall/waterfall.cxx:1601 msgid "Adjust cursor frequency" msgstr "Ajustar la frecuencia del cursor" -#: src/waterfall/waterfall.cxx:1551 +#: src/waterfall/waterfall.cxx:1606 msgid "" "Center in passband\n" "Right click to undo" @@ -1559,7 +1604,7 @@ msgstr "" "Centrar en el pasabanda\n" "Clic derecho para deshacer" -#: src/waterfall/waterfall.cxx:1557 +#: src/waterfall/waterfall.cxx:1612 msgid "" "Store mode and frequency\n" "Right click for list" @@ -1567,32 +1612,32 @@ msgstr "" "Almacenar modo y frecuencia\n" "Click derecho para listar" -#: src/waterfall/waterfall.cxx:1567 +#: src/waterfall/waterfall.cxx:1622 msgid "Lock transmit frequency" msgstr "Bloquear la frecuencia de transmisión" -#: src/waterfall/waterfall.cxx:1574 -#: src/dialogs/confdialog.cxx:3538 +#: src/waterfall/waterfall.cxx:1629 +#: src/dialogs/confdialog.cxx:3596 msgid "Reverse" msgstr "Invertir" -#: src/waterfall/waterfall.cxx:1582 +#: src/waterfall/waterfall.cxx:1637 msgid "Transmit/Receive" msgstr "Transmitir/Recibir" -#: src/waterfall/waterfall.cxx:2025 +#: src/waterfall/waterfall.cxx:2080 msgid "AFC range or BW" msgstr "Rango AFC o Ancho de banda" -#: src/waterfall/waterfall.cxx:2026 +#: src/waterfall/waterfall.cxx:2081 msgid "Signal search" msgstr "Búsqueda de señal" -#: src/waterfall/waterfall.cxx:2027 +#: src/waterfall/waterfall.cxx:2082 msgid "Modem carrier" msgstr "Portadora del modo" -#: src/waterfall/waterfall.cxx:2027 +#: src/waterfall/waterfall.cxx:2082 msgid "Scroll" msgstr "Desplazamiento" @@ -1791,7 +1836,7 @@ msgid "Look up call" msgstr "Buscar indicativo" #: src/widgets/FTextRXTX.cxx:109 -#: src/dialogs/confdialog.cxx:3482 +#: src/dialogs/confdialog.cxx:3540 #: src/logbook/lgbook.cxx:454 msgid "State" msgstr "Estado" @@ -1810,15 +1855,15 @@ msgid "RST(r)" msgstr "RST(r)" #: src/widgets/FTextRXTX.cxx:114 -#: src/dialogs/confdialog.cxx:3488 +#: src/dialogs/confdialog.cxx:3546 #: src/logbook/lgbook.cxx:478 #: src/logbook/lgbook.cxx:888 #: src/logbook/lgbook.cxx:1043 msgid "Exchange In" -msgstr "Intercambio entrante" +msgstr "Intercambio RX" #: src/widgets/FTextRXTX.cxx:115 -#: src/dialogs/confdialog.cxx:3413 +#: src/dialogs/confdialog.cxx:3471 msgid "Serial number" msgstr "Numero de serie" @@ -1836,19 +1881,19 @@ msgstr "Sugerencias de desplazamiento" #: src/widgets/FTextRXTX.cxx:630 msgid " in " -msgstr "en" +msgstr " en " #: src/widgets/FTextRXTX.cxx:632 msgid "Last QSO" msgstr "Último QSO" #: src/widgets/FTextRXTX.cxx:677 -#: src/dialogs/confdialog.cxx:4041 +#: src/dialogs/confdialog.cxx:4117 msgid "Transmit" msgstr "Transmitir" #: src/widgets/FTextRXTX.cxx:678 -#: src/dialogs/confdialog.cxx:3975 +#: src/dialogs/confdialog.cxx:4051 msgid "Receive" msgstr "Recibir" @@ -2097,212 +2142,212 @@ msgstr "SQL-2" msgid "Lighted button enabled colors" msgstr "Colores de los botones iluminados" -#: src/dialogs/confdialog.cxx:2946 +#: src/dialogs/confdialog.cxx:3004 msgid "Fldigi configuration" msgstr "Configuración" -#: src/dialogs/confdialog.cxx:2956 +#: src/dialogs/confdialog.cxx:3014 msgid "Operator information" msgstr "Información del operador" -#: src/dialogs/confdialog.cxx:2959 +#: src/dialogs/confdialog.cxx:3017 msgid "Station" msgstr "Estación" -#: src/dialogs/confdialog.cxx:2962 +#: src/dialogs/confdialog.cxx:3020 msgid "Callsign:" msgstr "Indicativo:" -#: src/dialogs/confdialog.cxx:2963 +#: src/dialogs/confdialog.cxx:3021 msgid "Operators callsign" msgstr "Indicativo del operador" -#: src/dialogs/confdialog.cxx:2976 +#: src/dialogs/confdialog.cxx:3034 msgid "Name:" msgstr "Nombre:" -#: src/dialogs/confdialog.cxx:2977 +#: src/dialogs/confdialog.cxx:3035 msgid "Operators name" msgstr "Nombre del operador" -#: src/dialogs/confdialog.cxx:2990 +#: src/dialogs/confdialog.cxx:3048 msgid "QTH:" msgstr "QTH:" -#: src/dialogs/confdialog.cxx:2991 +#: src/dialogs/confdialog.cxx:3049 msgid "Operators QTH" msgstr "QTH del operador" -#: src/dialogs/confdialog.cxx:3004 +#: src/dialogs/confdialog.cxx:3062 msgid "Locator:" msgstr "Localizador:" -#: src/dialogs/confdialog.cxx:3005 +#: src/dialogs/confdialog.cxx:3063 msgid "Maidenhead locator as in EM64qv" msgstr "Localizador como por ejemplo FL11aj" -#: src/dialogs/confdialog.cxx:3020 +#: src/dialogs/confdialog.cxx:3078 msgid "Antenna:" msgstr "Antena:" -#: src/dialogs/confdialog.cxx:3021 +#: src/dialogs/confdialog.cxx:3079 msgid "Short description of antenna" msgstr "Descripción corta de la antena" -#: src/dialogs/confdialog.cxx:3034 +#: src/dialogs/confdialog.cxx:3092 msgid "Test Signal - Do NOT use with transmitter" msgstr "Señal de prueba - NO USAR con el transmisor" -#: src/dialogs/confdialog.cxx:3038 +#: src/dialogs/confdialog.cxx:3096 msgid "Noise on" msgstr "Ruido encendido" -#: src/dialogs/confdialog.cxx:3043 +#: src/dialogs/confdialog.cxx:3101 msgid "dB" msgstr "dB" -#: src/dialogs/confdialog.cxx:3065 +#: src/dialogs/confdialog.cxx:3123 msgid "UI" msgstr "IU" -#: src/dialogs/confdialog.cxx:3069 +#: src/dialogs/confdialog.cxx:3127 msgid "Gen'" msgstr "General" -#: src/dialogs/confdialog.cxx:3072 +#: src/dialogs/confdialog.cxx:3130 msgid "Show tooltips" msgstr "Mostrar sugerencias" -#: src/dialogs/confdialog.cxx:3073 +#: src/dialogs/confdialog.cxx:3131 msgid "Enable / disable tooltips" msgstr "Activar/desactivar sugerencias" -#: src/dialogs/confdialog.cxx:3079 +#: src/dialogs/confdialog.cxx:3137 msgid "Show menu icons" msgstr "Mostrar íconos del menú" -#: src/dialogs/confdialog.cxx:3080 +#: src/dialogs/confdialog.cxx:3138 msgid "Enable / disable icons on menus" msgstr "Activar/desactivar los iconos en el menú" -#: src/dialogs/confdialog.cxx:3085 +#: src/dialogs/confdialog.cxx:3143 msgid "UI scheme" msgstr "Esquema de la Interfaz" -#: src/dialogs/confdialog.cxx:3086 +#: src/dialogs/confdialog.cxx:3144 msgid "Change application look and feel" msgstr "Cambiar la piel de la aplicación" -#: src/dialogs/confdialog.cxx:3095 +#: src/dialogs/confdialog.cxx:3153 msgid "Visible modes" msgstr "Modos visibles" -#: src/dialogs/confdialog.cxx:3096 +#: src/dialogs/confdialog.cxx:3154 msgid "Select modes for menu access" msgstr "Seleccionar los modos para acceso desde el menú" -#: src/dialogs/confdialog.cxx:3099 +#: src/dialogs/confdialog.cxx:3157 msgid "UI language" msgstr "Idioma de la IU" -#: src/dialogs/confdialog.cxx:3100 -#: src/dialogs/confdialog.cxx:3887 +#: src/dialogs/confdialog.cxx:3158 +#: src/dialogs/confdialog.cxx:3963 msgid "Changes take effect on next program startup" msgstr "Los cambios tomarán efecto en el próximo inicio del programa" -#: src/dialogs/confdialog.cxx:3107 +#: src/dialogs/confdialog.cxx:3165 msgid "QSO logging" msgstr "Salvado de los QSOs" -#: src/dialogs/confdialog.cxx:3110 +#: src/dialogs/confdialog.cxx:3168 msgid "Prompt to save log" msgstr "Preguntar si salvo el log" -#: src/dialogs/confdialog.cxx:3111 +#: src/dialogs/confdialog.cxx:3169 msgid "Bug me about saving log entries" msgstr "Molestame acerca de salvar entradas en el log" -#: src/dialogs/confdialog.cxx:3116 +#: src/dialogs/confdialog.cxx:3174 msgid "Clear on save" msgstr "Limpiar cuando salves" -#: src/dialogs/confdialog.cxx:3117 +#: src/dialogs/confdialog.cxx:3175 msgid "Clear log entries after saving or using macro " msgstr "" "Limpiar la entradas del log después\n" "de salvar o usar la macro " -#: src/dialogs/confdialog.cxx:3122 +#: src/dialogs/confdialog.cxx:3180 msgid "Auto-fill Country and Azimuth" msgstr "Auto rellenar el país y azimut" -#: src/dialogs/confdialog.cxx:3123 +#: src/dialogs/confdialog.cxx:3181 msgid "Fill in Country / Azimuth using cty.dat information" msgstr "Auto rellenar la información del país y el azimut usando el fichero cty.dat (Lo tienes instalado, cierto?)" -#: src/dialogs/confdialog.cxx:3128 +#: src/dialogs/confdialog.cxx:3186 msgid "Convert callsign to upper case" msgstr "Convertir el indicativo a mayúsculas" -#: src/dialogs/confdialog.cxx:3129 +#: src/dialogs/confdialog.cxx:3187 msgid "Force callsign field to UPPERCASE" msgstr "Forzar el campo indicativo a MAYUSCULAS" -#: src/dialogs/confdialog.cxx:3134 +#: src/dialogs/confdialog.cxx:3192 msgid "Sort by Date/Time OFF" msgstr "Ordenar por fecha y hora" -#: src/dialogs/confdialog.cxx:3135 +#: src/dialogs/confdialog.cxx:3193 msgid "Sort by date/time OFF - effects all ADIF/Cabrillo reports" msgstr "" "Ordenar por fecha y hora\n" "Afecta a todos los libros de guardias con formato Cabrillo/ADIF" -#: src/dialogs/confdialog.cxx:3140 +#: src/dialogs/confdialog.cxx:3198 msgid "Date time ON == OFF" msgstr "Fecha y hora de inicio = fin" -#: src/dialogs/confdialog.cxx:3141 +#: src/dialogs/confdialog.cxx:3199 msgid "Force date/time ON == date/time OFF" msgstr "Forzar fecha/hora de inicio = fecha/hora de final del QSO" -#: src/dialogs/confdialog.cxx:3146 +#: src/dialogs/confdialog.cxx:3204 msgid "Transmit Power" msgstr "Potencia TX" -#: src/dialogs/confdialog.cxx:3147 +#: src/dialogs/confdialog.cxx:3205 msgid "Tx power used for logbook entries" msgstr "Potencia de TX a poner en el log" -#: src/dialogs/confdialog.cxx:3161 +#: src/dialogs/confdialog.cxx:3219 msgid "Default RST out to 599" msgstr "Predetermina el RST enviado a 599" -#: src/dialogs/confdialog.cxx:3162 +#: src/dialogs/confdialog.cxx:3220 msgid "Clear log controls sets RST out to 599" msgstr "El limpiar los controles pone el RST enviado a 599" -#: src/dialogs/confdialog.cxx:3172 +#: src/dialogs/confdialog.cxx:3230 msgid "Double-click on RX text enters QSO data" msgstr "Doble clic en el texto de Rx carga los datos del QSO" -#: src/dialogs/confdialog.cxx:3173 +#: src/dialogs/confdialog.cxx:3231 msgid "Enable if you cannot use the middle mouse button" msgstr "Activalo si no puedes usar el botón del centro del ratón" -#: src/dialogs/confdialog.cxx:3178 +#: src/dialogs/confdialog.cxx:3236 msgid "Show callsign tooltips in received text" msgstr "Mostrar información de los indicativos en el texto recibido" -#: src/dialogs/confdialog.cxx:3179 +#: src/dialogs/confdialog.cxx:3237 msgid "Popup info after a 2 second hover on a callsign" msgstr "Mostrar información de un indicativo después de estar dos segundos con el ratón sobre este" -#: src/dialogs/confdialog.cxx:3184 +#: src/dialogs/confdialog.cxx:3242 msgid "Word delimiters" msgstr "Delimitadores" -#: src/dialogs/confdialog.cxx:3185 +#: src/dialogs/confdialog.cxx:3243 msgid "" "RX text QSO data entry is bounded by the non-word characters\n" "defined here. Tab and newline are automatically included." @@ -2311,23 +2356,23 @@ msgstr "" "caracteres definidos aquí, el tabulador, el espacio y la\n" "nueva línea están ya incluidos" -#: src/dialogs/confdialog.cxx:3205 +#: src/dialogs/confdialog.cxx:3263 msgid "Browser" msgstr "Navegador" -#: src/dialogs/confdialog.cxx:3209 +#: src/dialogs/confdialog.cxx:3267 msgid "Channels, first channel starts at waterfall lower limit" msgstr "Canales, el primer canal comienza en el límite inferior de la cascada" -#: src/dialogs/confdialog.cxx:3210 +#: src/dialogs/confdialog.cxx:3268 msgid "Change # of psk viewer channels" msgstr "Cambiar el número de canales del navegador" -#: src/dialogs/confdialog.cxx:3227 +#: src/dialogs/confdialog.cxx:3285 msgid "Inactivity timeout" msgstr "Tiempo de inactividad" -#: src/dialogs/confdialog.cxx:3228 +#: src/dialogs/confdialog.cxx:3286 msgid "" "Clear channel text after\n" "# seconds of inactivity" @@ -2336,48 +2381,48 @@ msgstr "" "después de N segundos\n" "de inactividad" -#: src/dialogs/confdialog.cxx:3244 +#: src/dialogs/confdialog.cxx:3302 msgid "Channel label" msgstr "Etiqueta del canal" -#: src/dialogs/confdialog.cxx:3245 +#: src/dialogs/confdialog.cxx:3303 msgid "Appearance of label on each channel" msgstr "Apariencia de la etiqueta de cada canal" -#: src/dialogs/confdialog.cxx:3249 +#: src/dialogs/confdialog.cxx:3307 msgid "Audio frequency" msgstr "Frecuencia de audio" -#: src/dialogs/confdialog.cxx:3250 +#: src/dialogs/confdialog.cxx:3308 msgid "Radio frequency" msgstr "Frecuencia RF" -#: src/dialogs/confdialog.cxx:3250 +#: src/dialogs/confdialog.cxx:3308 msgid "Channel number" msgstr "Número del canal" -#: src/dialogs/confdialog.cxx:3253 -#: src/dialogs/confdialog.cxx:3766 +#: src/dialogs/confdialog.cxx:3311 +#: src/dialogs/confdialog.cxx:3842 msgid "Font..." msgstr "Tipografía" -#: src/dialogs/confdialog.cxx:3254 +#: src/dialogs/confdialog.cxx:3312 msgid "select browser font" msgstr "Selecciona la letra del navegador" -#: src/dialogs/confdialog.cxx:3257 +#: src/dialogs/confdialog.cxx:3315 msgid "Fixed Intervals" msgstr "Intervalos Fijados" -#: src/dialogs/confdialog.cxx:3258 +#: src/dialogs/confdialog.cxx:3316 msgid "Force channel spacing to even 100 Hz increments" msgstr "Forzar el espaciado de los canales a incrementos de 100Hz" -#: src/dialogs/confdialog.cxx:3265 +#: src/dialogs/confdialog.cxx:3323 msgid "Continuous scrolling" msgstr "Movimiento contínuo" -#: src/dialogs/confdialog.cxx:3266 +#: src/dialogs/confdialog.cxx:3324 msgid "" "ON - Marquee style\n" "OFF - Clear & restart" @@ -2385,95 +2430,95 @@ msgstr "" "Activado - Estilo marquesina\n" "Desactivado - Limpiar y re-comenzar" -#: src/dialogs/confdialog.cxx:3271 +#: src/dialogs/confdialog.cxx:3329 msgid "Lowest freq on bottom of viewer" msgstr "Frecuencia más baja en la parte inferior del navegador" -#: src/dialogs/confdialog.cxx:3272 +#: src/dialogs/confdialog.cxx:3330 msgid "Change positions of low to high channels" msgstr "Cambiar la posición de los canales de abajo a arriba" -#: src/dialogs/confdialog.cxx:3277 +#: src/dialogs/confdialog.cxx:3335 msgid "Play back history when active channel selected" msgstr "Reproducir el historial cuando se selecciona un canal" -#: src/dialogs/confdialog.cxx:3278 +#: src/dialogs/confdialog.cxx:3336 msgid "Audio stream history decoded on selected signal" msgstr "Historial de audio decodificado al seleccionar" -#: src/dialogs/confdialog.cxx:3283 +#: src/dialogs/confdialog.cxx:3341 msgid "Detection Level Colors" msgstr "Colores de detección de nivel" -#: src/dialogs/confdialog.cxx:3286 +#: src/dialogs/confdialog.cxx:3344 msgid "Backgnd" msgstr "Fondo" -#: src/dialogs/confdialog.cxx:3287 +#: src/dialogs/confdialog.cxx:3345 msgid "Background color of signal viewer squelch control" msgstr "" "Color de fondo de control deslizante del\n" "silenciador del navegador" -#: src/dialogs/confdialog.cxx:3291 +#: src/dialogs/confdialog.cxx:3349 msgid "Button" msgstr "Botón" -#: src/dialogs/confdialog.cxx:3292 +#: src/dialogs/confdialog.cxx:3350 msgid "Slider hilite color of signal viewer squelch control" msgstr "" "Color resaltado del deslizante del control\n" "del silenciador del navegador" -#: src/dialogs/confdialog.cxx:3306 +#: src/dialogs/confdialog.cxx:3364 msgid "Mouse wheel active on macro buttons" msgstr "Rueda del ratón activa en los botones de macro" -#: src/dialogs/confdialog.cxx:3307 +#: src/dialogs/confdialog.cxx:3365 msgid "enable mouse wheel control of macro bar" msgstr "Activar la rueda del ratón como control de la barra de macros" -#: src/dialogs/confdialog.cxx:3314 +#: src/dialogs/confdialog.cxx:3372 msgid "Number and position of macro bars" msgstr "Seleccionar el # y posición de la(s) barra(s) de macro(s)" -#: src/dialogs/confdialog.cxx:3317 +#: src/dialogs/confdialog.cxx:3375 msgid "One bar (above waterfall)" msgstr "Una barra (Encima de la cascada)" -#: src/dialogs/confdialog.cxx:3322 +#: src/dialogs/confdialog.cxx:3380 msgid "One bar (below waterfall)" msgstr "Una barra (debajo de la cascada)" -#: src/dialogs/confdialog.cxx:3327 +#: src/dialogs/confdialog.cxx:3385 msgid "Two bars (scheme 1)" msgstr "Dos barras (Esquema 1)" -#: src/dialogs/confdialog.cxx:3332 +#: src/dialogs/confdialog.cxx:3390 msgid "Two bars (scheme 2)" msgstr "Dos barras (Esquema 2)" -#: src/dialogs/confdialog.cxx:3337 +#: src/dialogs/confdialog.cxx:3395 msgid "Two bars (scheme 3)" msgstr "Dos barras (Esquema 3)" -#: src/dialogs/confdialog.cxx:3342 +#: src/dialogs/confdialog.cxx:3400 msgid "Two bars (scheme 4)" msgstr "Dos barras (Esquema 4)" -#: src/dialogs/confdialog.cxx:3347 +#: src/dialogs/confdialog.cxx:3405 msgid "Two bars (scheme 5)" msgstr "Dos barras (Esquema 5)" -#: src/dialogs/confdialog.cxx:3352 +#: src/dialogs/confdialog.cxx:3410 msgid "Two bars (scheme 6)" msgstr "Dos barras (Esquema 6)" -#: src/dialogs/confdialog.cxx:3361 +#: src/dialogs/confdialog.cxx:3419 msgid "Load last used macro file on startup" msgstr "Cargar el último archivo de macro usado en el inicio" -#: src/dialogs/confdialog.cxx:3362 +#: src/dialogs/confdialog.cxx:3420 msgid "" "ON - use last set of macros\n" "OFF - use default set" @@ -2481,104 +2526,104 @@ msgstr "" "Activado - Usar el último conjunto de macros\n" "Desactivado - Usar el conjunto pre-establecido" -#: src/dialogs/confdialog.cxx:3367 +#: src/dialogs/confdialog.cxx:3425 msgid "Display macro filename on startup" msgstr "Mostrar el nombre del fichero de macros al iniciar" -#: src/dialogs/confdialog.cxx:3368 +#: src/dialogs/confdialog.cxx:3426 msgid "The filename is written to the RX text area" msgstr "El nombre de fichero es escrito en el panel de Rx" -#: src/dialogs/confdialog.cxx:3379 +#: src/dialogs/confdialog.cxx:3437 msgid "Exchanges" msgstr "Intercambio" -#: src/dialogs/confdialog.cxx:3382 +#: src/dialogs/confdialog.cxx:3440 msgid "Send:" msgstr "Enviado:" -#: src/dialogs/confdialog.cxx:3384 +#: src/dialogs/confdialog.cxx:3442 #: src/logbook/lgbook.cxx:481 #: src/logbook/lgbook.cxx:864 #: src/logbook/lgbook.cxx:1047 msgid "Exchange Out" -msgstr "Intercambio enviado" +msgstr "Intercambio TX" -#: src/dialogs/confdialog.cxx:3385 +#: src/dialogs/confdialog.cxx:3443 msgid "free form exchange" msgstr "Intercambio predefinido" -#: src/dialogs/confdialog.cxx:3399 +#: src/dialogs/confdialog.cxx:3457 msgid "RST always 599" msgstr "RST siempre 599" -#: src/dialogs/confdialog.cxx:3400 +#: src/dialogs/confdialog.cxx:3458 msgid "Force RST in/out to 599" msgstr "Forzar el RST recibido/enviado a 599" -#: src/dialogs/confdialog.cxx:3405 +#: src/dialogs/confdialog.cxx:3463 msgid "Send CW cut numbers" msgstr "Enviar números CW (5NN)" -#: src/dialogs/confdialog.cxx:3406 +#: src/dialogs/confdialog.cxx:3464 msgid "0 = T; 9 = N" msgstr "0 = T; 9 = N" -#: src/dialogs/confdialog.cxx:3416 +#: src/dialogs/confdialog.cxx:3474 msgid "Use leading zeros" msgstr "Usar ceros a la izquierda" -#: src/dialogs/confdialog.cxx:3417 +#: src/dialogs/confdialog.cxx:3475 msgid "Insert leading zeros into Xmtd serial number" msgstr "Insertar ceros a la izquierda en el número de serie enviado" -#: src/dialogs/confdialog.cxx:3422 +#: src/dialogs/confdialog.cxx:3480 msgid "Start" msgstr "Inicio" -#: src/dialogs/confdialog.cxx:3423 +#: src/dialogs/confdialog.cxx:3481 msgid "Starting number" msgstr "Número de inicio" -#: src/dialogs/confdialog.cxx:3438 +#: src/dialogs/confdialog.cxx:3496 msgid "Digits" msgstr "Dígitos" -#: src/dialogs/confdialog.cxx:3439 +#: src/dialogs/confdialog.cxx:3497 msgid "Number of digits in serial number" msgstr "Número de dígitos en el número de serie" -#: src/dialogs/confdialog.cxx:3455 +#: src/dialogs/confdialog.cxx:3513 msgid "Reset" msgstr "Resetear" -#: src/dialogs/confdialog.cxx:3456 +#: src/dialogs/confdialog.cxx:3514 msgid "Initialize the QSO logging fields" msgstr "Inicializar la cuenta del número serie" -#: src/dialogs/confdialog.cxx:3461 +#: src/dialogs/confdialog.cxx:3519 msgid "Duplicate check, CALL plus" msgstr "Chequear duplicados, Indicativo más..." -#: src/dialogs/confdialog.cxx:3464 +#: src/dialogs/confdialog.cxx:3522 msgid "On/Off" msgstr "On/Off" -#: src/dialogs/confdialog.cxx:3465 +#: src/dialogs/confdialog.cxx:3523 msgid "Check for duplicates" msgstr "Chequear duplicados" -#: src/dialogs/confdialog.cxx:3470 +#: src/dialogs/confdialog.cxx:3528 #: src/dialogs/notifydialog.cxx:188 #: src/logbook/lgbook.cxx:413 msgid "Band" msgstr "Banda" -#: src/dialogs/confdialog.cxx:3471 +#: src/dialogs/confdialog.cxx:3529 msgid "Bands must match" msgstr "Concordar en bandas" -#: src/dialogs/confdialog.cxx:3476 +#: src/dialogs/confdialog.cxx:3534 #: src/dialogs/notifydialog.cxx:191 #: src/logbook/lgbook.cxx:416 #: src/logbook/lgbook.cxx:601 @@ -2587,261 +2632,282 @@ msgstr "Concordar en bandas" msgid "Mode" msgstr "Modo" -#: src/dialogs/confdialog.cxx:3477 +#: src/dialogs/confdialog.cxx:3535 msgid "Mode must match" msgstr "Concordar en modo" -#: src/dialogs/confdialog.cxx:3483 +#: src/dialogs/confdialog.cxx:3541 msgid "State must match" msgstr "Concordar en estado (EE.UU.)" -#: src/dialogs/confdialog.cxx:3489 +#: src/dialogs/confdialog.cxx:3547 msgid "free form 1 must match" msgstr "Concordar en el número de intercambio" -#: src/dialogs/confdialog.cxx:3494 +#: src/dialogs/confdialog.cxx:3552 msgid "Time span over" msgstr "Rango de tiempo" -#: src/dialogs/confdialog.cxx:3495 +#: src/dialogs/confdialog.cxx:3553 msgid "QSO must not occur within a time period of" msgstr "El QSO no debe ocurrir dentro es período" -#: src/dialogs/confdialog.cxx:3500 +#: src/dialogs/confdialog.cxx:3558 msgid "minutes" msgstr "minutos" -#: src/dialogs/confdialog.cxx:3501 +#: src/dialogs/confdialog.cxx:3559 msgid "Enter time span in minutes" msgstr "Entre rango de tiempo en minutos" -#: src/dialogs/confdialog.cxx:3517 +#: src/dialogs/confdialog.cxx:3575 msgid "Dup Color" msgstr "Color Dup." -#: src/dialogs/confdialog.cxx:3518 +#: src/dialogs/confdialog.cxx:3576 msgid "Left click to select dup color" msgstr "Clic izquierdo para seleccionar el color de duplicados" -#: src/dialogs/confdialog.cxx:3530 +#: src/dialogs/confdialog.cxx:3588 msgid "WF Ctrls" msgstr "Cascada" -#: src/dialogs/confdialog.cxx:3534 +#: src/dialogs/confdialog.cxx:3592 msgid "Enable check box to show each respective operator control" msgstr "Activa la casilla para mostrar cada control respectivo" -#: src/dialogs/confdialog.cxx:3544 +#: src/dialogs/confdialog.cxx:3602 msgid "WF Magnification" msgstr "Ampliado de Cascada" -#: src/dialogs/confdialog.cxx:3550 +#: src/dialogs/confdialog.cxx:3608 msgid "WF carrier" msgstr "Carrier de la Cascada" -#: src/dialogs/confdialog.cxx:3556 +#: src/dialogs/confdialog.cxx:3614 msgid "WF Shift Controls" msgstr "Controles superiores de la Casc." -#: src/dialogs/confdialog.cxx:3562 +#: src/dialogs/confdialog.cxx:3620 msgid "WF ref level" msgstr "Nivel de referencia de la Cascada" -#: src/dialogs/confdialog.cxx:3568 +#: src/dialogs/confdialog.cxx:3626 msgid "WF drop rate" msgstr "Vel. de caída de la Cascada" -#: src/dialogs/confdialog.cxx:3574 +#: src/dialogs/confdialog.cxx:3632 msgid "WF amp span" msgstr "Amplitud de la Cascada" -#: src/dialogs/confdialog.cxx:3580 +#: src/dialogs/confdialog.cxx:3638 msgid "WF Store" msgstr "Almacenar frecuencia" -#: src/dialogs/confdialog.cxx:3586 +#: src/dialogs/confdialog.cxx:3644 msgid "WF mode" msgstr "Modo de la Cascada" -#: src/dialogs/confdialog.cxx:3592 +#: src/dialogs/confdialog.cxx:3650 msgid "QSY" msgstr "QSY" -#: src/dialogs/confdialog.cxx:3598 +#: src/dialogs/confdialog.cxx:3656 msgid "XMT lock" msgstr "Bloqueo en Tx" -#: src/dialogs/confdialog.cxx:3604 +#: src/dialogs/confdialog.cxx:3662 msgid "Enable all" msgstr "Activar" -#: src/dialogs/confdialog.cxx:3607 +#: src/dialogs/confdialog.cxx:3665 msgid "Disable all" msgstr "Desactivar" -#: src/dialogs/confdialog.cxx:3614 +#: src/dialogs/confdialog.cxx:3672 msgid "Rx Text" msgstr "Texto RX" -#: src/dialogs/confdialog.cxx:3616 +#: src/dialogs/confdialog.cxx:3674 msgid "Print CW / RTTY / THROB / CONTESTIA in lowercase" msgstr "" "Imprimir CW / RTTY / THROB / CONTESTIA en minúsculas\n" "(Estos modos solo reconocen las mayúsculas)" -#: src/dialogs/confdialog.cxx:3623 +#: src/dialogs/confdialog.cxx:3681 msgid "Log server" msgstr "Servidor de Logs" -#: src/dialogs/confdialog.cxx:3625 +#: src/dialogs/confdialog.cxx:3683 msgid "Client/Server Logbook" msgstr "Logs remotos cliente/servidor" -#: src/dialogs/confdialog.cxx:3628 +#: src/dialogs/confdialog.cxx:3686 msgid "Server Address:" msgstr "Servidor:" -#: src/dialogs/confdialog.cxx:3629 +#: src/dialogs/confdialog.cxx:3687 msgid "Enter URL address of server" msgstr "Entre la dirección URL del servidor" -#: src/dialogs/confdialog.cxx:3633 +#: src/dialogs/confdialog.cxx:3691 msgid "Server Port:" msgstr "Puerto" -#: src/dialogs/confdialog.cxx:3634 +#: src/dialogs/confdialog.cxx:3692 msgid "Enter Port # assigned to server" msgstr "Número de puerto asignado al servidor" -#: src/dialogs/confdialog.cxx:3638 +#: src/dialogs/confdialog.cxx:3696 msgid "Reconnect" msgstr "Reconectar" -#: src/dialogs/confdialog.cxx:3654 +#: src/dialogs/confdialog.cxx:3712 msgid "Display" msgstr "Mostrar" -#: src/dialogs/confdialog.cxx:3655 +#: src/dialogs/confdialog.cxx:3713 msgid "Colors and cursors" msgstr "Colores y cursores" -#: src/dialogs/confdialog.cxx:3673 -#: src/dialogs/confdialog.cxx:3677 -#: src/dialogs/confdialog.cxx:3681 -#: src/dialogs/confdialog.cxx:3685 -#: src/dialogs/confdialog.cxx:3689 -#: src/dialogs/confdialog.cxx:3693 -#: src/dialogs/confdialog.cxx:3697 -#: src/dialogs/confdialog.cxx:3701 -#: src/dialogs/confdialog.cxx:3705 -#: src/dialogs/confdialog.cxx:3723 -#: src/dialogs/confdialog.cxx:3736 -#: src/dialogs/confdialog.cxx:3749 +#: src/dialogs/confdialog.cxx:3716 +#, fuzzy +msgid "aa" +msgstr "aa" + +#: src/dialogs/confdialog.cxx:3731 +#: src/dialogs/confdialog.cxx:3735 +#: src/dialogs/confdialog.cxx:3739 +#: src/dialogs/confdialog.cxx:3743 +#: src/dialogs/confdialog.cxx:3747 +#: src/dialogs/confdialog.cxx:3751 +#: src/dialogs/confdialog.cxx:3755 +#: src/dialogs/confdialog.cxx:3759 +#: src/dialogs/confdialog.cxx:3763 +#: src/dialogs/confdialog.cxx:3781 +#: src/dialogs/confdialog.cxx:3794 +#: src/dialogs/confdialog.cxx:3807 +#: src/dialogs/confdialog.cxx:5040 msgid "Change color" msgstr "Cambiar color" -#: src/dialogs/confdialog.cxx:3708 +#: src/dialogs/confdialog.cxx:3766 msgid "Load..." msgstr "Cargar..." -#: src/dialogs/confdialog.cxx:3709 +#: src/dialogs/confdialog.cxx:3767 msgid "Load a new palette" msgstr "Cargar una nueva paleta" -#: src/dialogs/confdialog.cxx:3713 +#: src/dialogs/confdialog.cxx:3771 msgid "Save this palette" msgstr "Salvar esta paleta" -#: src/dialogs/confdialog.cxx:3716 +#: src/dialogs/confdialog.cxx:3774 msgid "Bandwidth cursor" msgstr "Ancho de banda" -#: src/dialogs/confdialog.cxx:3717 +#: src/dialogs/confdialog.cxx:3775 msgid "Show cursor with bandwidth lines" msgstr "Mostar el cursos con las líneas de ancho de banda" -#: src/dialogs/confdialog.cxx:3722 +#: src/dialogs/confdialog.cxx:3780 msgid "Cursor color" msgstr "Color del cursor" -#: src/dialogs/confdialog.cxx:3729 +#: src/dialogs/confdialog.cxx:3787 msgid "Cursor center line" msgstr "Linea central del cursor" -#: src/dialogs/confdialog.cxx:3730 +#: src/dialogs/confdialog.cxx:3788 msgid "Show cursor with center line" msgstr "Mostrar el cursor con la línea central" -#: src/dialogs/confdialog.cxx:3735 +#: src/dialogs/confdialog.cxx:3793 msgid "Center line color" msgstr "Línea central" -#: src/dialogs/confdialog.cxx:3742 +#: src/dialogs/confdialog.cxx:3800 msgid "Bandwidth tracks" msgstr "Pistas de ancho" -#: src/dialogs/confdialog.cxx:3743 +#: src/dialogs/confdialog.cxx:3801 +#: src/dialogs/confdialog.cxx:3814 +#: src/dialogs/confdialog.cxx:3820 +#: src/dialogs/confdialog.cxx:3826 msgid "Show bandwidth tracks on waterfall" msgstr "Mostrar las pistas de ancho de banda en la cascada" -#: src/dialogs/confdialog.cxx:3748 +#: src/dialogs/confdialog.cxx:3806 msgid "Tracks color" msgstr "Color de las pistas" -#: src/dialogs/confdialog.cxx:3757 +#: src/dialogs/confdialog.cxx:3813 +msgid "Wide tracks" +msgstr "Pistas anchas" + +#: src/dialogs/confdialog.cxx:3819 +msgid "Wide center line" +msgstr "Linea central ancha" + +#: src/dialogs/confdialog.cxx:3825 +msgid "Wide cursor" +msgstr "Cursor ancho" + +#: src/dialogs/confdialog.cxx:3833 msgid "Frequency scale" msgstr "Escala de frecuencia" -#: src/dialogs/confdialog.cxx:3760 +#: src/dialogs/confdialog.cxx:3836 msgid "Always show audio frequencies" msgstr "Siempre mostrar las frecuencias de audio" -#: src/dialogs/confdialog.cxx:3761 +#: src/dialogs/confdialog.cxx:3837 msgid "Audio or RF frequencies on waterfall scale" msgstr "Frecuencias de audio o RF en la escala de la cascada" -#: src/dialogs/confdialog.cxx:3767 +#: src/dialogs/confdialog.cxx:3843 msgid "Select waterfall scale font" msgstr "Selecciona la escala de la tipografía de la cascada" -#: src/dialogs/confdialog.cxx:3772 +#: src/dialogs/confdialog.cxx:3848 msgid "Transmit signal" msgstr "Señal transmitida" -#: src/dialogs/confdialog.cxx:3775 +#: src/dialogs/confdialog.cxx:3851 msgid "Monitor transmitted signal" msgstr "Monitorear la señal transmitida" -#: src/dialogs/confdialog.cxx:3776 +#: src/dialogs/confdialog.cxx:3852 msgid "Show transmit signal on waterfall" msgstr "Mostrar la señal transmitida en la cascada" -#: src/dialogs/confdialog.cxx:3781 +#: src/dialogs/confdialog.cxx:3857 msgid "Signal level" msgstr "Nivel de señal" -#: src/dialogs/confdialog.cxx:3782 +#: src/dialogs/confdialog.cxx:3858 msgid "Set level for good viewing" msgstr "Establecer el nivel para un visionado aceptable" -#: src/dialogs/confdialog.cxx:3804 +#: src/dialogs/confdialog.cxx:3880 msgid "FFT Processing" msgstr "Procesamiento FFT" -#: src/dialogs/confdialog.cxx:3808 -#: src/dialogs/confdialog.cxx:4085 +#: src/dialogs/confdialog.cxx:3884 +#: src/dialogs/confdialog.cxx:4161 msgid "Lower limit" msgstr "límite inferior" -#: src/dialogs/confdialog.cxx:3809 +#: src/dialogs/confdialog.cxx:3885 msgid "Low frequency limit in Hz" msgstr "Límite inferior de frecuencia en Hz" -#: src/dialogs/confdialog.cxx:3828 +#: src/dialogs/confdialog.cxx:3904 msgid "FFT latency (scan merging)" msgstr "Latencia de FFT (mezcla de escaneo)" -#: src/dialogs/confdialog.cxx:3829 +#: src/dialogs/confdialog.cxx:3905 msgid "" "Latency increases frequency resolution,\n" "decreases time resolution. 1 = no scan merging" @@ -2849,76 +2915,76 @@ msgstr "" "La latencia incrementa la resolución de frecuencia,\n" "disminuir a 1 para no mezclar" -#: src/dialogs/confdialog.cxx:3849 +#: src/dialogs/confdialog.cxx:3925 msgid "FFT averaging" msgstr "Promedio de FFT" -#: src/dialogs/confdialog.cxx:3850 +#: src/dialogs/confdialog.cxx:3926 msgid "Use averaging to decrease waterfall noise" msgstr "Usar promedio para disminuir el ruido en la cascada" -#: src/dialogs/confdialog.cxx:3855 +#: src/dialogs/confdialog.cxx:3931 msgid "FFT prefilter window function" msgstr "Función de ventana de prefiltro FFT" -#: src/dialogs/confdialog.cxx:3856 +#: src/dialogs/confdialog.cxx:3932 msgid "Select the type of FFT prefilter" msgstr "Seleccionar el tipo de prefiltro de FFT" -#: src/dialogs/confdialog.cxx:3860 +#: src/dialogs/confdialog.cxx:3936 msgid "Rectangular" msgstr "Rectangular" -#: src/dialogs/confdialog.cxx:3862 +#: src/dialogs/confdialog.cxx:3938 msgid "Triangular" msgstr "Triangular" -#: src/dialogs/confdialog.cxx:3865 -#: src/dialogs/confdialog.cxx:4097 +#: src/dialogs/confdialog.cxx:3941 +#: src/dialogs/confdialog.cxx:4173 msgid "Upper limit" msgstr "Límite superior" -#: src/dialogs/confdialog.cxx:3866 +#: src/dialogs/confdialog.cxx:3942 msgid "High frequency limit in Hz" msgstr "Límite superior de frecuencia en Hz" -#: src/dialogs/confdialog.cxx:3888 +#: src/dialogs/confdialog.cxx:3964 msgid "Show me more or less waterfall" msgstr "Mostrar más o menos cascada" -#: src/dialogs/confdialog.cxx:3891 +#: src/dialogs/confdialog.cxx:3967 msgid "Waterfall height in pixels" msgstr "Altura de la cascada" -#: src/dialogs/confdialog.cxx:3892 +#: src/dialogs/confdialog.cxx:3968 msgid "CPU usage increases with waterfall height" msgstr "El uso del CPU aumenta con el alto de la cascada" -#: src/dialogs/confdialog.cxx:3915 +#: src/dialogs/confdialog.cxx:3991 msgid "Mouse" msgstr "Ratón" -#: src/dialogs/confdialog.cxx:3919 +#: src/dialogs/confdialog.cxx:3995 msgid "Left or right click always replays audio history" msgstr "Clic derecho o izquierdo siempre reproduce la historia del audio" -#: src/dialogs/confdialog.cxx:3920 +#: src/dialogs/confdialog.cxx:3996 msgid "Replay trackline audio" msgstr "Reproducir el audio del buffer ante un clic en la cascada" -#: src/dialogs/confdialog.cxx:3925 +#: src/dialogs/confdialog.cxx:4001 msgid "Dragging on the waterfall scale changes frequency" msgstr "Agarrar y arrastar en la cascada cambia la frecuencia" -#: src/dialogs/confdialog.cxx:3926 +#: src/dialogs/confdialog.cxx:4002 msgid "Enable drag cursor on waterfall scale" msgstr "Activar el arrastrado del cursor en la cascada" -#: src/dialogs/confdialog.cxx:3931 +#: src/dialogs/confdialog.cxx:4007 msgid "Insert text on single left click" msgstr "Insertar texto en un solo clic izquierdo" -#: src/dialogs/confdialog.cxx:3932 +#: src/dialogs/confdialog.cxx:4008 msgid "" "Insert special text in Rx panel\n" "when waterfall clicked" @@ -2926,7 +2992,7 @@ msgstr "" "Insertar un texto especial en el panel de Rx\n" "cuando se da clic en la cascada" -#: src/dialogs/confdialog.cxx:3938 +#: src/dialogs/confdialog.cxx:4014 msgid "" "The string is replaced with\n" "the current modem and frequency" @@ -2934,11 +3000,11 @@ msgstr "" "La cadena es remplazada con\n" "el modo actual y la frecuencia" -#: src/dialogs/confdialog.cxx:3952 +#: src/dialogs/confdialog.cxx:4028 msgid "Wheel action" msgstr "Acción de la rueda del ratón en la cascada" -#: src/dialogs/confdialog.cxx:3953 +#: src/dialogs/confdialog.cxx:4029 msgid "" "Select how the mouse wheel\n" "behaves inside the waterfall" @@ -2946,943 +3012,956 @@ msgstr "" "Selecciona como la ruera del ratón se\n" "comporta dentro de la cascada" -#: src/dialogs/confdialog.cxx:3969 -#: src/dialogs/confdialog.cxx:6283 +#: src/dialogs/confdialog.cxx:4045 +#: src/dialogs/confdialog.cxx:6377 msgid "CW" msgstr "CW" -#: src/dialogs/confdialog.cxx:3973 -#: src/dialogs/confdialog.cxx:4756 -#: src/dialogs/confdialog.cxx:6201 +#: src/dialogs/confdialog.cxx:4049 +#: src/dialogs/confdialog.cxx:4833 +#: src/dialogs/confdialog.cxx:6295 msgid "General" msgstr "General" -#: src/dialogs/confdialog.cxx:3978 +#: src/dialogs/confdialog.cxx:4054 msgid "Filter bandwidth" msgstr "Ancho de banda del filtro" -#: src/dialogs/confdialog.cxx:3979 +#: src/dialogs/confdialog.cxx:4055 msgid "CW dsp filter bandwidth" msgstr "Ancho de banda del filtro DSP de CW" -#: src/dialogs/confdialog.cxx:3999 +#: src/dialogs/confdialog.cxx:4075 msgid "Tracking" msgstr "Seguimiento" -#: src/dialogs/confdialog.cxx:4000 +#: src/dialogs/confdialog.cxx:4076 msgid "Automatic Rx speed tracking" msgstr "Seguimiento automático de la velocidad de Rx" -#: src/dialogs/confdialog.cxx:4006 +#: src/dialogs/confdialog.cxx:4082 msgid "Tracking range (WPM)" msgstr "Rango de seguimiento (WPM)" -#: src/dialogs/confdialog.cxx:4007 +#: src/dialogs/confdialog.cxx:4083 msgid "Range +/- wpm" msgstr "Rango +/- wpm" -#: src/dialogs/confdialog.cxx:4031 +#: src/dialogs/confdialog.cxx:4107 msgid "Tracked CW speed in WPM" msgstr "Velocidad de seguimiento en CW (WPM)" -#: src/dialogs/confdialog.cxx:4036 +#: src/dialogs/confdialog.cxx:4112 msgid "RX WPM" msgstr "RX WPM" -#: src/dialogs/confdialog.cxx:4044 +#: src/dialogs/confdialog.cxx:4120 msgid "TX WPM" msgstr "TX WPM" -#: src/dialogs/confdialog.cxx:4045 -#: src/dialogs/confdialog.cxx:4110 +#: src/dialogs/confdialog.cxx:4121 +#: src/dialogs/confdialog.cxx:4186 msgid "My transmit CW WPM" msgstr "Mi velocidad CW (WPM)" -#: src/dialogs/confdialog.cxx:4065 +#: src/dialogs/confdialog.cxx:4141 msgid "Default" msgstr "Predeterminado" -#: src/dialogs/confdialog.cxx:4066 +#: src/dialogs/confdialog.cxx:4142 msgid "The default CW speed" msgstr "La velocidad predefinida en CW" -#: src/dialogs/confdialog.cxx:4086 +#: src/dialogs/confdialog.cxx:4162 msgid "No slower than this" msgstr "No más lento que" -#: src/dialogs/confdialog.cxx:4098 +#: src/dialogs/confdialog.cxx:4174 msgid "No faster than this" msgstr "No más rápido que" -#: src/dialogs/confdialog.cxx:4109 +#: src/dialogs/confdialog.cxx:4185 msgid "F-WPM" msgstr "F-WPM" -#: src/dialogs/confdialog.cxx:4130 +#: src/dialogs/confdialog.cxx:4206 msgid "Use Farnsworth timing" msgstr "Usar tiempos Farnsworth" -#: src/dialogs/confdialog.cxx:4139 +#: src/dialogs/confdialog.cxx:4215 msgid "Timing and QSK" msgstr "Tiempos y QSK" -#: src/dialogs/confdialog.cxx:4142 +#: src/dialogs/confdialog.cxx:4218 msgid "Timing" msgstr "Temporización" -#: src/dialogs/confdialog.cxx:4145 +#: src/dialogs/confdialog.cxx:4221 msgid "Weight (%)" msgstr "Peso (en %)" -#: src/dialogs/confdialog.cxx:4146 +#: src/dialogs/confdialog.cxx:4222 msgid "Dot to dot-space ratio" msgstr "Relación punto a punto-raya" -#: src/dialogs/confdialog.cxx:4165 -#: src/dialogs/confdialog.cxx:4166 +#: src/dialogs/confdialog.cxx:4241 +#: src/dialogs/confdialog.cxx:4242 msgid "Dash to dot ratio" msgstr "Relación punto a raya" -#: src/dialogs/confdialog.cxx:4184 +#: src/dialogs/confdialog.cxx:4260 msgid "Edge timing" msgstr "Tiempos de borde" -#: src/dialogs/confdialog.cxx:4185 +#: src/dialogs/confdialog.cxx:4261 msgid "Leading and Trailing edge risetimes (msec)" msgstr "Tiempos de subida y bajada del pulso (ms)" -#: src/dialogs/confdialog.cxx:4203 +#: src/dialogs/confdialog.cxx:4279 msgid "Edge shape" msgstr "Forma del borde" -#: src/dialogs/confdialog.cxx:4204 +#: src/dialogs/confdialog.cxx:4280 msgid "Raised cosine = Hanning" msgstr "Coseno elevado = Hanning" -#: src/dialogs/confdialog.cxx:4212 +#: src/dialogs/confdialog.cxx:4288 msgid "Edge decreases pulse width" msgstr "Los bordes de subida y bajada disminuyen el ancho del pulso" -#: src/dialogs/confdialog.cxx:4213 +#: src/dialogs/confdialog.cxx:4289 msgid "Weight decreases with increasing edge timing" msgstr "El peso disminuye con el incremento de los tiempos de borde de los pulsos" -#: src/dialogs/confdialog.cxx:4220 +#: src/dialogs/confdialog.cxx:4296 msgid "QSK" msgstr "QSK" -#: src/dialogs/confdialog.cxx:4223 +#: src/dialogs/confdialog.cxx:4299 msgid "QSK on right audio channel" msgstr "QSK en el canal derecho de audio" -#: src/dialogs/confdialog.cxx:4224 +#: src/dialogs/confdialog.cxx:4300 msgid "Generate square wave signal on right channel" msgstr "Generar una onda cuadrada en el canal derecho" -#: src/dialogs/confdialog.cxx:4229 +#: src/dialogs/confdialog.cxx:4305 msgid "Pre-keydown timing (ms)" msgstr "Tiempos anteriores al PTT (ms)" -#: src/dialogs/confdialog.cxx:4230 +#: src/dialogs/confdialog.cxx:4306 msgid "Msec pre-keydown (+ is earlier in time)" msgstr "PTT es enviado N milisegundos antes del pulso real" -#: src/dialogs/confdialog.cxx:4248 +#: src/dialogs/confdialog.cxx:4324 msgid "Post-keydown timing (ms)" msgstr "Tiempos posteriores al PTT (ms)" -#: src/dialogs/confdialog.cxx:4249 +#: src/dialogs/confdialog.cxx:4325 msgid "Msec post-keydown (+ is earlier in time)" msgstr "PTT es soltado N milisegundos después del pulso real" -#: src/dialogs/confdialog.cxx:4267 +#: src/dialogs/confdialog.cxx:4343 msgid "Send continuously" msgstr "Enviar continuamente" -#: src/dialogs/confdialog.cxx:4268 +#: src/dialogs/confdialog.cxx:4344 msgid "Send a continuous stream of test characters" msgstr "Enviar flujo de los carcteres de prueba" -#: src/dialogs/confdialog.cxx:4273 +#: src/dialogs/confdialog.cxx:4349 msgid "Test char" msgstr "Caracter de prueba" -#: src/dialogs/confdialog.cxx:4274 +#: src/dialogs/confdialog.cxx:4350 msgid "Test character for QSK adjustment" msgstr "Probar el caracter para ajuste de QSK" -#: src/dialogs/confdialog.cxx:4285 +#: src/dialogs/confdialog.cxx:4361 msgid "Prosigns" msgstr "Prosigns" -#: src/dialogs/confdialog.cxx:4290 +#: src/dialogs/confdialog.cxx:4366 msgid "Use '(' paren not KN" msgstr "Usar '(' en ves de KN" -#: src/dialogs/confdialog.cxx:4297 +#: src/dialogs/confdialog.cxx:4373 msgid "" msgstr "" -#: src/dialogs/confdialog.cxx:4304 +#: src/dialogs/confdialog.cxx:4380 msgid "" msgstr "" -#: src/dialogs/confdialog.cxx:4311 +#: src/dialogs/confdialog.cxx:4387 msgid "" msgstr "" -#: src/dialogs/confdialog.cxx:4318 +#: src/dialogs/confdialog.cxx:4394 msgid "" msgstr "" -#: src/dialogs/confdialog.cxx:4325 +#: src/dialogs/confdialog.cxx:4401 msgid "" msgstr "" -#: src/dialogs/confdialog.cxx:4332 +#: src/dialogs/confdialog.cxx:4408 msgid "" msgstr "" -#: src/dialogs/confdialog.cxx:4339 +#: src/dialogs/confdialog.cxx:4415 msgid "" msgstr "" -#: src/dialogs/confdialog.cxx:4346 +#: src/dialogs/confdialog.cxx:4422 msgid "" msgstr "" -#: src/dialogs/confdialog.cxx:4353 +#: src/dialogs/confdialog.cxx:4429 msgid "" msgstr "" -#: src/dialogs/confdialog.cxx:4366 +#: src/dialogs/confdialog.cxx:4442 msgid "DomEX" msgstr "DomEX" -#: src/dialogs/confdialog.cxx:4370 -#: src/dialogs/confdialog.cxx:5028 +#: src/dialogs/confdialog.cxx:4446 +#: src/dialogs/confdialog.cxx:5122 msgid "Secondary Text" msgstr "Texto secundario" -#: src/dialogs/confdialog.cxx:4371 -#: src/dialogs/confdialog.cxx:5029 +#: src/dialogs/confdialog.cxx:4447 +#: src/dialogs/confdialog.cxx:5123 msgid "Text to send during keyboard idle times" msgstr "" "Texto a enviar durante los períodos de no actividad\n" "del teclado (canal secundario)" -#: src/dialogs/confdialog.cxx:4385 -#: src/dialogs/confdialog.cxx:5043 +#: src/dialogs/confdialog.cxx:4461 +#: src/dialogs/confdialog.cxx:5137 msgid "Filtering" msgstr "Filtraje" -#: src/dialogs/confdialog.cxx:4386 +#: src/dialogs/confdialog.cxx:4462 msgid "Use DSP filter before decoder" msgstr "Usar el filtro DSP antes del decodificador" -#: src/dialogs/confdialog.cxx:4392 -#: src/dialogs/confdialog.cxx:5050 +#: src/dialogs/confdialog.cxx:4468 +#: src/dialogs/confdialog.cxx:5144 msgid "Filter bandwidth factor" msgstr "Factor de ancho de banda del filtro" -#: src/dialogs/confdialog.cxx:4393 -#: src/dialogs/confdialog.cxx:5051 +#: src/dialogs/confdialog.cxx:4469 +#: src/dialogs/confdialog.cxx:5145 msgid "Filter bandwidth relative to signal width" msgstr "Ancho de banda del filtro relativo al ancho de la señal" -#: src/dialogs/confdialog.cxx:4411 +#: src/dialogs/confdialog.cxx:4487 msgid "FEC" msgstr "FEC" -#: src/dialogs/confdialog.cxx:4412 +#: src/dialogs/confdialog.cxx:4488 msgid "Enable MultiPSK-compatible FEC" msgstr "Activar el FEC compatible con MultiPSK" -#: src/dialogs/confdialog.cxx:4417 -#: src/dialogs/confdialog.cxx:5069 +#: src/dialogs/confdialog.cxx:4493 +#: src/dialogs/confdialog.cxx:5163 msgid "CWI threshold" msgstr "Humbral de CWI" -#: src/dialogs/confdialog.cxx:4418 -#: src/dialogs/confdialog.cxx:5070 +#: src/dialogs/confdialog.cxx:4494 +#: src/dialogs/confdialog.cxx:5164 msgid "CWI detection and suppression" msgstr "Detección y supresión de CWI" -#: src/dialogs/confdialog.cxx:4434 -#: src/dialogs/confdialog.cxx:5086 +#: src/dialogs/confdialog.cxx:4510 +#: src/dialogs/confdialog.cxx:5180 msgid "Paths (hidden)" msgstr "Caminos (Oculto)" -#: src/dialogs/confdialog.cxx:4458 +#: src/dialogs/confdialog.cxx:4534 msgid "Feldhell" msgstr "Feldhell" -#: src/dialogs/confdialog.cxx:4462 +#: src/dialogs/confdialog.cxx:4538 msgid "Transmit font" msgstr "Tipografía de Tx" -#: src/dialogs/confdialog.cxx:4463 +#: src/dialogs/confdialog.cxx:4539 msgid "Select TX raster font" msgstr "Seleccionar la tipografía de Tx" -#: src/dialogs/confdialog.cxx:4470 +#: src/dialogs/confdialog.cxx:4546 msgid "Reverse video" msgstr "Video inverso" -#: src/dialogs/confdialog.cxx:4471 +#: src/dialogs/confdialog.cxx:4547 msgid "Display RX in reverse video" msgstr "Mostrar Rx en video inverso" -#: src/dialogs/confdialog.cxx:4476 +#: src/dialogs/confdialog.cxx:4552 msgid "Transmit width" msgstr "Ancho de la Transmisión" -#: src/dialogs/confdialog.cxx:4477 +#: src/dialogs/confdialog.cxx:4553 msgid "# of multiple scans / character line" msgstr "# de multiples escaneos / lineas de caracteres" -#: src/dialogs/confdialog.cxx:4492 +#: src/dialogs/confdialog.cxx:4568 msgid "Halve receive width" msgstr "Ancho de Rx a la mitad" -#: src/dialogs/confdialog.cxx:4493 +#: src/dialogs/confdialog.cxx:4569 msgid "Compress Rx in time" msgstr "Comprimir Rx en el tiempo" -#: src/dialogs/confdialog.cxx:4498 +#: src/dialogs/confdialog.cxx:4574 msgid "Pulse shape" msgstr "Forma del pulso" -#: src/dialogs/confdialog.cxx:4499 +#: src/dialogs/confdialog.cxx:4575 msgid "Raised cosine pulse shape factor" msgstr "Factor de forma pulsada al coseno elevado " -#: src/dialogs/confdialog.cxx:4503 +#: src/dialogs/confdialog.cxx:4579 msgid "Slow (4 msec)" msgstr "Lento (4 ms)" -#: src/dialogs/confdialog.cxx:4504 +#: src/dialogs/confdialog.cxx:4580 msgid "Fast (2 msec)" msgstr "Rápido (2 ms)" -#: src/dialogs/confdialog.cxx:4507 -#: src/dialogs/confdialog.cxx:4980 +#: src/dialogs/confdialog.cxx:4583 +#: src/dialogs/confdialog.cxx:5074 msgid "Receive filter bandwidth" msgstr "Ancho de banda del filtro de Rx" -#: src/dialogs/confdialog.cxx:4508 -#: src/dialogs/confdialog.cxx:4981 +#: src/dialogs/confdialog.cxx:4584 +#: src/dialogs/confdialog.cxx:5075 msgid "Adjust the DSP bandwidth" msgstr "Ajustar el ancho de banda del DSP" -#: src/dialogs/confdialog.cxx:4528 +#: src/dialogs/confdialog.cxx:4604 msgid "Transmit periods (.) when idle" msgstr "Transmitir puntos (...) cuando holgazanee" -#: src/dialogs/confdialog.cxx:4529 +#: src/dialogs/confdialog.cxx:4605 msgid "Transmits a diddle dot when no keyboard activity" msgstr "" "Transmitir puntos continuos (.......)\n" "cuando no halla que transmitir" -#: src/dialogs/confdialog.cxx:4535 +#: src/dialogs/confdialog.cxx:4611 msgid "2x Xmt Width (hidden)" msgstr "2x Tx ancho (oculto)" -#: src/dialogs/confdialog.cxx:4545 +#: src/dialogs/confdialog.cxx:4621 msgid "MT-63" msgstr "MT-63" -#: src/dialogs/confdialog.cxx:4550 +#: src/dialogs/confdialog.cxx:4626 msgid "64-bit (long) interleave" msgstr "Intervalo largo de 64Bits" -#: src/dialogs/confdialog.cxx:4556 -#: src/dialogs/confdialog.cxx:4671 -#: src/dialogs/confdialog.cxx:4743 +#: src/dialogs/confdialog.cxx:4632 +#: src/dialogs/confdialog.cxx:4747 +#: src/dialogs/confdialog.cxx:4819 msgid "8-bit extended characters" msgstr "Caracteres extendidos de 8bits" -#: src/dialogs/confdialog.cxx:4557 -#: src/dialogs/confdialog.cxx:4672 -#: src/dialogs/confdialog.cxx:4744 +#: src/dialogs/confdialog.cxx:4633 +#: src/dialogs/confdialog.cxx:4748 +#: src/dialogs/confdialog.cxx:4820 msgid "Enable this for Latin-1 accented characters" msgstr "Active esto para caracteres acentuados" -#: src/dialogs/confdialog.cxx:4562 +#: src/dialogs/confdialog.cxx:4638 msgid "Long receive integration" msgstr "Larga integración en Rx" -#: src/dialogs/confdialog.cxx:4563 +#: src/dialogs/confdialog.cxx:4639 msgid "Enable for very weak signals" msgstr "Activar para señales muy debiles" -#: src/dialogs/confdialog.cxx:4572 +#: src/dialogs/confdialog.cxx:4648 msgid "Transmit lower start tone" msgstr "Transmitir tono de inicio bajo" -#: src/dialogs/confdialog.cxx:4577 +#: src/dialogs/confdialog.cxx:4653 msgid "Transmit upper start tone" msgstr "Transmitir tono de inicio alto" -#: src/dialogs/confdialog.cxx:4583 +#: src/dialogs/confdialog.cxx:4659 msgid "Tone Duration (secs)" msgstr "Duración del tono (s)" -#: src/dialogs/confdialog.cxx:4599 +#: src/dialogs/confdialog.cxx:4675 msgid "Allow manual tuning" msgstr "Permitir sintonía manual" -#: src/dialogs/confdialog.cxx:4608 +#: src/dialogs/confdialog.cxx:4684 msgid "Olivia" msgstr "Olivia" -#: src/dialogs/confdialog.cxx:4612 -#: src/dialogs/confdialog.cxx:4684 +#: src/dialogs/confdialog.cxx:4688 +#: src/dialogs/confdialog.cxx:4760 msgid "Bandwidth" msgstr "Ancho de banda" -#: src/dialogs/confdialog.cxx:4613 -#: src/dialogs/confdialog.cxx:4685 +#: src/dialogs/confdialog.cxx:4689 +#: src/dialogs/confdialog.cxx:4761 msgid "Select bandwidth" msgstr "Selecciona el ancho de banda" -#: src/dialogs/confdialog.cxx:4620 -#: src/dialogs/confdialog.cxx:4692 +#: src/dialogs/confdialog.cxx:4696 +#: src/dialogs/confdialog.cxx:4768 msgid "Tones" msgstr "Tonos" -#: src/dialogs/confdialog.cxx:4621 -#: src/dialogs/confdialog.cxx:4693 +#: src/dialogs/confdialog.cxx:4697 +#: src/dialogs/confdialog.cxx:4769 msgid "Select number of tones" msgstr "Seleccionar número de tonos" -#: src/dialogs/confdialog.cxx:4628 -#: src/dialogs/confdialog.cxx:4700 +#: src/dialogs/confdialog.cxx:4704 +#: src/dialogs/confdialog.cxx:4776 msgid "Receive synchronizer" msgstr "Sincronizador de Rx" -#: src/dialogs/confdialog.cxx:4631 -#: src/dialogs/confdialog.cxx:4703 +#: src/dialogs/confdialog.cxx:4707 +#: src/dialogs/confdialog.cxx:4779 msgid "Tune margin (tone frequency spacing)" msgstr "Margen de sintonía (espaciado de los tonos)" -#: src/dialogs/confdialog.cxx:4632 -#: src/dialogs/confdialog.cxx:4651 -#: src/dialogs/confdialog.cxx:4704 -#: src/dialogs/confdialog.cxx:4723 +#: src/dialogs/confdialog.cxx:4708 +#: src/dialogs/confdialog.cxx:4727 +#: src/dialogs/confdialog.cxx:4780 +#: src/dialogs/confdialog.cxx:4799 msgid "Change ONLY to experiment" msgstr "Cambiar SOLO PARA EXPERIMENTAR" -#: src/dialogs/confdialog.cxx:4650 -#: src/dialogs/confdialog.cxx:4722 +#: src/dialogs/confdialog.cxx:4726 +#: src/dialogs/confdialog.cxx:4798 msgid "Integration period (FEC blocks)" msgstr "Periodo de integrción (bloques FEC)" -#: src/dialogs/confdialog.cxx:4680 +#: src/dialogs/confdialog.cxx:4756 msgid "Contestia" msgstr "Contestia" -#: src/dialogs/confdialog.cxx:4753 +#: src/dialogs/confdialog.cxx:4829 msgid "PSK" msgstr "PSK" -#: src/dialogs/confdialog.cxx:4758 +#: src/dialogs/confdialog.cxx:4835 msgid "AFC behavior" msgstr "Comportamiento AFC" -#: src/dialogs/confdialog.cxx:4761 +#: src/dialogs/confdialog.cxx:4838 msgid "Acquisition search range (Hz)" msgstr "Rango de búsqueda y adquisición (Hz)" -#: src/dialogs/confdialog.cxx:4762 +#: src/dialogs/confdialog.cxx:4839 msgid "Capture signals within this frequency range" msgstr "Capturar señales dentro de este rango de frecuencias" -#: src/dialogs/confdialog.cxx:4781 -#: src/dialogs/confdialog.cxx:6152 +#: src/dialogs/confdialog.cxx:4858 +#: src/dialogs/confdialog.cxx:6246 msgid "Acquisition S/N (dB)" msgstr "S/N (dB) de adquisición" -#: src/dialogs/confdialog.cxx:4782 -#: src/dialogs/confdialog.cxx:6153 +#: src/dialogs/confdialog.cxx:4859 +#: src/dialogs/confdialog.cxx:6247 msgid "Capture signals over this threshold" msgstr "Capturar señales por encima de este nivel" -#: src/dialogs/confdialog.cxx:4803 +#: src/dialogs/confdialog.cxx:4880 msgid "S/N and IMD behavior" msgstr "Comportamiento del S/N y IMD" -#: src/dialogs/confdialog.cxx:4806 +#: src/dialogs/confdialog.cxx:4883 msgid "after" msgstr "despues" -#: src/dialogs/confdialog.cxx:4807 +#: src/dialogs/confdialog.cxx:4884 msgid "Behavior of s/n imd" msgstr "Comportamiento del S/N y IMD" -#: src/dialogs/confdialog.cxx:4811 +#: src/dialogs/confdialog.cxx:4888 msgid "Dim" msgstr "Atenuar" -#: src/dialogs/confdialog.cxx:4814 +#: src/dialogs/confdialog.cxx:4891 msgid "seconds" msgstr "segundos" -#: src/dialogs/confdialog.cxx:4815 +#: src/dialogs/confdialog.cxx:4892 msgid "Will occur after this time in seconds" msgstr "Ocurirá despues de este tiempo (s)" -#: src/dialogs/confdialog.cxx:4835 +#: src/dialogs/confdialog.cxx:4912 msgid "Multi-Channel Signal Processing" msgstr "Procesamiento de la señal multi-canal" -#: src/dialogs/confdialog.cxx:4838 +#: src/dialogs/confdialog.cxx:4915 msgid "Multi-channel detector" msgstr "Detector multicanal" -#: src/dialogs/confdialog.cxx:4843 +#: src/dialogs/confdialog.cxx:4920 msgid "Disable on very slow CPUs of if signal browser is not used" msgstr "" "Procesamiento multicanal de la señal desactivado en PCs con CPUs\n" "muy lenta y no se usa el navegador de señal" -#: src/dialogs/confdialog.cxx:4854 -#: src/dialogs/confdialog.cxx:6302 +#: src/dialogs/confdialog.cxx:4931 +#: src/dialogs/confdialog.cxx:6396 msgid "RTTY" msgstr "RTTY" -#: src/dialogs/confdialog.cxx:4858 +#: src/dialogs/confdialog.cxx:4934 msgid "Carrier shift" msgstr "Salto de la portadora" -#: src/dialogs/confdialog.cxx:4859 +#: src/dialogs/confdialog.cxx:4935 msgid "Select carrier shift" msgstr "Seleccionar el salto de la portadora" -#: src/dialogs/confdialog.cxx:4866 +#: src/dialogs/confdialog.cxx:4942 msgid "Baud rate" msgstr "Tasa de baudios" -#: src/dialogs/confdialog.cxx:4867 +#: src/dialogs/confdialog.cxx:4943 msgid "Select carrier baudrate" msgstr "Seleccionar la tasa de baudios de la portadora" -#: src/dialogs/confdialog.cxx:4874 +#: src/dialogs/confdialog.cxx:4950 msgid "Bits per character" msgstr "Bits por caracter" -#: src/dialogs/confdialog.cxx:4875 +#: src/dialogs/confdialog.cxx:4951 msgid "Select # bits / char" msgstr "Selecciona el # bits / caracter" -#: src/dialogs/confdialog.cxx:4882 +#: src/dialogs/confdialog.cxx:4958 msgid "Parity" msgstr "Paridad" -#: src/dialogs/confdialog.cxx:4883 +#: src/dialogs/confdialog.cxx:4959 msgid "Select parity" msgstr "Seleccionar paridad" -#: src/dialogs/confdialog.cxx:4890 +#: src/dialogs/confdialog.cxx:4966 msgid "Stop bits" msgstr "Bits de parda" -#: src/dialogs/confdialog.cxx:4891 +#: src/dialogs/confdialog.cxx:4967 msgid "Select # stop bits" msgstr "Seleccionar # de bits de parada" -#: src/dialogs/confdialog.cxx:4900 +#: src/dialogs/confdialog.cxx:4976 msgid "AutoCRLF" msgstr "CRLF automático" -#: src/dialogs/confdialog.cxx:4901 +#: src/dialogs/confdialog.cxx:4977 msgid "Add CRLF after page width characters" msgstr "Añadir CRLF después de el ancho de caracteres de la página" -#: src/dialogs/confdialog.cxx:4906 +#: src/dialogs/confdialog.cxx:4982 msgid "CR-CR-LF" msgstr "CR-CR-LF" -#: src/dialogs/confdialog.cxx:4907 +#: src/dialogs/confdialog.cxx:4983 msgid "Use \"cr cr lf\" for \"cr lf\"" msgstr "Usar \"cr cr lf\" para \"cr lf\"" -#: src/dialogs/confdialog.cxx:4913 +#: src/dialogs/confdialog.cxx:4989 msgid "characters" msgstr "caracteres" -#: src/dialogs/confdialog.cxx:4914 +#: src/dialogs/confdialog.cxx:4990 msgid "Set page width" msgstr "Establecer el ancho de la página" -#: src/dialogs/confdialog.cxx:4932 +#: src/dialogs/confdialog.cxx:5008 msgid "after:" msgstr "después:" -#: src/dialogs/confdialog.cxx:4937 +#: src/dialogs/confdialog.cxx:5013 msgid "Unshift On Space" msgstr "No saltar en el espacio" -#: src/dialogs/confdialog.cxx:4940 +#: src/dialogs/confdialog.cxx:5016 msgid "RX" msgstr "RX" -#: src/dialogs/confdialog.cxx:4941 -#: src/dialogs/confdialog.cxx:4947 +#: src/dialogs/confdialog.cxx:5017 +#: src/dialogs/confdialog.cxx:5023 +#: src/dialogs/confdialog.cxx:5034 msgid "Revert to Unsifted char's on a space" msgstr "Revertir el salto en espacio de los caracteres" -#: src/dialogs/confdialog.cxx:4946 +#: src/dialogs/confdialog.cxx:5022 msgid "TX" msgstr "TX" -#: src/dialogs/confdialog.cxx:4954 -msgid "Use cross hair scope" -msgstr "Usar osciloscopio de hilos cruzados" +#: src/dialogs/confdialog.cxx:5030 +msgid "Log RTTY frequency" +msgstr "Frecuencia de log para RTTY" -#: src/dialogs/confdialog.cxx:4955 +#: src/dialogs/confdialog.cxx:5033 +msgid "Use MARK freq'" +msgstr "Usar frec. MARCA" + +#: src/dialogs/confdialog.cxx:5039 +msgid "track clr" +msgstr "Color" + +#: src/dialogs/confdialog.cxx:5048 +msgid "Use cross hair scope" +msgstr "Usar osc. de hilos cruzados" + +#: src/dialogs/confdialog.cxx:5049 msgid "Default to cross hair digiscope" msgstr "Osciloscopio de hilos cruzados por defecto" -#: src/dialogs/confdialog.cxx:4960 +#: src/dialogs/confdialog.cxx:5054 msgid "Pseudo-FSK on right audio channel" msgstr "Seudo-FSK en el canal derecho de audio" -#: src/dialogs/confdialog.cxx:4961 +#: src/dialogs/confdialog.cxx:5055 msgid "Create square wave on right channel" msgstr "Crear una onda cuadrada en el canal derecho de audio" -#: src/dialogs/confdialog.cxx:4966 +#: src/dialogs/confdialog.cxx:5060 msgid "AFC speed" msgstr "Vel. del AFC" -#: src/dialogs/confdialog.cxx:4967 +#: src/dialogs/confdialog.cxx:5061 msgid "AFC tracking speed" msgstr "Velocidad de rastreo del AFC" -#: src/dialogs/confdialog.cxx:4974 +#: src/dialogs/confdialog.cxx:5068 msgid "X-agc (hidden)" msgstr "X-agc (oculto)" -#: src/dialogs/confdialog.cxx:5001 +#: src/dialogs/confdialog.cxx:5095 msgid "Custom shift" msgstr "Salto ajustado" -#: src/dialogs/confdialog.cxx:5002 +#: src/dialogs/confdialog.cxx:5096 msgid "Input carrier shift" msgstr "Salto de la portadora" -#: src/dialogs/confdialog.cxx:5024 +#: src/dialogs/confdialog.cxx:5118 msgid "Thor" msgstr "Thor" -#: src/dialogs/confdialog.cxx:5044 +#: src/dialogs/confdialog.cxx:5138 msgid "Enable DSP prior to decoder" msgstr "Activar el DSP antes del decodificador" -#: src/dialogs/confdialog.cxx:5114 +#: src/dialogs/confdialog.cxx:5208 msgid "Rig" msgstr "Radio" -#: src/dialogs/confdialog.cxx:5115 +#: src/dialogs/confdialog.cxx:5209 msgid "Transceiver control" msgstr "Control del transceptor" -#: src/dialogs/confdialog.cxx:5119 +#: src/dialogs/confdialog.cxx:5213 msgid "Hardware PTT" msgstr "PTT real" -#: src/dialogs/confdialog.cxx:5121 +#: src/dialogs/confdialog.cxx:5215 msgid "h/w ptt device-pin" msgstr "Pin del dispositivo PTT" -#: src/dialogs/confdialog.cxx:5124 -#: src/dialogs/confdialog.cxx:5200 -#: src/dialogs/confdialog.cxx:5367 -#: src/dialogs/confdialog.cxx:5621 -#: src/dialogs/confdialog.cxx:5791 +#: src/dialogs/confdialog.cxx:5218 +#: src/dialogs/confdialog.cxx:5294 +#: src/dialogs/confdialog.cxx:5461 +#: src/dialogs/confdialog.cxx:5715 +#: src/dialogs/confdialog.cxx:5885 msgid "Device:" msgstr "Dispositivo:" -#: src/dialogs/confdialog.cxx:5125 +#: src/dialogs/confdialog.cxx:5219 msgid "Select serial port" msgstr "Seleccione el puerto serie" -#: src/dialogs/confdialog.cxx:5128 +#: src/dialogs/confdialog.cxx:5222 msgid "Use RTS" msgstr "Use RTS" -#: src/dialogs/confdialog.cxx:5129 +#: src/dialogs/confdialog.cxx:5223 msgid "RTS is PTT signal line" msgstr "RTS es PTT" -#: src/dialogs/confdialog.cxx:5133 +#: src/dialogs/confdialog.cxx:5227 msgid "RTS = +V" msgstr "RTS = +V" -#: src/dialogs/confdialog.cxx:5134 +#: src/dialogs/confdialog.cxx:5228 msgid "Initial voltage on RTS" msgstr "Voltaje inicial en RTS" -#: src/dialogs/confdialog.cxx:5138 +#: src/dialogs/confdialog.cxx:5232 msgid "Use DTR" msgstr "Use DTR" -#: src/dialogs/confdialog.cxx:5139 +#: src/dialogs/confdialog.cxx:5233 msgid "DTR is PTT signal line" msgstr "DTR es PTT" -#: src/dialogs/confdialog.cxx:5143 +#: src/dialogs/confdialog.cxx:5237 msgid "DTR = +V" msgstr "DTR = +V" -#: src/dialogs/confdialog.cxx:5144 +#: src/dialogs/confdialog.cxx:5238 msgid "Initial voltage on DTR" msgstr "Voltaje inicial en DTR" -#: src/dialogs/confdialog.cxx:5148 -#: src/dialogs/confdialog.cxx:5281 -#: src/dialogs/confdialog.cxx:5501 -#: src/dialogs/confdialog.cxx:5572 +#: src/dialogs/confdialog.cxx:5242 +#: src/dialogs/confdialog.cxx:5375 #: src/dialogs/confdialog.cxx:5595 -#: src/dialogs/confdialog.cxx:6266 +#: src/dialogs/confdialog.cxx:5666 +#: src/dialogs/confdialog.cxx:5689 +#: src/dialogs/confdialog.cxx:6360 msgid "Initialize" msgstr "Inicializar" -#: src/dialogs/confdialog.cxx:5149 +#: src/dialogs/confdialog.cxx:5243 msgid "Initialize the H/W PTT interface" msgstr "Inicialice el interfaz de HW para PTT" -#: src/dialogs/confdialog.cxx:5152 +#: src/dialogs/confdialog.cxx:5246 msgid "Use separate serial port PTT" msgstr "Utilice un PTT por puerto serie separado" -#: src/dialogs/confdialog.cxx:5157 +#: src/dialogs/confdialog.cxx:5251 msgid "Use parallel port PTT" msgstr "Utilice un PTT por puerto paralelo" -#: src/dialogs/confdialog.cxx:5162 +#: src/dialogs/confdialog.cxx:5256 msgid "Use uHRouter PTT" msgstr "Utilice PTT uHRouter" -#: src/dialogs/confdialog.cxx:5171 +#: src/dialogs/confdialog.cxx:5265 msgid "PTT tone on right audio channel " msgstr "Tono para PTT en el canar derecho de audio" -#: src/dialogs/confdialog.cxx:5172 +#: src/dialogs/confdialog.cxx:5266 msgid "Can be used in lieu of or in addition to other PTT types" msgstr "Puede ser usado en vez de o en adición de otros tipos de PTT" -#: src/dialogs/confdialog.cxx:5181 +#: src/dialogs/confdialog.cxx:5275 msgid "RigCAT" msgstr "RigCAT" -#: src/dialogs/confdialog.cxx:5182 +#: src/dialogs/confdialog.cxx:5276 msgid "Rig Control using xml spec file" msgstr "Control del radio usando un fichero xml" -#: src/dialogs/confdialog.cxx:5183 +#: src/dialogs/confdialog.cxx:5277 msgid "Use RigCAT" msgstr "Use RigCAT" -#: src/dialogs/confdialog.cxx:5184 +#: src/dialogs/confdialog.cxx:5278 msgid "RigCAT used for rig control" msgstr "Usar RigCAT para el control del radio" -#: src/dialogs/confdialog.cxx:5190 +#: src/dialogs/confdialog.cxx:5284 msgid "Rig description file:" msgstr "Fichero de descripción del radio:" -#: src/dialogs/confdialog.cxx:5191 +#: src/dialogs/confdialog.cxx:5285 msgid "Use Open to select descriptor file" msgstr "Usar Abrir para seleccionar un fichero descriptor" -#: src/dialogs/confdialog.cxx:5197 +#: src/dialogs/confdialog.cxx:5291 msgid "Select rig descriptor file" msgstr "Seleccionar un fichero descriptor del Radio" -#: src/dialogs/confdialog.cxx:5201 +#: src/dialogs/confdialog.cxx:5295 msgid "Serial device" msgstr "Dispositivo serie" -#: src/dialogs/confdialog.cxx:5205 -#: src/dialogs/confdialog.cxx:5372 +#: src/dialogs/confdialog.cxx:5299 +#: src/dialogs/confdialog.cxx:5466 msgid "Retries" msgstr "Reintentos" -#: src/dialogs/confdialog.cxx:5206 +#: src/dialogs/confdialog.cxx:5300 msgid "# retries before giving up" msgstr "# de reintentos antes de rendirnos" -#: src/dialogs/confdialog.cxx:5222 -#: src/dialogs/confdialog.cxx:5466 +#: src/dialogs/confdialog.cxx:5316 +#: src/dialogs/confdialog.cxx:5560 msgid "Retry interval (ms)" msgstr "Internvalo de reintentos (ms)" -#: src/dialogs/confdialog.cxx:5223 +#: src/dialogs/confdialog.cxx:5317 msgid "Time between retires in msec" msgstr "Tiempo entre reintentos (ms)" -#: src/dialogs/confdialog.cxx:5239 -#: src/dialogs/confdialog.cxx:5406 +#: src/dialogs/confdialog.cxx:5333 +#: src/dialogs/confdialog.cxx:5500 msgid "Write delay (ms)" msgstr "Ret. escritura (ms)" -#: src/dialogs/confdialog.cxx:5255 -#: src/dialogs/confdialog.cxx:5440 +#: src/dialogs/confdialog.cxx:5349 +#: src/dialogs/confdialog.cxx:5534 msgid "Baud rate:" msgstr "Tasa de baudios:" -#: src/dialogs/confdialog.cxx:5256 +#: src/dialogs/confdialog.cxx:5350 msgid "Pick baud rate from list" msgstr "Seleccionar la tasa de baudios desde la lista" -#: src/dialogs/confdialog.cxx:5262 -#: src/dialogs/confdialog.cxx:5447 +#: src/dialogs/confdialog.cxx:5356 +#: src/dialogs/confdialog.cxx:5541 msgid "Stopbits" msgstr "Bits de parada" -#: src/dialogs/confdialog.cxx:5282 +#: src/dialogs/confdialog.cxx:5376 msgid "Initialize RigCAT interface" msgstr "Inicializar la interfaz RigCAT" -#: src/dialogs/confdialog.cxx:5285 +#: src/dialogs/confdialog.cxx:5379 msgid "Commands are echoed" msgstr "Los comandos tienen eco" -#: src/dialogs/confdialog.cxx:5286 +#: src/dialogs/confdialog.cxx:5380 msgid "Rig or interface echos serial data" msgstr "El radio o la interface repite los datos enviados" -#: src/dialogs/confdialog.cxx:5291 +#: src/dialogs/confdialog.cxx:5385 msgid "CAT command for PTT" msgstr "Comandos CAT para el PTT" -#: src/dialogs/confdialog.cxx:5292 +#: src/dialogs/confdialog.cxx:5386 msgid "PTT is a CAT command (not hardware)" msgstr "El PTT es un comando CAT" -#: src/dialogs/confdialog.cxx:5298 +#: src/dialogs/confdialog.cxx:5392 msgid "Toggle RTS for PTT" msgstr "Activar RTS para PTT" -#: src/dialogs/confdialog.cxx:5299 +#: src/dialogs/confdialog.cxx:5393 msgid "RTS is ptt line" msgstr "RTS es la línea de PTT" -#: src/dialogs/confdialog.cxx:5304 +#: src/dialogs/confdialog.cxx:5398 msgid "Toggle DTR for PTT" msgstr "Activar DTR para PTT" -#: src/dialogs/confdialog.cxx:5305 +#: src/dialogs/confdialog.cxx:5399 msgid "DTR is ptt line" msgstr "DTR es la línea de PTT" -#: src/dialogs/confdialog.cxx:5310 +#: src/dialogs/confdialog.cxx:5404 msgid "RTS +12 v" msgstr "RTS +12 v" -#: src/dialogs/confdialog.cxx:5311 -#: src/dialogs/confdialog.cxx:5524 +#: src/dialogs/confdialog.cxx:5405 +#: src/dialogs/confdialog.cxx:5618 msgid "Initial state of RTS" msgstr "Estado inicial de RTS" -#: src/dialogs/confdialog.cxx:5316 +#: src/dialogs/confdialog.cxx:5410 msgid "DTR +12 v" msgstr "DTR +12 v" -#: src/dialogs/confdialog.cxx:5317 -#: src/dialogs/confdialog.cxx:5518 +#: src/dialogs/confdialog.cxx:5411 +#: src/dialogs/confdialog.cxx:5612 msgid "Initial state of DTR" msgstr "Estado inicial de DTR" -#: src/dialogs/confdialog.cxx:5322 -#: src/dialogs/confdialog.cxx:5529 +#: src/dialogs/confdialog.cxx:5416 +#: src/dialogs/confdialog.cxx:5623 msgid "RTS/CTS flow control" msgstr "Control de flujo RTS/CTS" -#: src/dialogs/confdialog.cxx:5323 +#: src/dialogs/confdialog.cxx:5417 msgid "Rig uses RTS/CTS handshake" msgstr "El radio usa RTS/CTS para comunicarse" -#: src/dialogs/confdialog.cxx:5328 -#: src/dialogs/confdialog.cxx:5542 +#: src/dialogs/confdialog.cxx:5422 +#: src/dialogs/confdialog.cxx:5636 msgid "Revert" msgstr "Revertir" -#: src/dialogs/confdialog.cxx:5329 -#: src/dialogs/confdialog.cxx:5502 -#: src/dialogs/confdialog.cxx:5543 +#: src/dialogs/confdialog.cxx:5423 +#: src/dialogs/confdialog.cxx:5596 +#: src/dialogs/confdialog.cxx:5637 msgid "Initialize hamlib interface" msgstr "Inicialice la interfaz Hamlib" -#: src/dialogs/confdialog.cxx:5333 +#: src/dialogs/confdialog.cxx:5427 msgid "VSP Enable" msgstr "VSP Activado" -#: src/dialogs/confdialog.cxx:5334 +#: src/dialogs/confdialog.cxx:5428 msgid "Virtual Serial Port Emulator - suppress WARNINGS" msgstr "Emulador Serie Virtual - Suprimir ADVERTENCIAS" -#: src/dialogs/confdialog.cxx:5343 +#: src/dialogs/confdialog.cxx:5437 msgid "Hamlib" msgstr "Hamlib" -#: src/dialogs/confdialog.cxx:5345 +#: src/dialogs/confdialog.cxx:5439 msgid "Use Hamlib" msgstr "Usar Hamlib" -#: src/dialogs/confdialog.cxx:5346 +#: src/dialogs/confdialog.cxx:5440 msgid "Hamlib used for rig control" msgstr "Utilice Hamlib para controlar el radio" -#: src/dialogs/confdialog.cxx:5352 +#: src/dialogs/confdialog.cxx:5446 msgid "Rig:" msgstr "Radio:" -#: src/dialogs/confdialog.cxx:5353 +#: src/dialogs/confdialog.cxx:5447 msgid "Select the rig by name" msgstr "Seleccione el radio por su nombre" -#: src/dialogs/confdialog.cxx:5368 +#: src/dialogs/confdialog.cxx:5462 msgid "Serial port" msgstr "Puerto serie" -#: src/dialogs/confdialog.cxx:5373 +#: src/dialogs/confdialog.cxx:5467 msgid "# times to resend command before giving up" msgstr "# de veces para renvio de comandos antes de rendirnos" -#: src/dialogs/confdialog.cxx:5389 +#: src/dialogs/confdialog.cxx:5483 msgid "Retry Interval (ms)" msgstr "Reintentos cada (ms)" -#: src/dialogs/confdialog.cxx:5390 -#: src/dialogs/confdialog.cxx:5467 +#: src/dialogs/confdialog.cxx:5484 +#: src/dialogs/confdialog.cxx:5561 msgid "Msec's between retries" msgstr "Milisegundos entre reintentos" -#: src/dialogs/confdialog.cxx:5407 +#: src/dialogs/confdialog.cxx:5501 msgid "Msec's between sequential commands" msgstr "Milisegundos entre comandos secuenciales" -#: src/dialogs/confdialog.cxx:5423 +#: src/dialogs/confdialog.cxx:5517 msgid "Post write delay (ms)" msgstr "Ret. post-envío (ms)" -#: src/dialogs/confdialog.cxx:5424 +#: src/dialogs/confdialog.cxx:5518 msgid "Wait interval (msecs) before reading response" msgstr "Intervalo de espera (ms) antes de leer la espuesta" -#: src/dialogs/confdialog.cxx:5441 +#: src/dialogs/confdialog.cxx:5535 msgid "Serial port baud rate" msgstr "Tasa de baudios del puerto serie" -#: src/dialogs/confdialog.cxx:5486 +#: src/dialogs/confdialog.cxx:5580 msgid "Advanced configuration:" msgstr "Configuración avanzada:" -#: src/dialogs/confdialog.cxx:5487 +#: src/dialogs/confdialog.cxx:5581 msgid "" "Optional configuration\n" "in format: param=val ..." @@ -3890,11 +3969,11 @@ msgstr "" "Configuración opcional\n" "en el formato: parámetro=valor..." -#: src/dialogs/confdialog.cxx:5505 +#: src/dialogs/confdialog.cxx:5599 msgid "Sideband:" msgstr "Banda lateral:" -#: src/dialogs/confdialog.cxx:5506 +#: src/dialogs/confdialog.cxx:5600 msgid "" "Force the rig sideband. Takes\n" "effect when rig mode changes." @@ -3902,39 +3981,39 @@ msgstr "" "Forzar el lateral del radio. Entra en efecto\n" "cuando el radio cambia de modo." -#: src/dialogs/confdialog.cxx:5510 +#: src/dialogs/confdialog.cxx:5604 msgid "PTT via Hamlib command" msgstr "PTT como comando de Hamlib" -#: src/dialogs/confdialog.cxx:5511 +#: src/dialogs/confdialog.cxx:5605 msgid "PTT is a hamlib command" msgstr "PTT es un comando de Hamlib" -#: src/dialogs/confdialog.cxx:5517 +#: src/dialogs/confdialog.cxx:5611 msgid "DTR +12" msgstr "DTR +12" -#: src/dialogs/confdialog.cxx:5523 +#: src/dialogs/confdialog.cxx:5617 msgid "RTS +12" msgstr "RTS +12" -#: src/dialogs/confdialog.cxx:5530 +#: src/dialogs/confdialog.cxx:5624 msgid "Rig requires RTS/CTS flow control" msgstr "El radio requiere control de flujo RTS/CTS" -#: src/dialogs/confdialog.cxx:5536 +#: src/dialogs/confdialog.cxx:5630 msgid "XON/XOFF flow control" msgstr "Control de flujo Xon/Xoff" -#: src/dialogs/confdialog.cxx:5537 +#: src/dialogs/confdialog.cxx:5631 msgid "Rig requires Xon/Xoff flow control" msgstr "El radio requiere control de flujo Xon/Xoff" -#: src/dialogs/confdialog.cxx:5551 +#: src/dialogs/confdialog.cxx:5645 msgid "MemMap" msgstr "MemMap" -#: src/dialogs/confdialog.cxx:5559 +#: src/dialogs/confdialog.cxx:5653 msgid "" "Control via Memory Mapped\n" "shared variables\n" @@ -3944,27 +4023,27 @@ msgstr "" "en memoria con variables\n" "compartidas: Kachina" -#: src/dialogs/confdialog.cxx:5561 +#: src/dialogs/confdialog.cxx:5655 msgid "Use Memmap" msgstr "Usar Memmap" -#: src/dialogs/confdialog.cxx:5562 +#: src/dialogs/confdialog.cxx:5656 msgid "Rig control via memory mapped Kachina" msgstr "Radio mapeado via memoria (Kachina)" -#: src/dialogs/confdialog.cxx:5567 +#: src/dialogs/confdialog.cxx:5661 msgid "Use Memmap PTT" msgstr "Usar PTT Memmap" -#: src/dialogs/confdialog.cxx:5573 +#: src/dialogs/confdialog.cxx:5667 msgid "Initialize Memmap interface" msgstr "Inicializar interface Memmap" -#: src/dialogs/confdialog.cxx:5580 +#: src/dialogs/confdialog.cxx:5674 msgid "XML-RPC" msgstr "XML-RPC" -#: src/dialogs/confdialog.cxx:5588 +#: src/dialogs/confdialog.cxx:5682 msgid "" "Rig control via external\n" "program using xmlrpc\n" @@ -3974,75 +4053,75 @@ msgstr "" "programa externo\n" "usando XML-RPC" -#: src/dialogs/confdialog.cxx:5590 +#: src/dialogs/confdialog.cxx:5684 msgid "Use XML-RPC program" msgstr "Usar un programa XML-RPC" -#: src/dialogs/confdialog.cxx:5591 +#: src/dialogs/confdialog.cxx:5685 msgid "Experimental" msgstr "Experimental" -#: src/dialogs/confdialog.cxx:5596 +#: src/dialogs/confdialog.cxx:5690 msgid "Initialize XML-RPC rig control" msgstr "Inicializar el control por XML-RPC" -#: src/dialogs/confdialog.cxx:5608 +#: src/dialogs/confdialog.cxx:5702 msgid "Audio devices" msgstr "Dispositivo de audio" -#: src/dialogs/confdialog.cxx:5612 +#: src/dialogs/confdialog.cxx:5706 msgid "Devices" msgstr "Dispositivos" -#: src/dialogs/confdialog.cxx:5615 +#: src/dialogs/confdialog.cxx:5709 msgid "OSS" msgstr "OSS" -#: src/dialogs/confdialog.cxx:5616 +#: src/dialogs/confdialog.cxx:5710 msgid "Use OSS audio server" msgstr "Usar servidor de audio OSS" -#: src/dialogs/confdialog.cxx:5622 +#: src/dialogs/confdialog.cxx:5716 msgid "Select device" msgstr "Seleccionar dispositivo" -#: src/dialogs/confdialog.cxx:5630 +#: src/dialogs/confdialog.cxx:5724 msgid "PortAudio" msgstr "PortAudio" -#: src/dialogs/confdialog.cxx:5631 +#: src/dialogs/confdialog.cxx:5725 msgid "Use Port Audio server" msgstr "Usar servidor PortAudio" -#: src/dialogs/confdialog.cxx:5636 +#: src/dialogs/confdialog.cxx:5730 msgid "Capture:" msgstr "Captura:" -#: src/dialogs/confdialog.cxx:5637 +#: src/dialogs/confdialog.cxx:5731 msgid "Audio input device" msgstr "Dispositivo de entrada de audio" -#: src/dialogs/confdialog.cxx:5641 +#: src/dialogs/confdialog.cxx:5735 msgid "Playback:" msgstr "Reproducción:" -#: src/dialogs/confdialog.cxx:5642 +#: src/dialogs/confdialog.cxx:5736 msgid "Audio output device" msgstr "Dispositivo de salida de audio" -#: src/dialogs/confdialog.cxx:5650 +#: src/dialogs/confdialog.cxx:5744 msgid "PulseAudio" msgstr "PulseAudio" -#: src/dialogs/confdialog.cxx:5651 +#: src/dialogs/confdialog.cxx:5745 msgid "Use Pulse Audio server" msgstr "Usar servidor PulseAudio" -#: src/dialogs/confdialog.cxx:5656 +#: src/dialogs/confdialog.cxx:5750 msgid "Server string:" msgstr "Servidor:" -#: src/dialogs/confdialog.cxx:5657 +#: src/dialogs/confdialog.cxx:5751 msgid "" "Leave this blank or refer to\n" "http://www.pulseaudio.org/wiki/ServerStrings" @@ -4051,27 +4130,27 @@ msgstr "" "referirse a http://www.pulseaudio.org/wiki/ServerStrings\n" "para más detalles" -#: src/dialogs/confdialog.cxx:5675 +#: src/dialogs/confdialog.cxx:5769 msgid "File I/O only" msgstr "Solo E/S desde fichero" -#: src/dialogs/confdialog.cxx:5676 +#: src/dialogs/confdialog.cxx:5770 msgid "NO AUDIO DEVICE AVAILABLE (or testing)" msgstr "NO HAY DISPOSITIVO DE AUDIO DISPONIBLE (o estas probando?)" -#: src/dialogs/confdialog.cxx:5685 +#: src/dialogs/confdialog.cxx:5779 msgid "Settings" msgstr "Configuraciones" -#: src/dialogs/confdialog.cxx:5687 +#: src/dialogs/confdialog.cxx:5781 msgid "Sample rate" msgstr "Tasa de muestreo" -#: src/dialogs/confdialog.cxx:5690 +#: src/dialogs/confdialog.cxx:5784 msgid "Capture" msgstr "Captura" -#: src/dialogs/confdialog.cxx:5691 +#: src/dialogs/confdialog.cxx:5785 msgid "" "Force a specific sample rate. Select \"Native\" if \"Auto\"\n" "does not work well with your audio device." @@ -4079,131 +4158,131 @@ msgstr "" "Forzar una taza de muestreo. Seleccionar \"Nativo\" si \"Auto\"\n" "no trabaja bien con tu dispositivo de audio." -#: src/dialogs/confdialog.cxx:5709 +#: src/dialogs/confdialog.cxx:5803 msgid "Converter" msgstr "Convertidor" -#: src/dialogs/confdialog.cxx:5710 +#: src/dialogs/confdialog.cxx:5804 msgid "Set the type of resampler used of offset correction" msgstr "Establecer el tipo de re-muestreo usado para correcciones" -#: src/dialogs/confdialog.cxx:5717 +#: src/dialogs/confdialog.cxx:5811 msgid "Corrections" msgstr "Correcciones" -#: src/dialogs/confdialog.cxx:5720 +#: src/dialogs/confdialog.cxx:5814 msgid "RX ppm" msgstr "RX ppm" -#: src/dialogs/confdialog.cxx:5721 +#: src/dialogs/confdialog.cxx:5815 msgid "RX sound card correction" msgstr "Corrección de RX en el dispositivo de audio" -#: src/dialogs/confdialog.cxx:5737 +#: src/dialogs/confdialog.cxx:5831 msgid "TX ppm" msgstr "TX ppm" -#: src/dialogs/confdialog.cxx:5738 +#: src/dialogs/confdialog.cxx:5832 msgid "TX sound card correction" msgstr "Corrección de TX en el dispositivo de audio" -#: src/dialogs/confdialog.cxx:5754 +#: src/dialogs/confdialog.cxx:5848 msgid "TX offset" msgstr "Dif. en Tx" -#: src/dialogs/confdialog.cxx:5755 +#: src/dialogs/confdialog.cxx:5849 msgid "Difference between Rx & Tx freq (rig offset)" msgstr "Diferencias entre frecuencias de Rx y Tx (en el radio)" -#: src/dialogs/confdialog.cxx:5773 +#: src/dialogs/confdialog.cxx:5867 msgid "Enable right audio channel" msgstr "Activar el canal derecho de audio" -#: src/dialogs/confdialog.cxx:5780 +#: src/dialogs/confdialog.cxx:5874 msgid "Mixer" msgstr "Mezclador" -#: src/dialogs/confdialog.cxx:5782 +#: src/dialogs/confdialog.cxx:5876 msgid "OSS mixer" msgstr "Mezclador OSS" -#: src/dialogs/confdialog.cxx:5785 +#: src/dialogs/confdialog.cxx:5879 msgid "Manage mixer" msgstr "Manejar el mezclador" -#: src/dialogs/confdialog.cxx:5786 +#: src/dialogs/confdialog.cxx:5880 msgid "Add mixer controls to main dialog" msgstr "Añadir controles del mezclador a la interface principal" -#: src/dialogs/confdialog.cxx:5792 +#: src/dialogs/confdialog.cxx:5886 msgid "Select Mixer device" msgstr "Seleccionar dispositivo de mezcla" -#: src/dialogs/confdialog.cxx:5796 +#: src/dialogs/confdialog.cxx:5890 msgid "Mic In" msgstr "Mic In" -#: src/dialogs/confdialog.cxx:5797 +#: src/dialogs/confdialog.cxx:5891 msgid "Use microphone input" msgstr "Usar entrada de micrófono" -#: src/dialogs/confdialog.cxx:5800 +#: src/dialogs/confdialog.cxx:5894 msgid "Line In" msgstr "Line In" -#: src/dialogs/confdialog.cxx:5801 +#: src/dialogs/confdialog.cxx:5895 msgid "Use Line-In device" msgstr "Usar dispositivo Line-in" -#: src/dialogs/confdialog.cxx:5805 +#: src/dialogs/confdialog.cxx:5899 msgid "PCM" msgstr "PCM" -#: src/dialogs/confdialog.cxx:5806 +#: src/dialogs/confdialog.cxx:5900 msgid "Set the sound card PCM level" msgstr "Establecer el volumen PCM de la tarjeta" -#: src/dialogs/confdialog.cxx:5826 +#: src/dialogs/confdialog.cxx:5920 msgid "TxLevel" msgstr "Nivel TX" -#: src/dialogs/confdialog.cxx:5828 +#: src/dialogs/confdialog.cxx:5922 msgid "Tx Attenuator" msgstr "Atenuación TX" -#: src/dialogs/confdialog.cxx:5831 +#: src/dialogs/confdialog.cxx:5925 msgid "Tx Atten (dB)" msgstr "Aten. Tx (dB)" -#: src/dialogs/confdialog.cxx:5847 +#: src/dialogs/confdialog.cxx:5941 msgid "ID" msgstr "ID" -#: src/dialogs/confdialog.cxx:5849 +#: src/dialogs/confdialog.cxx:5943 msgid "Video Preamble ID" msgstr "Preámbulo de Video ID" -#: src/dialogs/confdialog.cxx:5852 +#: src/dialogs/confdialog.cxx:5946 msgid "Transmit mode ID" msgstr "Transmitir el ID del modo" -#: src/dialogs/confdialog.cxx:5853 +#: src/dialogs/confdialog.cxx:5947 msgid "Waterfall video ID" msgstr "Video ID en la cascada" -#: src/dialogs/confdialog.cxx:5857 +#: src/dialogs/confdialog.cxx:5951 msgid "Transmit video text" msgstr "Transmitir el Video Texto" -#: src/dialogs/confdialog.cxx:5858 +#: src/dialogs/confdialog.cxx:5952 msgid "Waterfall video text" msgstr "Video Texto en la cascada" -#: src/dialogs/confdialog.cxx:5863 +#: src/dialogs/confdialog.cxx:5957 msgid ":" msgstr ":" -#: src/dialogs/confdialog.cxx:5864 +#: src/dialogs/confdialog.cxx:5958 msgid "" "Limit to a few characters,\n" "as in CQEM or IOTA etc." @@ -4211,11 +4290,11 @@ msgstr "" "Limitar a unos pocos caracteres\n" "Como en CQEM o IOTA etc." -#: src/dialogs/confdialog.cxx:5878 +#: src/dialogs/confdialog.cxx:5972 msgid "Use small font" msgstr "Usar tipografía pequeña" -#: src/dialogs/confdialog.cxx:5879 +#: src/dialogs/confdialog.cxx:5973 msgid "" "ON - small font\n" "OFF - large font" @@ -4223,59 +4302,59 @@ msgstr "" "On - Tipografía pequeña\n" "OFF - Tipografía grande" -#: src/dialogs/confdialog.cxx:5885 +#: src/dialogs/confdialog.cxx:5979 msgid "Chars/Row:" msgstr "Carac/Fila:" -#: src/dialogs/confdialog.cxx:5886 +#: src/dialogs/confdialog.cxx:5980 msgid "Set the number of characters per row" msgstr "Establecer el número de caracteres por fila" -#: src/dialogs/confdialog.cxx:5906 +#: src/dialogs/confdialog.cxx:6000 msgid "500 Hz limit" msgstr "Límite de 500 Hz" -#: src/dialogs/confdialog.cxx:5911 +#: src/dialogs/confdialog.cxx:6005 msgid "Mode width limit" msgstr "Límite del Modo" -#: src/dialogs/confdialog.cxx:5916 +#: src/dialogs/confdialog.cxx:6010 msgid "Video ID modes" msgstr "Modos de Video ID" -#: src/dialogs/confdialog.cxx:5921 +#: src/dialogs/confdialog.cxx:6015 msgid "CW Postamble ID" msgstr "Post-ámbulo de ID de CW" -#: src/dialogs/confdialog.cxx:5924 +#: src/dialogs/confdialog.cxx:6018 msgid "Transmit callsign" msgstr "Transmitir indicativo" -#: src/dialogs/confdialog.cxx:5925 +#: src/dialogs/confdialog.cxx:6019 msgid "Send Callsign in CW at end of every transmission" msgstr "Enviar tu indicativo en CW al finalizar cada Tx" -#: src/dialogs/confdialog.cxx:5930 +#: src/dialogs/confdialog.cxx:6024 msgid "Speed (WPM):" msgstr "Velocidad (WPM):" -#: src/dialogs/confdialog.cxx:5931 +#: src/dialogs/confdialog.cxx:6025 msgid "Send at this WPM" msgstr "Enviar a este WPM" -#: src/dialogs/confdialog.cxx:5951 +#: src/dialogs/confdialog.cxx:6045 msgid "CW ID modes" msgstr "Modos con CW ID" -#: src/dialogs/confdialog.cxx:5956 +#: src/dialogs/confdialog.cxx:6050 msgid "Reed-Solomon ID (Rx)" msgstr "Reed-Solomon ID (Rx)" -#: src/dialogs/confdialog.cxx:5959 +#: src/dialogs/confdialog.cxx:6053 msgid "Detector searches entire passband" msgstr "El detector busca en todo el pasabanda" -#: src/dialogs/confdialog.cxx:5960 +#: src/dialogs/confdialog.cxx:6054 msgid "" "ON - search over entire waterfall\n" "OFF - limit search to +/- 200 Hz" @@ -4283,11 +4362,11 @@ msgstr "" "ON - Buscar en toda cascada\n" "OFF - Limitar la búsqueda a +/- 200 Hz" -#: src/dialogs/confdialog.cxx:5965 +#: src/dialogs/confdialog.cxx:6059 msgid "Mark previous frequency and mode" msgstr "Marcar la frecuencia y modos anteriores" -#: src/dialogs/confdialog.cxx:5966 +#: src/dialogs/confdialog.cxx:6060 msgid "" "Insert RX text marker before\n" "changing frequency and modem" @@ -4295,19 +4374,19 @@ msgstr "" "Insertar el marcador de texto en el panel de Rx\n" "antes de cambiar la frecuencia y el modem" -#: src/dialogs/confdialog.cxx:5971 +#: src/dialogs/confdialog.cxx:6065 msgid "Reception disables detector" msgstr "La recepción deshabilita el detector" -#: src/dialogs/confdialog.cxx:5972 +#: src/dialogs/confdialog.cxx:6066 msgid "Disable further detection when RSID is received" msgstr "Desactivar la detección futura cuando un RSID es recibido" -#: src/dialogs/confdialog.cxx:5979 +#: src/dialogs/confdialog.cxx:6073 msgid "Notifications only" msgstr "Notificaciones solamente" -#: src/dialogs/confdialog.cxx:5980 +#: src/dialogs/confdialog.cxx:6074 msgid "" "Check this to be notified when an RSID is received\n" "without changing modem and frequency" @@ -4315,233 +4394,233 @@ msgstr "" "Marcar aquí para ser notificado cuando un RSID es recibido\n" "sin cambiar el modem y la frecuencia" -#: src/dialogs/confdialog.cxx:5986 +#: src/dialogs/confdialog.cxx:6080 msgid "Receive modes" msgstr "Modos de RX" -#: src/dialogs/confdialog.cxx:5989 +#: src/dialogs/confdialog.cxx:6083 msgid "Squelch open (sec)" msgstr "Silenciado abierto (s)" -#: src/dialogs/confdialog.cxx:5990 +#: src/dialogs/confdialog.cxx:6084 msgid "Open squelch for nn sec if RSID detected" msgstr "Abrir el silenciador por nn segundos si se detecta RSID" -#: src/dialogs/confdialog.cxx:6010 +#: src/dialogs/confdialog.cxx:6104 msgid "Reed-Solomon ID (Tx)" msgstr "Reed-Solomon ID (Tx)" -#: src/dialogs/confdialog.cxx:6013 +#: src/dialogs/confdialog.cxx:6107 msgid "Transmit modes" msgstr "Modos de TX" -#: src/dialogs/confdialog.cxx:6018 +#: src/dialogs/confdialog.cxx:6112 msgid "Pre-Signal Tone" msgstr "Tono pre-señal" -#: src/dialogs/confdialog.cxx:6021 +#: src/dialogs/confdialog.cxx:6115 msgid "Seconds" msgstr "Segundos" -#: src/dialogs/confdialog.cxx:6022 +#: src/dialogs/confdialog.cxx:6116 msgid "Use for triggering amplifier carrier detect" msgstr "Usado para disparar amplificadores que detectan carrier" -#: src/dialogs/confdialog.cxx:6036 +#: src/dialogs/confdialog.cxx:6130 msgid "CPU" msgstr "CPU" -#: src/dialogs/confdialog.cxx:6040 +#: src/dialogs/confdialog.cxx:6134 msgid "Slow CPU (less than 700MHz)" msgstr "CPU lenta (Menos de 700Mhz)" -#: src/dialogs/confdialog.cxx:6041 +#: src/dialogs/confdialog.cxx:6135 msgid "Enable if you're computer does not decode properly" msgstr "Activar si tu computadora no decodifica correctamente" -#: src/dialogs/confdialog.cxx:6050 +#: src/dialogs/confdialog.cxx:6144 msgid "NBEMS" msgstr "NBEMS" -#: src/dialogs/confdialog.cxx:6052 +#: src/dialogs/confdialog.cxx:6146 msgid "NBEMS data file interface" msgstr "Interface de datos NBEMS" -#: src/dialogs/confdialog.cxx:6055 +#: src/dialogs/confdialog.cxx:6149 msgid "Enable" msgstr "Activar" -#: src/dialogs/confdialog.cxx:6056 +#: src/dialogs/confdialog.cxx:6150 msgid "Extract files for use with external \"wrap / flmsg\" program" msgstr "Extraer archivos para usar con programas externos (wrap/flmsg)" -#: src/dialogs/confdialog.cxx:6061 +#: src/dialogs/confdialog.cxx:6155 msgid "Open message folder" msgstr "Abrir carpeta de mensajes" -#: src/dialogs/confdialog.cxx:6062 +#: src/dialogs/confdialog.cxx:6156 msgid "Opens NBEMS file folder upon successful capture" msgstr "Abrir la carpeta de NBEMS cuando capture ok" -#: src/dialogs/confdialog.cxx:6069 +#: src/dialogs/confdialog.cxx:6163 msgid "Reception of flmsg file" msgstr "Recepción de un fichero en flmsg" -#: src/dialogs/confdialog.cxx:6072 +#: src/dialogs/confdialog.cxx:6166 msgid "Open with flmsg" msgstr "Abrir con flmsg" -#: src/dialogs/confdialog.cxx:6073 +#: src/dialogs/confdialog.cxx:6167 msgid "Open message with flmsg" msgstr "Abrir mensaje con flmsg" -#: src/dialogs/confdialog.cxx:6078 +#: src/dialogs/confdialog.cxx:6172 msgid "flmsg:" msgstr "flmsg:" -#: src/dialogs/confdialog.cxx:6079 +#: src/dialogs/confdialog.cxx:6173 msgid "Enter full path-filename for flmsg" msgstr "Entre camino y nombre hasta el ejecutable de flmsg" -#: src/dialogs/confdialog.cxx:6092 +#: src/dialogs/confdialog.cxx:6186 msgid "Locate flmsg" msgstr "Buscar flmsg" -#: src/dialogs/confdialog.cxx:6096 +#: src/dialogs/confdialog.cxx:6190 msgid "Open in browser" msgstr "Abrir en el navegador por defecto" -#: src/dialogs/confdialog.cxx:6097 +#: src/dialogs/confdialog.cxx:6191 msgid "Open file with default browser" msgstr "Abrir fichero en el navegador por defecto" -#: src/dialogs/confdialog.cxx:6106 +#: src/dialogs/confdialog.cxx:6200 msgid "Pskmail" msgstr "Pskmail" -#: src/dialogs/confdialog.cxx:6109 +#: src/dialogs/confdialog.cxx:6203 msgid "Mail Server Attributes" msgstr "Atributos del servidor de correo (PSKMAIL)" -#: src/dialogs/confdialog.cxx:6112 +#: src/dialogs/confdialog.cxx:6206 msgid "Carrier frequency (Hz)" msgstr "Frecuencia portadora (Hz)" -#: src/dialogs/confdialog.cxx:6113 +#: src/dialogs/confdialog.cxx:6207 msgid "Default listen / transmit frequency" msgstr "Frecuencia de RX/TX predeterminada" -#: src/dialogs/confdialog.cxx:6132 +#: src/dialogs/confdialog.cxx:6226 msgid "Search range (Hz)" msgstr "Rango de búsqueda (Hz)" -#: src/dialogs/confdialog.cxx:6133 +#: src/dialogs/confdialog.cxx:6227 msgid "Listen for signals within this range" msgstr "Escuchar señales dentro de este rango" -#: src/dialogs/confdialog.cxx:6172 +#: src/dialogs/confdialog.cxx:6266 msgid "AFC range (Hz)" msgstr "Rango AFC (Hz)" -#: src/dialogs/confdialog.cxx:6173 +#: src/dialogs/confdialog.cxx:6267 msgid "Limit AFC movement to this range" msgstr "Limitar el movimiento del AFC a este rango" -#: src/dialogs/confdialog.cxx:6192 +#: src/dialogs/confdialog.cxx:6286 msgid "Reset to Carrier" msgstr "Ajustar a la portadora" -#: src/dialogs/confdialog.cxx:6193 +#: src/dialogs/confdialog.cxx:6287 msgid "When no signal present" msgstr "Cuando no halla señal presente" -#: src/dialogs/confdialog.cxx:6204 +#: src/dialogs/confdialog.cxx:6298 msgid "Report ARQ frames average S/N" msgstr "Reportar el promedio de S/N de tramas ARQ" -#: src/dialogs/confdialog.cxx:6213 +#: src/dialogs/confdialog.cxx:6307 msgid "Spotting" msgstr "Spotting" -#: src/dialogs/confdialog.cxx:6215 +#: src/dialogs/confdialog.cxx:6309 msgid "PSK Reporter" msgstr "PSK Reporter" -#: src/dialogs/confdialog.cxx:6218 +#: src/dialogs/confdialog.cxx:6312 msgid "Automatically spot callsigns in decoded text" msgstr "" "Hacer \"spot\" automáticamente con los\n" "indicativos decodificados en el texto recibido" -#: src/dialogs/confdialog.cxx:6219 +#: src/dialogs/confdialog.cxx:6313 msgid "Parse all incoming text" msgstr "Procesar todo el texto entrante" -#: src/dialogs/confdialog.cxx:6224 +#: src/dialogs/confdialog.cxx:6318 msgid "Send reception report when logging a QSO" msgstr "Enviar reporte cuando se llenan los datos del QSO" -#: src/dialogs/confdialog.cxx:6225 +#: src/dialogs/confdialog.cxx:6319 msgid "Send report only when QSO is logged" msgstr "Enviar reporte solo cuando se salvan los datos del QSO" -#: src/dialogs/confdialog.cxx:6230 +#: src/dialogs/confdialog.cxx:6324 msgid "Report rig frequency (enable only if you have rig control!)" msgstr "Reportar la frecuencia del radio (activar solo si tienes control del Radio)" -#: src/dialogs/confdialog.cxx:6231 +#: src/dialogs/confdialog.cxx:6325 msgid "Include the transmit frequency" msgstr "Incluir la frecuencia de Tx" -#: src/dialogs/confdialog.cxx:6236 +#: src/dialogs/confdialog.cxx:6330 msgid "Host:" msgstr "Host:" -#: src/dialogs/confdialog.cxx:6237 +#: src/dialogs/confdialog.cxx:6331 msgid "To whom the connection is made" msgstr "A quien se hace la conexión" -#: src/dialogs/confdialog.cxx:6251 +#: src/dialogs/confdialog.cxx:6345 msgid "Port:" msgstr "Puerto:" -#: src/dialogs/confdialog.cxx:6252 +#: src/dialogs/confdialog.cxx:6346 msgid "Using UDP port #" msgstr "Usando puerto UDP #" -#: src/dialogs/confdialog.cxx:6267 +#: src/dialogs/confdialog.cxx:6361 msgid "Initialize the socket client" msgstr "Inicializar el socket cliente" -#: src/dialogs/confdialog.cxx:6270 +#: src/dialogs/confdialog.cxx:6364 msgid "" msgstr "" -#: src/dialogs/confdialog.cxx:6278 +#: src/dialogs/confdialog.cxx:6372 msgid "Sweet Spot" msgstr "Frecuencia Inicial" -#: src/dialogs/confdialog.cxx:6284 +#: src/dialogs/confdialog.cxx:6378 msgid "Default CW tracking point" msgstr "Punto predefinido de rastreo de CW" -#: src/dialogs/confdialog.cxx:6303 +#: src/dialogs/confdialog.cxx:6397 msgid "Default RTTY tracking point" msgstr "Punto predefinido de rastreo de RTTY" -#: src/dialogs/confdialog.cxx:6321 +#: src/dialogs/confdialog.cxx:6415 msgid "PSK et al." msgstr "PSK et al." -#: src/dialogs/confdialog.cxx:6322 +#: src/dialogs/confdialog.cxx:6416 msgid "Default for all other modems" msgstr "Punto predefinido de rastreo para los otros modems" -#: src/dialogs/confdialog.cxx:6340 +#: src/dialogs/confdialog.cxx:6434 msgid "Always start new modems at these frequencies" msgstr "Siempre iniciar los modems nuevos en estas frecuencias" -#: src/dialogs/confdialog.cxx:6341 +#: src/dialogs/confdialog.cxx:6435 msgid "" "ON - start at default\n" "OFF - keep current wf cursor position" @@ -4549,15 +4628,15 @@ msgstr "" "ON - Iniciar en la pre-establecida\n" "OFF - Mantener la posición actual en la cascada" -#: src/dialogs/confdialog.cxx:6349 +#: src/dialogs/confdialog.cxx:6443 msgid "K3 A1A configuation" msgstr "Configuración de A1A para el Elecraft K3" -#: src/dialogs/confdialog.cxx:6352 +#: src/dialogs/confdialog.cxx:6446 msgid "CW is LSB" msgstr "CW es LSB" -#: src/dialogs/confdialog.cxx:6353 +#: src/dialogs/confdialog.cxx:6447 msgid "" "Select this for Elecraft K3\n" "Other radios should not need it." @@ -4565,59 +4644,68 @@ msgstr "" "Solo para el Elecraft K3\n" "Otros radios no lo necesitan." -#: src/dialogs/confdialog.cxx:6362 +#: src/dialogs/confdialog.cxx:6456 msgid "Text i/o" msgstr "E/S de Texto" -#: src/dialogs/confdialog.cxx:6364 +#: src/dialogs/confdialog.cxx:6458 msgid "Talker Socket (MS only)" msgstr "Talker Socket (Solo MS)" -#: src/dialogs/confdialog.cxx:6367 +#: src/dialogs/confdialog.cxx:6461 msgid "Talker" msgstr "Talker" -#: src/dialogs/confdialog.cxx:6371 +#: src/dialogs/confdialog.cxx:6465 msgid "Connect/disconnect to Talker socket server" msgstr "Conectar/desconectar el socket del servidor Talker" -#: src/dialogs/confdialog.cxx:6374 +#: src/dialogs/confdialog.cxx:6468 msgid "Auto connect when fldigi opens (server must be up)" msgstr "Auto conectar cuando fldigi se ejecute (el servidor debe estar encendido)" -#: src/dialogs/confdialog.cxx:6381 +#: src/dialogs/confdialog.cxx:6475 msgid "Capture rx text to external file" msgstr "Capturar el texto de Rx a un fichero externo" -#: src/dialogs/confdialog.cxx:6384 +#: src/dialogs/confdialog.cxx:6478 msgid "Enable rx text stream" msgstr "Activar el flujo de texto de recepción" -#: src/dialogs/confdialog.cxx:6385 +#: src/dialogs/confdialog.cxx:6479 +#: src/dialogs/confdialog.cxx:6491 msgid "Send rx text to file: textout.txt" msgstr "Enviar texto rx al fichero: textout.txt" -#: src/dialogs/confdialog.cxx:6398 +#: src/dialogs/confdialog.cxx:6488 +msgid "DTMF" +msgstr "DTMF" + +#: src/dialogs/confdialog.cxx:6490 +msgid "Decode DTMF tones" +msgstr "Decodificar tonos DTMF" + +#: src/dialogs/confdialog.cxx:6502 msgid "Callsign DB" msgstr "BD de Indic." -#: src/dialogs/confdialog.cxx:6399 +#: src/dialogs/confdialog.cxx:6503 msgid "Callsign database" msgstr "Base de datos de Indicativos" -#: src/dialogs/confdialog.cxx:6401 +#: src/dialogs/confdialog.cxx:6505 msgid "CDROM" msgstr "CDROM" -#: src/dialogs/confdialog.cxx:6405 +#: src/dialogs/confdialog.cxx:6509 msgid "Use CD or hard drive CD image" msgstr "Usar el CD o una imagen del CD en tu disco duro" -#: src/dialogs/confdialog.cxx:6410 +#: src/dialogs/confdialog.cxx:6514 msgid "at:" msgstr "en:" -#: src/dialogs/confdialog.cxx:6411 +#: src/dialogs/confdialog.cxx:6515 msgid "" "ie: /home/dave/CALLBK/ or C:/CALLBK/\n" "Leave blank to search for database" @@ -4625,15 +4713,15 @@ msgstr "" "ejemp.: /home/co7wt/CALLBK o C:/CALLBK\n" "Dejar en blanco para buscar" -#: src/dialogs/confdialog.cxx:6427 -msgid "Paid online subscription" -msgstr "Subscripción pagada" +#: src/dialogs/confdialog.cxx:6531 +msgid "Subscriber data" +msgstr "Datos del Subscriptor" -#: src/dialogs/confdialog.cxx:6430 +#: src/dialogs/confdialog.cxx:6534 msgid "QRZ.com" msgstr "QRZ.com" -#: src/dialogs/confdialog.cxx:6431 +#: src/dialogs/confdialog.cxx:6535 msgid "" "You need a paid QRZ online\n" "subscription to access" @@ -4641,11 +4729,12 @@ msgstr "" "Necesitas una subscripción\n" "pagada para acceder a QRZ" -#: src/dialogs/confdialog.cxx:6436 +#: src/dialogs/confdialog.cxx:6540 msgid "Hamcall.net" msgstr "Hamcall.net" -#: src/dialogs/confdialog.cxx:6437 +#: src/dialogs/confdialog.cxx:6541 +#: src/dialogs/confdialog.cxx:6582 msgid "" "You need a paid Hamcall online\n" "subscription to access" @@ -4653,60 +4742,64 @@ msgstr "" "Necesitas una subscripción\n" "pagada para acceder a Hamcall" -#: src/dialogs/confdialog.cxx:6442 +#: src/dialogs/confdialog.cxx:6546 msgid "User name" msgstr "Nombre de usuario" -#: src/dialogs/confdialog.cxx:6443 +#: src/dialogs/confdialog.cxx:6547 msgid "Your login name" msgstr "Tu nombre de usuario" -#: src/dialogs/confdialog.cxx:6457 +#: src/dialogs/confdialog.cxx:6561 msgid "Password" msgstr "Contraseña" -#: src/dialogs/confdialog.cxx:6458 +#: src/dialogs/confdialog.cxx:6562 msgid "Your login password" msgstr "Tu clave de usuario" -#: src/dialogs/confdialog.cxx:6473 +#: src/dialogs/confdialog.cxx:6577 msgid "Show" msgstr "Mostrar" -#: src/dialogs/confdialog.cxx:6474 +#: src/dialogs/confdialog.cxx:6578 msgid "Show password in plain text" msgstr "Mostrar claves en texto plano" -#: src/dialogs/confdialog.cxx:6482 +#: src/dialogs/confdialog.cxx:6581 +msgid "HamQTH.com" +msgstr "HamQTH.com" + +#: src/dialogs/confdialog.cxx:6592 msgid "Not available" msgstr "No disponible" -#: src/dialogs/confdialog.cxx:6483 +#: src/dialogs/confdialog.cxx:6593 msgid "Do not use callsign database" msgstr "No usar una base de datos de indicativos" -#: src/dialogs/confdialog.cxx:6489 +#: src/dialogs/confdialog.cxx:6599 msgid "QRZ online via default Internet Browser" msgstr "Sitio QRZ vía el navegador por defecto" -#: src/dialogs/confdialog.cxx:6490 +#: src/dialogs/confdialog.cxx:6600 msgid "Visit QRZ web site" msgstr "Visita el sitio web de QRZ" -#: src/dialogs/confdialog.cxx:6495 +#: src/dialogs/confdialog.cxx:6605 msgid "HamCall online via default Internet Browser" msgstr "Sitio HamCall vía el navegador por defecto" -#: src/dialogs/confdialog.cxx:6496 -#: src/dialogs/confdialog.cxx:6502 +#: src/dialogs/confdialog.cxx:6606 +#: src/dialogs/confdialog.cxx:6612 msgid "Visit Hamcall web site" msgstr "Visita el sitio web de HamCall" -#: src/dialogs/confdialog.cxx:6501 +#: src/dialogs/confdialog.cxx:6611 msgid "Callook.info lookup (US callsigns only)" msgstr "Búsqueda en Callbook.info (Solo indicativos de EE.UU.)" -#: src/dialogs/confdialog.cxx:6519 +#: src/dialogs/confdialog.cxx:6629 msgid "Restore defaults" msgstr "Cargar por defecto" @@ -4846,11 +4939,11 @@ msgstr "Frecuencia" #: src/logbook/lgbook.cxx:420 msgid "QSO Date On" -msgstr "Fecha de inicio del QSO" +msgstr "Fecha de inicio" #: src/logbook/lgbook.cxx:424 msgid "QSO Date Off" -msgstr "Fecha de fin del QSO" +msgstr "Fecha de fin" #: src/logbook/lgbook.cxx:428 msgid "Time ON" @@ -4886,21 +4979,21 @@ msgstr "LOC" #: src/logbook/lgbook.cxx:466 msgid "QSL rcvd date" -msgstr "Fecha de recibo de la QSL" +msgstr "Fecha de RX QSL" #: src/logbook/lgbook.cxx:469 msgid "QSL sent date" -msgstr "Fecha de envio de la QSL" +msgstr "Fecha de TX QSL" #: src/logbook/lgbook.cxx:472 #: src/logbook/lgbook.cxx:1035 msgid "Serial # in" -msgstr "# de serie recibido" +msgstr "Serie recibida" #: src/logbook/lgbook.cxx:475 #: src/logbook/lgbook.cxx:1039 msgid "Serial # out" -msgstr "# de serie enviado" +msgstr "Serie enviada" #: src/logbook/lgbook.cxx:484 #: src/logbook/lgbook.cxx:735 @@ -5118,17 +5211,121 @@ msgstr "Concurso:" msgid "QSO Date" msgstr "Fecha QSO" +#~ msgid "Dom" +#~ msgstr "DomEX" + +#~ msgid "FH" +#~ msgstr "Feld Hell" + +#~ msgid "Packet" +#~ msgstr "Packet" + +#~ msgid "Select packet baudrate" +#~ msgstr "Seleccionar velocidad de packet" + +#~ msgid "RX Low Freq Gain" +#~ msgstr "Gan. Rx en frec. bajas" + +#~ msgid "Processing gain to apply to lower tone (in dB)" +#~ msgstr "Ganancia a aplicar a los tonos bajos (en dB)" + +#~ msgid "RX High Freq Gain" +#~ msgstr "Gan. Rx en frec. altas" + +#~ msgid "Processing gain to apply to higher tone (in dB)" +#~ msgstr "Ganancia a aplicar a los tonos altos (en dB)" + +#~ msgid "TX Low Freq Gain" +#~ msgstr "Gan. Tx en frec. bajas" + +#~ msgid "TX High Freq Gain" +#~ msgstr "Gan. Tx en frec. altas" + +#~ msgid "add RX timestamps" +#~ msgstr "añadir marcas de tiempo en RX" + +#~ msgid "Prepend timestamp to each RX packet" +#~ msgstr "Anteponer marcas de tiempo a cada paquete recibido" + +#~ msgid "decode Compressed data" +#~ msgstr "decodificar datos comprimidos" + +#~ msgid "Decode received Compressed Position data" +#~ msgstr "Decodificar datos comprimidos de posición" + +#~ msgid "decode Mic-E data" +#~ msgstr "decodificar datos Mic-E" + +#~ msgid "Decode received Mic-E data" +#~ msgstr "Decodificar datos recibidos Mic-E" + +#~ msgid "decode PHG data" +#~ msgstr "decodificar datos PHG" + +#~ msgid "Decode received PHG data" +#~ msgstr "Decodificar datos PHG recibidos" + +#~ msgid "use SI units" +#~ msgstr "usar unidades del SIU" + +#~ msgid "Display decoded data values in SI units" +#~ msgstr "Mostrar datos decodificados en unidades del SIU (m, Km)" + +#~ msgid "use English units" +#~ msgstr "usar unidades Inglesas" + +#~ msgid "Display decoded data in English units" +#~ msgstr "Mostrar datos decodificados en unidades Inglesas (pies, millas)" + +#~ msgid "Use cross-hair scope" +#~ msgstr "Usar osciloscopio de hilos cruzados" + +#~ msgid "Defaults to syncscope instead of phase (cross-hair) scope" +#~ msgstr "" +#~ "Por defecto muestra la sincronía en vez de los hilos cruzados en el " +#~ "osciloscopio" + +#~ msgid "boost Audio input" +#~ msgstr "Amplificar la entrada de audio" + +#~ msgid "add additional gain to audio input for low-output interfaces" +#~ msgstr "Añadir ganancia adicional a la entrada de audio" + +#~ msgid "Display true frequency in the waterfall" +#~ msgstr "Mostrar la frecuencia real en la cascada" + +#~ msgid "" +#~ "Enable to show the true transmit frequency on the waterfall when the " +#~ "radio is in CW (A1A) mode" +#~ msgstr "" +#~ "Habilitar para mostrar la frecuencia real de transmisión en la cascada " +#~ "cuando el radio está en CW (A1A)" + +#~ msgid "Paid online subscription" +#~ msgstr "Subscripción pagada" + +#~ msgid "Text:" +#~ msgstr "Texto:" + +#~ msgid "\tTx digits string" +#~ msgstr "\tTransmite los dígitos en DTMF" + #~ msgid "Freq Analysis" #~ msgstr "Análisis de frecuencia" + #~ msgid "flmsg specific" #~ msgstr "Para uso específico con flmsg" + #~ msgid "Autostart flmsg upon detection of compatible file" #~ msgstr "" #~ "Iniciar automáticamente el FlMsg en la detección de un archivo compatible" + #~ msgid "Autostart flmsg / browser upon detection of compatible file" #~ msgstr "Iniciar automáticamente el flmsg cuando se reciba un mensaje" + #~ msgid "Auto Extract files from rx stream" #~ msgstr "Extracción automática de ficheros del flujo de Rx" + #~ msgid "" #~ "0\n" #~ "1\n" @@ -5137,10 +5334,13 @@ msgstr "Fecha QSO" #~ "0\n" #~ "1\n" #~ "2" + #~ msgid "Enable detection && extraction" #~ msgstr "Activar detección y extracción" + #~ msgid "Auto open wrap folder" #~ msgstr "Abrir automáticamente la carpeta" + #~ msgid "Search for reg-exp in browser text(s)" #~ msgstr "Buscar esta expresión regular en el texto del navegador" @@ -5167,4 +5367,3 @@ msgstr "Fecha QSO" #, fuzzy #~ msgid "2-C" #~ msgstr "2-C" - From 120f2d4a2c32311ba1eaabb00cc7f71985b68f84 Mon Sep 17 00:00:00 2001 From: David Freese Date: Fri, 28 Oct 2011 17:30:26 -0500 Subject: [PATCH 41/54] Version 3.21.22 Maintenance release --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index dbea734d..efc3d53d 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [3]) m4_define(FLDIGI_MINOR, [21]) -m4_define(FLDIGI_PATCH, [.21]) +m4_define(FLDIGI_PATCH, [.22]) m4_define(FLARQ_MAJOR, [4]) m4_define(FLARQ_MINOR, [3]) m4_define(FLARQ_PATCH, [.1]) From 2ffb4a5894545f38cac83ccd7dcb2a53bfa6bb98 Mon Sep 17 00:00:00 2001 From: David Freese Date: Sun, 30 Oct 2011 14:35:16 -0500 Subject: [PATCH 42/54] Auto-send * Added command-line parameter --auto-dir for specifying absolute pathname to autosend directory. --- src/main.cxx | 77 +++++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/src/main.cxx b/src/main.cxx index 8df7525f..22b62e77 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -117,41 +117,41 @@ string appname; string scDevice[2]; -string HomeDir; -string RigsDir; -string ScriptsDir; -string PalettesDir; -string LogsDir; -string PicsDir; -string HelpDir; -string MacrosDir; -string WrapDir; -string TalkDir; -string TempDir; -string PskMailDir; +string HomeDir = ""; +string RigsDir = ""; +string ScriptsDir = ""; +string PalettesDir = ""; +string LogsDir = ""; +string PicsDir = ""; +string HelpDir = ""; +string MacrosDir = ""; +string WrapDir = ""; +string TalkDir = ""; +string TempDir = ""; +string PskMailDir = ""; -string NBEMS_dir; -string ARQ_dir; -string ARQ_files_dir; -string ARQ_recv_dir; -string ARQ_send; -string WRAP_dir; -string WRAP_recv_dir; -string WRAP_send_dir; -string WRAP_auto_dir; -string ICS_dir; -string ICS_msg_dir; -string ICS_tmp_dir; +string NBEMS_dir = ""; +string ARQ_dir = ""; +string ARQ_files_dir = ""; +string ARQ_recv_dir = ""; +string ARQ_send = ""; +string WRAP_dir = ""; +string WRAP_recv_dir = ""; +string WRAP_send_dir = ""; +string WRAP_auto_dir = ""; +string ICS_dir = ""; +string ICS_msg_dir = ""; +string ICS_tmp_dir = ""; -string FLMSG_dir; -string FLMSG_dir_default; -string FLMSG_WRAP_dir; -string FLMSG_WRAP_recv_dir; -string FLMSG_WRAP_send_dir; -string FLMSG_WRAP_auto_dir; -string FLMSG_ICS_dir; -string FLMSG_ICS_msg_dir; -string FLMSG_ICS_tmp_dir; +string FLMSG_dir = ""; +string FLMSG_dir_default = ""; +string FLMSG_WRAP_dir = ""; +string FLMSG_WRAP_recv_dir = ""; +string FLMSG_WRAP_send_dir = ""; +string FLMSG_WRAP_auto_dir = ""; +string FLMSG_ICS_dir = ""; +string FLMSG_ICS_msg_dir = ""; +string FLMSG_ICS_tmp_dir = ""; string PskMailFile; string ArqFilename; @@ -481,6 +481,9 @@ void generate_option_help(void) { << " --flmsg-dir DIRECTORY\n" << " Look for flmsg files in DIRECTORY\n" << " The default is " << FLMSG_dir_default << "\n\n" + << " --auto-dir DIRECTORY\n" + << " Look for auto-send files in DIRECTORY\n" + << " The default is " << HomeDir << "/autosend" << "\n\n" #if USE_XMLRPC << " --xmlrpc-server-address HOSTNAME\n" @@ -631,6 +634,7 @@ int parse_args(int argc, char **argv, int& idx) OPT_ARQ_ADDRESS, OPT_ARQ_PORT, OPT_SHOW_CPU_CHECK, OPT_FLMSG_DIR, + OPT_AUTOSEND_DIR, #if USE_XMLRPC OPT_CONFIG_XMLRPC_ADDRESS, OPT_CONFIG_XMLRPC_PORT, @@ -663,6 +667,7 @@ int parse_args(int argc, char **argv, int& idx) { "arq-server-address", 1, 0, OPT_ARQ_ADDRESS }, { "arq-server-port", 1, 0, OPT_ARQ_PORT }, { "flmsg-dir", 1, 0, OPT_FLMSG_DIR }, + { "auto-dir", 1, 0, OPT_AUTOSEND_DIR }, { "cpu-speed-test", 0, 0, OPT_SHOW_CPU_CHECK }, @@ -755,6 +760,10 @@ int parse_args(int argc, char **argv, int& idx) FLMSG_dir_default = optarg; break; + case OPT_AUTOSEND_DIR: + FLMSG_WRAP_auto_dir = optarg; + break; + #if USE_XMLRPC case OPT_CONFIG_XMLRPC_ADDRESS: progdefaults.xmlrpc_address = optarg; @@ -1188,7 +1197,7 @@ void check_nbems_dirs(void) }; for (size_t i = 0; i < sizeof(FLMSG_dirs)/sizeof(*FLMSG_dirs); i++) { - if (FLMSG_dirs[i].suffix) + if (FLMSG_dirs[i].dir.empty() && FLMSG_dirs[i].suffix) FLMSG_dirs[i].dir.assign(FLMSG_dir).append(FLMSG_dirs[i].suffix).append("/"); if ((r = mkdir(FLMSG_dirs[i].dir.c_str(), 0777)) == -1 && errno != EEXIST) { From 047543ab1104ea8ae4fa35dfa29eb3bff86d9d7f Mon Sep 17 00:00:00 2001 From: David Freese Date: Thu, 3 Nov 2011 07:05:57 -0500 Subject: [PATCH 43/54] HamQTH * Added error statements to notes: - Failure to obtain certificate - Callsign not found * Corrected parsing of QTH and QSL_VIA --- src/misc/lookupcall.cxx | 58 +++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/src/misc/lookupcall.cxx b/src/misc/lookupcall.cxx index 0c10ae97..c5e91475 100644 --- a/src/misc/lookupcall.cxx +++ b/src/misc/lookupcall.cxx @@ -720,6 +720,9 @@ void HAMCALLquery() static string HAMQTH_session_id = ""; static string HAMQTH_reply = ""; +#define HAMQTH_DEBUG 1 +#undef HAMQTH_DEBUG + bool HAMQTH_get_session_id() { string url = ""; @@ -745,7 +748,9 @@ bool HAMQTH_get_session_id() } p2 = retstr.find(""); HAMQTH_session_id = retstr.substr(p1 + 12, p2 - p1 - 12); -//printf("session id = %s\n", HAMQTH_session_id.c_str()); +//#ifdef HAMQTH_DEBUG +// printf("session id = %s\n", HAMQTH_session_id.c_str()); +//#endif return true; } @@ -756,6 +761,20 @@ void parse_HAMQTH_html(const string& htmlpage) clear_Lookup(); + lookup_fname.clear(); + lookup_qth.clear(); + lookup_state.clear(); + lookup_grid.clear(); + lookup_notes.clear(); + lookup_country.clear(); + + if ((p = htmlpage.find("")) != string::npos) { + p += 7; + p1 = htmlpage.find(""); + if (p1 != string::npos) + lookup_notes.append(htmlpage.substr(p, p1 - p)); + return; + } if ((p = htmlpage.find("")) != string::npos) { p += 6; p1 = htmlpage.find("", p); @@ -764,12 +783,18 @@ void parse_HAMQTH_html(const string& htmlpage) camel_case(lookup_fname); } } - if ((p = htmlpage.find("")) != string::npos) { - p += 10; - p1 = htmlpage.find("", p); + if ((p = htmlpage.find("")) != string::npos) { + p += 5; + p1 = htmlpage.find("", p); if (p1 != string::npos) lookup_qth = htmlpage.substr(p, p1 - p); } + if ((p = htmlpage.find("")) != string::npos) { + p += 9; + p1 = htmlpage.find("", p); + if (p1 != string::npos) + lookup_country = htmlpage.substr(p, p1 - p); + } if ((p = htmlpage.find("")) != string::npos) { p += 10; p1 = htmlpage.find(""); @@ -782,11 +807,17 @@ void parse_HAMQTH_html(const string& htmlpage) if (p1 != string::npos) lookup_grid = htmlpage.substr(p, p1 - p); } + if ((p = htmlpage.find("")) != string::npos) { + p += 9; + p1 = htmlpage.find(""); + if (p1 != string::npos) + lookup_notes.append("QSL via: ").append(htmlpage.substr(p, p1 - p)).append("\n"); + } if ((p = htmlpage.find("")) != string::npos) { p += 10; p1 = htmlpage.find(""); if (p1 != string::npos) - lookup_notes = htmlpage.substr(p, p1 - p).append("\n"); + lookup_notes.append(htmlpage.substr(p, p1 - p)).append("\n"); } if ((p = htmlpage.find("")) != string::npos) { p += 13; @@ -812,12 +843,6 @@ void parse_HAMQTH_html(const string& htmlpage) if (p1 != string::npos) lookup_notes.append(" ").append(htmlpage.substr(p, p1 - p)); } - if ((p == htmlpage.find("")) != string::npos) { - p += 9; - p1 = htmlpage.find(""); - if (p1 != string::npos) - lookup_notes.append("\nQSL via: ").append(htmlpage.substr(p, p1 - p)); - } } bool HAMQTHget(string& htmlpage) @@ -832,14 +857,19 @@ bool HAMQTHget(string& htmlpage) url.append("&prg=fldigi-").append(VERSION); ret = fetch_http(url, htmlpage, 5.0); -//printf("%s\n", htmlpage.c_str()); if (htmlpage.find("") != string::npos) { htmlpage.clear(); - if (!HAMQTH_get_session_id()) + if (!HAMQTH_get_session_id()) { + lookup_notes = "Get session id failed!\n"; return false; + } ret = fetch_http(url, htmlpage, 5.0); -//printf("%s\n", htmlpage.c_str()); } +#ifdef HAMQTH_DEBUG + FILE *fetchit = fopen("fetchit.txt", "a"); + fprintf(fetchit, "%s\n", htmlpage.c_str()); + fclose(fetchit); +#endif return ret; } From 7a87f22dc7a5b34c017f789d1519957b96592b65 Mon Sep 17 00:00:00 2001 From: David Freese Date: Thu, 3 Nov 2011 08:47:35 -0500 Subject: [PATCH 44/54] Version 3.21.23 Maintenance release --- ChangeLog | 19 +++++++++++++++++-- configure.ac | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 497444dc..213b6db4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,24 @@ +2011-11-03 David Freese + + 36a64e5: HamQTH + 2ffb4a5: Auto-send + + +=Version 3.21.22= + + +2011-10-28 Pavel Milanes Costa + + b66a4d7: es.po update + +2011-10-28 David Freese + + 269ae3a: RSID defaults + 1b3e852: NBEMS-FLMSG Directories =Version 3.21.21= -2011-10-25 David Freese - 3163fd2: Resize fault diff --git a/configure.ac b/configure.ac index efc3d53d..1556a5a1 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [3]) m4_define(FLDIGI_MINOR, [21]) -m4_define(FLDIGI_PATCH, [.22]) +m4_define(FLDIGI_PATCH, [.23]) m4_define(FLARQ_MAJOR, [4]) m4_define(FLARQ_MINOR, [3]) m4_define(FLARQ_PATCH, [.1]) From 0859928baed60f40603a738027cd4abed85f9279 Mon Sep 17 00:00:00 2001 From: David Freese Date: Mon, 7 Nov 2011 10:06:24 -0600 Subject: [PATCH 45/54] QRZ on-line lookup * Changed on line lookup URL format to comply with changes to QRZ.com --- src/misc/lookupcall.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/lookupcall.cxx b/src/misc/lookupcall.cxx index c5e91475..c5a1d606 100644 --- a/src/misc/lookupcall.cxx +++ b/src/misc/lookupcall.cxx @@ -890,7 +890,7 @@ void HAMQTHquery() void QRZ_DETAILS_query() { - string qrzurl = "http://www.qrz.com/callsign.html?callsign="; + string qrzurl = "http://www.qrz.com/db/"; qrzurl.append(callsign); cb_mnuVisitURL(0, (void*)qrzurl.c_str()); From 16fc289561e5a34cf4d48942f5a878d7ba9ba261 Mon Sep 17 00:00:00 2001 From: David Freese Date: Thu, 10 Nov 2011 10:06:34 -0600 Subject: [PATCH 46/54] Exec macro * On Linux and OS X - modified child process environment variable PATH to include the scripts directory as the first in the PATH string - required for xdg-open to find executable in the scripts directory --- src/misc/macros.cxx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/misc/macros.cxx b/src/misc/macros.cxx index e16cd248..01fdfa91 100644 --- a/src/misc/macros.cxx +++ b/src/misc/macros.cxx @@ -1531,6 +1531,14 @@ void set_macro_env(void) for (size_t j = 0; j < ENV_SIZE; j++) setenv(env[j].var, env[j].val, 1); + + string path = getenv("PATH"); + string mypath = ScriptsDir; + if (mypath[mypath.length()-1] == '/') + mypath.erase(mypath.length()-1, 1); + mypath.append(":"); + path.insert(0,mypath); + setenv("PATH", path.c_str(), 1); } // this is only for the case where the user tries to nest ... @@ -1564,6 +1572,7 @@ static void pEXEC(std::string &s, size_t &i, size_t endbracket) within_exec = true; MACROTEXT m; execstr = m.expandMacro(execstr); +// execstr.insert(0,ScriptsDir); within_exec = false; int pfd[2]; From 7bae7afae421e920a04c4ca6e37d34d037915c55 Mon Sep 17 00:00:00 2001 From: David Freese Date: Fri, 11 Nov 2011 06:13:09 -0600 Subject: [PATCH 47/54] Version 3.21.24 Maintenance release --- ChangeLog | 10 ++++++++-- configure.ac | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 213b6db4..00329477 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,12 @@ -2011-11-03 David Freese +2011-11-10 David Freese - 36a64e5: HamQTH + 16fc289: Exec macro + 0859928: QRZ on-line lookup + + +=Version 3.21.23= + + 047543a: HamQTH 2ffb4a5: Auto-send diff --git a/configure.ac b/configure.ac index 1556a5a1..afdc11c0 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [3]) m4_define(FLDIGI_MINOR, [21]) -m4_define(FLDIGI_PATCH, [.23]) +m4_define(FLDIGI_PATCH, [.24]) m4_define(FLARQ_MAJOR, [4]) m4_define(FLARQ_MINOR, [3]) m4_define(FLARQ_PATCH, [.1]) From c2ba559f1cad6f9ecf6ecb9f7d84be4796d86b91 Mon Sep 17 00:00:00 2001 From: David Freese Date: Sat, 12 Nov 2011 07:44:16 -0600 Subject: [PATCH 48/54] eQSL * Added EQSL macro tag - sends current log data to eQSL on line - CALL, BAND, MODE, QSO_DATE, QSO_TIME_ON, RST_SENT - optional message, --- src/dialogs/confdialog.cxx | 351 ++++++++++++++++++++++-------------- src/dialogs/confdialog.fl | 265 ++++++++++++++++----------- src/dialogs/fl_digi.cxx | 2 +- src/include/confdialog.h | 12 +- src/include/configuration.h | 10 + src/include/lookupcall.h | 2 + src/include/threads.h | 2 +- src/misc/lookupcall.cxx | 95 ++++++++++ src/misc/macroedit.cxx | 1 + src/misc/macros.cxx | 98 ++++++++++ 10 files changed, 593 insertions(+), 245 deletions(-) diff --git a/src/dialogs/confdialog.cxx b/src/dialogs/confdialog.cxx index d21129fe..19d80af8 100644 --- a/src/dialogs/confdialog.cxx +++ b/src/dialogs/confdialog.cxx @@ -2875,6 +2875,38 @@ static void cb_chkDTMFdecode(Fl_Check_Button* o, void*) { Fl_Group *tabQRZ=(Fl_Group *)0; +Fl_Round_Button *btnQRZnotavailable=(Fl_Round_Button *)0; + +static void cb_btnQRZnotavailable(Fl_Round_Button* o, void*) { + set_qrz_buttons(o); +progdefaults.QRZ = QRZNONE; +progdefaults.changed = true; +} + +Fl_Round_Button *btnQRZonline=(Fl_Round_Button *)0; + +static void cb_btnQRZonline(Fl_Round_Button* o, void*) { + set_qrz_buttons(o); +progdefaults.QRZ = QRZHTML; +progdefaults.changed = true; +} + +Fl_Round_Button *btnHAMCALLonline=(Fl_Round_Button *)0; + +static void cb_btnHAMCALLonline(Fl_Round_Button* o, void*) { + set_qrz_buttons(o); +progdefaults.QRZ = HAMCALLHTML; +progdefaults.changed = true; +} + +Fl_Round_Button *btnCALLOOK=(Fl_Round_Button *)0; + +static void cb_btnCALLOOK(Fl_Round_Button* o, void*) { + set_qrz_buttons(o); +progdefaults.QRZ = CALLOOK; +progdefaults.changed = true; +} + Fl_Round_Button *btnQRZcdrom=(Fl_Round_Button *)0; static void cb_btnQRZcdrom(Fl_Round_Button* o, void*) { @@ -2937,35 +2969,32 @@ progdefaults.QRZ = HAMQTH; progdefaults.changed = true; } -Fl_Round_Button *btnQRZnotavailable=(Fl_Round_Button *)0; +Fl_Input2 *inpEQSL_id=(Fl_Input2 *)0; -static void cb_btnQRZnotavailable(Fl_Round_Button* o, void*) { - set_qrz_buttons(o); -progdefaults.QRZ = QRZNONE; +static void cb_inpEQSL_id(Fl_Input2* o, void*) { + progdefaults.eqsl_id = o->value(); progdefaults.changed = true; } -Fl_Round_Button *btnQRZonline=(Fl_Round_Button *)0; +Fl_Input2 *inpEQSL_pwd=(Fl_Input2 *)0; -static void cb_btnQRZonline(Fl_Round_Button* o, void*) { - set_qrz_buttons(o); -progdefaults.QRZ = QRZHTML; +static void cb_inpEQSL_pwd(Fl_Input2* o, void*) { + progdefaults.eqsl_pwd = o->value(); progdefaults.changed = true; } -Fl_Round_Button *btnHAMCALLonline=(Fl_Round_Button *)0; +Fl_Button *btnEQSL_pwd_show=(Fl_Button *)0; -static void cb_btnHAMCALLonline(Fl_Round_Button* o, void*) { - set_qrz_buttons(o); -progdefaults.QRZ = HAMCALLHTML; -progdefaults.changed = true; +static void cb_btnEQSL_pwd_show(Fl_Button* o, void*) { + inpEQSL_pwd->type(inpEQSL_pwd->type() ^ FL_SECRET_INPUT); +inpEQSL_pwd->redraw(); +o->label((inpEQSL_pwd->type() & FL_SECRET_INPUT) ? "Show" : "Hide"); } -Fl_Round_Button *btnCALLOOK=(Fl_Round_Button *)0; +Fl_Input2 *inpEQSL_nick=(Fl_Input2 *)0; -static void cb_btnCALLOOK(Fl_Round_Button* o, void*) { - set_qrz_buttons(o); -progdefaults.QRZ = CALLOOK; +static void cb_inpEQSL_nick(Fl_Input2* o, void*) { + progdefaults.eqsl_nick = o->value(); progdefaults.changed = true; } @@ -6499,123 +6528,183 @@ d frequency")); } // Fl_Tabs* tabsMisc tabMisc->end(); } // Fl_Group* tabMisc - { tabQRZ = new Fl_Group(0, 25, 500, 345, _("Callsign DB")); + { tabQRZ = new Fl_Group(0, 25, 500, 345, _("Web")); tabQRZ->tooltip(_("Callsign database")); tabQRZ->hide(); - { Fl_Group* o = new Fl_Group(5, 176, 490, 55, _("CDROM")); - o->box(FL_ENGRAVED_FRAME); - o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); - { Fl_Round_Button* o = btnQRZcdrom = new Fl_Round_Button(25, 196, 70, 20, _("QRZ")); - btnQRZcdrom->tooltip(_("Use CD or hard drive CD image")); - btnQRZcdrom->down_box(FL_DOWN_BOX); - btnQRZcdrom->callback((Fl_Callback*)cb_btnQRZcdrom); - o->value(progdefaults.QRZ == QRZCD); - } // Fl_Round_Button* btnQRZcdrom - { Fl_Input2* o = txtQRZpathname = new Fl_Input2(104, 196, 300, 20, _("at:")); - txtQRZpathname->tooltip(_("ie: /home/dave/CALLBK/ or C:/CALLBK/\nLeave blank to search for database")); - txtQRZpathname->box(FL_DOWN_BOX); - txtQRZpathname->color((Fl_Color)FL_BACKGROUND2_COLOR); - txtQRZpathname->selection_color((Fl_Color)FL_SELECTION_COLOR); - txtQRZpathname->labeltype(FL_NORMAL_LABEL); - txtQRZpathname->labelfont(0); - txtQRZpathname->labelsize(14); - txtQRZpathname->labelcolor((Fl_Color)FL_FOREGROUND_COLOR); - txtQRZpathname->callback((Fl_Callback*)cb_txtQRZpathname); - txtQRZpathname->align(FL_ALIGN_LEFT); - txtQRZpathname->when(FL_WHEN_RELEASE); - o->value(progdefaults.QRZpathname.c_str()); - txtQRZpathname->labelsize(FL_NORMAL_SIZE); - } // Fl_Input2* txtQRZpathname + { Fl_Tabs* o = new Fl_Tabs(0, 25, 500, 345); + { Fl_Group* o = new Fl_Group(0, 46, 500, 324, _("QRZ/etal")); + { Fl_Group* o = new Fl_Group(5, 55, 490, 120); + o->box(FL_ENGRAVED_FRAME); + o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + { Fl_Round_Button* o = btnQRZnotavailable = new Fl_Round_Button(25, 64, 337, 20, _("Not available")); + btnQRZnotavailable->tooltip(_("Do not use callsign database")); + btnQRZnotavailable->down_box(FL_DOWN_BOX); + btnQRZnotavailable->value(1); + btnQRZnotavailable->callback((Fl_Callback*)cb_btnQRZnotavailable); + o->value(progdefaults.QRZ == QRZNONE); + } // Fl_Round_Button* btnQRZnotavailable + { Fl_Round_Button* o = btnQRZonline = new Fl_Round_Button(25, 92, 337, 20, _("QRZ online via default Internet Browser")); + btnQRZonline->tooltip(_("Visit QRZ web site")); + btnQRZonline->down_box(FL_DOWN_BOX); + btnQRZonline->callback((Fl_Callback*)cb_btnQRZonline); + o->value(progdefaults.QRZ == QRZHTML); + } // Fl_Round_Button* btnQRZonline + { Fl_Round_Button* o = btnHAMCALLonline = new Fl_Round_Button(25, 120, 337, 20, _("HamCall online via default Internet Browser")); + btnHAMCALLonline->tooltip(_("Visit Hamcall web site")); + btnHAMCALLonline->down_box(FL_DOWN_BOX); + btnHAMCALLonline->callback((Fl_Callback*)cb_btnHAMCALLonline); + o->value(progdefaults.QRZ == HAMCALLHTML); + } // Fl_Round_Button* btnHAMCALLonline + { Fl_Round_Button* o = btnCALLOOK = new Fl_Round_Button(25, 148, 337, 20, _("Callook.info lookup (US callsigns only)")); + btnCALLOOK->tooltip(_("Visit Hamcall web site")); + btnCALLOOK->down_box(FL_DOWN_BOX); + btnCALLOOK->callback((Fl_Callback*)cb_btnCALLOOK); + o->value(progdefaults.QRZ == CALLOOK); + } // Fl_Round_Button* btnCALLOOK + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(5, 176, 490, 55, _("CDROM")); + o->box(FL_ENGRAVED_FRAME); + o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + { Fl_Round_Button* o = btnQRZcdrom = new Fl_Round_Button(25, 196, 70, 20, _("QRZ")); + btnQRZcdrom->tooltip(_("Use CD or hard drive CD image")); + btnQRZcdrom->down_box(FL_DOWN_BOX); + btnQRZcdrom->callback((Fl_Callback*)cb_btnQRZcdrom); + o->value(progdefaults.QRZ == QRZCD); + } // Fl_Round_Button* btnQRZcdrom + { Fl_Input2* o = txtQRZpathname = new Fl_Input2(104, 196, 300, 20, _("at:")); + txtQRZpathname->tooltip(_("ie: /home/dave/CALLBK/ or C:/CALLBK/\nLeave blank to search for database")); + txtQRZpathname->box(FL_DOWN_BOX); + txtQRZpathname->color((Fl_Color)FL_BACKGROUND2_COLOR); + txtQRZpathname->selection_color((Fl_Color)FL_SELECTION_COLOR); + txtQRZpathname->labeltype(FL_NORMAL_LABEL); + txtQRZpathname->labelfont(0); + txtQRZpathname->labelsize(14); + txtQRZpathname->labelcolor((Fl_Color)FL_FOREGROUND_COLOR); + txtQRZpathname->callback((Fl_Callback*)cb_txtQRZpathname); + txtQRZpathname->align(FL_ALIGN_LEFT); + txtQRZpathname->when(FL_WHEN_RELEASE); + o->value(progdefaults.QRZpathname.c_str()); + txtQRZpathname->labelsize(FL_NORMAL_SIZE); + } // Fl_Input2* txtQRZpathname + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(5, 232, 490, 134, _("Subscriber data")); + o->box(FL_ENGRAVED_FRAME); + o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + { Fl_Round_Button* o = btnQRZsub = new Fl_Round_Button(25, 263, 90, 20, _("QRZ.com")); + btnQRZsub->tooltip(_("You need a paid QRZ online\nsubscription to access")); + btnQRZsub->down_box(FL_DOWN_BOX); + btnQRZsub->callback((Fl_Callback*)cb_btnQRZsub); + o->value(progdefaults.QRZ == QRZNET); + } // Fl_Round_Button* btnQRZsub + { Fl_Round_Button* o = btnHamcall = new Fl_Round_Button(25, 297, 105, 20, _("Hamcall.net")); + btnHamcall->tooltip(_("You need a paid Hamcall online\nsubscription to access")); + btnHamcall->down_box(FL_DOWN_BOX); + btnHamcall->callback((Fl_Callback*)cb_btnHamcall); + o->value(progdefaults.QRZ == HAMCALLNET); + } // Fl_Round_Button* btnHamcall + { Fl_Input2* o = inpQRZusername = new Fl_Input2(235, 263, 150, 20, _("User name")); + inpQRZusername->tooltip(_("Your login name")); + inpQRZusername->box(FL_DOWN_BOX); + inpQRZusername->color((Fl_Color)FL_BACKGROUND2_COLOR); + inpQRZusername->selection_color((Fl_Color)FL_SELECTION_COLOR); + inpQRZusername->labeltype(FL_NORMAL_LABEL); + inpQRZusername->labelfont(0); + inpQRZusername->labelsize(14); + inpQRZusername->labelcolor((Fl_Color)FL_FOREGROUND_COLOR); + inpQRZusername->callback((Fl_Callback*)cb_inpQRZusername); + inpQRZusername->align(FL_ALIGN_LEFT); + inpQRZusername->when(FL_WHEN_RELEASE); + o->value(progdefaults.QRZusername.c_str()); + inpQRZusername->labelsize(FL_NORMAL_SIZE); + } // Fl_Input2* inpQRZusername + { Fl_Input2* o = inpQRZuserpassword = new Fl_Input2(235, 297, 150, 20, _("Password")); + inpQRZuserpassword->tooltip(_("Your login password")); + inpQRZuserpassword->box(FL_DOWN_BOX); + inpQRZuserpassword->color((Fl_Color)FL_BACKGROUND2_COLOR); + inpQRZuserpassword->selection_color((Fl_Color)FL_SELECTION_COLOR); + inpQRZuserpassword->labeltype(FL_NORMAL_LABEL); + inpQRZuserpassword->labelfont(0); + inpQRZuserpassword->labelsize(14); + inpQRZuserpassword->labelcolor((Fl_Color)FL_FOREGROUND_COLOR); + inpQRZuserpassword->callback((Fl_Callback*)cb_inpQRZuserpassword); + inpQRZuserpassword->align(FL_ALIGN_LEFT); + inpQRZuserpassword->when(FL_WHEN_RELEASE); + o->value(progdefaults.QRZuserpassword.c_str()); + o->type(FL_SECRET_INPUT); + inpQRZuserpassword->labelsize(FL_NORMAL_SIZE); + } // Fl_Input2* inpQRZuserpassword + { btnQRZpasswordShow = new Fl_Button(395, 297, 70, 20, _("Show")); + btnQRZpasswordShow->tooltip(_("Show password in plain text")); + btnQRZpasswordShow->callback((Fl_Callback*)cb_btnQRZpasswordShow); + } // Fl_Button* btnQRZpasswordShow + { Fl_Round_Button* o = btnHamQTH = new Fl_Round_Button(26, 332, 121, 20, _("HamQTH.com (free service http://www.hamqth.com)")); + btnHamQTH->tooltip(_("You need a paid Hamcall online\nsubscription to access")); + btnHamQTH->down_box(FL_DOWN_BOX); + btnHamQTH->callback((Fl_Callback*)cb_btnHamQTH); + o->value(progdefaults.QRZ == HAMQTH); + } // Fl_Round_Button* btnHamQTH + o->end(); + } // Fl_Group* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(0, 50, 500, 320, _("eQSL")); + o->hide(); + { Fl_Input2* o = inpEQSL_id = new Fl_Input2(176, 75, 150, 20, _("User ID")); + inpEQSL_id->tooltip(_("Your login name")); + inpEQSL_id->box(FL_DOWN_BOX); + inpEQSL_id->color((Fl_Color)FL_BACKGROUND2_COLOR); + inpEQSL_id->selection_color((Fl_Color)FL_SELECTION_COLOR); + inpEQSL_id->labeltype(FL_NORMAL_LABEL); + inpEQSL_id->labelfont(0); + inpEQSL_id->labelsize(14); + inpEQSL_id->labelcolor((Fl_Color)FL_FOREGROUND_COLOR); + inpEQSL_id->callback((Fl_Callback*)cb_inpEQSL_id); + inpEQSL_id->align(FL_ALIGN_LEFT); + inpEQSL_id->when(FL_WHEN_RELEASE); + o->value(progdefaults.eqsl_id.c_str()); + inpEQSL_id->labelsize(FL_NORMAL_SIZE); + } // Fl_Input2* inpEQSL_id + { Fl_Input2* o = inpEQSL_pwd = new Fl_Input2(176, 106, 150, 20, _("Password")); + inpEQSL_pwd->tooltip(_("Your login password")); + inpEQSL_pwd->box(FL_DOWN_BOX); + inpEQSL_pwd->color((Fl_Color)FL_BACKGROUND2_COLOR); + inpEQSL_pwd->selection_color((Fl_Color)FL_SELECTION_COLOR); + inpEQSL_pwd->labeltype(FL_NORMAL_LABEL); + inpEQSL_pwd->labelfont(0); + inpEQSL_pwd->labelsize(14); + inpEQSL_pwd->labelcolor((Fl_Color)FL_FOREGROUND_COLOR); + inpEQSL_pwd->callback((Fl_Callback*)cb_inpEQSL_pwd); + inpEQSL_pwd->align(FL_ALIGN_LEFT); + inpEQSL_pwd->when(FL_WHEN_RELEASE); + o->value(progdefaults.eqsl_pwd.c_str()); + o->type(FL_SECRET_INPUT); + inpEQSL_pwd->labelsize(FL_NORMAL_SIZE); + } // Fl_Input2* inpEQSL_pwd + { btnEQSL_pwd_show = new Fl_Button(344, 106, 70, 20, _("Show")); + btnEQSL_pwd_show->tooltip(_("Show password in plain text")); + btnEQSL_pwd_show->callback((Fl_Callback*)cb_btnEQSL_pwd_show); + } // Fl_Button* btnEQSL_pwd_show + { Fl_Input2* o = inpEQSL_nick = new Fl_Input2(176, 137, 150, 20, _("QTH Nickname")); + inpEQSL_nick->tooltip(_("Your login name")); + inpEQSL_nick->box(FL_DOWN_BOX); + inpEQSL_nick->color((Fl_Color)FL_BACKGROUND2_COLOR); + inpEQSL_nick->selection_color((Fl_Color)FL_SELECTION_COLOR); + inpEQSL_nick->labeltype(FL_NORMAL_LABEL); + inpEQSL_nick->labelfont(0); + inpEQSL_nick->labelsize(14); + inpEQSL_nick->labelcolor((Fl_Color)FL_FOREGROUND_COLOR); + inpEQSL_nick->callback((Fl_Callback*)cb_inpEQSL_nick); + inpEQSL_nick->align(FL_ALIGN_LEFT); + inpEQSL_nick->when(FL_WHEN_RELEASE); + o->value(progdefaults.eqsl_nick.c_str()); + inpEQSL_nick->labelsize(FL_NORMAL_SIZE); + } // Fl_Input2* inpEQSL_nick + o->end(); + } // Fl_Group* o o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(5, 232, 490, 134, _("Subscriber data")); - o->box(FL_ENGRAVED_FRAME); - o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); - { Fl_Round_Button* o = btnQRZsub = new Fl_Round_Button(25, 263, 90, 20, _("QRZ.com")); - btnQRZsub->tooltip(_("You need a paid QRZ online\nsubscription to access")); - btnQRZsub->down_box(FL_DOWN_BOX); - btnQRZsub->callback((Fl_Callback*)cb_btnQRZsub); - o->value(progdefaults.QRZ == QRZNET); - } // Fl_Round_Button* btnQRZsub - { Fl_Round_Button* o = btnHamcall = new Fl_Round_Button(25, 297, 105, 20, _("Hamcall.net")); - btnHamcall->tooltip(_("You need a paid Hamcall online\nsubscription to access")); - btnHamcall->down_box(FL_DOWN_BOX); - btnHamcall->callback((Fl_Callback*)cb_btnHamcall); - o->value(progdefaults.QRZ == HAMCALLNET); - } // Fl_Round_Button* btnHamcall - { Fl_Input2* o = inpQRZusername = new Fl_Input2(235, 263, 150, 20, _("User name")); - inpQRZusername->tooltip(_("Your login name")); - inpQRZusername->box(FL_DOWN_BOX); - inpQRZusername->color((Fl_Color)FL_BACKGROUND2_COLOR); - inpQRZusername->selection_color((Fl_Color)FL_SELECTION_COLOR); - inpQRZusername->labeltype(FL_NORMAL_LABEL); - inpQRZusername->labelfont(0); - inpQRZusername->labelsize(14); - inpQRZusername->labelcolor((Fl_Color)FL_FOREGROUND_COLOR); - inpQRZusername->callback((Fl_Callback*)cb_inpQRZusername); - inpQRZusername->align(FL_ALIGN_LEFT); - inpQRZusername->when(FL_WHEN_RELEASE); - o->value(progdefaults.QRZusername.c_str()); - inpQRZusername->labelsize(FL_NORMAL_SIZE); - } // Fl_Input2* inpQRZusername - { Fl_Input2* o = inpQRZuserpassword = new Fl_Input2(235, 297, 150, 20, _("Password")); - inpQRZuserpassword->tooltip(_("Your login password")); - inpQRZuserpassword->box(FL_DOWN_BOX); - inpQRZuserpassword->color((Fl_Color)FL_BACKGROUND2_COLOR); - inpQRZuserpassword->selection_color((Fl_Color)FL_SELECTION_COLOR); - inpQRZuserpassword->labeltype(FL_NORMAL_LABEL); - inpQRZuserpassword->labelfont(0); - inpQRZuserpassword->labelsize(14); - inpQRZuserpassword->labelcolor((Fl_Color)FL_FOREGROUND_COLOR); - inpQRZuserpassword->callback((Fl_Callback*)cb_inpQRZuserpassword); - inpQRZuserpassword->align(FL_ALIGN_LEFT); - inpQRZuserpassword->when(FL_WHEN_RELEASE); - o->value(progdefaults.QRZuserpassword.c_str()); - o->type(FL_SECRET_INPUT); - inpQRZuserpassword->labelsize(FL_NORMAL_SIZE); - } // Fl_Input2* inpQRZuserpassword - { btnQRZpasswordShow = new Fl_Button(395, 297, 70, 20, _("Show")); - btnQRZpasswordShow->tooltip(_("Show password in plain text")); - btnQRZpasswordShow->callback((Fl_Callback*)cb_btnQRZpasswordShow); - } // Fl_Button* btnQRZpasswordShow - { Fl_Round_Button* o = btnHamQTH = new Fl_Round_Button(26, 332, 121, 20, _("HamQTH.com")); - btnHamQTH->tooltip(_("You need a paid Hamcall online\nsubscription to access")); - btnHamQTH->down_box(FL_DOWN_BOX); - btnHamQTH->callback((Fl_Callback*)cb_btnHamQTH); - o->value(progdefaults.QRZ == HAMQTH); - } // Fl_Round_Button* btnHamQTH - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(5, 35, 490, 140); - o->box(FL_ENGRAVED_FRAME); - o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); - { Fl_Round_Button* o = btnQRZnotavailable = new Fl_Round_Button(25, 45, 337, 20, _("Not available")); - btnQRZnotavailable->tooltip(_("Do not use callsign database")); - btnQRZnotavailable->down_box(FL_DOWN_BOX); - btnQRZnotavailable->value(1); - btnQRZnotavailable->callback((Fl_Callback*)cb_btnQRZnotavailable); - o->value(progdefaults.QRZ == QRZNONE); - } // Fl_Round_Button* btnQRZnotavailable - { Fl_Round_Button* o = btnQRZonline = new Fl_Round_Button(25, 76, 337, 20, _("QRZ online via default Internet Browser")); - btnQRZonline->tooltip(_("Visit QRZ web site")); - btnQRZonline->down_box(FL_DOWN_BOX); - btnQRZonline->callback((Fl_Callback*)cb_btnQRZonline); - o->value(progdefaults.QRZ == QRZHTML); - } // Fl_Round_Button* btnQRZonline - { Fl_Round_Button* o = btnHAMCALLonline = new Fl_Round_Button(25, 107, 337, 20, _("HamCall online via default Internet Browser")); - btnHAMCALLonline->tooltip(_("Visit Hamcall web site")); - btnHAMCALLonline->down_box(FL_DOWN_BOX); - btnHAMCALLonline->callback((Fl_Callback*)cb_btnHAMCALLonline); - o->value(progdefaults.QRZ == HAMCALLHTML); - } // Fl_Round_Button* btnHAMCALLonline - { Fl_Round_Button* o = btnCALLOOK = new Fl_Round_Button(25, 139, 337, 20, _("Callook.info lookup (US callsigns only)")); - btnCALLOOK->tooltip(_("Visit Hamcall web site")); - btnCALLOOK->down_box(FL_DOWN_BOX); - btnCALLOOK->callback((Fl_Callback*)cb_btnCALLOOK); - o->value(progdefaults.QRZ == CALLOOK); - } // Fl_Round_Button* btnCALLOOK - o->end(); - } // Fl_Group* o + } // Fl_Tabs* o tabQRZ->end(); } // Fl_Group* tabQRZ tabsConfigure->end(); diff --git a/src/dialogs/confdialog.fl b/src/dialogs/confdialog.fl index 0202ae26..cdf1f387 100644 --- a/src/dialogs/confdialog.fl +++ b/src/dialogs/confdialog.fl @@ -3655,125 +3655,174 @@ progdefaults.changed = true;} } } Fl_Group tabQRZ { - label {Callsign DB} open + label Web open tooltip {Callsign database} xywh {0 25 500 345} hide } { - Fl_Group {} { - label CDROM open - xywh {5 176 490 55} box ENGRAVED_FRAME align 21 + Fl_Tabs {} {open + xywh {0 25 500 345} } { - Fl_Round_Button btnQRZcdrom { - label QRZ - callback {set_qrz_buttons(o); -progdefaults.QRZ = QRZCD; -progdefaults.changed = true;} - tooltip {Use CD or hard drive CD image} xywh {25 196 70 20} down_box DOWN_BOX - code0 {o->value(progdefaults.QRZ == QRZCD);} - } - Fl_Input txtQRZpathname { - label {at:} - callback {progdefaults.QRZpathname = o->value(); -progdefaults.QRZchanged = true; -progdefaults.changed = true;} - tooltip {ie: /home/dave/CALLBK/ or C:/CALLBK/ -Leave blank to search for database} xywh {104 196 300 20} - code0 {o->value(progdefaults.QRZpathname.c_str());} - code1 {txtQRZpathname->labelsize(FL_NORMAL_SIZE);} - class Fl_Input2 - } - } - Fl_Group {} { - label {Subscriber data} open - xywh {5 232 490 134} box ENGRAVED_FRAME align 21 - } { - Fl_Round_Button btnQRZsub { - label {QRZ.com} - callback {set_qrz_buttons(o); -progdefaults.QRZ = QRZNET; -progdefaults.changed = true;} - tooltip {You need a paid QRZ online -subscription to access} xywh {25 263 90 20} down_box DOWN_BOX - code0 {o->value(progdefaults.QRZ == QRZNET);} - } - Fl_Round_Button btnHamcall { - label {Hamcall.net} - callback {set_qrz_buttons(o); -progdefaults.QRZ = HAMCALLNET; -progdefaults.changed = true;} - tooltip {You need a paid Hamcall online -subscription to access} xywh {25 297 105 20} down_box DOWN_BOX - code0 {o->value(progdefaults.QRZ == HAMCALLNET);} - } - Fl_Input inpQRZusername { - label {User name} - callback {progdefaults.QRZusername = o->value(); -progdefaults.changed = true;} - tooltip {Your login name} xywh {235 263 150 20} - code0 {o->value(progdefaults.QRZusername.c_str());} - code1 {inpQRZusername->labelsize(FL_NORMAL_SIZE);} - class Fl_Input2 - } - Fl_Input inpQRZuserpassword { - label Password - callback {progdefaults.QRZuserpassword = o->value(); -progdefaults.changed = true;} - tooltip {Your login password} xywh {235 297 150 20} - code0 {o->value(progdefaults.QRZuserpassword.c_str());} - code1 {o->type(FL_SECRET_INPUT);} - code2 {inpQRZuserpassword->labelsize(FL_NORMAL_SIZE);} - class Fl_Input2 - } - Fl_Button btnQRZpasswordShow { - label Show - callback {inpQRZuserpassword->type(inpQRZuserpassword->type() ^ FL_SECRET_INPUT); -inpQRZuserpassword->redraw(); -o->label((inpQRZuserpassword->type() & FL_SECRET_INPUT) ? "Show" : "Hide");} - tooltip {Show password in plain text} xywh {395 297 70 20} - } - Fl_Round_Button btnHamQTH { - label {HamQTH.com} - callback {set_qrz_buttons(o); -progdefaults.QRZ = HAMQTH; -progdefaults.changed = true;} - tooltip {You need a paid Hamcall online -subscription to access} xywh {26 332 121 20} down_box DOWN_BOX - code0 {o->value(progdefaults.QRZ == HAMQTH);} - } - } - Fl_Group {} {open - xywh {5 35 490 140} box ENGRAVED_FRAME align 21 - } { - Fl_Round_Button btnQRZnotavailable { - label {Not available} - callback {set_qrz_buttons(o); + Fl_Group {} { + label {QRZ/etal} open + xywh {0 46 500 324} + } { + Fl_Group {} {open + xywh {5 55 490 120} box ENGRAVED_FRAME align 21 + } { + Fl_Round_Button btnQRZnotavailable { + label {Not available} + callback {set_qrz_buttons(o); progdefaults.QRZ = QRZNONE; progdefaults.changed = true;} - tooltip {Do not use callsign database} xywh {25 45 337 20} down_box DOWN_BOX value 1 - code0 {o->value(progdefaults.QRZ == QRZNONE);} - } - Fl_Round_Button btnQRZonline { - label {QRZ online via default Internet Browser} - callback {set_qrz_buttons(o); + tooltip {Do not use callsign database} xywh {25 64 337 20} down_box DOWN_BOX value 1 + code0 {o->value(progdefaults.QRZ == QRZNONE);} + } + Fl_Round_Button btnQRZonline { + label {QRZ online via default Internet Browser} + callback {set_qrz_buttons(o); progdefaults.QRZ = QRZHTML; progdefaults.changed = true;} - tooltip {Visit QRZ web site} xywh {25 76 337 20} down_box DOWN_BOX - code0 {o->value(progdefaults.QRZ == QRZHTML);} - } - Fl_Round_Button btnHAMCALLonline { - label {HamCall online via default Internet Browser} - callback {set_qrz_buttons(o); + tooltip {Visit QRZ web site} xywh {25 92 337 20} down_box DOWN_BOX + code0 {o->value(progdefaults.QRZ == QRZHTML);} + } + Fl_Round_Button btnHAMCALLonline { + label {HamCall online via default Internet Browser} + callback {set_qrz_buttons(o); progdefaults.QRZ = HAMCALLHTML; progdefaults.changed = true;} - tooltip {Visit Hamcall web site} xywh {25 107 337 20} down_box DOWN_BOX - code0 {o->value(progdefaults.QRZ == HAMCALLHTML);} - } - Fl_Round_Button btnCALLOOK { - label {Callook.info lookup (US callsigns only)} - callback {set_qrz_buttons(o); + tooltip {Visit Hamcall web site} xywh {25 120 337 20} down_box DOWN_BOX + code0 {o->value(progdefaults.QRZ == HAMCALLHTML);} + } + Fl_Round_Button btnCALLOOK { + label {Callook.info lookup (US callsigns only)} + callback {set_qrz_buttons(o); progdefaults.QRZ = CALLOOK; progdefaults.changed = true;} - tooltip {Visit Hamcall web site} xywh {25 139 337 20} down_box DOWN_BOX - code0 {o->value(progdefaults.QRZ == CALLOOK);} + tooltip {Visit Hamcall web site} xywh {25 148 337 20} down_box DOWN_BOX + code0 {o->value(progdefaults.QRZ == CALLOOK);} + } + } + Fl_Group {} { + label CDROM open + xywh {5 176 490 55} box ENGRAVED_FRAME align 21 + } { + Fl_Round_Button btnQRZcdrom { + label QRZ + callback {set_qrz_buttons(o); +progdefaults.QRZ = QRZCD; +progdefaults.changed = true;} + tooltip {Use CD or hard drive CD image} xywh {25 196 70 20} down_box DOWN_BOX + code0 {o->value(progdefaults.QRZ == QRZCD);} + } + Fl_Input txtQRZpathname { + label {at:} + callback {progdefaults.QRZpathname = o->value(); +progdefaults.QRZchanged = true; +progdefaults.changed = true;} + tooltip {ie: /home/dave/CALLBK/ or C:/CALLBK/ +Leave blank to search for database} xywh {104 196 300 20} + code0 {o->value(progdefaults.QRZpathname.c_str());} + code1 {txtQRZpathname->labelsize(FL_NORMAL_SIZE);} + class Fl_Input2 + } + } + Fl_Group {} { + label {Subscriber data} open + xywh {5 232 490 134} box ENGRAVED_FRAME align 21 + } { + Fl_Round_Button btnQRZsub { + label {QRZ.com} + callback {set_qrz_buttons(o); +progdefaults.QRZ = QRZNET; +progdefaults.changed = true;} + tooltip {You need a paid QRZ online +subscription to access} xywh {25 263 90 20} down_box DOWN_BOX + code0 {o->value(progdefaults.QRZ == QRZNET);} + } + Fl_Round_Button btnHamcall { + label {Hamcall.net} + callback {set_qrz_buttons(o); +progdefaults.QRZ = HAMCALLNET; +progdefaults.changed = true;} + tooltip {You need a paid Hamcall online +subscription to access} xywh {25 297 105 20} down_box DOWN_BOX + code0 {o->value(progdefaults.QRZ == HAMCALLNET);} + } + Fl_Input inpQRZusername { + label {User name} + callback {progdefaults.QRZusername = o->value(); +progdefaults.changed = true;} + tooltip {Your login name} xywh {235 263 150 20} + code0 {o->value(progdefaults.QRZusername.c_str());} + code1 {inpQRZusername->labelsize(FL_NORMAL_SIZE);} + class Fl_Input2 + } + Fl_Input inpQRZuserpassword { + label Password + callback {progdefaults.QRZuserpassword = o->value(); +progdefaults.changed = true;} + tooltip {Your login password} xywh {235 297 150 20} + code0 {o->value(progdefaults.QRZuserpassword.c_str());} + code1 {o->type(FL_SECRET_INPUT);} + code2 {inpQRZuserpassword->labelsize(FL_NORMAL_SIZE);} + class Fl_Input2 + } + Fl_Button btnQRZpasswordShow { + label Show + callback {inpQRZuserpassword->type(inpQRZuserpassword->type() ^ FL_SECRET_INPUT); +inpQRZuserpassword->redraw(); +o->label((inpQRZuserpassword->type() & FL_SECRET_INPUT) ? "Show" : "Hide");} + tooltip {Show password in plain text} xywh {395 297 70 20} + } + Fl_Round_Button btnHamQTH { + label {HamQTH.com (free service http://www.hamqth.com)} + callback {set_qrz_buttons(o); +progdefaults.QRZ = HAMQTH; +progdefaults.changed = true;} + tooltip {You need a paid Hamcall online +subscription to access} xywh {26 332 121 20} down_box DOWN_BOX + code0 {o->value(progdefaults.QRZ == HAMQTH);} + } + } + } + Fl_Group {} { + label eQSL open + xywh {0 50 500 320} hide + } { + Fl_Input inpEQSL_id { + label {User ID} + callback {progdefaults.eqsl_id = o->value(); +progdefaults.changed = true;} + tooltip {Your login name} xywh {176 75 150 20} + code0 {o->value(progdefaults.eqsl_id.c_str());} + code1 {inpEQSL_id->labelsize(FL_NORMAL_SIZE);} + class Fl_Input2 + } + Fl_Input inpEQSL_pwd { + label Password + callback {progdefaults.eqsl_pwd = o->value(); +progdefaults.changed = true;} + tooltip {Your login password} xywh {176 106 150 20} + code0 {o->value(progdefaults.eqsl_pwd.c_str());} + code1 {o->type(FL_SECRET_INPUT);} + code2 {inpEQSL_pwd->labelsize(FL_NORMAL_SIZE);} + class Fl_Input2 + } + Fl_Button btnEQSL_pwd_show { + label Show + callback {inpEQSL_pwd->type(inpEQSL_pwd->type() ^ FL_SECRET_INPUT); +inpEQSL_pwd->redraw(); +o->label((inpEQSL_pwd->type() & FL_SECRET_INPUT) ? "Show" : "Hide");} + tooltip {Show password in plain text} xywh {344 106 70 20} + } + Fl_Input inpEQSL_nick { + label {QTH Nickname} + callback {progdefaults.eqsl_nick = o->value(); +progdefaults.changed = true;} + tooltip {Your login name} xywh {176 137 150 20} + code0 {o->value(progdefaults.eqsl_nick.c_str());} + code1 {inpEQSL_nick->labelsize(FL_NORMAL_SIZE);} + class Fl_Input2 + } } } } diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 078ab5d9..c4290447 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -3086,7 +3086,7 @@ Fl_Menu_Item menu_[] = { { make_icon_label(_("Misc")), 0, (Fl_Callback*)cb_mnuConfigMisc, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, { make_icon_label(_("Notifications")), 0, (Fl_Callback*)cb_mnuConfigNotify, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, { make_icon_label(CONTEST_MLABEL), 0, (Fl_Callback*)cb_mnuConfigContest, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, -{ make_icon_label(_("QRZ"), net_icon), 0, (Fl_Callback*)cb_mnuConfigQRZ, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL, 0, 14, 0}, +{ make_icon_label(_("QRZ/eQSL"), net_icon), 0, (Fl_Callback*)cb_mnuConfigQRZ, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL, 0, 14, 0}, { make_icon_label(_("Save Config"), save_icon), 0, (Fl_Callback*)cb_mnuSaveConfig, 0, 0, _FL_MULTI_LABEL, 0, 14, 0}, {0,0,0,0,0,0,0,0,0}, diff --git a/src/include/confdialog.h b/src/include/confdialog.h index 6c4196f7..03c2da4a 100644 --- a/src/include/confdialog.h +++ b/src/include/confdialog.h @@ -404,6 +404,10 @@ extern Fl_Check_Button *chkRxStream; extern Fl_Group *tabDTMF; extern Fl_Check_Button *chkDTMFdecode; extern Fl_Group *tabQRZ; +extern Fl_Round_Button *btnQRZnotavailable; +extern Fl_Round_Button *btnQRZonline; +extern Fl_Round_Button *btnHAMCALLonline; +extern Fl_Round_Button *btnCALLOOK; extern Fl_Round_Button *btnQRZcdrom; extern Fl_Input2 *txtQRZpathname; extern Fl_Round_Button *btnQRZsub; @@ -412,10 +416,10 @@ extern Fl_Input2 *inpQRZusername; extern Fl_Input2 *inpQRZuserpassword; extern Fl_Button *btnQRZpasswordShow; extern Fl_Round_Button *btnHamQTH; -extern Fl_Round_Button *btnQRZnotavailable; -extern Fl_Round_Button *btnQRZonline; -extern Fl_Round_Button *btnHAMCALLonline; -extern Fl_Round_Button *btnCALLOOK; +extern Fl_Input2 *inpEQSL_id; +extern Fl_Input2 *inpEQSL_pwd; +extern Fl_Button *btnEQSL_pwd_show; +extern Fl_Input2 *inpEQSL_nick; extern Fl_Button *btnSaveConfig; #include extern Fl_Return_Button *btnCloseConfig; diff --git a/src/include/configuration.h b/src/include/configuration.h index f57b0a4e..2c9a82c5 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -662,6 +662,16 @@ "QRZ or HamCall subscriber password", \ "") \ ELEM_(bool, QRZchanged, "", "", false) \ + /* eQSL */ \ + ELEM_(std::string, eqsl_id, "EQSL_ID", \ + "eQSL login id", \ + "") \ + ELEM_(std::string, eqsl_pwd, "EQSL_PASSWORD", \ + "eQSL login password", \ + "") \ + ELEM_(std::string, eqsl_nick, "EQSL_NICKNAME", \ + "eQSL nickname", \ + "") \ /* Rig control */ \ ELEM_(bool, btnusb, "BTNUSB", \ "This setting is currently unused", \ diff --git a/src/include/lookupcall.h b/src/include/lookupcall.h index 0a746a97..632ab500 100644 --- a/src/include/lookupcall.h +++ b/src/include/lookupcall.h @@ -18,4 +18,6 @@ extern void clear_Lookup(); extern void CALLSIGNquery(); enum qrz_query_t { QRZ_EXIT = -1, QRZNONE, QRZNET, QRZCD, HAMCALLNET, QRZHTML, HAMCALLHTML, CALLOOK, HAMQTH }; +extern void sendEQSL(const char *url); + #endif diff --git a/src/include/threads.h b/src/include/threads.h index 5231773c..938494c8 100644 --- a/src/include/threads.h +++ b/src/include/threads.h @@ -49,7 +49,7 @@ int pthread_cond_timedwait_rel(pthread_cond_t* cond, pthread_mutex_t* mutex, dou //}; enum { INVALID_TID = -1, - TRX_TID, QRZ_TID, RIGCTL_TID, NORIGCTL_TID, + TRX_TID, QRZ_TID, RIGCTL_TID, NORIGCTL_TID, EQSL_TID, #if USE_XMLRPC XMLRPC_TID, #endif diff --git a/src/misc/lookupcall.cxx b/src/misc/lookupcall.cxx index c5a1d606..c195e2c8 100644 --- a/src/misc/lookupcall.cxx +++ b/src/misc/lookupcall.cxx @@ -1005,3 +1005,98 @@ void CALLSIGNquery() pthread_cond_signal(&qrz_cond); pthread_mutex_unlock(&qrz_mutex); } + +//====================================================================== +// thread to support sending log entry to eQSL +//====================================================================== + +pthread_t* EQSLthread = 0; +pthread_mutex_t EQSLmutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t EQSLcond = PTHREAD_COND_INITIALIZER; + +static void *EQSL_loop(void *args); +static void EQSL_init(void); + +void EQSL_close(void); +void EQSL_send(); + +static std::string EQSL_url = ""; +static std::string EQSL_xmlpage = ""; + +static bool EQSLEXIT = false; + +static void *EQSL_loop(void *args) +{ + SET_THREAD_ID(EQSL_TID); + + SET_THREAD_CANCEL(); + + for (;;) { + TEST_THREAD_CANCEL(); + pthread_mutex_lock(&EQSLmutex); + pthread_cond_wait(&EQSLcond, &EQSLmutex); + pthread_mutex_unlock(&EQSLmutex); + + if (EQSLEXIT) + return NULL; + + size_t p; + if (fetch_http(EQSL_url, EQSL_xmlpage, 5.0) == -1) + LOG_ERROR("%s", "eQSL not available"); + + else if ((p = EQSL_xmlpage.find("Error:")) != std::string::npos) { + size_t p2 = EQSL_xmlpage.find('\n', p); + LOG_ERROR("%s", EQSL_xmlpage.substr(p, p2 - p - 1).c_str()); + } else + LOG_INFO("eQSL logged %s", EQSL_url.c_str()); + + } + return NULL; +} + +void EQSL_close(void) +{ + ENSURE_THREAD(FLMAIN_TID); + + if (!EQSLthread) + return; + + CANCEL_THREAD(*EQSLthread); + + pthread_mutex_lock(&qrz_mutex); + EQSLEXIT = true; + pthread_cond_signal(&qrz_cond); + pthread_mutex_unlock(&qrz_mutex); + + pthread_join(*QRZ_thread, NULL); + delete QRZ_thread; + QRZ_thread = 0; +} + +static void EQSL_init(void) +{ + ENSURE_THREAD(FLMAIN_TID); + + if (EQSLthread) + return; + EQSLthread = new pthread_t; + EQSLEXIT = false; + if (pthread_create(EQSLthread, NULL, EQSL_loop, NULL) != 0) { + LOG_PERROR("pthread_create"); + return; + } + MilliSleep(10); +} + +void sendEQSL(const char *url) +{ + ENSURE_THREAD(FLMAIN_TID); + + if (!EQSLthread) + EQSL_init(); + + pthread_mutex_lock(&EQSLmutex); + EQSL_url = url; + pthread_cond_signal(&EQSLcond); + pthread_mutex_unlock(&EQSLmutex); +} diff --git a/src/misc/macroedit.cxx b/src/misc/macroedit.cxx index f84cbd74..68d29aee 100644 --- a/src/misc/macroedit.cxx +++ b/src/misc/macroedit.cxx @@ -104,6 +104,7 @@ void loadBrowser(Fl_Widget *widget) { w->add(_("\tsave QSO data")); w->add(_("\tlog at xmt time")); w->add(_("\tclear log fields")); + w->add(_("\tlog eQSL optional msg")); w->add(LINE_SEP); w->add(_("\tQSO time (HHMM))")); diff --git a/src/misc/macros.cxx b/src/misc/macros.cxx index 01fdfa91..7f819e99 100644 --- a/src/misc/macros.cxx +++ b/src/misc/macros.cxx @@ -44,6 +44,9 @@ #include "qrunner.h" #include "waterfall.h" #include "rigsupport.h" +#include "network.h" +#include "logsupport.h" +#include "icons.h" #include #include @@ -1666,6 +1669,100 @@ static void pEXEC(std::string& s, size_t& i, size_t endbracket) } #endif // !__MINGW32__ +static void pEQSL(std::string& s, size_t& i, size_t endbracket) +{ + if (within_exec) { + s.replace(i, endbracket - i + 1, ""); + return; + } + size_t start = s.find(':', i); + + std::string msg = ""; + if (start != std::string::npos) + msg = s.substr(start + 1, endbracket-start-1); + + char sztemp[100]; + std::string tempstr; + std::string eQSL_url; + +// eqsl url header + eQSL_url = "http://www.eqsl.cc/qslcard/importADIF.cfm?ADIFdata=upload 2.1.9"; + snprintf(sztemp, sizeof(sztemp),"%s%s", + progdefaults.eqsl_id.length(), progdefaults.eqsl_id.c_str(), + progdefaults.eqsl_pwd.length(), progdefaults.eqsl_pwd.c_str()); + eQSL_url.append(sztemp); +// eqsl nickname + if (!progdefaults.eqsl_nick.empty()) { + snprintf(sztemp, sizeof(sztemp), "%s", + progdefaults.eqsl_nick.length(), progdefaults.eqsl_nick.c_str()); + eQSL_url.append(sztemp); + } + eQSL_url.append("FLDIGI"); +// band + tempstr = band_name(band(wf->rfcarrier())); + snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); + eQSL_url.append(sztemp); +// call + tempstr = inpCall->value(); + snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); + eQSL_url.append(sztemp); +// mode + tempstr = mode_info[active_modem->get_mode()].adif_name; +// test for modes not supported by eQSL + if ((tempstr.find("MFSK4") != std::string::npos) || + (tempstr.find("MFSK11") != std::string::npos) || + (tempstr.find("MFSK22") != std::string::npos) || + (tempstr.find("MFSK31") != std::string::npos) || + (tempstr.find("MFSK32") != std::string::npos) || + (tempstr.find("MFSK64") != std::string::npos) ) + tempstr = "MFSK16"; + if ((tempstr.find("PSK250") != std::string::npos) || + (tempstr.find("PSK500") != std::string::npos) || + (tempstr.find("PSK125R") != std::string::npos) || + (tempstr.find("PSK250R") != std::string::npos) || + (tempstr.find("PSK500R") != std::string::npos)) + tempstr = "PSK125"; + if ((tempstr.find("QPSK250") != std::string::npos) || + (tempstr.find("QPSK500") != std::string::npos) || + (tempstr.find("QPSK125R") != std::string::npos) || + (tempstr.find("QPSK250R") != std::string::npos) || + (tempstr.find("QPSK500R") != std::string::npos)) + tempstr = "QPSK125"; + + snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); + eQSL_url.append(sztemp); +// qso date + snprintf(sztemp, sizeof(sztemp), "%s", sDate_on.length(), sDate_on.c_str()); + eQSL_url.append(sztemp); +// qso time + tempstr = inpTimeOn->value(); + snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); + eQSL_url.append(sztemp); +// rst sent + tempstr = inpRstOut->value(); + snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); + eQSL_url.append(sztemp); +// message + if (!msg.empty()) { + snprintf(sztemp, sizeof(sztemp), "%s", msg.length(), msg.c_str()); + eQSL_url.append(sztemp); + } + eQSL_url.append(""); + + tempstr.clear(); + for (size_t n = 0; n < eQSL_url.length(); n++) { + if (eQSL_url[n] == ' ') tempstr.append("%20"); + else if (eQSL_url[n] == '<') tempstr.append("%3c"); + else if (eQSL_url[n] == '>') tempstr.append("%3e"); + else tempstr += eQSL_url[n]; + } + + sendEQSL(tempstr.c_str()); + + s.replace(i, endbracket - i + 1, ""); + return; +} + static void MAPIT(int how) { float lat = 0, lon = 0; @@ -1860,6 +1957,7 @@ static const MTAGS mtags[] = { {"", pLOG}, {"", pLNW}, {"", pCLRLOG}, +{" Date: Sun, 13 Nov 2011 09:49:02 -0600 Subject: [PATCH 49/54] guard lock * Added guard lock class - impacts upon - xmlrpc class implementation - wefax implementation * This ensures that a mutex is always unlocked when leaving a function or block --- src/include/threads.h | 24 +++++ src/include/wefax-pic.h | 2 + src/include/wefax.h | 26 +++++ src/misc/threads.cxx | 51 ++++++++- src/misc/xmlrpc.cxx | 227 ++++++++++++++++++++++++++++++++++++++-- src/wefax/wefax-pic.cxx | 225 +++++++++++++++++++++++++++++---------- src/wefax/wefax.cxx | 203 ++++++++++++++++++++++++++++++----- 7 files changed, 668 insertions(+), 90 deletions(-) diff --git a/src/include/threads.h b/src/include/threads.h index 938494c8..5a4b3525 100644 --- a/src/include/threads.h +++ b/src/include/threads.h @@ -124,4 +124,28 @@ bool thread_in_list(int id, const int* list); #include "fl_lock.h" +/// This ensures that a mutex is always unlocked when leaving a function or block. +class guard_lock +{ +public: + guard_lock(pthread_mutex_t* m); + ~guard_lock(void); +private: + pthread_mutex_t* mutex; +}; + +/// This wraps together a mutex and a condition variable which are used +/// together very often for queues etc... +class syncobj +{ + pthread_mutex_t m_mutex ; + pthread_cond_t m_cond ; +public: + syncobj(); + ~syncobj(); + pthread_mutex_t * mtxp(void) { return & m_mutex; } + void signal(); + bool wait( double seconds ); +}; + #endif // !THREADS_H_ diff --git a/src/include/wefax-pic.h b/src/include/wefax-pic.h index 989e4525..bdd4efa7 100644 --- a/src/include/wefax-pic.h +++ b/src/include/wefax-pic.h @@ -35,6 +35,8 @@ public: static void setpicture_link(wefax *me); static void save_image(const std::string & fil_name, const std::string & extra_comments); static void power( double start, double phase, double image, double black, double stop ); + static void send_image( const std::string & fil_name ); + static void restore_max_lines(void); }; #endif // _WEFAX_PIC_H diff --git a/src/include/wefax.h b/src/include/wefax.h index 3c69a7ca..07d01f42 100644 --- a/src/include/wefax.h +++ b/src/include/wefax.h @@ -28,6 +28,11 @@ class wefax : public modem { /// For updating the logbook when loading/saving an image file. cQsoRec m_qso_rec ; + + /// Non-copiable object. + wefax (); + wefax ( const wefax & ); + wefax & operator=( const wefax & ); public: wefax (trx_mode md); virtual ~wefax (); @@ -103,6 +108,27 @@ public: { m_adif_log = the_flag ; } + + /// Helper string indicating the internal state of the wefax engine. + std::string state_string(void) const; + + /// Maximum wait time when getting information about received and sent files. + static const int max_delay = 3600 * 24 * 365 ; + + /// Called by the engine when a file is received. + void put_received_file(const std::string & filnam); + + /// Used by XML-RPC to get the list of received files. + std::string get_received_file(double max_seconds=max_delay); + + /// Called by XML-RPC to send a file which resides on the machine where fldigi runs. + std::string send_file( const std::string & filnam, double max_seconds=max_delay); + + /// Called before sending a file. Transmitting is an exclusive process. + bool transmit_lock_acquire( const std::string & filnam, double max_seconds=max_delay); + + /// Called after sending a file so another sending can take place. + void transmit_lock_release( const std::string & err_msg ); }; #endif diff --git a/src/misc/threads.cxx b/src/misc/threads.cxx index f4849dc6..e03d69ce 100644 --- a/src/misc/threads.cxx +++ b/src/misc/threads.cxx @@ -21,7 +21,9 @@ // ---------------------------------------------------------------------------- #include - +#include +#include +#include #include "threads.h" THREAD_ID_TYPE thread_id_; @@ -99,3 +101,50 @@ void linux_log_tid(void) LOG_DEBUG(PACKAGE_TARNAME " thread %" PRIdPTR " is LWP %ld", GET_THREAD_ID(), syscall(SYS_gettid)); } #endif + +// Synchronization objects. + +guard_lock::guard_lock(pthread_mutex_t* m) : mutex(m) +{ + pthread_mutex_lock(mutex); +} + +guard_lock::~guard_lock(void) +{ + pthread_mutex_unlock(mutex); +} + +syncobj::syncobj() +{ + pthread_mutex_init( & m_mutex, NULL ); + pthread_cond_init( & m_cond, NULL ); +} + +syncobj::~syncobj() +{ + pthread_mutex_destroy( & m_mutex ); + pthread_cond_destroy( & m_cond ); +} + +void syncobj::signal() +{ + int rc = pthread_cond_signal( &m_cond ); + if( rc ) + { + throw std::runtime_error(strerror(rc)); + } +} + +bool syncobj::wait( double seconds ) +{ + int rc = pthread_cond_timedwait_rel( &m_cond, &m_mutex, seconds ); + switch( rc ) + { + case 0 : return true ; + default : throw std::runtime_error(strerror(rc)); + case ETIMEDOUT: return false ; + } +} + + + diff --git a/src/misc/xmlrpc.cxx b/src/misc/xmlrpc.cxx index ae9d7b1f..555d2d52 100644 --- a/src/misc/xmlrpc.cxx +++ b/src/misc/xmlrpc.cxx @@ -57,6 +57,8 @@ #include "waterfall.h" #include "macros.h" #include "qrunner.h" +#include "wefax.h" +#include "wefax-pic.h" #if USE_HAMLIB #include "hamlib.h" @@ -189,16 +191,8 @@ ostream& XML_RPC_Server::list_methods(ostream& out) // ============================================================================= // Methods that change the server state must call XMLRPC_LOCK - -class xmlrpc_lock -{ -public: - xmlrpc_lock(pthread_mutex_t* m) : mutex(m) { pthread_mutex_lock(mutex); } - ~xmlrpc_lock(void) { pthread_mutex_unlock(mutex); } -private: - pthread_mutex_t* mutex; -}; -#define XMLRPC_LOCK SET_THREAD_ID(XMLRPC_TID); xmlrpc_lock autolock_(server_mutex) +// guard_lock (include/threads.h) ensures that mutex are always unlocked. +#define XMLRPC_LOCK SET_THREAD_ID(XMLRPC_TID); guard_lock autolock_(server_mutex) // ============================================================================= @@ -2433,6 +2427,206 @@ public: // ============================================================================= +// Returns the current wefax modem pointer. +static wefax * get_wefax(void) +{ + if( ( active_modem->get_mode() >= MODE_WEFAX_FIRST ) + && ( active_modem->get_mode() <= MODE_WEFAX_LAST ) ) + { + wefax * ptr = dynamic_cast( active_modem ); + if( ptr == NULL ) throw runtime_error("Inconsistent wefax object"); + return ptr ; + } + throw runtime_error("Not in wefax mode"); +} + +struct Wefax_state_string : public xmlrpc_c::method +{ + Wefax_state_string() { + _signature = "s:n"; + _help = "Returns Wefax engine state (tx and rx) for information."; } + + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + try + { + *retval = xmlrpc_c::value_string( get_wefax()->state_string() ); + } + catch( const exception & e ) + { + *retval = xmlrpc_c::value_string( e.what()); + } +}; + +struct Wefax_skip_apt : public xmlrpc_c::method +{ + Wefax_skip_apt() { + _signature = "s:n"; + _help = "Skip APT during Wefax reception"; } + + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + try + { + get_wefax()->skip_apt(); + *retval = xmlrpc_c::value_string( "" ); + } + catch( const exception & e ) + { + *retval = xmlrpc_c::value_string( e.what() ); + } +}; + +/// TODO: Refresh the screen with the new value. +struct Wefax_skip_phasing : public xmlrpc_c::method +{ + Wefax_skip_phasing() { + _signature = "s:n"; + _help = "Skip phasing during Wefax reception"; } + + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + try + { + get_wefax()->skip_phasing(true); + *retval = xmlrpc_c::value_string( "" ); + } + catch( const exception & e ) + { + *retval = xmlrpc_c::value_string( e.what() ); + } +}; + +// TODO: The image should be reloaded just like cancelling from the GUI. +struct Wefax_set_tx_abort_flag : public xmlrpc_c::method +{ + Wefax_set_tx_abort_flag() { + _signature = "s:n"; + _help = "Cancels Wefax image transmission"; } + + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + try + { + get_wefax()->set_tx_abort_flag(); + *retval = xmlrpc_c::value_string( "" ); + } + catch( const exception & e ) + { + *retval = xmlrpc_c::value_string( e.what() ); + } +}; + +struct Wefax_end_reception : public xmlrpc_c::method +{ + Wefax_end_reception() { + _signature = "s:n"; + _help = "End Wefax image reception"; } + + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + try + { + get_wefax()->end_reception(); + *retval = xmlrpc_c::value_string( "" ); + } + catch( const exception & e ) + { + *retval = xmlrpc_c::value_string( e.what() ); + } +}; + +struct Wefax_start_manual_reception : public xmlrpc_c::method +{ + Wefax_start_manual_reception() { + _signature = "s:n"; + _help = "Starts fax image reception in manual mode"; } + + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + try + { + get_wefax()->set_rx_manual_mode(true); + get_wefax()->skip_apt(); + get_wefax()->skip_phasing(true); + *retval = xmlrpc_c::value_string( "" ); + } + catch( const exception & e ) + { + *retval = xmlrpc_c::value_string( e.what() ); + } +}; + +struct Wefax_set_adif_log : public xmlrpc_c::method +{ + Wefax_set_adif_log() { + _signature = "s:b"; + _help = "Set/reset logging to received/transmit images to ADIF log file"; } + + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + try + { + get_wefax()->set_adif_log( params.getBoolean(0)); + *retval = xmlrpc_c::value_string( "" ); + } + catch( const exception & e ) + { + *retval = xmlrpc_c::value_string( e.what() ); + } +}; + +struct Wefax_set_max_lines : public xmlrpc_c::method +{ + Wefax_set_max_lines() { + _signature = "s:i"; + _help = "Set maximum lines for fax image reception"; } + + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + try + { + get_wefax()->set_max_lines( params.getInt(0)); + /// This updates the GUI. + REQ( wefax_pic::restore_max_lines ); + *retval = xmlrpc_c::value_string( "" ); + } + catch( const exception & e ) + { + *retval = xmlrpc_c::value_string( e.what() ); + } +}; + +struct Wefax_get_received_file : public xmlrpc_c::method +{ + Wefax_get_received_file() { + _signature = "s:i"; + _help = "Waits for next received fax file, returns its name with a delay. Empty string if timeout."; } + + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + try + { + std::string filename = get_wefax()->get_received_file( params.getInt(0)); + *retval = xmlrpc_c::value_string( filename ); + } + catch( const exception & e ) + { + *retval = xmlrpc_c::value_string( e.what() ); + } +}; + +struct Wefax_send_file : public xmlrpc_c::method +{ + Wefax_send_file() { + _signature = "s:si"; + _help = "Send file. returns an empty string if OK otherwise an error message."; } + + void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval) + try + { + std::string status = get_wefax()->send_file( params.getString(0), params.getInt(1) ); + *retval = xmlrpc_c::value_string( status ); + } + catch( const exception & e ) + { + *retval = xmlrpc_c::value_string( e.what() ); + } +}; + +// ============================================================================= + // End XML-RPC interface // method list: ELEM_(class_name, "method_name") @@ -2586,7 +2780,18 @@ public: ELEM_(Spot_get_auto, "spot.get_auto") \ ELEM_(Spot_set_auto, "spot.set_auto") \ ELEM_(Spot_toggle_auto, "spot.toggle_auto") \ - ELEM_(Spot_pskrep_get_count, "spot.pskrep.get_count") + ELEM_(Spot_pskrep_get_count, "spot.pskrep.get_count") \ + \ + ELEM_(Wefax_state_string, "wefax.state_string") \ + ELEM_(Wefax_skip_apt, "wefax.skip_apt") \ + ELEM_(Wefax_skip_phasing, "wefax.skip_phasing") \ + ELEM_(Wefax_set_tx_abort_flag, "wefax.set_tx_abort_flag") \ + ELEM_(Wefax_end_reception, "wefax.end_reception") \ + ELEM_(Wefax_start_manual_reception, "wefax.start_manual_reception") \ + ELEM_(Wefax_set_adif_log, "wefax.set_adif_log") \ + ELEM_(Wefax_set_max_lines, "wefax.set_max_lines") \ + ELEM_(Wefax_get_received_file, "wefax.get_received_file") \ + ELEM_(Wefax_send_file, "wefax.send_file") \ struct rm_pred diff --git a/src/wefax/wefax-pic.cxx b/src/wefax/wefax-pic.cxx index f823cb79..eafccfc1 100644 --- a/src/wefax/wefax-pic.cxx +++ b/src/wefax/wefax-pic.cxx @@ -91,14 +91,20 @@ static Fl_Choice *wefax_choice_tx_lpm = (Fl_Choice *)0; static Fl_Round_Button *wefax_round_tx_adif_log = (Fl_Round_Button *)0; static Fl_Button *wefax_btn_tx_send_color = (Fl_Button *)0; static Fl_Button *wefax_btn_tx_send_grey = (Fl_Button *)0; +static Fl_Output *wefax_out_tx_row_num = (Fl_Output *)0; static Fl_Button *wefax_btn_tx_send_abort = (Fl_Button *)0; static Fl_Button *wefax_btn_tx_load = (Fl_Button *)0; +static Fl_Button *wefax_btn_tx_clear = (Fl_Button *)0; static Fl_Button *wefax_btn_tx_close = (Fl_Button *)0; static Fl_Shared_Image *wefax_shared_tx_img = (Fl_Shared_Image *)0; static unsigned char *wefax_xmtimg = (unsigned char *)0; static unsigned char *wefax_xmtpicbuff = (unsigned char *)0; +/// This indicates whether an image to send is loaded in the GUI. +/// It allows to acquire twice when re-loading an image without sending. +static bool wefax_image_loaded_in_gui = false ; + /// Used for shifting the received image left and right. static volatile int center_val_prev = 0 ; @@ -144,6 +150,43 @@ static const int mini_max_fax_lines = 1000 ; /// However, when the printing resumes, the position is not altered. static volatile bool reception_paused = false ; +/// Sets the label of the received or sent image. +static void set_win_label( Fl_Double_Window * wefax_pic, const std::string & lab) +{ + char* label = strdup(lab.c_str()); + wefax_pic->copy_label(label); + free(label); + wefax_pic->redraw(); +} + +/// Called when clearing the image to send. +static void clear_image(void) +{ + if (wefax_xmtimg) + { + delete [] wefax_xmtimg; + wefax_xmtimg = NULL ; + } + if (wefax_shared_tx_img) { + wefax_shared_tx_img->release(); + wefax_shared_tx_img = 0; + } + set_win_label(wefax_pic_tx_win,""); +} + +/// Clears the loaded image. It allows XML-RPC clients to send an image. +static void wefax_cb_pic_tx_clear( Fl_Widget *, void *) +{ + FL_LOCK_D(); + wefax_image_loaded_in_gui = false ; + clear_image(); + wefax_pic_tx_picture->clear(); + wefax_pic::restart_tx_viewer(); + /// Now the lock can be acquired by XML-RPC. + wefax_serviceme->transmit_lock_release( "Cleared" ); + FL_UNLOCK_D(); +} + static void wefax_cb_pic_tx_close( Fl_Widget *, void *) { FL_LOCK_D(); @@ -386,8 +429,7 @@ void wefax_pic::update_rx_pic_bw(unsigned char data, int pix_pos ) /// Prints the row number sometimes only, to save CPU. if( ( pix_pos % 1000 ) == 0 ) { char row_num_buffer[20]; - snprintf( row_num_buffer, sizeof(row_num_buffer), - "%d", row_number ); + snprintf( row_num_buffer, sizeof(row_num_buffer), "%d", row_number ); wefax_out_rx_row_num->value( row_num_buffer ); } @@ -439,6 +481,15 @@ static void wefax_cb_pic_rx_resume( Fl_Widget *, void *) wefax_serviceme->update_rx_label(); } +static void LocalSleep( int seconds ) +{ +#ifdef __MINGW32__ + MilliSleep(seconds); +#else + usleep(100000*seconds); +#endif +} + /// Displays the latest image file saved. static void add_to_files_list( const std::string & the_fil_nam ) { @@ -459,22 +510,21 @@ static void add_to_files_list( const std::string & the_fil_nam ) /// This window is hidden/shown to signal that a file was added. static const int nb_blink = 5 ; for( int ix_blink = 0 ; ix_blink < nb_blink ; ++ix_blink ) { -#ifdef __MINGW32__ wefax_browse_rx_events->hide(); wefax_browse_rx_events->redraw(); - MilliSleep(1); + LocalSleep(1); wefax_browse_rx_events->show(); wefax_browse_rx_events->redraw(); - MilliSleep(1); -#else - wefax_browse_rx_events->hide(); - wefax_browse_rx_events->redraw(); - usleep(100000); - wefax_browse_rx_events->show(); - wefax_browse_rx_events->redraw(); - usleep(100000); -#endif + LocalSleep(1); } + + /// If there is not directory specification, adds the default dir. + if( the_fil_nam.empty() ) + LOG_WARN("Empty file name"); + else if( the_fil_nam[0] != '/' ) + wefax_serviceme->put_received_file( progdefaults.wefax_save_dir + '/' + the_fil_nam ); + else + wefax_serviceme->put_received_file( the_fil_nam ); }; static void wefax_cb_pic_rx_abort( Fl_Widget *, void *) @@ -628,7 +678,7 @@ static void wefax_cb_rx_set_filter( Fl_Widget *, void * ) wefax_serviceme->set_rx_filter(ix_filter); } -static void restore_max_lines(void) +void wefax_pic::restore_max_lines(void) { char buf_max_lines[20]; snprintf( buf_max_lines, sizeof(buf_max_lines), "%d", wefax_serviceme->get_max_lines() ); @@ -643,15 +693,15 @@ static void wefax_cb_pic_max_lines( Fl_Widget *, void * ) /// The value given by FLTK should be an integer, but better to be sure. if( 1 != sscanf( ptr_val_gui, "%d", &max_val_gui ) ) { - LOG_ERROR( "Cannot parse: %s", ptr_val_gui ) ; - restore_max_lines(); + LOG_ERROR( _("Cannot parse: %s"), ptr_val_gui ) ; + wefax_pic::restore_max_lines(); return ; } /// Faxes should not be too small otherwise we will spend all our time /// saving automatic image files. if( max_val_gui < mini_max_fax_lines ) { - restore_max_lines(); + wefax_pic::restore_max_lines(); return ; } @@ -952,7 +1002,7 @@ void wefax_pic::create_rx_viewer(void) /// This buffer will never change so it does not matter if it is static. static char tooltip_max_lines[256]; snprintf(tooltip_max_lines, sizeof(tooltip_max_lines), - "Maximum number of lines per image. Must be bigger than %d", + "Maximum number of lines per image. Minimum value is %d", mini_max_fax_lines ); wefax_int_rx_max->tooltip(tooltip_max_lines); @@ -1068,11 +1118,7 @@ void wefax_pic::set_rx_label(const std::string & win_label) } /// This copy seems strange, but otherwise the label is not updated. - char* label = strdup(tmp_label.c_str()); - wefax_pic_rx_win->copy_label(label); - free(label); - - wefax_pic_rx_win->redraw_label(); + set_win_label(wefax_pic_rx_win, tmp_label); FL_UNLOCK_D(); } @@ -1090,33 +1136,31 @@ void wefax_pic::save_image(const std::string & fil_name, const std::string & ext wefax_serviceme->qso_rec_save(); } -static void wefax_load_image(const char *fil_name) +/// Protected by an exclusive mutex. +static std::string wefax_load_image_after_acquire(const char * fil_name) { - if (wefax_serviceme != active_modem) return; + if (wefax_serviceme != active_modem) return "Not in WEFAX mode"; wefax_serviceme->qso_rec_init(); qso_notes( "TX:", fil_name ); - if (wefax_shared_tx_img) { - wefax_shared_tx_img->release(); - wefax_shared_tx_img = 0; - } + clear_image(); wefax_shared_tx_img = Fl_Shared_Image::get(fil_name); if (!wefax_shared_tx_img) { - LOG_ERROR("Could not Fl_Shared_Image::get %s", fil_name); - return; + std::string err_msg("Cannot call Fl_Shared_Image::get on file:" + std::string(fil_name) ); + LOG_ERROR("%s",err_msg.c_str()); + return err_msg; } if (wefax_shared_tx_img->count() > 1) { // we only handle rgb images - LOG_ERROR("Handle only RGB images: %s", fil_name ); - wefax_shared_tx_img->release(); - wefax_shared_tx_img = 0; - return; + std::string err_msg("Handle only RGB images: " + std::string(fil_name) ); + LOG_ERROR("%s",err_msg.c_str()); + clear_image(); + return err_msg; } unsigned char * img_data = (unsigned char *)wefax_shared_tx_img->data()[0]; int img_wid = wefax_shared_tx_img->w(); int img_hei = wefax_shared_tx_img->h(); int img_depth = wefax_shared_tx_img->d(); - if (wefax_xmtimg) delete [] wefax_xmtimg; wefax_xmtimg = new unsigned char [img_wid * img_hei * bytes_per_pix]; if (img_depth == bytes_per_pix) memcpy(wefax_xmtimg, img_data, img_wid*img_hei*bytes_per_pix); @@ -1135,22 +1179,23 @@ static void wefax_load_image(const char *fil_name) wefax_xmtimg[j] = wefax_xmtimg[j+1] = wefax_xmtimg[j+2] = img_data[i]; } } else { - LOG_ERROR( "Inconsistent img_depth=%d\n", img_depth ); - exit(EXIT_FAILURE); + std::stringstream err_strm ; + err_strm << "Inconsistent img_depth=" << img_depth << " for " << fil_name ; + std::string err_msg = err_strm.str(); + LOG_ERROR("%s",err_msg.c_str()); + return err_msg ; }; wefax_pic::tx_viewer_resize(img_wid, img_hei); - char* label = strdup(fil_name); - wefax_pic_tx_win->copy_label(basename(label)); - free(label); + set_win_label(wefax_pic_tx_win, fil_name); + wefax_pic_tx_box->label(0); // load the picture widget with the rgb image FL_LOCK_D(); wefax_pic_tx_picture->show(); wefax_pic_tx_picture->clear(); - wefax_pic_tx_win->redraw(); wefax_pic_tx_picture->video(wefax_xmtimg, img_wid * img_hei * bytes_per_pix); int tim_color = wefax_serviceme->tx_time( img_wid * img_hei * bytes_per_pix ); @@ -1167,7 +1212,22 @@ static void wefax_load_image(const char *fil_name) wefax_btn_tx_send_grey->tooltip(wefax_txgry_tooltip); wefax_btn_tx_send_grey->activate(); + wefax_btn_tx_clear->activate(); + FL_UNLOCK_D(); + return std::string(); +} + +static void wefax_load_image(const char * fil_name) +{ + if (wefax_serviceme != active_modem) return; + if( false == wefax_image_loaded_in_gui ) + { + /// So we do not re-acquire the exclusive access to wefax transmission. + wefax_serviceme->transmit_lock_acquire(fil_name); + wefax_image_loaded_in_gui = true ; + } + wefax_load_image_after_acquire(fil_name); } void wefax_pic::set_tx_pic(unsigned char data, int col, int row, int tx_img_col, bool is_color ) @@ -1190,6 +1250,15 @@ void wefax_pic::set_tx_pic(unsigned char data, int col, int row, int tx_img_col, wefax_pic_tx_picture->pixel( data, tripleOffset + 1 ); wefax_pic_tx_picture->pixel( data, tripleOffset + 2 ); } + + static int previous_row = -1 ; + if( row != previous_row ) + { + previous_row = row ; + char row_num_buffer[20]; + snprintf( row_num_buffer, sizeof(row_num_buffer), "%d", row ); + wefax_out_tx_row_num->value( row_num_buffer ); + } } static void wefax_cb_pic_tx_load(Fl_Widget *, void *) @@ -1218,13 +1287,18 @@ static void wefax_pic_tx_send_common( FL_LOCK_D(); wefax_choice_tx_lpm->hide(); + wefax_round_tx_adif_log->hide(); wefax_btn_tx_send_color->hide(); wefax_btn_tx_send_grey->hide(); wefax_btn_tx_load->hide(); + wefax_btn_tx_clear->hide(); wefax_btn_tx_close->hide(); + wefax_out_tx_row_num->show(); wefax_btn_tx_send_abort->show(); wefax_pic_tx_picture->clear(); + wefax_out_tx_row_num->value( "Init" ); + wefax_serviceme->set_tx_parameters( get_choice_lpm_value( wefax_choice_tx_lpm ), wefax_xmtpicbuff, @@ -1306,12 +1380,27 @@ static void wefax_cb_pic_tx_adif_log( Fl_Widget *, void *) void wefax_pic::restart_tx_viewer(void) { + wefax_out_tx_row_num->hide(); wefax_btn_tx_send_abort->hide(); - wefax_choice_tx_lpm->show(); - wefax_btn_tx_send_color->show(); - wefax_btn_tx_send_grey->show(); + wefax_round_tx_adif_log->show(); wefax_btn_tx_load->show(); wefax_btn_tx_close->show(); + if( wefax_image_loaded_in_gui ) + { + // If the image was loaded from the GUI. + wefax_choice_tx_lpm->show(); + wefax_btn_tx_send_color->show(); + wefax_btn_tx_send_grey->show(); + wefax_btn_tx_clear->show(); + } + else + { + /// If the image was loaded and sent from XML-RPC, or no image present. + wefax_choice_tx_lpm->deactivate(); + wefax_btn_tx_send_color->deactivate(); + wefax_btn_tx_send_grey->deactivate(); + wefax_btn_tx_clear->deactivate(); + } } void wefax_pic::create_tx_viewer(void) @@ -1351,7 +1440,7 @@ void wefax_pic::create_tx_viewer(void) static const int hei_tx_btn = 24 ; int width_btn = 0; - int width_offset = 35; + int width_offset = 30; width_btn = 70 ; wefax_choice_tx_lpm = make_lpm_choice( width_offset, y_btn, width_btn, hei_tx_btn ); @@ -1366,33 +1455,46 @@ void wefax_pic::create_tx_viewer(void) wefax_round_tx_adif_log->align(FL_ALIGN_LEFT); width_offset += width_btn ; - width_btn = 60 ; - wefax_btn_tx_send_color = new Fl_Button(width_offset, y_btn, width_btn, hei_tx_btn, "Xmt Color"); + width_btn = 50 ; + wefax_btn_tx_send_color = new Fl_Button(width_offset, y_btn, width_btn, hei_tx_btn, "Tx Color"); wefax_btn_tx_send_color->callback(wefax_cb_pic_tx_send_color, 0); width_offset += width_btn ; - width_btn = 60 ; - wefax_btn_tx_send_grey = new Fl_Button(width_offset, y_btn, width_btn, hei_tx_btn, "Xmt Grey"); + width_btn = 50 ; + wefax_btn_tx_send_grey = new Fl_Button(width_offset, y_btn, width_btn, hei_tx_btn, "Tx B/W"); wefax_btn_tx_send_grey->callback( wefax_cb_pic_tx_send_grey, 0); width_offset += width_btn ; - width_btn = 40 ; + width_btn = 35 ; wefax_btn_tx_load = new Fl_Button(width_offset, y_btn, width_btn, hei_tx_btn, _("Load")); wefax_btn_tx_load->callback(wefax_cb_pic_tx_load, 0); wefax_btn_tx_load->tooltip("Load image to send"); width_offset += width_btn ; - width_btn = 40 ; + width_btn = 35 ; + wefax_btn_tx_clear = new Fl_Button(width_offset, y_btn, width_btn, hei_tx_btn, _("Clear")); + wefax_btn_tx_clear->callback(wefax_cb_pic_tx_clear, 0); + + width_offset += width_btn ; + width_btn = 35 ; wefax_btn_tx_close = new Fl_Button(width_offset, y_btn, width_btn, hei_tx_btn, _("Close")); wefax_btn_tx_close->callback(wefax_cb_pic_tx_close, 0); - wefax_btn_tx_send_abort = new Fl_Button(84, y_btn, 122, hei_tx_btn, "Abort Xmt"); + static const char * title_row_num = "" ; + width_offset += fl_width( title_row_num ); + wefax_out_tx_row_num = new Fl_Output(20, y_btn, 100, hei_tx_btn, _(title_row_num)); + wefax_out_tx_row_num->align(FL_ALIGN_LEFT); + wefax_out_tx_row_num->tooltip("Fax line number being sent."); + + wefax_btn_tx_send_abort = new Fl_Button(180, y_btn, 122, hei_tx_btn, "Abort Xmt"); wefax_btn_tx_send_abort->callback(wefax_cb_pic_tx_send_abort, 0); wefax_btn_tx_send_abort->tooltip("Abort transmission"); + wefax_out_tx_row_num->hide(); wefax_btn_tx_send_abort->hide(); wefax_btn_tx_send_color->deactivate(); wefax_btn_tx_send_grey->deactivate(); + wefax_btn_tx_clear->deactivate(); wefax_pic_tx_win->end(); FL_UNLOCK_D(); @@ -1511,4 +1613,21 @@ void wefax_pic::cb_mnu_pic_viewer(Fl_Menu_ *, void *) { } } +/// Called from XML-RPC thread. +void wefax_pic::send_image( const std::string & fil_nam ) +{ + LOG_INFO("%s", fil_nam.c_str() ); + /// Here, transmit_lock_acquire is called by the XML-RPC client. + std::string err_msg = wefax_load_image_after_acquire( fil_nam.c_str() ); + if( ! err_msg.empty() ) + { + if (wefax_serviceme == active_modem) + { + /// Allows another XML-RPC client or the GUI to send an image. + wefax_serviceme->transmit_lock_release( err_msg ); + } + return ; + } + wefax_cb_pic_tx_send_grey( NULL, NULL ); +} diff --git a/src/wefax/wefax.cxx b/src/wefax/wefax.cxx index ff359e99..a881d1e5 100644 --- a/src/wefax/wefax.cxx +++ b/src/wefax/wefax.cxx @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include "debug.h" @@ -277,7 +279,7 @@ static const char * state_to_str(fax_state a_state) case TXIMAGE : return "Sending image" ; case IDLE : return "Idle" ; } - return "UNKOWN" ; + return "UNKNOWN" ; }; /// TODO: This should be hidden to this class. @@ -351,12 +353,6 @@ class fax_implementation { double m_i_fir_old; double m_q_fir_old; - /// Returns a string telling the RX state. Mostly for debugging. - const char * state_rx_str(void) const - { - return state_to_str(m_rx_state); - }; - void decode(const int* buf, int nb_samples); /// Used for transmission. @@ -378,6 +374,7 @@ class fax_implementation { m_img_sample = 0; m_pix_samples_nb = 0; } + public: fax_implementation(int fax_mode, wefax * ptr_wefax ); void init_rx(int the_smpl_rate); @@ -395,7 +392,7 @@ public: int img_w, int img_h, int xmt_bytes ); - void trx_do_next(void); + bool trx_do_next(void); void tx_apt_stop(void); double carrier(void) const @@ -446,6 +443,21 @@ public: /// This generates a filename based on the frequency, current time, internal state etc... std::string generate_filename( const char *extra_msg ) const ; + std::string state_rx_str(void) const + { + return state_to_str(m_rx_state); + } + + /// Returns a string telling the state. Informational purpose. + std::string state_string(void) const + { + std::stringstream result ; + result << "tx:" << state_to_str(m_tx_state) + << " " + << "rx:" << state_to_str(m_rx_state); + return result.str(); + }; + private: /// Centered around the frequency. double power_usb_noise(void) const @@ -685,9 +697,107 @@ private: void decode_apt(int x, const fax_signal & the_signal ); void decode_phasing(int x, const fax_signal & the_signal ); bool decode_image(int x); + +private: + /// Each received file has its name pushed in this queue. + syncobj m_sync_rx ; + std::queue< std::string > m_received_files ; +public: + /// Called by the engine each time a file is saved. + void put_received_file( const std::string &filnam ) + { + guard_lock g( m_sync_rx.mtxp() ); + LOG_INFO("%s", filnam.c_str() ); + m_received_files.push( filnam ); + m_sync_rx.signal(); + } + + /// Returns a received file name, by chronological order. + std::string get_received_file( double max_seconds ) + { + guard_lock g( m_sync_rx.mtxp() ); + + LOG_INFO("delay=%f", max_seconds ); + if( m_received_files.empty() ) + { + if( ! m_sync_rx.wait(max_seconds) ) return std::string(); + } + std::string filnam = m_received_files.front(); + m_received_files.pop(); + return filnam ; + } +private: + /// No unicity if the same filename is sent by several clients at the same time. + /// This does not really matter because the error codes should be the same. + syncobj m_sync_tx_fil ; + std::string m_tx_fil ; // Filename being transmitted. + + syncobj m_sync_tx_msg ; + typedef std::map< std::string, std::string > sent_files_type ; + sent_files_type m_sent_files ; +public: + /// If the delay is exceeded, returns with an error message. + std::string send_file( const std::string & filnam, double max_seconds ) + { + LOG_INFO("%s", filnam.c_str() ); + bool is_acquired = transmit_lock_acquire(filnam, max_seconds); + if( ! is_acquired ) return "Timeout sending " + filnam ; + + REQ( wefax_pic::send_image, filnam ); + + guard_lock g( m_sync_tx_fil.mtxp() ); + + sent_files_type::iterator itFi ; + while(true) + { + itFi = m_sent_files.find( filnam ); + if( itFi != m_sent_files.end() ) + { + break ; + } + if( ! m_sync_tx_msg.wait( max_seconds ) ) + { + return "Timeout"; + } + } + std::string err_msg = itFi->second ; + m_sent_files.erase( itFi ); + return err_msg ; + } + + /// Called when loading a file from the GUI, or indirectly from XML-RPC. + bool transmit_lock_acquire(const std::string & filnam, double delay = wefax::max_delay ) + { + LOG_INFO("%s", filnam.c_str() ); + guard_lock g( m_sync_tx_fil.mtxp() ); + if ( ! m_tx_fil.empty() ) + { + if( ! m_sync_tx_fil.wait( delay ) ) return false ; + } + m_tx_fil = filnam ; + return true ; + } + + /// Allows to send another file. Called by XML-RPC and the GUI. + void transmit_lock_release( const std::string & err_msg ) + { + guard_lock g( m_sync_tx_msg.mtxp() ); + LOG_INFO("%s %s", m_tx_fil.c_str(), err_msg.c_str() ); + if( m_tx_fil.empty() ) + { + LOG_WARN("%s File name should not be empty", err_msg.c_str() ); + } + else + { + m_sent_files[ m_tx_fil ] = err_msg ; + m_tx_fil.clear(); + } + m_sync_tx_msg.signal(); + } + }; // class fax_implementation -/// Narrow, middle etc... input filters. Constructed at program startup. +/// Narrow, middle etc... input filters. Constructed at program startup. Readonly. fir_filter_pair_set fax_implementation::m_rx_filters ; fax_implementation::fax_implementation( int fax_mode, wefax * ptr_wefax ) @@ -704,6 +814,8 @@ fax_implementation::fax_implementation( int fax_mode, wefax * ptr_wefax ) m_start_duration = 5 ; m_stop_duration = 5 ; m_manual_mode = false ; + m_rx_state = IDLE ; + m_tx_state = IDLE ; int index_of_correlation ; /// http://en.wikipedia.org/wiki/Radiofax @@ -1124,7 +1236,7 @@ void fax_implementation::skip_apt_rx(void) { wefax_pic::skip_rx_apt(); if(m_rx_state!=RXAPTSTART) { - LOG_ERROR("Should be in APT state. State=%s. Manual=%d", state_rx_str(), m_manual_mode ); + LOG_ERROR("Should be in APT state. State=%s. Manual=%d", state_rx_str().c_str(), m_manual_mode ); } m_lpm_img=m_lpm_sum_rx=0; m_rx_state=RXPHASING; @@ -1143,7 +1255,7 @@ void fax_implementation::skip_phasing_to_image(bool auto_center) REQ( wefax_pic::skip_rx_phasing, auto_center ); if(m_rx_state!=RXPHASING) { - LOG_ERROR("Should be in phasing state. State=%s", state_rx_str() ); + LOG_ERROR("Should be in phasing state. State=%s", state_rx_str().c_str() ); } m_rx_state=RXIMAGE; @@ -1167,7 +1279,7 @@ void fax_implementation::skip_phasing_to_image(bool auto_center) void fax_implementation::skip_phasing_rx(bool auto_center) { if(m_rx_state!=RXPHASING) { - LOG_ERROR("Should be in phasing state. State=%s", state_rx_str() ); + LOG_ERROR("Should be in phasing state. State=%s", state_rx_str().c_str() ); } skip_phasing_to_image(auto_center); @@ -1307,10 +1419,9 @@ void fax_implementation::modulate(const double* buffer, int number) m_ptr_wefax->ModulateXmtr( stack_xmt_buf, number ); } -/// Returns the number of pixels written from the image. -void fax_implementation::trx_do_next(void) +/// Returns true if succesful +bool fax_implementation::trx_do_next(void) { - LOG_DEBUG("m_xmt_bytes=%d m_lpm_img=%f", m_xmt_bytes, m_lpm_img ); /// The number of samples sent for one line. The LPM is given by the GUI. @@ -1321,8 +1432,8 @@ void fax_implementation::trx_do_next(void) double buf[block_len]; bool end_of_loop = false ; + bool tx_completed = true ; int curr_sample_idx = 0 , nb_samples_to_send = 0 ; - const char * curr_status_msg = "APT start" ; for(int num_bytes_to_write=0; ; ++num_bytes_to_write ) { bool disp_msg = ( ( num_bytes_to_write % block_len ) == 0 ) && ( num_bytes_to_write > 0 ); @@ -1330,9 +1441,11 @@ void fax_implementation::trx_do_next(void) if( disp_msg ) { modulate( buf, num_bytes_to_write); + const char * curr_status_msg = state_to_str( m_tx_state ); /// TODO: Should be multiplied by 3 when sending in BW ? if( m_ptr_wefax->is_tx_finished(curr_sample_idx, nb_samples_to_send, curr_status_msg ) ) { end_of_loop = true ; + tx_completed = false; continue ; }; num_bytes_to_write = 0 ; @@ -1347,7 +1460,6 @@ void fax_implementation::trx_do_next(void) curr_sample_idx++; } else { m_tx_state=TXPHASING; - curr_status_msg = "Phasing" ; curr_sample_idx=0; } } @@ -1361,7 +1473,6 @@ void fax_implementation::trx_do_next(void) curr_sample_idx++; } else { m_tx_state=ENDPHASING; - curr_status_msg = "End phasing" ; curr_sample_idx=0; } } @@ -1372,7 +1483,6 @@ void fax_implementation::trx_do_next(void) curr_sample_idx++; } else { m_tx_state=TXIMAGE; - curr_status_msg = "Sending image" ; curr_sample_idx=0; } } @@ -1447,7 +1557,6 @@ void fax_implementation::trx_do_next(void) } } else { m_tx_state=TXAPTSTOP; - curr_status_msg = "APT stop" ; curr_sample_idx=0; } } @@ -1458,12 +1567,12 @@ void fax_implementation::trx_do_next(void) curr_sample_idx++; } else { m_tx_state=IDLE; - curr_status_msg = "Finished" ; end_of_loop = true ; continue ; } } } // loop + return tx_completed ; } void fax_implementation::tx_params_set( @@ -1724,14 +1833,20 @@ void wefax::set_tx_parameters( /// Callback continuously called by fldigi modem class. int wefax::tx_process() { - m_impl->trx_do_next(); - + bool tx_was_completed = m_impl->trx_do_next(); + std::string status ; + if( false == tx_was_completed ) { + status = "Transmission cancelled"; + LOG_INFO("Sending cancelled" ); + m_qso_rec.putField(NOTES, status.c_str() ); + } qso_rec_save(); REQ_FLUSH(GET_THREAD_ID()); FL_LOCK_E(); wefax_pic::restart_tx_viewer(); + transmit_lock_release(status); m_abortxmt = false; FL_UNLOCK_E(); m_impl->tx_apt_stop(); @@ -1779,10 +1894,10 @@ void wefax::set_lpm( int the_lpm ) return m_impl->lpm_set( the_lpm ); } -/// Transmission time in seconds. +/// Transmission time in seconds. Factor 3 if b/w image. int wefax::tx_time( int nb_bytes ) const { - return (double)nb_bytes / modem::samplerate ; + return (double)nb_bytes / ( modem::samplerate * 3.0 ); } /// This prints a message about the progress of image sending, @@ -1825,6 +1940,7 @@ std::string wefax::suggested_filename(void) const return m_impl->generate_filename( "gui" ); }; +/// This creates a QSO record to be written to an adif file. void wefax::qso_rec_init(void) { if( m_adif_log == false ) { @@ -1884,6 +2000,7 @@ void wefax::qso_rec_init(void) // m_qso_rec.putField(TX_PWR, inpTX_pwr_log->value()); } +/// Called once a QSO rec has been filled with information. Saved to adif file. void wefax::qso_rec_save(void) { if( m_adif_log == false ) { @@ -1914,3 +2031,39 @@ void wefax::set_freq(double) modem::set_freq(m_impl->carrier()); } +// String telling the tx and rx internal state. +std::string wefax::state_string(void) const +{ + return m_impl->state_string(); +} + +/// Called when a file is saved, so XML-RPC calls can get the filename. +void wefax::put_received_file( const std::string &filnam ) +{ + m_impl->put_received_file( filnam ); +} + +/// Returns a received file name, by chronological order. +std::string wefax::get_received_file( double max_seconds ) +{ + return m_impl->get_received_file( max_seconds ); +} + +/// This is not thread-safe, at all. +std::string wefax::send_file( const std::string & filnam, double max_seconds ) +{ + return m_impl->send_file( filnam, max_seconds ); +} + +/// Transmitting files is done in exclusive mode. +bool wefax::transmit_lock_acquire(const std::string & filnam, double max_seconds ) +{ + return m_impl->transmit_lock_acquire( filnam, max_seconds ); +} + +/// Called after a file is sent. +void wefax::transmit_lock_release( const std::string & err_msg ) +{ + m_impl->transmit_lock_release( err_msg ); +} + From ae91a9063bc11d9e9b46afb2f6a513366ff825d0 Mon Sep 17 00:00:00 2001 From: David Freese Date: Sun, 13 Nov 2011 17:39:07 -0600 Subject: [PATCH 50/54] Version 3.21.25 Maintenance release --- ChangeLog | 12 +++++++++++- configure.ac | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 00329477..722d3c86 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,14 @@ -2011-11-10 David Freese + + +=Version 3.21.25= + +2011-11-13 David Freese + + 50fa414: guard lock + c2ba559: eQSL + + +=Version 3.21.24= 16fc289: Exec macro 0859928: QRZ on-line lookup diff --git a/configure.ac b/configure.ac index afdc11c0..412b4bb0 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [3]) m4_define(FLDIGI_MINOR, [21]) -m4_define(FLDIGI_PATCH, [.24]) +m4_define(FLDIGI_PATCH, [.25]) m4_define(FLARQ_MAJOR, [4]) m4_define(FLARQ_MINOR, [3]) m4_define(FLARQ_PATCH, [.1]) From ee27d64e6e195cd9db6ecc2d35ed40ff3794d178 Mon Sep 17 00:00:00 2001 From: David Freese Date: Mon, 14 Nov 2011 06:34:51 -0600 Subject: [PATCH 51/54] eQSL update * Added embedded tags to optional message - {CALL} other operators callsign - {NAME} other operators name - {MODE} full mode / submode eQSL.cc does not accept all submodes, i.e MFSK11 must be logged at MFSK16 THROB4 must be logged as THRB etc. This tag allows you to add specificity to the eQSL record * Added default message * Added switch to enable sending eQSL when either - log button is pressed - or is encountered in macro - logic to disallow duplicating eQSL submission --- src/dialogs/confdialog.cxx | 63 +++++++++++++++++++++ src/dialogs/confdialog.fl | 47 +++++++++++++++- src/include/confdialog.h | 5 ++ src/include/configuration.h | 6 ++ src/include/lookupcall.h | 1 + src/logger/logger.cxx | 4 ++ src/misc/lookupcall.cxx | 107 +++++++++++++++++++++++++++++++++++- src/misc/macros.cxx | 82 +-------------------------- 8 files changed, 233 insertions(+), 82 deletions(-) diff --git a/src/dialogs/confdialog.cxx b/src/dialogs/confdialog.cxx index 19d80af8..09d16c54 100644 --- a/src/dialogs/confdialog.cxx +++ b/src/dialogs/confdialog.cxx @@ -4,6 +4,7 @@ #include "confdialog.h" #include #include +#include #include #include "main.h" #include "fl_digi.h" @@ -2998,6 +2999,26 @@ static void cb_inpEQSL_nick(Fl_Input2* o, void*) { progdefaults.changed = true; } +Fl_Check_Button *btn_send_when_logged=(Fl_Check_Button *)0; + +static void cb_btn_send_when_logged(Fl_Check_Button* o, void*) { + progdefaults.eqsl_when_logged = o->value(); +progdefaults.changed = true; +} + +Fl_Input2 *txt_eqsl_default_message=(Fl_Input2 *)0; + +static void cb_txt_eqsl_default_message(Fl_Input2* o, void*) { + progdefaults.eqsl_default_message = o->value(); +progdefaults.changed = true; +} + +Fl_Box *eqsl_txt1=(Fl_Box *)0; + +Fl_Box *eqsl_txt2=(Fl_Box *)0; + +Fl_Box *eqsl_txt3=(Fl_Box *)0; + Fl_Button *btnSaveConfig=(Fl_Button *)0; static void cb_btnSaveConfig(Fl_Button*, void*) { @@ -6701,6 +6722,48 @@ d frequency")); o->value(progdefaults.eqsl_nick.c_str()); inpEQSL_nick->labelsize(FL_NORMAL_SIZE); } // Fl_Input2* inpEQSL_nick + { Fl_Group* o = new Fl_Group(4, 170, 492, 194, _("Options")); + o->box(FL_ENGRAVED_FRAME); + o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + { Fl_Check_Button* o = btn_send_when_logged = new Fl_Check_Button(29, 191, 70, 15, _("send when logged (log button, , )")); + btn_send_when_logged->tooltip(_("eQSL upload when record logged")); + btn_send_when_logged->down_box(FL_DOWN_BOX); + btn_send_when_logged->callback((Fl_Callback*)cb_btn_send_when_logged); + o->value(progdefaults.eqsl_when_logged); + } // Fl_Check_Button* btn_send_when_logged + { Fl_Input2* o = txt_eqsl_default_message = new Fl_Input2(33, 226, 451, 40, _("Default message")); + txt_eqsl_default_message->tooltip(_("Default message sent with eQSL")); + txt_eqsl_default_message->type(4); + txt_eqsl_default_message->box(FL_DOWN_BOX); + txt_eqsl_default_message->color((Fl_Color)FL_BACKGROUND2_COLOR); + txt_eqsl_default_message->selection_color((Fl_Color)FL_SELECTION_COLOR); + txt_eqsl_default_message->labeltype(FL_NORMAL_LABEL); + txt_eqsl_default_message->labelfont(0); + txt_eqsl_default_message->labelsize(14); + txt_eqsl_default_message->labelcolor((Fl_Color)FL_FOREGROUND_COLOR); + txt_eqsl_default_message->callback((Fl_Callback*)cb_txt_eqsl_default_message); + txt_eqsl_default_message->align(FL_ALIGN_TOP_LEFT); + txt_eqsl_default_message->when(FL_WHEN_CHANGED); + o->value(progdefaults.eqsl_default_message.c_str()); + } // Fl_Input2* txt_eqsl_default_message + { Fl_Group* o = new Fl_Group(8, 270, 484, 90, _("Text Tags (tags use {} delimiters)")); + o->box(FL_THIN_DOWN_BOX); + o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + { eqsl_txt1 = new Fl_Box(14, 317, 220, 17, _("{CALL} other ops call sign")); + eqsl_txt1->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + } // Fl_Box* eqsl_txt1 + { eqsl_txt2 = new Fl_Box(12, 336, 220, 17, _("{MODE} full mode / submode")); + eqsl_txt2->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + } // Fl_Box* eqsl_txt2 + { eqsl_txt3 = new Fl_Box(260, 317, 220, 17, _("{NAME} other ops name")); + eqsl_txt3->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + } // Fl_Box* eqsl_txt3 + { new Fl_Box(28, 293, 440, 17, _("These tags can also be used in ")); + } // Fl_Box* o + o->end(); + } // Fl_Group* o + o->end(); + } // Fl_Group* o o->end(); } // Fl_Group* o o->end(); diff --git a/src/dialogs/confdialog.fl b/src/dialogs/confdialog.fl index cdf1f387..3266ebe7 100644 --- a/src/dialogs/confdialog.fl +++ b/src/dialogs/confdialog.fl @@ -9,6 +9,8 @@ decl {\#include } {} decl {\#include } {} +decl {\#include } {} + decl {\#include } {} decl {\#include "main.h"} {} @@ -98,14 +100,14 @@ static const char szBaudRates[] = "300|600|1200|2400|4800|9600|19200|38400|57600 static const char szProsigns[] = "~|%|&|+|=|{|}|<|>|[|]| ";} {} Fl_Window {} { label {Fldigi configuration} open - xywh {644 190 500 400} type Double color 45 selection_color 51 labelsize 18 align 80 non_modal visible + xywh {592 125 500 400} type Double color 45 selection_color 51 labelsize 18 align 80 non_modal visible } { Fl_Tabs tabsConfigure {open xywh {-4 0 521 372} color 50 selection_color 50 } { Fl_Group tabOperator { label Operator - callback {progdefaults.changed = true;} selected + callback {progdefaults.changed = true;} open selected tooltip {Operator information} xywh {0 25 500 345} when 1 } { Fl_Group {} { @@ -3823,6 +3825,47 @@ progdefaults.changed = true;} code1 {inpEQSL_nick->labelsize(FL_NORMAL_SIZE);} class Fl_Input2 } + Fl_Group {} { + label Options open + xywh {4 170 492 194} box ENGRAVED_FRAME align 21 + } { + Fl_Check_Button btn_send_when_logged { + label {send when logged (log button, , )} + callback {progdefaults.eqsl_when_logged = o->value(); +progdefaults.changed = true;} + tooltip {eQSL upload when record logged} xywh {29 191 70 15} down_box DOWN_BOX + code0 {o->value(progdefaults.eqsl_when_logged);} + } + Fl_Input txt_eqsl_default_message { + label {Default message} + callback {progdefaults.eqsl_default_message = o->value(); +progdefaults.changed = true;} + tooltip {Default message sent with eQSL} xywh {33 226 451 40} type Multiline align 5 when 1 + code0 {o->value(progdefaults.eqsl_default_message.c_str());} + class Fl_Input2 + } + Fl_Group {} { + label {Text Tags (tags use {} delimiters)} open + xywh {8 270 484 90} box THIN_DOWN_BOX align 21 + } { + Fl_Box eqsl_txt1 { + label {{CALL} other ops call sign} + xywh {14 317 220 17} align 20 + } + Fl_Box eqsl_txt2 { + label {{MODE} full mode / submode} + xywh {12 336 220 17} align 20 + } + Fl_Box eqsl_txt3 { + label {{NAME} other ops name} + xywh {260 317 220 17} align 20 + } + Fl_Box {} { + label {These tags can also be used in } + xywh {28 293 440 17} + } + } + } } } } diff --git a/src/include/confdialog.h b/src/include/confdialog.h index 03c2da4a..bc0ca26b 100644 --- a/src/include/confdialog.h +++ b/src/include/confdialog.h @@ -420,6 +420,11 @@ extern Fl_Input2 *inpEQSL_id; extern Fl_Input2 *inpEQSL_pwd; extern Fl_Button *btnEQSL_pwd_show; extern Fl_Input2 *inpEQSL_nick; +extern Fl_Check_Button *btn_send_when_logged; +extern Fl_Input2 *txt_eqsl_default_message; +extern Fl_Box *eqsl_txt1; +extern Fl_Box *eqsl_txt2; +extern Fl_Box *eqsl_txt3; extern Fl_Button *btnSaveConfig; #include extern Fl_Return_Button *btnCloseConfig; diff --git a/src/include/configuration.h b/src/include/configuration.h index 2c9a82c5..a3632daf 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -672,6 +672,12 @@ ELEM_(std::string, eqsl_nick, "EQSL_NICKNAME", \ "eQSL nickname", \ "") \ + ELEM_(std::string, eqsl_default_message, "EQSL_DEF_MSG", \ + "eQSl default message", \ + "") \ + ELEM_(bool, eqsl_when_logged, "EQSL_WHEN_LOGGED", \ + "Send eQSL when other log action invoked", \ + false) \ /* Rig control */ \ ELEM_(bool, btnusb, "BTNUSB", \ "This setting is currently unused", \ diff --git a/src/include/lookupcall.h b/src/include/lookupcall.h index 632ab500..4afff113 100644 --- a/src/include/lookupcall.h +++ b/src/include/lookupcall.h @@ -19,5 +19,6 @@ extern void CALLSIGNquery(); enum qrz_query_t { QRZ_EXIT = -1, QRZNONE, QRZNET, QRZCD, HAMCALLNET, QRZHTML, HAMCALLHTML, CALLOOK, HAMQTH }; extern void sendEQSL(const char *url); +extern void makeEQSL(const char *msg); #endif diff --git a/src/logger/logger.cxx b/src/logger/logger.cxx index a482919a..263c4869 100644 --- a/src/logger/logger.cxx +++ b/src/logger/logger.cxx @@ -46,6 +46,7 @@ #include "configuration.h" #include "logsupport.h" +#include "lookupcall.h" #include @@ -215,6 +216,9 @@ void submit_log(void) logmode = mode_info[active_modem->get_mode()].adif_name; + if (progdefaults.eqsl_when_logged) + makeEQSL(""); + if (progdefaults.xml_logbook) xml_add_record(); else diff --git a/src/misc/lookupcall.cxx b/src/misc/lookupcall.cxx index c195e2c8..de557716 100644 --- a/src/misc/lookupcall.cxx +++ b/src/misc/lookupcall.cxx @@ -44,10 +44,12 @@ #include "configuration.h" #include "lookupcall.h" +#include "logsupport.h" #include "main.h" #include "confdialog.h" #include "fl_digi.h" #include "qrzlib.h" +#include "trx.h" #include "xmlreader.h" @@ -1046,7 +1048,7 @@ static void *EQSL_loop(void *args) else if ((p = EQSL_xmlpage.find("Error:")) != std::string::npos) { size_t p2 = EQSL_xmlpage.find('\n', p); - LOG_ERROR("%s", EQSL_xmlpage.substr(p, p2 - p - 1).c_str()); + LOG_ERROR("%s\n%s", EQSL_xmlpage.substr(p, p2 - p - 1).c_str(), EQSL_url.c_str()); } else LOG_INFO("eQSL logged %s", EQSL_url.c_str()); @@ -1100,3 +1102,106 @@ void sendEQSL(const char *url) pthread_cond_signal(&EQSLcond); pthread_mutex_unlock(&EQSLmutex); } + +// this function may be called from several places including macro +// expansion and execution + +void makeEQSL(const char *message) +{ + char sztemp[100]; + std::string tempstr; + std::string eQSL_url; + std::string msg; + size_t p = 0; + + msg = message; + + if (msg.empty()) msg = progdefaults.eqsl_default_message; + +// replace message tags {CALL}, {NAME}, {MODE} + while ((p = msg.find("{CALL}")) != std::string::npos) + msg.replace(p, 6, inpCall->value()); + while ((p = msg.find("{NAME}")) != std::string::npos) + msg.replace(p, 6, inpName->value()); + while ((p = msg.find("{MODE}")) != std::string::npos) + msg.replace(p, 6, mode_info[active_modem->get_mode()].adif_name); + + +// eqsl url header + eQSL_url = "http://www.eqsl.cc/qslcard/importADIF.cfm?ADIFdata=upload 2.1.9"; + snprintf(sztemp, sizeof(sztemp),"%s%s", + progdefaults.eqsl_id.length(), progdefaults.eqsl_id.c_str(), + progdefaults.eqsl_pwd.length(), progdefaults.eqsl_pwd.c_str()); + eQSL_url.append(sztemp); +// eqsl nickname + if (!progdefaults.eqsl_nick.empty()) { + snprintf(sztemp, sizeof(sztemp), "%s", + progdefaults.eqsl_nick.length(), progdefaults.eqsl_nick.c_str()); + eQSL_url.append(sztemp); + } + eQSL_url.append("FLDIGI"); + +// eqsl record +// band + tempstr = band_name(band(wf->rfcarrier())); + snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); + eQSL_url.append(sztemp); +// call + tempstr = inpCall->value(); + snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); + eQSL_url.append(sztemp); +// mode + tempstr = mode_info[active_modem->get_mode()].adif_name; +// test for modes not supported by eQSL + if ((tempstr.find("MFSK4") != std::string::npos) || + (tempstr.find("MFSK11") != std::string::npos) || + (tempstr.find("MFSK22") != std::string::npos) || + (tempstr.find("MFSK31") != std::string::npos) || + (tempstr.find("MFSK32") != std::string::npos) || + (tempstr.find("MFSK64") != std::string::npos) ) + tempstr = "MFSK16"; + if ((tempstr.find("PSK250") != std::string::npos) || + (tempstr.find("PSK500") != std::string::npos) || + (tempstr.find("PSK125R") != std::string::npos) || + (tempstr.find("PSK250R") != std::string::npos) || + (tempstr.find("PSK500R") != std::string::npos)) + tempstr = "PSK125"; + if ((tempstr.find("QPSK250") != std::string::npos) || + (tempstr.find("QPSK500") != std::string::npos) || + (tempstr.find("QPSK125R") != std::string::npos) || + (tempstr.find("QPSK250R") != std::string::npos) || + (tempstr.find("QPSK500R") != std::string::npos)) + tempstr = "QPSK125"; + + snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); + eQSL_url.append(sztemp); +// qso date + snprintf(sztemp, sizeof(sztemp), "%s", sDate_on.length(), sDate_on.c_str()); + eQSL_url.append(sztemp); +// qso time + tempstr = inpTimeOn->value(); + snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); + eQSL_url.append(sztemp); +// rst sent + tempstr = inpRstOut->value(); + snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); + eQSL_url.append(sztemp); +// message + if (!msg.empty()) { + snprintf(sztemp, sizeof(sztemp), "%s", msg.length(), msg.c_str()); + eQSL_url.append(sztemp); + } + eQSL_url.append(""); + + tempstr.clear(); + for (size_t n = 0; n < eQSL_url.length(); n++) { + if (eQSL_url[n] == ' ') tempstr.append("%20"); + else if (eQSL_url[n] == '<') tempstr.append("%3c"); + else if (eQSL_url[n] == '>') tempstr.append("%3e"); + else tempstr += eQSL_url[n]; + } + + sendEQSL(tempstr.c_str()); + +} + diff --git a/src/misc/macros.cxx b/src/misc/macros.cxx index 7f819e99..7134a6ea 100644 --- a/src/misc/macros.cxx +++ b/src/misc/macros.cxx @@ -1671,7 +1671,7 @@ static void pEXEC(std::string& s, size_t& i, size_t endbracket) static void pEQSL(std::string& s, size_t& i, size_t endbracket) { - if (within_exec) { + if (within_exec || progdefaults.eqsl_when_logged) { s.replace(i, endbracket - i + 1, ""); return; } @@ -1681,83 +1681,7 @@ static void pEQSL(std::string& s, size_t& i, size_t endbracket) if (start != std::string::npos) msg = s.substr(start + 1, endbracket-start-1); - char sztemp[100]; - std::string tempstr; - std::string eQSL_url; - -// eqsl url header - eQSL_url = "http://www.eqsl.cc/qslcard/importADIF.cfm?ADIFdata=upload 2.1.9"; - snprintf(sztemp, sizeof(sztemp),"%s%s", - progdefaults.eqsl_id.length(), progdefaults.eqsl_id.c_str(), - progdefaults.eqsl_pwd.length(), progdefaults.eqsl_pwd.c_str()); - eQSL_url.append(sztemp); -// eqsl nickname - if (!progdefaults.eqsl_nick.empty()) { - snprintf(sztemp, sizeof(sztemp), "%s", - progdefaults.eqsl_nick.length(), progdefaults.eqsl_nick.c_str()); - eQSL_url.append(sztemp); - } - eQSL_url.append("FLDIGI"); -// band - tempstr = band_name(band(wf->rfcarrier())); - snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); - eQSL_url.append(sztemp); -// call - tempstr = inpCall->value(); - snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); - eQSL_url.append(sztemp); -// mode - tempstr = mode_info[active_modem->get_mode()].adif_name; -// test for modes not supported by eQSL - if ((tempstr.find("MFSK4") != std::string::npos) || - (tempstr.find("MFSK11") != std::string::npos) || - (tempstr.find("MFSK22") != std::string::npos) || - (tempstr.find("MFSK31") != std::string::npos) || - (tempstr.find("MFSK32") != std::string::npos) || - (tempstr.find("MFSK64") != std::string::npos) ) - tempstr = "MFSK16"; - if ((tempstr.find("PSK250") != std::string::npos) || - (tempstr.find("PSK500") != std::string::npos) || - (tempstr.find("PSK125R") != std::string::npos) || - (tempstr.find("PSK250R") != std::string::npos) || - (tempstr.find("PSK500R") != std::string::npos)) - tempstr = "PSK125"; - if ((tempstr.find("QPSK250") != std::string::npos) || - (tempstr.find("QPSK500") != std::string::npos) || - (tempstr.find("QPSK125R") != std::string::npos) || - (tempstr.find("QPSK250R") != std::string::npos) || - (tempstr.find("QPSK500R") != std::string::npos)) - tempstr = "QPSK125"; - - snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); - eQSL_url.append(sztemp); -// qso date - snprintf(sztemp, sizeof(sztemp), "%s", sDate_on.length(), sDate_on.c_str()); - eQSL_url.append(sztemp); -// qso time - tempstr = inpTimeOn->value(); - snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); - eQSL_url.append(sztemp); -// rst sent - tempstr = inpRstOut->value(); - snprintf(sztemp, sizeof(sztemp), "%s", tempstr.length(), tempstr.c_str()); - eQSL_url.append(sztemp); -// message - if (!msg.empty()) { - snprintf(sztemp, sizeof(sztemp), "%s", msg.length(), msg.c_str()); - eQSL_url.append(sztemp); - } - eQSL_url.append(""); - - tempstr.clear(); - for (size_t n = 0; n < eQSL_url.length(); n++) { - if (eQSL_url[n] == ' ') tempstr.append("%20"); - else if (eQSL_url[n] == '<') tempstr.append("%3c"); - else if (eQSL_url[n] == '>') tempstr.append("%3e"); - else tempstr += eQSL_url[n]; - } - - sendEQSL(tempstr.c_str()); + makeEQSL(msg.c_str()); s.replace(i, endbracket - i + 1, ""); return; @@ -1957,7 +1881,7 @@ static const MTAGS mtags[] = { {"", pLOG}, {"", pLNW}, {"", pCLRLOG}, -{" Date: Sat, 12 Nov 2011 21:19:49 +0000 Subject: [PATCH 52/54] Use Logbook record * Added Dial button in logbook editor to set frequency / mode / operator to the the current record. - allows easy retrieval of logged data to either continue a QSO or set one up based on a log entry. --- src/include/lgbook.h | 2 ++ src/include/logsupport.h | 1 + src/include/qso_db.h | 2 +- src/logbook/adif_io.cxx | 4 ++-- src/logbook/lgbook.cxx | 12 ++++++++++ src/logbook/lgbook.fl | 17 +++++++++----- src/logbook/logsupport.cxx | 47 +++++++++++++++++++++++++++++++++++++- src/logbook/qso_db.cxx | 2 +- 8 files changed, 76 insertions(+), 11 deletions(-) diff --git a/src/include/lgbook.h b/src/include/lgbook.h index 146c49ea..58e8c612 100644 --- a/src/include/lgbook.h +++ b/src/include/lgbook.h @@ -83,6 +83,8 @@ extern void cb_btnUpdateCancel(Fl_Button*, void*); extern Fl_Button *bUpdateCancel; extern void cb_btnDelete(Fl_Button*, void*); extern Fl_Button *bDelete; +extern void cb_btnDialFreq(Fl_Button*, void*); +extern Fl_Button *bDialFreq; extern Fl_Input2 *txtNbrRecs_log; extern Fl_Input2 *inpSerNoOut_log; extern Fl_Input2 *inpMyXchg_log; diff --git a/src/include/logsupport.h b/src/include/logsupport.h index c999c8fa..e8d22353 100644 --- a/src/include/logsupport.h +++ b/src/include/logsupport.h @@ -52,6 +52,7 @@ extern void clearRecord (); extern void updateRecord (); extern void deleteRecord (); extern void AddRecord (); +extern void DisplayRecord (int idxRec); extern void SearchLastQSO (const char *); extern cQsoRec* SearchLog(const char *callsign); extern void DupCheck(); diff --git a/src/include/qso_db.h b/src/include/qso_db.h index 49b41ba5..423aa77b 100644 --- a/src/include/qso_db.h +++ b/src/include/qso_db.h @@ -30,7 +30,7 @@ public: void putField (int, const char *); void putField (int, const char *, int); void addtoField (int, const char *); - const char *getField (int); + const char *getField (int) const; void trimFields(); void clearRec (); int validRec(); diff --git a/src/logbook/adif_io.cxx b/src/logbook/adif_io.cxx index a35940b9..4365c0de 100644 --- a/src/logbook/adif_io.cxx +++ b/src/logbook/adif_io.cxx @@ -90,13 +90,13 @@ FIELD fields[] = { {XCHG1, 0, &btnSelectXchgIn} // contest exchange #1 / free1 in xlog }; -void initfields() +static void initfields() { for (int i = 0; i < NUMFIELDS; i++) fields[i].name = new string(fieldnames[i]); } -int findfield( char *p ) +static int findfield( const char *p ) { int m; int test; diff --git a/src/logbook/lgbook.cxx b/src/logbook/lgbook.cxx index 484bd26c..e71d07bd 100644 --- a/src/logbook/lgbook.cxx +++ b/src/logbook/lgbook.cxx @@ -261,6 +261,8 @@ Fl_Button *bUpdateCancel=(Fl_Button *)0; Fl_Button *bDelete=(Fl_Button *)0; +Fl_Button *bDialFreq=(Fl_Button *)0; + Fl_Input2 *txtNbrRecs_log=(Fl_Input2 *)0; Fl_Input2 *inpSerNoOut_log=(Fl_Input2 *)0; @@ -818,23 +820,33 @@ void create_logbook_dialogs() { inpNotes_log->when(FL_WHEN_RELEASE); } // Fl_Input2* inpNotes_log { bNewSave = new Fl_Button(163, 263, 55, 22, _("New")); + bNewSave->tooltip(_("New record / Save record")); bNewSave->shortcut(0x8004e); bNewSave->color((Fl_Color)FL_LIGHT1); bNewSave->selection_color((Fl_Color)48); bNewSave->callback((Fl_Callback*)cb_btnNewSave); } // Fl_Button* bNewSave { bUpdateCancel = new Fl_Button(235, 263, 55, 22, _("Update")); + bUpdateCancel->tooltip(_("Update the current record")); bUpdateCancel->shortcut(0x80055); bUpdateCancel->color((Fl_Color)FL_LIGHT1); bUpdateCancel->selection_color((Fl_Color)48); bUpdateCancel->callback((Fl_Callback*)cb_btnUpdateCancel); } // Fl_Button* bUpdateCancel { bDelete = new Fl_Button(307, 263, 55, 22, _("Delete")); + bDelete->tooltip(_("Delete the current record")); bDelete->shortcut(0x80044); bDelete->color((Fl_Color)FL_LIGHT1); bDelete->selection_color((Fl_Color)48); bDelete->callback((Fl_Callback*)cb_btnDelete); } // Fl_Button* bDelete + { bDialFreq = new Fl_Button(380, 263, 55, 22, _("Dial")); + bDialFreq->tooltip(_("Retrieve for active modem use")); + bDialFreq->shortcut(0x50066); + bDialFreq->color((Fl_Color)FL_LIGHT1); + bDialFreq->selection_color((Fl_Color)48); + bDialFreq->callback((Fl_Callback*)cb_btnDialFreq); + } // Fl_Button* bDialFreq { txtNbrRecs_log = new Fl_Input2(41, 263, 65, 22, _("Recs")); txtNbrRecs_log->tooltip(_("# Records in logbook")); txtNbrRecs_log->box(FL_DOWN_BOX); diff --git a/src/logbook/lgbook.fl b/src/logbook/lgbook.fl index 5c1389b9..b2e2715e 100644 --- a/src/logbook/lgbook.fl +++ b/src/logbook/lgbook.fl @@ -20,7 +20,7 @@ Function {create_logbook_dialogs()} {open return_type void } { Fl_Window wExport { label {Export Setup} open - xywh {588 534 655 385} type Double modal visible + xywh {588 534 655 385} type Double hide modal } { Fl_Group {} { label {Select Records to Export} open @@ -283,7 +283,7 @@ btnSelectNotes->value(0);} label Logbook open xywh {574 55 585 410} type Double color 47 resizable visible } { - Fl_Group editGroup {open selected + Fl_Group editGroup {open xywh {2 2 602 290} box ENGRAVED_FRAME color 52 } { Fl_Input inpDate_log { @@ -420,17 +420,22 @@ btnSelectNotes->value(0);} Fl_Button bNewSave { label New callback cb_btnNewSave - xywh {163 263 55 22} shortcut 0x8004e color 50 selection_color 48 + tooltip {New record / Save record} xywh {163 263 55 22} shortcut 0x8004e color 50 selection_color 48 } Fl_Button bUpdateCancel { label Update callback cb_btnUpdateCancel - xywh {235 263 55 22} shortcut 0x80055 color 50 selection_color 48 + tooltip {Update the current record} xywh {235 263 55 22} shortcut 0x80055 color 50 selection_color 48 } Fl_Button bDelete { label Delete callback cb_btnDelete - xywh {307 263 55 22} shortcut 0x80044 color 50 selection_color 48 + tooltip {Delete the current record} xywh {307 263 55 22} shortcut 0x80044 color 50 selection_color 48 + } + Fl_Button bDialFreq { + label Dial + callback cb_btnDialFreq + tooltip {Retrieve for active modem use} xywh {380 263 55 22} shortcut 0x50066 color 50 selection_color 48 } Fl_Input txtNbrRecs_log { label Recs @@ -475,7 +480,7 @@ btnSelectNotes->value(0);} code0 {bSearchPrev->image(new Fl_Pixmap(left_arrow_icon));} } Fl_Button bSearchNext { - callback cb_search + callback cb_search selected tooltip {Find next} xywh {550 263 24 22} color 50 selection_color 48 align 16 code0 {bSearchNext->image(new Fl_Pixmap(right_arrow_icon));} } diff --git a/src/logbook/logsupport.cxx b/src/logbook/logsupport.cxx index 538a3441..c5cf946d 100644 --- a/src/logbook/logsupport.cxx +++ b/src/logbook/logsupport.cxx @@ -42,6 +42,7 @@ #include "adif_io.h" #include "textio.h" #include "logbook.h" +#include "rigsupport.h" #include "logger.h" #include "fl_digi.h" @@ -547,7 +548,51 @@ int log_search_handler(int) return 1; } -int editNbr = 0; +static int editNbr = 0; + +void cb_btnDialFreq(Fl_Button* b, void* d) +{ + double drf = atof(inpFreq_log->value()); + if (!drf) return; + + int rf1, rf, audio; + rf1 = drf * 1e6; + rf = rf1 / 10000; + rf *= 10000; + audio = rf1 - rf; +// try to keep within normal xcvr bw, 500 - 3000 Hz + while (audio > 3000) { + audio -= 3000; + rf += 3000; + } + if (audio < 500) { + audio += 500; + rf -= 500; + } + qsy(rf, audio); + + std::string mode_name = inpMode_log->value(); + trx_mode m; + for (m = 0; m < NUM_MODES; m++) + if (mode_name == mode_info[m].adif_name) + break; + // do we have a valid modem? + if (m < NUM_MODES && active_modem->get_mode() != mode_info[m].mode) + init_modem(mode_info[m].mode); + + const cQsoRec *qsoPtr = qsodb.getRec(editNbr); + inpCall->value(qsoPtr->getField(CALL)); + inpName->value (qsoPtr->getField(NAME)); + inpTimeOn->value (inpTimeOff->value()); + inpState->value (qsoPtr->getField(STATE)); + inpCountry->value (qsoPtr->getField(COUNTRY)); + inpXchgIn->value(qsoPtr->getField(XCHG1)); + inpQth->value (qsoPtr->getField(QTH)); + inpLoc->value (qsoPtr->getField(GRIDSQUARE)); + inpNotes->value (qsoPtr->getField(NOTES)); + + wBrowser->take_focus(); +} void clearRecord() { Date tdy; diff --git a/src/logbook/qso_db.cxx b/src/logbook/qso_db.cxx index 177838da..0779e260 100644 --- a/src/logbook/qso_db.cxx +++ b/src/logbook/qso_db.cxx @@ -106,7 +106,7 @@ void cQsoRec::trimFields () { } } -const char * cQsoRec::getField (int n) { +const char * cQsoRec::getField (int n) const { if (n < 0 || n >= NUMFIELDS) return 0; return (qsofield[n].c_str()); } From 8baf07bb49c935e51d7d9cf0f18720bbce1448ea Mon Sep 17 00:00:00 2001 From: Remi Chateauneu Date: Sat, 12 Nov 2011 21:23:37 +0000 Subject: [PATCH 53/54] Wefax enhancements. * Adjustable carrier frequency. Can adjust the carrier frequency from the GUI. * All messages are now internationalised. * Images absence/presence better detected also with line-to-line statistic correlation. --- src/wefax/wefax.cxx | 361 +++++++++++++++++++++++++++++++------------- 1 file changed, 259 insertions(+), 102 deletions(-) diff --git a/src/wefax/wefax.cxx b/src/wefax/wefax.cxx index a881d1e5..0d158ce3 100644 --- a/src/wefax/wefax.cxx +++ b/src/wefax/wefax.cxx @@ -38,6 +38,7 @@ #include #include "debug.h" +#include "gettext.h" #include "wefax.h" #include "modem.h" #include "main.h" @@ -339,6 +340,9 @@ class fax_implementation { int m_max_fax_rows ; // Max admissible number of received lines. bool m_manual_mode ; // Tells whether everything is read, or apt+phasing detection. + /// The number of samples sent for one line. The LPM is given by the GUI. Typically 5512. + double m_smpl_per_lin ;// Recalculated each time m_lpm_img is updated. + int m_ix_filt ; // Index of the current reception filter. /// This is always the same filter for all objects. @@ -360,12 +364,6 @@ class fax_implementation { fax_implementation(); - /// This could be recalculated each time m_lpm_img is updated. - double samples_per_line(void) - { - return m_sample_rate * 60.0 / m_lpm_img ; - }; - /// Needed when starting image reception, after phasing. void reset_counters(void) { @@ -375,6 +373,24 @@ class fax_implementation { m_pix_samples_nb = 0; } + /// Called at init time or when the carrier changes. + void reset_increments(void) + { + /// This might happen at startup. Not a problem. + if(m_sample_rate == 0) { + return; + } + m_dbl_sine.set_increment(m_dbl_sine.size()*m_carrier/m_sample_rate); + m_dbl_cosine.set_increment(m_dbl_cosine.size()*m_carrier/m_sample_rate); + m_dbl_sine.reset(); + m_dbl_cosine.reset(); + + m_short_sine.reset(); + if(!m_freq_mod ) { + m_short_sine.set_increment(m_short_sine.size()*m_carrier/m_sample_rate); + } + } + public: fax_implementation(int fax_mode, wefax * ptr_wefax ); void init_rx(int the_smpl_rate); @@ -400,6 +416,13 @@ public: return m_carrier ; } + /// The trigo tables have an increment which depends on the carrier frequency. + void set_carrier(double freq) + { + m_carrier = freq ; + reset_increments(); + } + int fax_width(void) const { return m_img_width ; @@ -434,10 +457,15 @@ public: return m_max_fax_rows ; } + int lpm_to_samples( int the_lpm ) const { + return m_sample_rate * 60.0 / the_lpm ; + } + /// Called by the GUI. void lpm_set( int the_lpm ) { m_lpm_img = the_lpm ; + m_smpl_per_lin = lpm_to_samples( m_lpm_img ); } /// This generates a filename based on the frequency, current time, internal state etc... @@ -544,6 +572,7 @@ private: double _apt_stop ; fax_state _state ; /// Deduction made based on signal power. + const char * _text; /// Finer tests can be added. These are all rule-of-thumb values based /// on observation of real signals. @@ -551,12 +580,14 @@ private: void set_state(void) { _state = IDLE ; + _text = ""; if( ( _apt_start > 20.0 ) && ( _phasing < 10.0 ) && ( _image < 10.0 ) && ( _apt_stop < 10.0 ) ) { _state = RXAPTSTART ; + _text = _("Strong APT start signal: Skip to phasing."); } if( /// The image signal may be weak if the others signals are even weaker. ( ( _apt_start < 1.0 ) && @@ -572,12 +603,14 @@ private: ( _image > 15.0 ) && ( _apt_stop < 1.0 ) ) ) { _state = RXIMAGE ; + _text = _("Strong image signal when getting APT start: Starting phasing."); } if( ( _apt_start < 10.0 ) && ( _phasing > 20.0 ) && ( _image < 10.0 ) && ( _apt_stop < 10.0 ) ) { _state = RXPHASING ; + _text = _("Strong phasing signal when getting APT start: Starting phasing."); } if( ( ( _apt_start < 2.0 ) && @@ -589,6 +622,7 @@ private: ( _image < 1.0 ) && ( _apt_stop > 6.0 ) ) ) { _state = RXAPTSTOP ; + _text = _("Strong APT stop signal: Stopping reception."); } /// Maybe this is a constant freq. If so, the power is very big @@ -599,6 +633,23 @@ private: } if( _image > 100 * _black ) { _state = RXAPTSTOP ; + _text = _("Constant frequency detected: Stopping reception."); + } + + /// Consecutive lines in a wefax image have a strong statistical correlation. + fax_state state_corr = _ptr_fax->correlation_state(); + if( ( _state == RXIMAGE ) || ( _state == IDLE ) ) { + if( state_corr == RXAPTSTOP ) { + _state = RXAPTSTOP ; + _text = _("No significant line-to-line correlation: Stopping reception."); + } + } + + if( ( _state == IDLE ) || ( _state == RXAPTSTART ) || ( _state == RXPHASING ) ) { + if( state_corr == RXIMAGE ) { + _state = RXIMAGE ; + _text = _("Significant line-to-line correlation: Starting reception."); + } } } @@ -625,7 +676,7 @@ private: { /// Values reevaluated every X input samples. Must be smaller /// than the typical audio input frames (512 samples). - static const int validity = 100 ; + static const int validity = 1000 ; /// Calculated at least the first time. if( ( _cnt % validity ) == 0 ) { @@ -638,7 +689,8 @@ private: fax_signal( const fax_implementation * ptr_fax) : _ptr_fax(ptr_fax), _cnt(0) {} - fax_state state(void) const { return _state ; } + fax_state signal_state(void) const { return _state ; } + const char * signal_text(void) const { return _text; }; double image_noise_ratio(void) const { return _image ; } @@ -693,7 +745,6 @@ private: void save_automatic(const char * extra_msg); - void adjust_metric(double snr); void decode_apt(int x, const fax_signal & the_signal ); void decode_phasing(int x, const fax_signal & the_signal ); bool decode_image(int x); @@ -717,7 +768,7 @@ public: { guard_lock g( m_sync_rx.mtxp() ); - LOG_INFO("delay=%f", max_seconds ); + LOG_INFO(_("delay=%f"), max_seconds ); if( m_received_files.empty() ) { if( ! m_sync_rx.wait(max_seconds) ) return std::string(); @@ -785,7 +836,7 @@ public: LOG_INFO("%s %s", m_tx_fil.c_str(), err_msg.c_str() ); if( m_tx_fil.empty() ) { - LOG_WARN("%s File name should not be empty", err_msg.c_str() ); + LOG_WARN(_("%s: File name should not be empty"), err_msg.c_str() ); } else { @@ -795,11 +846,131 @@ public: m_sync_tx_msg.signal(); } + /// Maybe we could reset this buffer when we change the state so that we could + /// use the current LPM width. + mutable std::vector m_correlation_buffer ; + mutable double m_current_corr ; + mutable double m_curr_corr_avg ; + mutable size_t m_corr_calls_nb; + static const size_t m_min_corr_lines = 20 ; + + /// Absolute value of statistical correlation between the current line and the previous one. + /// Called once per maximum sample line. + void correlation_calc(void) const { + ++m_corr_calls_nb; + /// We should in fact take the smallest one, 60. + size_t corr_samples_line = lpm_to_samples( LPM_DEFAULT ); + size_t corr_samples_line_plus_img_sample = corr_samples_line + m_img_sample ; + size_t corr_buff_sz = 2 * corr_samples_line ; + + int avg_pred = 0, avg_curr = 0 ; + for( size_t i = m_img_sample ; i < corr_samples_line_plus_img_sample ; ++i ) { + int pix_pred = m_correlation_buffer[ ( i ) % corr_buff_sz ]; + int pix_curr = m_correlation_buffer[ ( i + corr_samples_line ) % corr_buff_sz ]; + avg_pred += pix_pred; + avg_curr += pix_curr ; + } + avg_pred /= corr_samples_line; + avg_curr /= corr_samples_line; + + /// Use integers because it is faster. Samples are chars, so no overflow possible. + int numerator = 0, denom_pred = 0, denom_curr = 0 ; + for( size_t i = m_img_sample ; i < corr_samples_line_plus_img_sample ; ++i ) { + int pix_pred = m_correlation_buffer[ ( i ) % corr_buff_sz ]; + int pix_curr = m_correlation_buffer[ ( i + corr_samples_line ) % corr_buff_sz ]; + int delta_pred = pix_pred - avg_pred ; + int delta_curr = pix_curr - avg_curr ; + numerator += delta_pred * delta_curr ; + denom_pred += delta_pred * delta_pred ; + denom_curr += delta_curr * delta_curr ; + } + double denominator = sqrt( (double)denom_pred * (double)denom_curr ); + if( denominator == 0.0 ) { + m_current_corr = 0.0 ; + } else { + m_current_corr = fabs( numerator / (double)denominator ); + } + + /// This never happened, but who knows (Inaccuracy etc...)? + if( m_current_corr > 1.0 ) { + LOG_WARN("Inconsistent correlation:%lf", m_current_corr ); + m_current_corr = 1.0; + } + + if( m_corr_calls_nb < m_min_corr_lines ) { + m_curr_corr_avg = m_current_corr ; + } else { + m_curr_corr_avg = ( m_curr_corr_avg * m_min_corr_lines + m_current_corr ) / ( m_min_corr_lines + 1 ); + } + /// Debugging purpose only. + if( ( m_corr_calls_nb % 10000 ) == 0 ) { + LOG_INFO( "m_current_corr=%lf m_curr_corr_avg=%lf m_corr_calls_nb=%d", + m_current_corr, m_curr_corr_avg, m_corr_calls_nb ); + } + double metric = m_curr_corr_avg * 100.0 ; + m_ptr_wefax->display_metric(metric); + } + + /// This is called quite often. It estimates, based on the mobile + /// average of statistical correlation between consecutive lines, whether this is a wefax + /// signal or not. + fax_state correlation_state(void) const { + + static fax_state stable_state = IDLE ; + + /// If the mobile abverage is not computed on enough lines, returns IDLE + /// which means "Do not know" in this context. + if( m_corr_calls_nb >= m_min_corr_lines ) { + /// The threshold are very approximate. + if( m_curr_corr_avg < 0.05 ) { + stable_state = RXAPTSTOP ; + } else if( m_curr_corr_avg > 0.20 ) { + stable_state = RXIMAGE ; + } else { + stable_state = IDLE ; + } + } + + /// Message for first detection. + if( (stable_state == IDLE) && (m_corr_calls_nb == m_min_corr_lines) ) { + LOG_INFO("Correlation average %lf: Detected %s", m_curr_corr_avg, state_to_str(stable_state) ); + } + + return stable_state; + } + + /// We compute about the same when plotting a pixel. + void correlation_update( int the_sample ) { + size_t corr_samples_line = lpm_to_samples( LPM_DEFAULT ); + size_t corr_buff_sz = 2 * corr_samples_line ; + + static size_t cnt_upd = 0 ; + + if( cnt_upd == 0 ) { + if( m_correlation_buffer.size() != corr_buff_sz ) { + m_correlation_buffer.resize( corr_buff_sz, 0 ); + m_current_corr = 0.0 ; + m_curr_corr_avg = 0.0 ; + return ; + } + } + + if( ( cnt_upd % corr_samples_line ) == 0 ) { + correlation_calc(); + } + ++cnt_upd ; + + m_correlation_buffer[ m_img_sample % corr_buff_sz ] = the_sample ; + } }; // class fax_implementation /// Narrow, middle etc... input filters. Constructed at program startup. Readonly. fir_filter_pair_set fax_implementation::m_rx_filters ; +// http://www.newearth.demon.co.uk/radio/hfwefax1.htm +// "...the total offset is 1900Hz, so to tune a fax station on 4610kHz, tune to 4608.1kHz USB." +static const double wefax_default_carrier = 1900; + fax_implementation::fax_implementation( int fax_mode, wefax * ptr_wefax ) : m_ptr_wefax( ptr_wefax ) , m_dbl_sine(8192),m_dbl_cosine(8192),m_dbl_arc_sine(256) @@ -810,12 +981,13 @@ fax_implementation::fax_implementation( int fax_mode, wefax * ptr_wefax ) m_phase_inverted = false ; m_img_color = false ; m_tx_phasing_lin = 20 ; - m_carrier = 1900 ; + m_carrier = wefax_default_carrier ; m_start_duration = 5 ; m_stop_duration = 5 ; m_manual_mode = false ; m_rx_state = IDLE ; m_tx_state = IDLE ; + m_sample_rate = 0 ; int index_of_correlation ; /// http://en.wikipedia.org/wiki/Radiofax @@ -830,7 +1002,7 @@ fax_implementation::fax_implementation( int fax_mode, wefax * ptr_wefax ) index_of_correlation = IOC_288 ; break; default: - LOG_ERROR("Invalid fax mode:%d", fax_mode); + LOG_ERROR(_("Invalid fax mode:%d"), fax_mode); abort(); } @@ -856,7 +1028,8 @@ void fax_implementation::init_rx(int the_smpl_rat) m_rx_state=RXAPTSTART; m_apt_count=m_apt_trans=0; m_apt_high=false; - reset_counters(); + /// Centers the carriers on the GUI and reinits the trigonometric tables. + m_ptr_wefax->set_freq(wefax_default_carrier); /// No weather fax can have such a huge number of rows. m_max_fax_rows = 5000 ; @@ -864,11 +1037,9 @@ void fax_implementation::init_rx(int the_smpl_rat) /// Default value, can be the with the GUI. m_ix_filt = 0 ; // 0=narrow, 1=middle, 2=wide. - m_dbl_sine.set_increment(m_dbl_sine.size()*m_carrier/m_sample_rate); - m_dbl_cosine.set_increment(m_dbl_cosine.size()*m_carrier/m_sample_rate); - m_dbl_sine.reset(); - m_dbl_cosine.reset(); + reset_increments(); m_i_fir_old=m_q_fir_old=0; + m_corr_calls_nb = 0; } /// Values are between 0 and 255. @@ -876,7 +1047,7 @@ void fax_implementation::decode(const int* buf, int nb_samples) { if(nb_samples==0) { - LOG_WARN("Empty buffer."); + LOG_WARN(_("Empty buffer.")); end_rx(); } fax_signal my_signal(this); @@ -897,15 +1068,17 @@ void fax_implementation::decode(const int* buf, int nb_samples) } } + correlation_update(crr_val); + if( m_manual_mode ) { m_rx_state = RXIMAGE; bool is_max_lines_reached = decode_image(crr_val); if( is_max_lines_reached ) { skip_apt_rx(); skip_phasing_rx(false); - LOG_INFO("Max lines reached in manual mode: Resuming reception."); + LOG_INFO(_("Max lines reached in manual mode: Resuming reception.")); if( m_manual_mode == false ) { - LOG_ERROR("Inconsistent manual mode."); + LOG_ERROR(_("Inconsistent manual mode.")); } } } else { @@ -918,28 +1091,10 @@ void fax_implementation::decode(const int* buf, int nb_samples) decode_image(crr_val); } } + m_img_sample++; } } -// Estimate a rough metric which must be between 0 and 1. -// 20 = 20.0 * log10(snr) is a reasonable value, i.e. snr=10 -void fax_implementation::adjust_metric(double snr) -{ - // Computes on the fly the max and min of snr, so we can clamp. - static double max_snr = 0.0, min_snr = 0.0 ; - if( snr > max_snr ) - max_snr = snr ; - else - if( snr < min_snr ) - min_snr = snr ; - - if( min_snr == max_snr ) return ; - - double metric = 100 * (snr - min_snr) / (max_snr - min_snr); - - m_ptr_wefax->display_metric(metric); -} - // The number of transitions between black and white is counted. After 1/2 // second, the frequency is calculated. If it matches the APT start frequency, // the state skips to the detection of phasing lines, if it matches the apt @@ -956,42 +1111,44 @@ void fax_implementation::decode_apt(int x, const fax_signal & the_signal ) if( m_apt_count >= m_sample_rate/2 ) { int curr_freq=m_sample_rate*m_apt_trans/m_apt_count; + /// This writes the S/R level on the status bar. double tmp_snr = the_signal.image_noise_ratio(); - char snr_buffer[128]; - snprintf(snr_buffer, sizeof(snr_buffer), "s/n %3.0f dB", 20.0 * log10(tmp_snr)); - put_Status1(snr_buffer); - adjust_metric(tmp_snr); + char snr_buffer[64]; + snprintf(snr_buffer, sizeof(snr_buffer), "s/n %3.0f dB", 20.0 * log10(tmp_snr)); + put_Status1(snr_buffer); m_apt_count=m_apt_trans=0; if(m_rx_state==RXAPTSTART) { if( is_near_freq(curr_freq,m_apt_start_freq, 8 ) ) { skip_apt_rx(); - PUT_STATUS( state_rx_str() << ", frequency: " << curr_freq << " Hz. Skipping." ); + PUT_STATUS( state_rx_str() << ", " << _("frequency") << ": " + << curr_freq << " Hz. " << _("Skipping.") ); return ; } if( is_near_freq(curr_freq,m_apt_stop_freq, 2 ) ) { - LOG_INFO("Spurious APT stop frequency=%d Hz as waiting for APT start. SNR=%f", + LOG_INFO(_("Spurious APT stop frequency=%d Hz as waiting for APT start. SNR=%f"), curr_freq, tmp_snr ); return ; } - PUT_STATUS( state_rx_str() << ", frequency: " << curr_freq << " Hz." ); + PUT_STATUS( state_rx_str() << ", " << _("frequency") << ": " << curr_freq << " Hz." ); } if( is_near_freq(curr_freq,m_apt_stop_freq, 12 ) ) { - PUT_STATUS( state_rx_str() << " Apt stop frequency: " << curr_freq << " Hz. Stopping." ); + PUT_STATUS( state_rx_str() << " " << _("Apt stop frequency") << ": " + << curr_freq << " Hz. " << _("Stopping.") ); save_automatic("ok"); end_rx(); return ; } - switch( the_signal.state() ) { + switch( the_signal.signal_state() ) { case RXAPTSTART : switch( m_rx_state ) { case RXAPTSTART : skip_apt_rx(); - LOG_INFO( "Strong APT start signal, skip to phasing" ); + LOG_INFO( the_signal.signal_text() ); break ; default : break ; } @@ -1000,7 +1157,7 @@ void fax_implementation::decode_apt(int x, const fax_signal & the_signal ) switch( m_rx_state ) { case RXAPTSTART : skip_apt_rx(); - LOG_INFO( "Strong phasing signal when getting APT start, starting phasing" ); + LOG_INFO( the_signal.signal_text() ); break ; default : break ; } @@ -1011,7 +1168,7 @@ void fax_implementation::decode_apt(int x, const fax_signal & the_signal ) skip_apt_rx(); /// The phasing step will start receiving the image later. First we try /// to phase the image correctly. - LOG_INFO( "Strong image signal when getting APT start, starting phasing" ); + LOG_INFO( the_signal.signal_text() ); break ; default : break ; } @@ -1019,7 +1176,7 @@ void fax_implementation::decode_apt(int x, const fax_signal & the_signal ) case RXAPTSTOP : switch( m_rx_state ) { case RXIMAGE : - LOG_INFO("Strong APT stop signal, stopping reception" ); + LOG_INFO( the_signal.signal_text() ); save_automatic("stop"); end_rx(); break; @@ -1061,7 +1218,7 @@ void fax_implementation::save_automatic(const char * extra_msg) static const int max_fax_pix_num = 200000 ; if( m_fax_pix_num < max_fax_pix_num ) { - LOG_INFO( "Do not save small image (%d bytes). Manual=%d", m_fax_pix_num, m_manual_mode ); + LOG_INFO( _("Do not save small image (%d bytes). Manual=%d"), m_fax_pix_num, m_manual_mode ); return ; } @@ -1109,15 +1266,15 @@ void fax_implementation::decode_phasing(int x, const fax_signal & the_signal ) ++m_phase_lines; PUT_STATUS( state_rx_str() - << ". Decoding phasing line, lpm = " << tmp_lpm - << " count=" << m_phase_lines ); + << ". " << _("Decoding phasing line") << ", lpm = " << tmp_lpm + << " " << _("count") << "=" << m_phase_lines ); /// The precision cannot really increase because there cannot // be more than a couple of loops. This is used for guessing // whether the LPM is around 120 or 60. - m_lpm_img=m_lpm_sum_rx/m_phase_lines; + lpm_set( m_lpm_sum_rx / m_phase_lines ); - double smpl_per_lin = samples_per_line(); + double smpl_per_lin = m_smpl_per_lin; /// Half of the band of the phasing line. m_img_sample=static_cast(1.025 * smpl_per_lin ); @@ -1130,31 +1287,31 @@ void fax_implementation::decode_phasing(int x, const fax_signal & the_signal ) m_num_phase_lines=0; /// NOTE: If five or more, blacks stripes appear on the image ??? if( m_phase_lines >= 4 ) { - LOG_INFO("Skipping to reception: m_phase_lines=%d m_num_phase_lines=%d. LPM=%f", + LOG_INFO( _("Skipping to reception: m_phase_lines=%d m_num_phase_lines=%d. LPM=%f"), m_phase_lines, m_num_phase_lines, m_lpm_img ); skip_phasing_to_image(false); } } else if(m_phase_lines>0 && ++m_num_phase_lines>=5) { /// TODO: Compare with m_tx_phasing_lin which indicates the number of phasing /// lines sent when transmitting an image. - LOG_INFO("Missed last phasing line m_phase_lines=%d m_num_phase_lines=%d. LPM=%f", + LOG_INFO( _("Missed last phasing line m_phase_lines=%d m_num_phase_lines=%d. LPM=%f"), m_phase_lines, m_num_phase_lines, m_lpm_img ); /// Phasing header is finished but could not get the center. skip_phasing_to_image(true); } else if(m_curr_phase_len>5*m_sample_rate) { m_curr_phase_len=0; - PUT_STATUS( state_rx_str() << ". Decoding phasing line, resetting." ); + PUT_STATUS( state_rx_str() << ". " << _("Decoding phasing line, resetting.") ); } else { /// Here, if no phasing is detected. Must be very fast. } - PUT_STATUS( state_rx_str() << ". Decoding phasing line, reset." ); + PUT_STATUS( state_rx_str() << ". " << _("Decoding phasing line, reset.") ); m_curr_phase_len=m_curr_phase_high=0; } else { /// We do not the LPM so we assume the default. /// TODO: We could take the one given by the GUI. - double smpl_per_lin = m_sample_rate * 60.0 / LPM_DEFAULT ; + double smpl_per_lin = lpm_to_samples( LPM_DEFAULT ); int smpl_per_lin_int = smpl_per_lin ; int nb_tested_phasing_lines = m_phasing_calls_nb / smpl_per_lin ; @@ -1163,14 +1320,14 @@ void fax_implementation::decode_phasing(int x, const fax_signal & the_signal ) (m_num_phase_lines == 0) && (nb_tested_phasing_lines >= 30) && ( (m_phasing_calls_nb % smpl_per_lin_int) == 0 ) ) { - switch( the_signal.state() ) { + switch( the_signal.signal_state() ) { case RXIMAGE : - LOG_INFO( "Strong image signal when phasing, starting to receive" ); + LOG_INFO( _("Starting reception when phasing:%s"), the_signal.signal_text() ); skip_phasing_to_image(true); break ; /// If RXPHASING, we stay in phasing mode. case RXAPTSTOP : - LOG_INFO("Strong APT stop signal when phasing" ); + LOG_INFO( _("Strong APT stop when phasing:%s"), the_signal.signal_text() ); end_rx(); skip_apt_rx(); default : break ; @@ -1181,10 +1338,7 @@ void fax_implementation::decode_phasing(int x, const fax_signal & the_signal ) bool fax_implementation::decode_image(int x) { - /// TODO: Put this in the class because it it used at many other places. - double smpl_per_lin = samples_per_line(); - - double current_row_dbl = m_img_sample / smpl_per_lin ; + double current_row_dbl = m_img_sample / m_smpl_per_lin ; int current_row = current_row_dbl ; int curr_col= m_img_width * (current_row_dbl - current_row) ; @@ -1211,18 +1365,17 @@ bool fax_implementation::decode_image(int x) m_pixel_val=x; m_pix_samples_nb=1; } - m_img_sample++; /// Prints the status from time to time. if( (m_img_sample % 10000) == 0 ) { PUT_STATUS( state_rx_str() - << ". Image reception," - << " sample=" << m_img_sample ); + << ". " << _("Image reception") + << ", " << _("sample") << "=" << m_img_sample ); } /// Hard-limit to the number of rows. if( current_row >= m_max_fax_rows ) { - LOG_INFO("Maximum number of rows reached:%d. Manual=%d", current_row, m_manual_mode ); + LOG_INFO( _("Maximum number of rows reached:%d. Manual=%d"), current_row, m_manual_mode ); save_automatic("max"); end_rx(); return true ; @@ -1236,14 +1389,16 @@ void fax_implementation::skip_apt_rx(void) { wefax_pic::skip_rx_apt(); if(m_rx_state!=RXAPTSTART) { - LOG_ERROR("Should be in APT state. State=%s. Manual=%d", state_rx_str().c_str(), m_manual_mode ); + LOG_ERROR( _("Should be in APT state. State=%s. Manual=%d"), state_rx_str().c_str(), m_manual_mode ); } - m_lpm_img=m_lpm_sum_rx=0; + lpm_set( 0 ); + m_lpm_sum_rx = 0; m_rx_state=RXPHASING; m_phasing_calls_nb = 0 ; m_phase_high = m_current_value>=128 ? true : false; m_curr_phase_len=m_curr_phase_high=0; m_phase_lines=m_num_phase_lines=0; + m_img_sample=0; /// Used for correlation between consecutive lines. } /// Called by the user when skipping phasing, @@ -1255,7 +1410,7 @@ void fax_implementation::skip_phasing_to_image(bool auto_center) REQ( wefax_pic::skip_rx_phasing, auto_center ); if(m_rx_state!=RXPHASING) { - LOG_ERROR("Should be in phasing state. State=%s", state_rx_str().c_str() ); + LOG_ERROR( _("Should be in phasing state. State=%s"), state_rx_str().c_str() ); } m_rx_state=RXIMAGE; @@ -1264,29 +1419,29 @@ void fax_implementation::skip_phasing_to_image(bool auto_center) int lpm_integer = wefax_pic::normalize_lpm( m_lpm_img ); if( m_lpm_img != lpm_integer ) { - LOG_INFO("LPM rounded from %f to %d. Manual=%d", m_lpm_img, lpm_integer, m_manual_mode ); + LOG_INFO( _("LPM rounded from %f to %d. Manual=%d"), m_lpm_img, lpm_integer, m_manual_mode ); } reset_counters(); /// From now on, m_lpm_img will never change and has a normalized value. REQ( wefax_pic::update_rx_lpm, lpm_integer); - PUT_STATUS( state_rx_str() << ". Decoding phasing line LPM=" << lpm_integer ); - m_lpm_img = lpm_integer ; + PUT_STATUS( state_rx_str() << ". " << _("Decoding phasing line LPM=") << lpm_integer ); + lpm_set( lpm_integer ); } /// Called by the user when clicking button. Never called automatically. void fax_implementation::skip_phasing_rx(bool auto_center) { if(m_rx_state!=RXPHASING) { - LOG_ERROR("Should be in phasing state. State=%s", state_rx_str().c_str() ); + LOG_ERROR( _("Should be in phasing state. State=%s"), state_rx_str().c_str() ); } skip_phasing_to_image(auto_center); /// We force these two values because these could not be detected automatically. if( m_lpm_img != LPM_DEFAULT ) { - m_lpm_img = LPM_DEFAULT ; - LOG_INFO("Forcing m_lpm_img=%f. Manual=%d", m_lpm_img, m_manual_mode ); + lpm_set( LPM_DEFAULT ); + LOG_INFO( _("Forcing m_lpm_img=%f. Manual=%d"), m_lpm_img, m_manual_mode ); } m_img_sample=0; /// The image start may not be what the phasing would have told. } @@ -1390,10 +1545,9 @@ void fax_implementation::rx_new_samples(const double* audio_ptr, int audio_sz) void fax_implementation::init_tx(int the_smpl_rat) { m_sample_rate=the_smpl_rat; - m_short_sine.reset(); - if(!m_freq_mod ) { - m_short_sine.set_increment(m_short_sine.size()*m_carrier/m_sample_rate); - } + set_carrier(wefax_default_carrier); + /// These reset increments of trigo tables. + m_ptr_wefax->set_freq(wefax_default_carrier); m_tx_state=TXAPTSTART; } @@ -1425,7 +1579,7 @@ bool fax_implementation::trx_do_next(void) LOG_DEBUG("m_xmt_bytes=%d m_lpm_img=%f", m_xmt_bytes, m_lpm_img ); /// The number of samples sent for one line. The LPM is given by the GUI. - const int smpl_per_lin= samples_per_line(); + const int smpl_per_lin= m_smpl_per_lin; /// Should not be too big because it is allocated on the stack, gcc feature. static const int block_len = 256 ; @@ -1589,12 +1743,12 @@ void fax_implementation::tx_params_set( m_img_tx_cols=img_w; m_xmt_bytes = xmt_bytes ; m_img_color = is_color ; - m_lpm_img = the_lpm ; + lpm_set( the_lpm ); m_xmt_pic_buf = xmtpic_buffer ; - PUT_STATUS( "Sending picture. Bytes=" << m_xmt_bytes - << " rows=" << m_img_tx_rows - << " cols=" << m_img_tx_cols ); + PUT_STATUS( _("Sending picture.") << " " << _("Bytes") << "=" << m_xmt_bytes + << _(" rows=") << m_img_tx_rows + << _(" cols=") << m_img_tx_cols ); } void fax_implementation::tx_apt_stop(void) @@ -1618,13 +1772,13 @@ void wefax::tx_init(SoundBase *sc) /// This updates the window label according to the state. void wefax::update_rx_label(void) const { - std::string tmp_label("Reception "); + std::string tmp_label( _("Reception ") ); tmp_label += mode_info[modem::mode].name ; if( m_impl->manual_mode_get() ) { - tmp_label += " - Manual" ; + tmp_label += _(" - Manual") ; } else { - tmp_label += " - APT control" ; + tmp_label += _(" - APT control") ; } REQ( wefax_pic::set_rx_label, tmp_label ); @@ -1768,7 +1922,7 @@ int wefax::rx_process(const double *buf, int len) /// Wait some seconds otherwise not significant. if( idx >= avg_buf_size ) { if( idx == avg_buf_size ) { - LOG_INFO("Starting samples loss control avg_buf_size=%d", avg_buf_size); + LOG_INFO( _("Starting samples loss control avg_buf_size=%d"), avg_buf_size); } int idx_mod_first = idx % avg_buf_size ; double total_tim = buf_tim[idx_mod] - buf_tim[idx_mod_first]; @@ -1785,7 +1939,7 @@ int wefax::rx_process(const double *buf, int len) int expected_samples = (int)( modem::samplerate * total_tim + 0.5 ); int missing_samples = expected_samples - total_len ; - LOG_INFO("Lost %d samples idx=%d estim_smpl_rate=%f total_tim=%f total_len=%d", + LOG_INFO(_("Lost %d samples idx=%d estim_smpl_rate=%f total_tim=%f total_len=%d"), missing_samples, idx, estim_smpl_rate, @@ -1794,7 +1948,7 @@ int wefax::rx_process(const double *buf, int len) if( missing_samples <= 0 ) { /// This should practically never happen. - LOG_WARN("Cannot compensate"); + LOG_WARN(_("Cannot compensate")); } else { /// Adjust the number of received pixels, /// so the lost frames are signaled once only. @@ -1836,7 +1990,7 @@ int wefax::tx_process() bool tx_was_completed = m_impl->trx_do_next(); std::string status ; if( false == tx_was_completed ) { - status = "Transmission cancelled"; + status = _("Transmission cancelled"); LOG_INFO("Sending cancelled" ); m_qso_rec.putField(NOTES, status.c_str() ); } @@ -2023,12 +2177,15 @@ void wefax::qso_rec_save(void) qsodb.qsoNewRec (&m_qso_rec); // dxcc_entity_cache_add(&rec); - LOG_INFO("Updating log book %s", logbook_filename.c_str() ); + LOG_INFO( _("Updating log book %s"), logbook_filename.c_str() ); } -void wefax::set_freq(double) +/// Called when changing the carrier in the GUI, and by class modem with 1000Hz, when initializing. +void wefax::set_freq(double freq) { - modem::set_freq(m_impl->carrier()); + modem::set_freq(freq); + /// This must recompute the increments of the trigonometric tables. + m_impl->set_carrier( freq ); } // String telling the tx and rx internal state. From a5be80f1c5a80b4d3f6ee9ec77c4d15d2d038628 Mon Sep 17 00:00:00 2001 From: David Freese Date: Mon, 14 Nov 2011 12:22:15 -0600 Subject: [PATCH 54/54] Version 3.21.26 Maintenance release --- ChangeLog | 17 +++++++++++++++-- configure.ac | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 722d3c86..c3c942b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,23 @@ +=Version 3.21.26= + +2011-11-14 David Freese + + 77551e8: eQSL update + + =Version 3.21.25= -2011-11-13 David Freese - 50fa414: guard lock + +2011-11-12 Remi Chateauneu + + dae542e: Wefax enhancements. + e75cc0e: Use Logbook record + +2011-11-12 David Freese + c2ba559: eQSL diff --git a/configure.ac b/configure.ac index 412b4bb0..fc730430 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [3]) m4_define(FLDIGI_MINOR, [21]) -m4_define(FLDIGI_PATCH, [.25]) +m4_define(FLDIGI_PATCH, [.26]) m4_define(FLARQ_MAJOR, [4]) m4_define(FLARQ_MINOR, [3]) m4_define(FLARQ_PATCH, [.1])