diff --git a/src/Makefile.am b/src/Makefile.am index 0b1c4101..3536253a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -394,6 +394,7 @@ fldigi_SOURCES += \ include/jalocha/pj_mfsk.h \ include/jalocha/pj_struc.h \ include/kiss_io.h \ + include/maclogger.h \ include/ax25_decode.h \ include/coordinate.h \ include/gfft.h \ @@ -514,6 +515,7 @@ fldigi_SOURCES += \ logbook/logbook.cxx \ logbook/logsupport.cxx \ logbook/lookupcall.cxx \ + logbook/maclogger.cxx \ logbook/qrzlib.cxx \ logbook/qso_db.cxx \ logbook/table.cxx \ diff --git a/src/dialogs/confdialog.cxx b/src/dialogs/confdialog.cxx index 7cc07a7d..466653f9 100644 --- a/src/dialogs/confdialog.cxx +++ b/src/dialogs/confdialog.cxx @@ -695,6 +695,8 @@ progdefaults.changed = true; Fl_Group *tabLogServer=(Fl_Group *)0; +Fl_Tabs *tabsLog=(Fl_Tabs *)0; + Fl_Check_Button *btnNagMe=(Fl_Check_Button *)0; static void cb_btnNagMe(Fl_Check_Button* o, void*) { @@ -813,6 +815,67 @@ static void cb_btnUSunits(Fl_Check_Button* o, void*) { progdefaults.changed = true; } +Fl_Check_Button *btnConnectToMaclogger=(Fl_Check_Button *)0; + +static void cb_btnConnectToMaclogger(Fl_Check_Button* o, void*) { + progdefaults.connect_to_maclogger = o->value(); +if (progdefaults.connect_to_maclogger == false) + maclogger_close(); +else + maclogger_init(); +progdefaults.changed = true; +} + +Fl_Check_Button *btn_capture_maclogger_radio=(Fl_Check_Button *)0; + +static void cb_btn_capture_maclogger_radio(Fl_Check_Button* o, void*) { + progdefaults.capture_maclogger_radio = o->value(); +progdefaults.changed = true; +} + +Fl_Check_Button *btn_capture_maclogger_log=(Fl_Check_Button *)0; + +static void cb_btn_capture_maclogger_log(Fl_Check_Button* o, void*) { + progdefaults.capture_maclogger_log = o->value(); +progdefaults.changed = true; +} + +Fl_Check_Button *btn_capture_maclogger_lookup=(Fl_Check_Button *)0; + +static void cb_btn_capture_maclogger_lookup(Fl_Check_Button* o, void*) { + progdefaults.capture_maclogger_lookup = o->value(); +progdefaults.changed = true; +} + +Fl_Check_Button *btn_capture_maclogger_spot_tune=(Fl_Check_Button *)0; + +static void cb_btn_capture_maclogger_spot_tune(Fl_Check_Button* o, void*) { + progdefaults.capture_maclogger_spot_tune = o->value(); +progdefaults.changed = true; +} + +Fl_Check_Button *btn_capture_maclogger_spot_report=(Fl_Check_Button *)0; + +static void cb_btn_capture_maclogger_spot_report(Fl_Check_Button* o, void*) { + progdefaults.capture_maclogger_spot_report = o->value(); +progdefaults.changed = true; +} + +Fl_Check_Button *btn_enable_maclogger_log=(Fl_Check_Button *)0; + +static void cb_btn_enable_maclogger_log(Fl_Check_Button* o, void*) { + progdefaults.enable_maclogger_log = o->value(); +progdefaults.changed = true; +} + +Fl_Text_Display *txt_UDP_data=(Fl_Text_Display *)0; + +Fl_Output *txt_maclogger_log_filename=(Fl_Output *)0; + +static void cb_Clear(Fl_Button*, void*) { + txt_UDP_data->buffer()->text(""); +} + Fl_Group *tabMBars=(Fl_Group *)0; Fl_Check_Button *btnMacroMouseWheel=(Fl_Check_Button *)0; @@ -5789,7 +5852,7 @@ Fl_Double_Window* ConfigureDialog() { o->selection_color((Fl_Color)51); o->labelsize(18); o->align(Fl_Align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE)); - { tabsConfigure = new Fl_Tabs(0, 0, 600, 380); + { tabsConfigure = new Fl_Tabs(0, 0, 600, 385); tabsConfigure->color(FL_LIGHT1); tabsConfigure->selection_color(FL_LIGHT1); { tabOperator = new Fl_Group(0, 25, 600, 355, _("Operator")); @@ -5911,10 +5974,10 @@ Fl_Double_Window* ConfigureDialog() { } // Fl_Group* grpNoise tabOperator->end(); } // Fl_Group* tabOperator - { tabUI = new Fl_Group(0, 25, 600, 355, _("UI")); + { tabUI = new Fl_Group(0, 25, 600, 360, _("UI")); tabUI->tooltip(_("User Interface")); tabUI->hide(); - { tabsUI = new Fl_Tabs(0, 25, 600, 355); + { tabsUI = new Fl_Tabs(0, 25, 600, 360); tabsUI->selection_color(FL_LIGHT1); { tabBrowser = new Fl_Group(0, 50, 600, 330, _("Browser")); tabBrowser->tooltip(_("User Interface - Browser")); @@ -6328,61 +6391,63 @@ Fl_Double_Window* ConfigureDialog() { } // Fl_Group* o tabUserInterface->end(); } // Fl_Group* tabUserInterface - { tabLogServer = new Fl_Group(0, 50, 600, 330, _("Log")); - tabLogServer->tooltip(_("User Interface - Logging")); + { tabLogServer = new Fl_Group(0, 50, 600, 335, _("Log")); + tabLogServer->tooltip(_("User Interface - Colors / Fonts")); tabLogServer->hide(); - { Fl_Group* o = new Fl_Group(52, 59, 496, 198, _("QSO logging")); - o->box(FL_ENGRAVED_FRAME); - o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE)); - { Fl_Check_Button* o = btnNagMe = new Fl_Check_Button(69, 81, 236, 20, _("Prompt to save log on exit")); + { tabsLog = new Fl_Tabs(0, 55, 600, 330); + { Fl_Group* o = new Fl_Group(0, 80, 600, 300, _("QSO")); + { Fl_Group* o = new Fl_Group(60, 112, 496, 198, _("QSO logging")); + o->box(FL_ENGRAVED_FRAME); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE)); + { Fl_Check_Button* o = btnNagMe = new Fl_Check_Button(77, 134, 236, 20, _("Prompt to save log on exit")); btnNagMe->tooltip(_("Bug me about saving log entries")); btnNagMe->down_box(FL_DOWN_BOX); btnNagMe->callback((Fl_Callback*)cb_btnNagMe); o->value(progdefaults.NagMe); - } // Fl_Check_Button* btnNagMe - { Fl_Check_Button* o = btnClearOnSave = new Fl_Check_Button(69, 110, 236, 20, _("Clear on save")); + } // Fl_Check_Button* btnNagMe + { Fl_Check_Button* o = btnClearOnSave = new Fl_Check_Button(77, 163, 236, 20, _("Clear on save")); btnClearOnSave->tooltip(_("Clear log entries after saving or using macro ")); btnClearOnSave->down_box(FL_DOWN_BOX); btnClearOnSave->callback((Fl_Callback*)cb_btnClearOnSave); o->value(progdefaults.ClearOnSave); - } // Fl_Check_Button* btnClearOnSave - { Fl_Check_Button* o = btnCallUpperCase = new Fl_Check_Button(69, 139, 236, 20, _("Convert callsign to upper case")); + } // Fl_Check_Button* btnClearOnSave + { Fl_Check_Button* o = btnCallUpperCase = new Fl_Check_Button(77, 192, 236, 20, _("Convert callsign to upper case")); btnCallUpperCase->tooltip(_("Force callsign field to UPPERCASE")); btnCallUpperCase->down_box(FL_DOWN_BOX); btnCallUpperCase->callback((Fl_Callback*)cb_btnCallUpperCase); o->value(progdefaults.calluppercase); - } // Fl_Check_Button* btnCallUpperCase - { Fl_Check_Button* o = btnAutoFillQSO = new Fl_Check_Button(69, 169, 236, 20, _("Auto-fill Country and Azimuth")); + } // Fl_Check_Button* btnCallUpperCase + { Fl_Check_Button* o = btnAutoFillQSO = new Fl_Check_Button(77, 222, 236, 20, _("Auto-fill Country and Azimuth")); btnAutoFillQSO->tooltip(_("Fill in Country / Azimuth using cty.dat information")); btnAutoFillQSO->down_box(FL_DOWN_BOX); btnAutoFillQSO->callback((Fl_Callback*)cb_btnAutoFillQSO); o->value(progdefaults.autofill_qso_fields); - } // Fl_Check_Button* btnAutoFillQSO - { Fl_Check_Button* o = btnDateTimeSort = new Fl_Check_Button(322, 81, 190, 20, _("Sort by Date/Time OFF")); + } // Fl_Check_Button* btnAutoFillQSO + { Fl_Check_Button* o = btnDateTimeSort = new Fl_Check_Button(330, 134, 190, 20, _("Sort by Date/Time OFF")); btnDateTimeSort->tooltip(_("Sort by date/time OFF - effects all ADIF/Cabrillo reports")); btnDateTimeSort->down_box(FL_DOWN_BOX); btnDateTimeSort->callback((Fl_Callback*)cb_btnDateTimeSort); o->value(progdefaults.sort_date_time_off); - } // Fl_Check_Button* btnDateTimeSort - { Fl_Check_Button* o = btndate_time_force = new Fl_Check_Button(322, 110, 190, 20, _("Date time ON == OFF")); + } // Fl_Check_Button* btnDateTimeSort + { Fl_Check_Button* o = btndate_time_force = new Fl_Check_Button(330, 163, 190, 20, _("Date time ON == OFF")); btndate_time_force->tooltip(_("Force date/time ON == date/time OFF")); btndate_time_force->down_box(FL_DOWN_BOX); btndate_time_force->callback((Fl_Callback*)cb_btndate_time_force); o->value(progdefaults.force_date_time); - } // Fl_Check_Button* btndate_time_force - { Fl_Check_Button* o = btnRSTindefault = new Fl_Check_Button(322, 139, 213, 20, _("Default RST in to 599/59")); + } // Fl_Check_Button* btndate_time_force + { Fl_Check_Button* o = btnRSTindefault = new Fl_Check_Button(330, 192, 213, 20, _("Default RST in to 599/59")); btnRSTindefault->tooltip(_("Clear log controls sets RST in to 599/59")); btnRSTindefault->down_box(FL_DOWN_BOX); btnRSTindefault->callback((Fl_Callback*)cb_btnRSTindefault); o->value(progdefaults.RSTin_default); - } // Fl_Check_Button* btnRSTindefault - { Fl_Check_Button* o = btnRSTdefault = new Fl_Check_Button(322, 169, 216, 20, _("Default RST out to 599/59")); + } // Fl_Check_Button* btnRSTindefault + { Fl_Check_Button* o = btnRSTdefault = new Fl_Check_Button(330, 222, 216, 20, _("Default RST out to 599/59")); btnRSTdefault->tooltip(_("Clear log controls sets RST out to 599/59")); btnRSTdefault->down_box(FL_DOWN_BOX); btnRSTdefault->callback((Fl_Callback*)cb_btnRSTdefault); o->value(progdefaults.RSTdefault); - } // Fl_Check_Button* btnRSTdefault - { Fl_Input2* o = txt_cty_dat_pathname = new Fl_Input2(189, 196, 346, 24, _("cty.dat folder")); + } // Fl_Check_Button* btnRSTdefault + { Fl_Input2* o = txt_cty_dat_pathname = new Fl_Input2(197, 249, 346, 24, _("cty.dat folder")); txt_cty_dat_pathname->tooltip(_("Enter full path-name for cty.dat folder")); txt_cty_dat_pathname->box(FL_DOWN_BOX); txt_cty_dat_pathname->color(FL_BACKGROUND2_COLOR); @@ -6395,20 +6460,20 @@ Fl_Double_Window* ConfigureDialog() { txt_cty_dat_pathname->align(Fl_Align(FL_ALIGN_LEFT)); txt_cty_dat_pathname->when(FL_WHEN_CHANGED); o->value(progdefaults.cty_dat_pathname.c_str()); - } // Fl_Input2* txt_cty_dat_pathname - { btn_select_cty_dat = new Fl_Button(70, 225, 75, 24, _("Browse")); + } // Fl_Input2* txt_cty_dat_pathname + { btn_select_cty_dat = new Fl_Button(78, 278, 75, 24, _("Browse")); btn_select_cty_dat->tooltip(_("Locate cty.dat file")); btn_select_cty_dat->callback((Fl_Callback*)cb_btn_select_cty_dat); - } // Fl_Button* btn_select_cty_dat - { btn_default_cty_dat = new Fl_Button(165, 225, 75, 24, _("Default")); + } // Fl_Button* btn_select_cty_dat + { btn_default_cty_dat = new Fl_Button(173, 278, 75, 24, _("Default")); btn_default_cty_dat->tooltip(_("Restore cty.dat default folder")); btn_default_cty_dat->callback((Fl_Callback*)cb_btn_default_cty_dat); - } // Fl_Button* btn_default_cty_dat - { btn_reload_cty_dat = new Fl_Button(260, 225, 75, 24, _("Reload")); + } // Fl_Button* btn_default_cty_dat + { btn_reload_cty_dat = new Fl_Button(268, 278, 75, 24, _("Reload")); btn_reload_cty_dat->tooltip(_("Reload cty.dat")); btn_reload_cty_dat->callback((Fl_Callback*)cb_btn_reload_cty_dat); - } // Fl_Button* btn_reload_cty_dat - { Fl_Input2* o = inpMyPower = new Fl_Input2(485, 225, 50, 24, _("Transmit Power")); + } // Fl_Button* btn_reload_cty_dat + { Fl_Input2* o = inpMyPower = new Fl_Input2(493, 278, 50, 24, _("Transmit Power")); inpMyPower->tooltip(_("Tx power used for logbook entries")); inpMyPower->box(FL_DOWN_BOX); inpMyPower->color(FL_BACKGROUND2_COLOR); @@ -6422,25 +6487,29 @@ Fl_Double_Window* ConfigureDialog() { inpMyPower->when(FL_WHEN_RELEASE); o->value(progdefaults.mytxpower.c_str()); o->labelsize(FL_NORMAL_SIZE); - } // Fl_Input2* inpMyPower - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(52, 263, 496, 110, _("Rx Text")); - o->box(FL_ENGRAVED_FRAME); - o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE)); - { Fl_Check_Button* o = btnRXClicks = new Fl_Check_Button(75, 318, 191, 20, _("Single-click to capture")); + } // Fl_Input2* inpMyPower + o->end(); + } // Fl_Group* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(0, 80, 600, 300, _("Rx Text")); + o->hide(); + { Fl_Group* o = new Fl_Group(62, 100, 496, 110, _("Rx Text")); + o->box(FL_ENGRAVED_FRAME); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE)); + { Fl_Check_Button* o = btnRXClicks = new Fl_Check_Button(85, 155, 191, 20, _("Single-click to capture")); btnRXClicks->tooltip(_("Enable for single click capure of text in Rx panel")); btnRXClicks->down_box(FL_DOWN_BOX); btnRXClicks->callback((Fl_Callback*)cb_btnRXClicks); o->value(progdefaults.rxtext_clicks_qso_data); - } // Fl_Check_Button* btnRXClicks - { Fl_Check_Button* o = btnRXTooltips = new Fl_Check_Button(277, 318, 254, 20, _("callsign tooltips in received text")); + } // Fl_Check_Button* btnRXClicks + { Fl_Check_Button* o = btnRXTooltips = new Fl_Check_Button(287, 155, 254, 20, _("callsign tooltips in received text")); btnRXTooltips->tooltip(_("Popup info after a 2 second hover on a callsign")); btnRXTooltips->down_box(FL_DOWN_BOX); btnRXTooltips->callback((Fl_Callback*)cb_btnRXTooltips); o->value(progdefaults.rxtext_tooltips); - } // Fl_Check_Button* btnRXTooltips - { Fl_Input2* o = inpNonword = new Fl_Input2(194, 288, 279, 24, _("Word delimiters")); + } // Fl_Check_Button* btnRXTooltips + { Fl_Input2* o = inpNonword = new Fl_Input2(204, 125, 279, 24, _("Word delimiters")); inpNonword->tooltip(_("RX text QSO data entry is bounded by the non-word characters\ndefined here. T\ ab and newline are automatically included.")); inpNonword->box(FL_DOWN_BOX); @@ -6456,15 +6525,70 @@ ab and newline are automatically included.")); inpNonword->when(FL_WHEN_RELEASE); o->value(progdefaults.nonwordchars.c_str()); o->labelsize(FL_NORMAL_SIZE); - } // Fl_Input2* inpNonword - { Fl_Check_Button* o = btnUSunits = new Fl_Check_Button(277, 343, 220, 20, _("US units of distance (QRB)")); + } // Fl_Input2* inpNonword + { Fl_Check_Button* o = btnUSunits = new Fl_Check_Button(287, 180, 220, 20, _("US units of distance (QRB)")); btnUSunits->tooltip(_("Enable for single click capure of text in Rx panel")); btnUSunits->down_box(FL_DOWN_BOX); btnUSunits->callback((Fl_Callback*)cb_btnUSunits); o->value(progdefaults.us_units); - } // Fl_Check_Button* btnUSunits - o->end(); - } // Fl_Group* o + } // Fl_Check_Button* btnUSunits + o->end(); + } // Fl_Group* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(0, 80, 600, 300, _("MacLogger")); + o->hide(); + { Fl_Check_Button* o = btnConnectToMaclogger = new Fl_Check_Button(10, 95, 186, 20, _("Connect to MacLogger")); + btnConnectToMaclogger->down_box(FL_DOWN_BOX); + btnConnectToMaclogger->callback((Fl_Callback*)cb_btnConnectToMaclogger); + o->value(progdefaults.connect_to_maclogger); + } // Fl_Check_Button* btnConnectToMaclogger + { Fl_Check_Button* o = btn_capture_maclogger_radio = new Fl_Check_Button(205, 95, 186, 20, _("Capture Radio Report")); + btn_capture_maclogger_radio->down_box(FL_DOWN_BOX); + btn_capture_maclogger_radio->value(1); + btn_capture_maclogger_radio->callback((Fl_Callback*)cb_btn_capture_maclogger_radio); + o->value(progdefaults.capture_maclogger_radio); + } // Fl_Check_Button* btn_capture_maclogger_radio + { Fl_Check_Button* o = btn_capture_maclogger_log = new Fl_Check_Button(205, 120, 186, 20, _("Capture Log Report")); + btn_capture_maclogger_log->down_box(FL_DOWN_BOX); + btn_capture_maclogger_log->callback((Fl_Callback*)cb_btn_capture_maclogger_log); + o->value(progdefaults.capture_maclogger_log); + } // Fl_Check_Button* btn_capture_maclogger_log + { Fl_Check_Button* o = btn_capture_maclogger_lookup = new Fl_Check_Button(405, 95, 186, 20, _("Capture Lookup ")); + btn_capture_maclogger_lookup->down_box(FL_DOWN_BOX); + btn_capture_maclogger_lookup->callback((Fl_Callback*)cb_btn_capture_maclogger_lookup); + o->value(progdefaults.capture_maclogger_lookup); + } // Fl_Check_Button* btn_capture_maclogger_lookup + { Fl_Check_Button* o = btn_capture_maclogger_spot_tune = new Fl_Check_Button(405, 120, 186, 20, _("Capture Spot Tune")); + btn_capture_maclogger_spot_tune->down_box(FL_DOWN_BOX); + btn_capture_maclogger_spot_tune->callback((Fl_Callback*)cb_btn_capture_maclogger_spot_tune); + o->value(progdefaults.capture_maclogger_spot_tune); + } // Fl_Check_Button* btn_capture_maclogger_spot_tune + { Fl_Check_Button* o = btn_capture_maclogger_spot_report = new Fl_Check_Button(405, 147, 186, 20, _("Capture Spot Report")); + btn_capture_maclogger_spot_report->down_box(FL_DOWN_BOX); + btn_capture_maclogger_spot_report->callback((Fl_Callback*)cb_btn_capture_maclogger_spot_report); + o->value(progdefaults.capture_maclogger_spot_report); + } // Fl_Check_Button* btn_capture_maclogger_spot_report + { Fl_Check_Button* o = btn_enable_maclogger_log = new Fl_Check_Button(10, 175, 165, 25, _("Enable UDP log file")); + btn_enable_maclogger_log->down_box(FL_DOWN_BOX); + btn_enable_maclogger_log->callback((Fl_Callback*)cb_btn_enable_maclogger_log); + o->value(progdefaults.enable_maclogger_log); + } // Fl_Check_Button* btn_enable_maclogger_log + { Fl_Text_Display* o = txt_UDP_data = new Fl_Text_Display(10, 220, 580, 156, _("UDP data stream")); + txt_UDP_data->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + Fl_Text_Buffer *txtbuffer = new Fl_Text_Buffer(); + o->buffer(txtbuffer); + } // Fl_Text_Display* txt_UDP_data + { Fl_Output* o = txt_maclogger_log_filename = new Fl_Output(178, 175, 272, 25); + o->value(progdefaults.maclogger_log_filename.c_str()); + } // Fl_Output* txt_maclogger_log_filename + { Fl_Button* o = new Fl_Button(460, 175, 129, 25, _("Clear UDP text")); + o->callback((Fl_Callback*)cb_Clear); + } // Fl_Button* o + o->end(); + } // Fl_Group* o + tabsLog->end(); + } // Fl_Tabs* tabsLog tabLogServer->end(); } // Fl_Group* tabLogServer { tabMBars = new Fl_Group(0, 50, 600, 330, _("Macros")); @@ -6675,8 +6799,9 @@ ab and newline are automatically included.")); tabColorsFonts->tooltip(_("User Interface - Colors / Fonts")); tabColorsFonts->hide(); { tabsColors = new Fl_Tabs(0, 55, 600, 325); - { Fl_Group* o = new Fl_Group(0, 75, 600, 305, _("Rx/Tx")); - { Fl_ListBox* o = listbox_charset_status = new Fl_ListBox(96, 85, 165, 24, _("Rx/Tx Character set")); + { Fl_Group* o = new Fl_Group(0, 80, 600, 300, _("Rx/Tx")); + o->hide(); + { Fl_ListBox* o = listbox_charset_status = new Fl_ListBox(96, 90, 165, 24, _("Rx/Tx Character set")); listbox_charset_status->tooltip(_("Select Rx/Tx Character Set")); listbox_charset_status->box(FL_BORDER_BOX); listbox_charset_status->color((Fl_Color)55); @@ -6691,92 +6816,92 @@ ab and newline are automatically included.")); listbox_charset_status->callback(cb_listbox_charset, 0); listbox_charset_status->end(); } // Fl_ListBox* listbox_charset_status - { RxText = new Fl_Input(96, 116, 220, 36); + { RxText = new Fl_Input(96, 121, 220, 36); RxText->value("Receive Text"); RxText->color(fl_rgb_color(progdefaults.RxColor.R, progdefaults.RxColor.G, progdefaults.RxColor.B)); RxText->textfont(progdefaults.RxFontnbr); RxText->textsize(progdefaults.RxFontsize); RxText->textcolor(progdefaults.RxFontcolor); RxText->type(FL_MULTILINE_INPUT_WRAP); } // Fl_Input* RxText - { btnRxColor = new Fl_Button(326, 123, 75, 21, _("Rx bkgnd")); + { btnRxColor = new Fl_Button(326, 128, 75, 21, _("Rx bkgnd")); btnRxColor->callback((Fl_Callback*)cb_btnRxColor); } // Fl_Button* btnRxColor - { btnTxColor = new Fl_Button(326, 166, 75, 21, _("Tx bkgnd")); + { btnTxColor = new Fl_Button(326, 171, 75, 21, _("Tx bkgnd")); btnTxColor->callback((Fl_Callback*)cb_btnTxColor); } // Fl_Button* btnTxColor - { TxText = new Fl_Input(96, 158, 220, 37); + { TxText = new Fl_Input(96, 163, 220, 37); TxText->value("Transmit Text"); TxText->color(fl_rgb_color(progdefaults.TxColor.R, progdefaults.TxColor.G, progdefaults.TxColor.B)); TxText->textfont(progdefaults.TxFontnbr); TxText->textsize(progdefaults.TxFontsize); TxText->textcolor(progdefaults.TxFontcolor); TxText->type(FL_MULTILINE_INPUT_WRAP); } // Fl_Input* TxText - { btnRxFont = new Fl_Button(411, 123, 75, 21, _("Rx font")); + { btnRxFont = new Fl_Button(411, 128, 75, 21, _("Rx font")); btnRxFont->callback((Fl_Callback*)cb_btnRxFont); } // Fl_Button* btnRxFont - { btnTxFont = new Fl_Button(411, 166, 75, 21, _("Tx font")); + { btnTxFont = new Fl_Button(411, 171, 75, 21, _("Tx font")); btnTxFont->callback((Fl_Callback*)cb_btnTxFont); } // Fl_Button* btnTxFont - { MacroText = new Fl_Input(96, 201, 220, 37); + { MacroText = new Fl_Input(96, 206, 220, 37); MacroText->value("Macro editor text"); MacroText->textfont(progdefaults.MacroEditFontnbr); MacroText->textsize(progdefaults.MacroEditFontsize); MacroText->type(FL_MULTILINE_INPUT_WRAP); } // Fl_Input* MacroText - { btnMacroEditFont = new Fl_Button(326, 209, 120, 21, _("Macro Edit Font")); + { btnMacroEditFont = new Fl_Button(326, 214, 120, 21, _("Macro Edit Font")); btnMacroEditFont->callback((Fl_Callback*)cb_btnMacroEditFont); } // Fl_Button* btnMacroEditFont - { Fl_Group* o = new Fl_Group(86, 248, 404, 81, _("Text Highlighting")); + { Fl_Group* o = new Fl_Group(86, 253, 404, 81, _("Text Highlighting")); o->box(FL_ENGRAVED_FRAME); o->align(Fl_Align(FL_ALIGN_TOP|FL_ALIGN_INSIDE)); - { btnXMIT = new Fl_Button(104, 276, 40, 21, _("XMIT")); + { btnXMIT = new Fl_Button(104, 281, 40, 21, _("XMIT")); btnXMIT->tooltip(_("Sent chars in Rx/Tx pane")); btnXMIT->callback((Fl_Callback*)cb_btnXMIT); btnXMIT->align(Fl_Align(FL_ALIGN_BOTTOM)); btnXMIT->color(progdefaults.XMITcolor); } // Fl_Button* btnXMIT - { btnCTRL = new Fl_Button(147, 276, 40, 21, _("CTRL")); + { btnCTRL = new Fl_Button(147, 281, 40, 21, _("CTRL")); btnCTRL->tooltip(_("Control chars in Rx/Tx pane")); btnCTRL->callback((Fl_Callback*)cb_btnCTRL); btnCTRL->align(Fl_Align(FL_ALIGN_BOTTOM)); btnCTRL->color(progdefaults.CTRLcolor); } // Fl_Button* btnCTRL - { btnSKIP = new Fl_Button(191, 276, 40, 21, _("SKIP")); + { btnSKIP = new Fl_Button(191, 281, 40, 21, _("SKIP")); btnSKIP->tooltip(_("Skipped chars in Tx pane\n(Tx on/off in CW)")); btnSKIP->callback((Fl_Callback*)cb_btnSKIP); btnSKIP->align(Fl_Align(FL_ALIGN_BOTTOM)); btnSKIP->color(progdefaults.SKIPcolor); } // Fl_Button* btnSKIP - { btnALTR = new Fl_Button(234, 276, 40, 21, _("ALTR")); + { btnALTR = new Fl_Button(234, 281, 40, 21, _("ALTR")); btnALTR->tooltip(_("Alternate character color in Rx panelr")); btnALTR->callback((Fl_Callback*)cb_btnALTR); btnALTR->align(Fl_Align(FL_ALIGN_BOTTOM)); btnALTR->color(progdefaults.ALTRcolor); } // Fl_Button* btnALTR - { btnSEL = new Fl_Button(278, 276, 39, 21, _("SEL")); + { btnSEL = new Fl_Button(278, 281, 39, 21, _("SEL")); btnSEL->tooltip(_("Selection background color in Rx Tx panels")); btnSEL->callback((Fl_Callback*)cb_btnSEL); btnSEL->align(Fl_Align(FL_ALIGN_BOTTOM)); btnSEL->color(progdefaults.RxTxSelectcolor); } // Fl_Button* btnSEL - { btnNoTextColor = new Fl_Button(325, 276, 70, 21, _("System")); + { btnNoTextColor = new Fl_Button(325, 281, 70, 21, _("System")); btnNoTextColor->callback((Fl_Callback*)cb_btnNoTextColor); } // Fl_Button* btnNoTextColor - { btnTextDefaults = new Fl_Button(399, 276, 70, 21, _("Defaults")); + { btnTextDefaults = new Fl_Button(399, 281, 70, 21, _("Defaults")); btnTextDefaults->callback((Fl_Callback*)cb_btnTextDefaults); } // Fl_Button* btnTextDefaults o->end(); } // Fl_Group* o - { Fl_Check_Button* o = btn_show_all_codes = new Fl_Check_Button(110, 340, 25, 25, _("display Rx control chars as ascii string")); + { Fl_Check_Button* o = btn_show_all_codes = new Fl_Check_Button(110, 345, 25, 25, _("display Rx control chars as ascii string")); btn_show_all_codes->down_box(FL_DOWN_BOX); btn_show_all_codes->callback((Fl_Callback*)cb_btn_show_all_codes); o->value(progdefaults.show_all_codes); } // Fl_Check_Button* btn_show_all_codes o->end(); } // Fl_Group* o - { Fl_Group* o = new Fl_Group(0, 75, 600, 305, _("FreqDisp / Meters")); + { Fl_Group* o = new Fl_Group(0, 80, 600, 300, _("FreqDisp / Meters")); o->hide(); - { Fl_Group* o = new Fl_Group(115, 88, 394, 87); + { Fl_Group* o = new Fl_Group(115, 108, 395, 87); o->box(FL_ENGRAVED_FRAME); - { Fl_Box* o = FDdisplay = new Fl_Box(195, 92, 235, 45, _("14070.150")); + { Fl_Box* o = FDdisplay = new Fl_Box(195, 112, 235, 45, _("14070.150")); FDdisplay->box(FL_DOWN_BOX); FDdisplay->color((Fl_Color)55); FDdisplay->labelfont(4); @@ -6785,47 +6910,47 @@ ab and newline are automatically included.")); o->labelcolor(fl_rgb_color(progdefaults.FDforeground.R,progdefaults.FDforeground.G,progdefaults.FDforeground.B)); o->labelfont(progdefaults.FreqControlFontnbr); } // Fl_Box* FDdisplay - { btn_freq_control_font = new Fl_Button(122, 143, 90, 24, _("Font")); + { btn_freq_control_font = new Fl_Button(122, 163, 90, 24, _("Font")); btn_freq_control_font->callback((Fl_Callback*)cb_btn_freq_control_font); } // Fl_Button* btn_freq_control_font - { btnBackgroundColor = new Fl_Button(218, 143, 90, 24, _("Bg Color")); + { btnBackgroundColor = new Fl_Button(218, 163, 90, 24, _("Bg Color")); btnBackgroundColor->callback((Fl_Callback*)cb_btnBackgroundColor); } // Fl_Button* btnBackgroundColor - { btnForegroundColor = new Fl_Button(314, 143, 90, 24, _("Digit Color")); + { btnForegroundColor = new Fl_Button(314, 163, 90, 24, _("Digit Color")); btnForegroundColor->callback((Fl_Callback*)cb_btnForegroundColor); } // Fl_Button* btnForegroundColor - { btnFD_SystemColor = new Fl_Button(410, 143, 90, 24, _("Sys Colors")); + { btnFD_SystemColor = new Fl_Button(410, 163, 90, 24, _("Sys Colors")); btnFD_SystemColor->callback((Fl_Callback*)cb_btnFD_SystemColor); } // Fl_Button* btnFD_SystemColor o->end(); } // Fl_Group* o - { Fl_Group* o = new Fl_Group(115, 179, 420, 62, _("S-meter")); + { Fl_Group* o = new Fl_Group(115, 199, 395, 62, _("S-meter")); o->box(FL_ENGRAVED_FRAME); o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE)); - { btnSmeter_bg_color = new Fl_Button(122, 206, 90, 24, _("Bg Color")); + { btnSmeter_bg_color = new Fl_Button(122, 226, 90, 24, _("Bg Color")); btnSmeter_bg_color->callback((Fl_Callback*)cb_btnSmeter_bg_color); } // Fl_Button* btnSmeter_bg_color - { btnSmeter_scale_color = new Fl_Button(218, 206, 90, 24, _("Scale Color")); + { btnSmeter_scale_color = new Fl_Button(218, 226, 90, 24, _("Scale Color")); btnSmeter_scale_color->callback((Fl_Callback*)cb_btnSmeter_scale_color); } // Fl_Button* btnSmeter_scale_color - { btnSmeter_meter_color = new Fl_Button(314, 206, 90, 24, _("Meter Color")); + { btnSmeter_meter_color = new Fl_Button(314, 226, 90, 24, _("Meter Color")); btnSmeter_meter_color->callback((Fl_Callback*)cb_btnSmeter_meter_color); } // Fl_Button* btnSmeter_meter_color o->end(); } // Fl_Group* o - { Fl_Group* o = new Fl_Group(115, 248, 394, 67, _("PWR-meter")); + { Fl_Group* o = new Fl_Group(115, 268, 395, 67, _("PWR-meter")); o->box(FL_ENGRAVED_FRAME); o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE)); - { btnPWR_bg_color = new Fl_Button(122, 275, 90, 24, _("Bg Color")); + { btnPWR_bg_color = new Fl_Button(122, 295, 90, 24, _("Bg Color")); btnPWR_bg_color->callback((Fl_Callback*)cb_btnPWR_bg_color); } // Fl_Button* btnPWR_bg_color - { btnPWR_scale_color = new Fl_Button(218, 275, 90, 24, _("Scale Color")); + { btnPWR_scale_color = new Fl_Button(218, 295, 90, 24, _("Scale Color")); btnPWR_scale_color->callback((Fl_Callback*)cb_btnPWR_scale_color); } // Fl_Button* btnPWR_scale_color - { btnPWR_meter_Color = new Fl_Button(314, 275, 90, 24, _("Meter Color")); + { btnPWR_meter_Color = new Fl_Button(314, 295, 90, 24, _("Meter Color")); btnPWR_meter_Color->callback((Fl_Callback*)cb_btnPWR_meter_Color); } // Fl_Button* btnPWR_meter_Color - { Fl_ListBox* o = listboxPWRselect = new Fl_ListBox(410, 275, 80, 24, _("Power scale")); + { Fl_ListBox* o = listboxPWRselect = new Fl_ListBox(410, 295, 80, 24, _("Power scale")); listboxPWRselect->tooltip(_("Select the type of FFT prefilter")); listboxPWRselect->box(FL_DOWN_BOX); listboxPWRselect->color(FL_BACKGROUND2_COLOR); @@ -6846,7 +6971,7 @@ ab and newline are automatically included.")); } // Fl_Group* o o->end(); } // Fl_Group* o - { Fl_Group* o = new Fl_Group(0, 75, 600, 305, _("Log")); + { Fl_Group* o = new Fl_Group(0, 80, 600, 300, _("Log")); o->hide(); { Fl_Group* o = new Fl_Group(114, 101, 372, 65, _("Logging Panel Controls")); o->box(FL_ENGRAVED_FRAME); @@ -6890,7 +7015,7 @@ ab and newline are automatically included.")); } // Fl_Group* o o->end(); } // Fl_Group* o - { Fl_Group* o = new Fl_Group(0, 75, 600, 305, _("F_keys")); + { Fl_Group* o = new Fl_Group(0, 80, 600, 300, _("F_keys")); o->hide(); { btnUseGroupColors = new Fl_Check_Button(135, 107, 165, 21, _("Use colored buttons")); btnUseGroupColors->down_box(FL_DOWN_BOX); @@ -6923,7 +7048,7 @@ ab and newline are automatically included.")); } // Fl_Button* btnMacroBtnFont o->end(); } // Fl_Group* o - { Fl_Group* o = new Fl_Group(0, 75, 600, 305, _("Tabs")); + { Fl_Group* o = new Fl_Group(0, 80, 600, 300, _("Tabs")); o->hide(); { btnTabColor = new Fl_Button(200, 113, 75, 21, _("Tab Color")); btnTabColor->callback((Fl_Callback*)cb_btnTabColor); @@ -6933,7 +7058,7 @@ ab and newline are automatically included.")); } // Fl_Button* btnTabDefaultColor o->end(); } // Fl_Group* o - { Fl_Group* o = new Fl_Group(0, 75, 600, 305, _("Buttons")); + { Fl_Group* o = new Fl_Group(0, 80, 600, 300, _("Buttons")); o->hide(); { btnSpotColor = new Fl_Button(159, 121, 70, 21, _("Spot")); btnSpotColor->callback((Fl_Callback*)cb_btnSpotColor); @@ -7013,8 +7138,7 @@ ab and newline are automatically included.")); } // Fl_Box* o o->end(); } // Fl_Group* o - { Fl_Group* o = new Fl_Group(0, 75, 600, 305, _("SigLvl")); - o->hide(); + { Fl_Group* o = new Fl_Group(0, 80, 600, 300, _("SigLvl")); { btnLowSignal = new Fl_Button(210, 142, 70, 21, _("Low")); btnLowSignal->callback((Fl_Callback*)cb_btnLowSignal); } // Fl_Button* btnLowSignal diff --git a/src/dialogs/confdialog.fl b/src/dialogs/confdialog.fl index a6411fec..06b05abe 100644 --- a/src/dialogs/confdialog.fl +++ b/src/dialogs/confdialog.fl @@ -359,10 +359,10 @@ static const char szBaudRates[] = "300|600|1200|2400|4800|9600|19200|38400|57600 static const char szProsigns[] = "~|%|&|+|=|{|}|<|>|[|]| ";} {} Fl_Window {} { label {Fldigi configuration} open - xywh {958 64 600 415} type Double color 45 selection_color 51 labelsize 18 align 80 non_modal visible + xywh {914 185 600 415} type Double color 45 selection_color 51 labelsize 18 align 80 non_modal visible } { Fl_Tabs tabsConfigure {open - xywh {0 0 600 380} color 50 selection_color 50 + xywh {0 0 600 385} color 50 selection_color 50 } { Fl_Group tabOperator { label Operator @@ -457,10 +457,10 @@ progdefaults.changed = true;} } Fl_Group tabUI { label UI open - tooltip {User Interface} xywh {0 25 600 355} hide + tooltip {User Interface} xywh {0 25 600 360} hide } { Fl_Tabs tabsUI {open - xywh {0 25 600 355} selection_color 50 + xywh {0 25 600 360} selection_color 50 } { Fl_Group tabBrowser { label Browser @@ -915,138 +915,226 @@ progdefaults.changed = true;} } Fl_Group tabLogServer { label Log open - tooltip {User Interface - Logging} xywh {0 50 600 330} hide + tooltip {User Interface - Colors / Fonts} xywh {0 50 600 335} hide } { - Fl_Group {} { - label {QSO logging} open - xywh {52 59 496 198} box ENGRAVED_FRAME align 21 + Fl_Tabs tabsLog {open + xywh {0 55 600 330} } { - Fl_Check_Button btnNagMe { - label {Prompt to save log on exit} - callback {btn2NagMe->value(o->value()); + Fl_Group {} { + label QSO + xywh {0 80 600 300} + } { + Fl_Group {} { + label {QSO logging} open + xywh {60 112 496 198} box ENGRAVED_FRAME align 21 + } { + Fl_Check_Button btnNagMe { + label {Prompt to save log on exit} + callback {btn2NagMe->value(o->value()); progdefaults.NagMe=o->value(); progdefaults.changed = true;} - tooltip {Bug me about saving log entries} xywh {69 81 236 20} down_box DOWN_BOX - code0 {o->value(progdefaults.NagMe);} - } - Fl_Check_Button btnClearOnSave { - label {Clear on save} - callback {progdefaults.ClearOnSave=o->value(); + tooltip {Bug me about saving log entries} xywh {77 134 236 20} down_box DOWN_BOX + code0 {o->value(progdefaults.NagMe);} + } + Fl_Check_Button btnClearOnSave { + label {Clear on save} + callback {progdefaults.ClearOnSave=o->value(); progdefaults.changed = true;} - tooltip {Clear log entries after saving or using macro } xywh {69 110 236 20} down_box DOWN_BOX - code0 {o->value(progdefaults.ClearOnSave);} - } - Fl_Check_Button btnCallUpperCase { - label {Convert callsign to upper case} - callback {progdefaults.calluppercase = o->value(); + tooltip {Clear log entries after saving or using macro } xywh {77 163 236 20} down_box DOWN_BOX + code0 {o->value(progdefaults.ClearOnSave);} + } + Fl_Check_Button btnCallUpperCase { + label {Convert callsign to upper case} + callback {progdefaults.calluppercase = o->value(); progdefaults.changed = true;} - tooltip {Force callsign field to UPPERCASE} xywh {69 139 236 20} down_box DOWN_BOX - code0 {o->value(progdefaults.calluppercase);} - } - Fl_Check_Button btnAutoFillQSO { - label {Auto-fill Country and Azimuth} - callback {progdefaults.autofill_qso_fields = o->value(); + tooltip {Force callsign field to UPPERCASE} xywh {77 192 236 20} down_box DOWN_BOX + code0 {o->value(progdefaults.calluppercase);} + } + Fl_Check_Button btnAutoFillQSO { + label {Auto-fill Country and Azimuth} + callback {progdefaults.autofill_qso_fields = o->value(); progdefaults.changed = true;} - tooltip {Fill in Country / Azimuth using cty.dat information} xywh {69 169 236 20} down_box DOWN_BOX - code0 {o->value(progdefaults.autofill_qso_fields);} - } - Fl_Check_Button btnDateTimeSort { - label {Sort by Date/Time OFF} - callback {progdefaults.sort_date_time_off = o->value(); + tooltip {Fill in Country / Azimuth using cty.dat information} xywh {77 222 236 20} down_box DOWN_BOX + code0 {o->value(progdefaults.autofill_qso_fields);} + } + Fl_Check_Button btnDateTimeSort { + label {Sort by Date/Time OFF} + callback {progdefaults.sort_date_time_off = o->value(); progdefaults.changed = true; reload_browser();} - tooltip {Sort by date/time OFF - effects all ADIF/Cabrillo reports} xywh {322 81 190 20} down_box DOWN_BOX - code0 {o->value(progdefaults.sort_date_time_off);} - } - Fl_Check_Button btndate_time_force { - label {Date time ON == OFF} - callback {progdefaults.force_date_time = o->value(); + tooltip {Sort by date/time OFF - effects all ADIF/Cabrillo reports} xywh {330 134 190 20} down_box DOWN_BOX + code0 {o->value(progdefaults.sort_date_time_off);} + } + Fl_Check_Button btndate_time_force { + label {Date time ON == OFF} + callback {progdefaults.force_date_time = o->value(); progdefaults.changed = true;} - tooltip {Force date/time ON == date/time OFF} xywh {322 110 190 20} down_box DOWN_BOX - code0 {o->value(progdefaults.force_date_time);} - } - Fl_Check_Button btnRSTindefault { - label {Default RST in to 599/59} - callback {progdefaults.RSTin_default = o->value(); + tooltip {Force date/time ON == date/time OFF} xywh {330 163 190 20} down_box DOWN_BOX + code0 {o->value(progdefaults.force_date_time);} + } + Fl_Check_Button btnRSTindefault { + label {Default RST in to 599/59} + callback {progdefaults.RSTin_default = o->value(); progdefaults.changed = true;} - tooltip {Clear log controls sets RST in to 599/59} xywh {322 139 213 20} down_box DOWN_BOX - code0 {o->value(progdefaults.RSTin_default);} - } - Fl_Check_Button btnRSTdefault { - label {Default RST out to 599/59} - callback {progdefaults.RSTdefault = o->value(); + tooltip {Clear log controls sets RST in to 599/59} xywh {330 192 213 20} down_box DOWN_BOX + code0 {o->value(progdefaults.RSTin_default);} + } + Fl_Check_Button btnRSTdefault { + label {Default RST out to 599/59} + callback {progdefaults.RSTdefault = o->value(); progdefaults.changed = true;} - tooltip {Clear log controls sets RST out to 599/59} xywh {322 169 216 20} down_box DOWN_BOX - code0 {o->value(progdefaults.RSTdefault);} - } - Fl_Input txt_cty_dat_pathname { - label {cty.dat folder} - callback {progdefaults.cty_dat_pathname = o->value(); + tooltip {Clear log controls sets RST out to 599/59} xywh {330 222 216 20} down_box DOWN_BOX + code0 {o->value(progdefaults.RSTdefault);} + } + Fl_Input txt_cty_dat_pathname { + label {cty.dat folder} + callback {progdefaults.cty_dat_pathname = o->value(); progdefaults.changed = true;} - tooltip {Enter full path-name for cty.dat folder} xywh {189 196 346 24} when 1 - code0 {o->value(progdefaults.cty_dat_pathname.c_str());} - code1 {\#include "dxcc.h"} - class Fl_Input2 - } - Fl_Button btn_select_cty_dat { - label Browse - callback {select_cty_dat_pathname();} - tooltip {Locate cty.dat file} xywh {70 225 75 24} - } - Fl_Button btn_default_cty_dat { - label Default - callback {default_cty_dat_pathname();} - tooltip {Restore cty.dat default folder} xywh {165 225 75 24} - } - Fl_Button btn_reload_cty_dat { - label Reload - callback {reload_cty_dat();} - tooltip {Reload cty.dat} xywh {260 225 75 24} - } - Fl_Input inpMyPower { - label {Transmit Power} - callback {progdefaults.mytxpower = o->value(); + tooltip {Enter full path-name for cty.dat folder} xywh {197 249 346 24} when 1 + code0 {o->value(progdefaults.cty_dat_pathname.c_str());} + code1 {\#include "dxcc.h"} + class Fl_Input2 + } + Fl_Button btn_select_cty_dat { + label Browse + callback {select_cty_dat_pathname();} + tooltip {Locate cty.dat file} xywh {78 278 75 24} + } + Fl_Button btn_default_cty_dat { + label Default + callback {default_cty_dat_pathname();} + tooltip {Restore cty.dat default folder} xywh {173 278 75 24} + } + Fl_Button btn_reload_cty_dat { + label Reload + callback {reload_cty_dat();} + tooltip {Reload cty.dat} xywh {268 278 75 24} + } + Fl_Input inpMyPower { + label {Transmit Power} + callback {progdefaults.mytxpower = o->value(); progdefaults.changed = true;} - tooltip {Tx power used for logbook entries} xywh {485 225 50 24} - code0 {o->value(progdefaults.mytxpower.c_str());} - code1 {o->labelsize(FL_NORMAL_SIZE);} - class Fl_Input2 + tooltip {Tx power used for logbook entries} xywh {493 278 50 24} + code0 {o->value(progdefaults.mytxpower.c_str());} + code1 {o->labelsize(FL_NORMAL_SIZE);} + class Fl_Input2 + } + } } - } - Fl_Group {} { - label {Rx Text} open - xywh {52 263 496 110} box ENGRAVED_FRAME align 21 - } { - Fl_Check_Button btnRXClicks { - label {Single-click to capture} - callback {progdefaults.rxtext_clicks_qso_data = o->value(); + Fl_Group {} { + label {Rx Text} open + xywh {0 80 600 300} hide + } { + Fl_Group {} { + label {Rx Text} open + xywh {62 100 496 110} box ENGRAVED_FRAME align 21 + } { + Fl_Check_Button btnRXClicks { + label {Single-click to capture} + callback {progdefaults.rxtext_clicks_qso_data = o->value(); progdefaults.changed = true;} - tooltip {Enable for single click capure of text in Rx panel} xywh {75 318 191 20} down_box DOWN_BOX - code0 {o->value(progdefaults.rxtext_clicks_qso_data);} + tooltip {Enable for single click capure of text in Rx panel} xywh {85 155 191 20} down_box DOWN_BOX + code0 {o->value(progdefaults.rxtext_clicks_qso_data);} + } + Fl_Check_Button btnRXTooltips { + label {callsign tooltips in received text} + callback {progdefaults.rxtext_tooltips = o->value(); +progdefaults.changed = true;} + tooltip {Popup info after a 2 second hover on a callsign} xywh {287 155 254 20} down_box DOWN_BOX + code0 {o->value(progdefaults.rxtext_tooltips);} + } + Fl_Input inpNonword { + label {Word delimiters} + callback {progdefaults.nonwordchars = o->value(); +progdefaults.changed = true;} + tooltip {RX text QSO data entry is bounded by the non-word characters +defined here. Tab and newline are automatically included.} xywh {204 125 279 24} textfont 4 + code0 {o->value(progdefaults.nonwordchars.c_str());} + code1 {o->labelsize(FL_NORMAL_SIZE);} + class Fl_Input2 + } + Fl_Check_Button btnUSunits { + label {US units of distance (QRB)} + callback {progdefaults.us_units = o->value(); +progdefaults.changed = true;} + tooltip {Enable for single click capure of text in Rx panel} xywh {287 180 220 20} down_box DOWN_BOX + code0 {o->value(progdefaults.us_units);} + } + } } - Fl_Check_Button btnRXTooltips { - label {callsign tooltips in received text} - callback {progdefaults.rxtext_tooltips = o->value(); + Fl_Group {} { + label MacLogger open + xywh {0 80 600 300} hide + } { + Fl_Check_Button btnConnectToMaclogger { + label {Connect to MacLogger} + callback {progdefaults.connect_to_maclogger = o->value(); +if (progdefaults.connect_to_maclogger == false) + maclogger_close(); +else + maclogger_init(); progdefaults.changed = true;} - tooltip {Popup info after a 2 second hover on a callsign} xywh {277 318 254 20} down_box DOWN_BOX - code0 {o->value(progdefaults.rxtext_tooltips);} - } - Fl_Input inpNonword { - label {Word delimiters} - callback {progdefaults.nonwordchars = o->value(); + xywh {10 95 186 20} down_box DOWN_BOX + code0 {o->value(progdefaults.connect_to_maclogger);} + code1 {\#include "maclogger.h"} + } + Fl_Check_Button btn_capture_maclogger_radio { + label {Capture Radio Report} + callback {progdefaults.capture_maclogger_radio = o->value(); progdefaults.changed = true;} - tooltip {RX text QSO data entry is bounded by the non-word characters -defined here. Tab and newline are automatically included.} xywh {194 288 279 24} textfont 4 - code0 {o->value(progdefaults.nonwordchars.c_str());} - code1 {o->labelsize(FL_NORMAL_SIZE);} - class Fl_Input2 - } - Fl_Check_Button btnUSunits { - label {US units of distance (QRB)} - callback {progdefaults.us_units = o->value(); + xywh {205 95 186 20} down_box DOWN_BOX value 1 + code0 {o->value(progdefaults.capture_maclogger_radio);} + } + Fl_Check_Button btn_capture_maclogger_log { + label {Capture Log Report} + callback {progdefaults.capture_maclogger_log = o->value(); progdefaults.changed = true;} - tooltip {Enable for single click capure of text in Rx panel} xywh {277 343 220 20} down_box DOWN_BOX - code0 {o->value(progdefaults.us_units);} + xywh {205 120 186 20} down_box DOWN_BOX + code0 {o->value(progdefaults.capture_maclogger_log);} + } + Fl_Check_Button btn_capture_maclogger_lookup { + label {Capture Lookup } + callback {progdefaults.capture_maclogger_lookup = o->value(); +progdefaults.changed = true;} + xywh {405 95 186 20} down_box DOWN_BOX + code0 {o->value(progdefaults.capture_maclogger_lookup);} + } + Fl_Check_Button btn_capture_maclogger_spot_tune { + label {Capture Spot Tune} + callback {progdefaults.capture_maclogger_spot_tune = o->value(); +progdefaults.changed = true;} + xywh {405 120 186 20} down_box DOWN_BOX + code0 {o->value(progdefaults.capture_maclogger_spot_tune);} + } + Fl_Check_Button btn_capture_maclogger_spot_report { + label {Capture Spot Report} + callback {progdefaults.capture_maclogger_spot_report = o->value(); +progdefaults.changed = true;} + xywh {405 147 186 20} down_box DOWN_BOX + code0 {o->value(progdefaults.capture_maclogger_spot_report);} + } + Fl_Check_Button btn_enable_maclogger_log { + label {Enable UDP log file} + callback {progdefaults.enable_maclogger_log = o->value(); +progdefaults.changed = true;} + xywh {10 175 165 25} down_box DOWN_BOX + code0 {o->value(progdefaults.enable_maclogger_log);} + } + Fl_Text_Display txt_UDP_data { + label {UDP data stream} + xywh {10 220 580 156} align 5 + code0 {Fl_Text_Buffer *txtbuffer = new Fl_Text_Buffer();} + code1 {o->buffer(txtbuffer);} + } + Fl_Output txt_maclogger_log_filename { + xywh {178 175 272 25} + code0 {o->value(progdefaults.maclogger_log_filename.c_str());} + } + Fl_Button {} { + label {Clear UDP text} + callback {txt_UDP_data->buffer()->text("");} + xywh {460 175 129 25} + } } } } @@ -1361,18 +1449,18 @@ WF_UI();} } { Fl_Group {} { label {Rx/Tx} open - xywh {0 75 600 305} + xywh {0 80 600 300} hide } { Fl_Group listbox_charset_status { label {Rx/Tx Character set} open - tooltip {Select Rx/Tx Character Set} xywh {96 85 165 24} box BORDER_BOX color 55 align 8 + tooltip {Select Rx/Tx Character Set} xywh {96 90 165 24} box BORDER_BOX color 55 align 8 code0 {\#include "fl_digi.h"} code1 {o->labelsize(FL_NORMAL_SIZE); listbox_charset_status->callback(cb_listbox_charset, 0);} class Fl_ListBox } {} Fl_Input RxText { - xywh {96 116 220 36} + xywh {96 121 220 36} code0 {RxText->value("Receive Text");} code1 {RxText->color(fl_rgb_color(progdefaults.RxColor.R, progdefaults.RxColor.G, progdefaults.RxColor.B));} code2 {RxText->textfont(progdefaults.RxFontnbr); RxText->textsize(progdefaults.RxFontsize); RxText->textcolor(progdefaults.RxFontcolor);} @@ -1397,7 +1485,7 @@ WF_UI();} ReceiveText->redraw(); progdefaults.changed = true;} - xywh {326 123 75 21} + xywh {326 128 75 21} } Fl_Button btnTxColor { label {Tx bkgnd} @@ -1418,10 +1506,10 @@ WF_UI();} TransmitText->redraw(); progdefaults.changed = true;} - xywh {326 166 75 21} + xywh {326 171 75 21} } Fl_Input TxText { - xywh {96 158 220 37} + xywh {96 163 220 37} code0 {TxText->value("Transmit Text");} code1 {TxText->color(fl_rgb_color(progdefaults.TxColor.R, progdefaults.TxColor.G, progdefaults.TxColor.B));} code2 {TxText->textfont(progdefaults.TxFontnbr); TxText->textsize(progdefaults.TxFontsize); TxText->textcolor(progdefaults.TxFontcolor);} @@ -1435,7 +1523,7 @@ progdefaults.changed = true;} font_browser->fontFilter(Font_Browser::ALL_TYPES); font_browser->callback(cbRxFontBrowser); font_browser->show();} - xywh {411 123 75 21} + xywh {411 128 75 21} } Fl_Button btnTxFont { label {Tx font} @@ -1445,10 +1533,10 @@ font_browser->show();} font_browser->fontFilter(Font_Browser::ALL_TYPES); font_browser->callback(cbTxFontBrowser); font_browser->show();} - xywh {411 166 75 21} + xywh {411 171 75 21} } Fl_Input MacroText { - xywh {96 201 220 37} + xywh {96 206 220 37} code0 {MacroText->value("Macro editor text");} code1 {MacroText->textfont(progdefaults.MacroEditFontnbr);} code2 {MacroText->textsize(progdefaults.MacroEditFontsize);} @@ -1461,11 +1549,11 @@ font_browser->fontSize(progdefaults.MacroEditFontsize); font_browser->fontFilter(Font_Browser::ALL_TYPES); font_browser->callback(cbMacroEditFontBrowser); font_browser->show();} - xywh {326 209 120 21} + xywh {326 214 120 21} } Fl_Group {} { label {Text Highlighting} open - xywh {86 248 404 81} box ENGRAVED_FRAME align 17 + xywh {86 253 404 81} box ENGRAVED_FRAME align 17 } { Fl_Button btnXMIT { label XMIT @@ -1476,7 +1564,7 @@ font_browser->show();} ReceiveText->setFontColor(progdefaults.XMITcolor, FTextBase::XMIT); progdefaults.changed = true;} - tooltip {Sent chars in Rx/Tx pane} xywh {104 276 40 21} align 2 + tooltip {Sent chars in Rx/Tx pane} xywh {104 281 40 21} align 2 code0 {btnXMIT->color(progdefaults.XMITcolor);} } Fl_Button btnCTRL { @@ -1488,7 +1576,7 @@ font_browser->show();} ReceiveText->setFontColor(progdefaults.CTRLcolor, FTextBase::CTRL); progdefaults.changed = true;} - tooltip {Control chars in Rx/Tx pane} xywh {147 276 40 21} align 2 + tooltip {Control chars in Rx/Tx pane} xywh {147 281 40 21} align 2 code0 {btnCTRL->color(progdefaults.CTRLcolor);} } Fl_Button btnSKIP { @@ -1501,7 +1589,7 @@ font_browser->show();} progdefaults.changed = true;} tooltip {Skipped chars in Tx pane -(Tx on/off in CW)} xywh {191 276 40 21} align 2 +(Tx on/off in CW)} xywh {191 281 40 21} align 2 code0 {btnSKIP->color(progdefaults.SKIPcolor);} } Fl_Button btnALTR { @@ -1513,7 +1601,7 @@ font_browser->show();} ReceiveText->setFontColor(progdefaults.ALTRcolor, FTextBase::ALTR); progdefaults.changed = true;} - tooltip {Alternate character color in Rx panelr} xywh {234 276 40 21} align 2 + tooltip {Alternate character color in Rx panelr} xywh {234 281 40 21} align 2 code0 {btnALTR->color(progdefaults.ALTRcolor);} } Fl_Button btnSEL { @@ -1535,7 +1623,7 @@ TransmitText->color( progdefaults.RxTxSelectcolor); progdefaults.changed = true;} - tooltip {Selection background color in Rx Tx panels} xywh {278 276 39 21} align 2 + tooltip {Selection background color in Rx Tx panels} xywh {278 281 39 21} align 2 code0 {btnSEL->color(progdefaults.RxTxSelectcolor);} } Fl_Button btnNoTextColor { @@ -1594,7 +1682,7 @@ progdefaults.changed = true;} TransmitText->redraw(); progdefaults.changed = true;} - xywh {325 276 70 21} + xywh {325 281 70 21} } Fl_Button btnTextDefaults { label Defaults @@ -1653,27 +1741,27 @@ progdefaults.changed = true;} TransmitText->redraw(); progdefaults.changed = true;} - xywh {399 276 70 21} + xywh {399 281 70 21} } } Fl_Check_Button btn_show_all_codes { label {display Rx control chars as ascii string} callback {progdefaults.show_all_codes=o->value(); progdefaults.changed = true;} - xywh {110 340 25 25} down_box DOWN_BOX + xywh {110 345 25 25} down_box DOWN_BOX code0 {o->value(progdefaults.show_all_codes);} } } Fl_Group {} { label {FreqDisp / Meters} open - xywh {0 75 600 305} hide + xywh {0 80 600 300} hide } { Fl_Group {} {open - xywh {115 88 394 87} box ENGRAVED_FRAME + xywh {115 108 395 87} box ENGRAVED_FRAME } { Fl_Box FDdisplay { label {14070.150} - xywh {195 92 235 45} box DOWN_BOX color 55 labelfont 4 labelsize 40 + xywh {195 112 235 45} box DOWN_BOX color 55 labelfont 4 labelsize 40 code0 {o->color(fl_rgb_color(progdefaults.FDbackground.R,progdefaults.FDbackground.G,progdefaults.FDbackground.B));} code1 {o->labelcolor(fl_rgb_color(progdefaults.FDforeground.R,progdefaults.FDforeground.G,progdefaults.FDforeground.B));} code2 {o->labelfont(progdefaults.FreqControlFontnbr);} @@ -1687,7 +1775,7 @@ progdefaults.changed = true;} font_browser->fontFilter(Font_Browser::ALL_TYPES); font_browser->callback(cbFreqControlFontBrowser); font_browser->show();} - xywh {122 143 90 24} + xywh {122 163 90 24} } Fl_Button btnBackgroundColor { label {Bg Color} @@ -1717,7 +1805,7 @@ font_browser->show();} qsoFreqDisp->redraw(); } progdefaults.changed = true;} - xywh {218 143 90 24} + xywh {218 163 90 24} } Fl_Button btnForegroundColor { label {Digit Color} @@ -1747,7 +1835,7 @@ font_browser->show();} qsoFreqDisp->redraw(); } progdefaults.changed = true;} - xywh {314 143 90 24} + xywh {314 163 90 24} } Fl_Button btnFD_SystemColor { label {Sys Colors} @@ -1783,12 +1871,12 @@ font_browser->show();} qsoFreqDisp->redraw(); } progdefaults.changed = true;} - xywh {410 143 90 24} + xywh {410 163 90 24} } } Fl_Group {} { label {S-meter} open - xywh {115 179 420 62} box ENGRAVED_FRAME align 21 + xywh {115 199 395 62} box ENGRAVED_FRAME align 21 } { Fl_Button btnSmeter_bg_color { label {Bg Color} @@ -1807,7 +1895,7 @@ font_browser->show();} set_smeter_colors(); progdefaults.changed = true;} - xywh {122 206 90 24} + xywh {122 226 90 24} } Fl_Button btnSmeter_scale_color { label {Scale Color} @@ -1826,7 +1914,7 @@ font_browser->show();} set_smeter_colors(); progdefaults.changed = true;} - xywh {218 206 90 24} + xywh {218 226 90 24} } Fl_Button btnSmeter_meter_color { label {Meter Color} @@ -1845,12 +1933,12 @@ font_browser->show();} set_smeter_colors(); progdefaults.changed = true;} - xywh {314 206 90 24} + xywh {314 226 90 24} } } Fl_Group {} { label {PWR-meter} open - xywh {115 248 394 67} box ENGRAVED_FRAME align 21 + xywh {115 268 395 67} box ENGRAVED_FRAME align 21 } { Fl_Button btnPWR_bg_color { label {Bg Color} @@ -1869,7 +1957,7 @@ font_browser->show();} set_smeter_colors(); progdefaults.changed = true;} - xywh {122 275 90 24} + xywh {122 295 90 24} } Fl_Button btnPWR_scale_color { label {Scale Color} @@ -1888,7 +1976,7 @@ font_browser->show();} set_smeter_colors(); progdefaults.changed = true;} - xywh {218 275 90 24} + xywh {218 295 90 24} } Fl_Button btnPWR_meter_Color { label {Meter Color} @@ -1907,14 +1995,14 @@ font_browser->show();} set_smeter_colors(); progdefaults.changed = true;} - xywh {314 275 90 24} + xywh {314 295 90 24} } Fl_Group listboxPWRselect { label {Power scale} callback {progdefaults.PWRselect = o->index(); set_smeter_colors(); progdefaults.changed = true;} open - tooltip {Select the type of FFT prefilter} xywh {410 275 80 24} box DOWN_BOX color 7 + tooltip {Select the type of FFT prefilter} xywh {410 295 80 24} box DOWN_BOX color 7 code0 {o->add(_("25 W")); o->add("50 W");} code1 {o->add("100 W"); o->add("200 W"); o->add("AUTO");} code3 {o->index(progdefaults.PWRselect);o->labelsize(FL_NORMAL_SIZE);} @@ -1924,7 +2012,7 @@ progdefaults.changed = true;} open } Fl_Group {} { label Log open - xywh {0 75 600 305} hide + xywh {0 80 600 300} hide } { Fl_Group {} { label {Logging Panel Controls} open @@ -2045,7 +2133,7 @@ progdefaults.changed = true;} } Fl_Group {} { label F_keys open - xywh {0 75 600 305} hide + xywh {0 80 600 300} hide } { Fl_Check_Button btnUseGroupColors { label {Use colored buttons} @@ -2177,7 +2265,7 @@ font_browser->show();} } Fl_Group {} { label Tabs open - xywh {0 75 600 305} hide + xywh {0 80 600 300} hide } { Fl_Button btnTabColor { label {Tab Color} @@ -2196,7 +2284,7 @@ progdefaults.changed = true;} } Fl_Group {} { label Buttons open - xywh {0 75 600 305} hide + xywh {0 80 600 300} hide } { Fl_Button btnSpotColor { label Spot @@ -2335,7 +2423,7 @@ progdefaults.changed = true;} } Fl_Group {} { label SigLvl open - xywh {0 75 600 305} hide + xywh {0 80 600 300} } { Fl_Button btnLowSignal { label Low diff --git a/src/include/confdialog.h b/src/include/confdialog.h index 5c4b7e55..3f5df5ff 100644 --- a/src/include/confdialog.h +++ b/src/include/confdialog.h @@ -89,6 +89,7 @@ extern Fl_Check_Button *btn2NagMe; extern Fl_Check_Button *btn2_confirm_exit; extern Fl_Check_Button *btn_check_for_updates; extern Fl_Group *tabLogServer; +extern Fl_Tabs *tabsLog; extern Fl_Check_Button *btnNagMe; extern Fl_Check_Button *btnClearOnSave; extern Fl_Check_Button *btnCallUpperCase; @@ -107,6 +108,18 @@ extern Fl_Check_Button *btnRXClicks; extern Fl_Check_Button *btnRXTooltips; extern Fl_Input2 *inpNonword; extern Fl_Check_Button *btnUSunits; +#include "maclogger.h" +extern Fl_Check_Button *btnConnectToMaclogger; +extern Fl_Check_Button *btn_capture_maclogger_radio; +extern Fl_Check_Button *btn_capture_maclogger_log; +extern Fl_Check_Button *btn_capture_maclogger_lookup; +extern Fl_Check_Button *btn_capture_maclogger_spot_tune; +extern Fl_Check_Button *btn_capture_maclogger_spot_report; +extern Fl_Check_Button *btn_enable_maclogger_log; +#include +extern Fl_Text_Display *txt_UDP_data; +#include +extern Fl_Output *txt_maclogger_log_filename; extern Fl_Group *tabMBars; extern Fl_Check_Button *btnMacroMouseWheel; extern Fl_Counter *cnt_macro_height; @@ -174,7 +187,6 @@ extern Fl_Button *btnPWR_bg_color; extern Fl_Button *btnPWR_scale_color; extern Fl_Button *btnPWR_meter_Color; extern Fl_ListBox *listboxPWRselect; -#include extern Fl_Output *LOGGINGdisplay; extern Fl_Button *btnLOGGING_color; extern Fl_Button *btn_LOGGING_font; diff --git a/src/include/configuration.h b/src/include/configuration.h index fe52acd0..29012d71 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -949,6 +949,31 @@ ELEM_(bool, eqsl_datetime_off, "EQSL_DATETIME_OFF", \ "Send logbook date/time off vice date on (default)", \ false) \ + /* MacLogger interface */ \ + ELEM_(bool, connect_to_maclogger, "CONNECT_TO_MACLOGGER", \ + "Connect to MacLogger UDP server on 255.255.255.255 / 9932", \ + false) \ + ELEM_(bool, capture_maclogger_radio, "CAPTURE_MACLOGGER_RADIO", \ + "Capture and use UDP Radio Report data", \ + true) \ + ELEM_(bool, capture_maclogger_spot_tune, "CAPTURE_MACLOGGER_SPOT_TUNE", \ + "Capture and use UDP Spot Tune data", \ + false) \ + ELEM_(bool, capture_maclogger_spot_report, "CAPTURE_MACLOGGER_SPOT_REPORT", \ + "Capture and use UDP Spot Report data", \ + false) \ + ELEM_(bool, capture_maclogger_log, "CAPTURE_MACLOGGER_LOG", \ + "Capture and use UDP Log Report data", \ + false) \ + ELEM_(bool, capture_maclogger_lookup, "CAPTURE_MACLOGGER_LOOKUP", \ + "Capture and use UDP Lookup Report data", \ + false) \ + ELEM_(bool, enable_maclogger_log, "ENABLE_MACLOGGER_LOG", \ + "Enable UDP string capture to file", \ + false) \ + ELEM_(std::string, maclogger_log_filename, "MACLOGGER_LOG_FILENAME", \ + "Filename for maclogger UDP datastream file", \ + "maclogger_udp_strings.txt") \ /* Rig control */ \ ELEM_(bool, btnusb, "BTNUSB", \ "This setting is currently unused", \ diff --git a/src/include/debug.h b/src/include/debug.h index 23cd6597..411c14dc 100644 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -43,7 +43,8 @@ public: LOG_RPC = 1 << 5, LOG_SPOTTER = 1 << 6, LOG_KISSCONTROL = 1 << 7, - LOG_OTHER = 1 << 8 + LOG_MACLOGGER = 1 << 8, + LOG_OTHER = 1 << 9 }; static void start(const char* filename); static void stop(void); diff --git a/src/include/maclogger.h b/src/include/maclogger.h new file mode 100644 index 00000000..483f9b2c --- /dev/null +++ b/src/include/maclogger.h @@ -0,0 +1,18 @@ +#ifndef MACLOGGERIO_H +#define MACLOGGERIO_H + +#include + +#include "threads.h" +#include "socket.h" +#include "modem.h" + +#define MACLOGGER_BUFFER_SIZE 2048 + +extern void get_maclogger_udp(); +extern void *maclogger_loop(void *args); +extern void maclogger_init(void); +extern bool maclogger_start(void); +extern void maclogger_close(void); + +#endif // MACLOGGERIO_H diff --git a/src/include/qrunner.h b/src/include/qrunner.h index 9646ac28..12bfec97 100644 --- a/src/include/qrunner.h +++ b/src/include/qrunner.h @@ -51,6 +51,8 @@ namespace qrbind { #include "qrunner/fqueue.h" extern void write_message(int line_no, const char *func, const char *msg); +extern void qrunner_debug(int tid, const char * name); +extern const char *sztid[]; #ifndef __MINGW32__ # define QRUNNER_READ(fd__, buf__, len__) read(fd__, buf__, len__) @@ -106,12 +108,14 @@ public: bool request(const F& f) { if (fifo->push(f)) { +int resp = QRUNNER_WRITE(pfd[1], "", 1); +qrunner_debug(GET_THREAD_ID(), typeid(F).name()); #ifdef NDEBUG - if (unlikely(QRUNNER_WRITE(pfd[1], "", 1) != 1)) { + if (unlikely(resp != 1)) { throw qexception(errno); } #else - assert(QRUNNER_WRITE(pfd[1], "", 1) == 1); +assert(resp); #endif return true; } diff --git a/src/include/threads.h b/src/include/threads.h index 5cfb6d3a..cf763dc5 100644 --- a/src/include/threads.h +++ b/src/include/threads.h @@ -52,6 +52,7 @@ enum { XMLRPC_TID, ARQ_TID, ARQSOCKET_TID, + MACLOGGER_TID, KISS_TID, KISSSOCKET_TID, FLMAIN_TID, @@ -107,6 +108,7 @@ bool thread_in_list(int id, const int* list); // which will also interrupt blocking calls. On woe32 we use // pthread_cancel and there is no good/sane way to interrupt. #ifndef __WOE32__ +#include # define SET_THREAD_CANCEL() \ do { \ sigset_t usr2; \ diff --git a/src/logbook/maclogger.cxx b/src/logbook/maclogger.cxx new file mode 100644 index 00000000..1242e61c --- /dev/null +++ b/src/logbook/maclogger.cxx @@ -0,0 +1,441 @@ +// ===================================================================== +// +// maclogger.cxx +// +// receive log data from maclogger udp broadcast message +// +// Copyright (C) 2016 +// 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 + +#include +#include + +#include "rigsupport.h" +#include "modem.h" +#include "trx.h" +#include "fl_digi.h" +#include "configuration.h" +#include "main.h" +#include "waterfall.h" +#include "macros.h" +#include "qrunner.h" +#include "debug.h" +#include "status.h" +#include "icons.h" + +#include "maclogger.h" + +#include "confdialog.h" + +LOG_FILE_SOURCE(debug::LOG_MACLOGGER); + +using namespace std; + +//====================================================================== +// Socket MACLOGGER i/o used on all platforms +//====================================================================== + +pthread_t maclogger_thread; +pthread_t maclogger_rx_socket_thread; +pthread_mutex_t mclg_str_mutex = PTHREAD_MUTEX_INITIALIZER; +Socket *maclogger_socket = 0; + +bool maclogger_enabled = false; +bool maclogger_exit = false; + +string maclogger_ip_address= "";; +string maclogger_ip_port= "";; + +string mclg_str = ""; +int mclg_rxhz; +int mclg_txhz; +string mclg_band; +string mclg_mode; +string mclg_power; +string mclg_call; +string mclg_dxccnum; +string mclg_dxccstr; +string mclg_city; +string mclg_state; +string mclg_firstname; +string mclg_lastname; +string mclg_comment; +string mclg_bearing; +string mclg_longpath; +string mclg_distance; + +//====================================================================== +// MacLogger UDP string parsing +//====================================================================== + +static string get_str(string s) +{ + size_t p = s.find(":"); + if (p == string::npos) return ""; + s.erase(0, p+1); + p = s.find(","); + if (p == string::npos) p = s.find("]"); + if (p == string::npos) return ""; + string s2 = s.substr(0, p); + if (s2 == "(null)") return ""; + return s2; +} + +static int get_freq(string s) +{ + string s2 = get_str(s); + float mhz; + sscanf(s2.c_str(), "%f", &mhz); + int hz = mhz * 1e6; + return hz; +} + +void maclogger_set_qsy() +{ + int hz = mclg_txhz; + if (hz <= 0) hz = mclg_rxhz; + if (hz <= 0) return; + wf->rfcarrier(hz); + wf->movetocenter(); + show_frequency(hz); +} + +void maclogger_set_call() +{ + inpCall->value(mclg_call.c_str()); + inpCall->do_callback(); +} + +void maclogger_set_name() +{ + inpName->value(mclg_firstname.c_str()); + inpName->do_callback(); +} + +void maclogger_set_mode() +{ +// inpMode->value(mclg_mode.c_str()); +// inpMode->do_callback(); +} + +void maclogger_set_qth() +{ + inpQth->value(mclg_city.c_str()); + inpQth->do_callback(); +} + +void maclogger_set_state() +{ + inpState->value(mclg_state.c_str()); + inpState->do_callback(); +} + +void maclogger_disp_report(const char * s) +{ + txt_UDP_data->insert(s); + txt_UDP_data->redraw(); +} + +void show_mac_strings() +{ + SET_THREAD_ID(MACLOGGER_TID); + + if (mclg_txhz > 0) REQ(maclogger_set_qsy); + else if (mclg_rxhz > 0) REQ(maclogger_set_qsy); + if (!mclg_mode.empty()) REQ(maclogger_set_mode); + if (!mclg_call.empty()) REQ(maclogger_set_call); + if (!mclg_city.empty()) REQ(maclogger_set_qth); + if (!mclg_state.empty()) REQ(maclogger_set_state); + if (!mclg_firstname.empty()) REQ(maclogger_set_name); + +// if (!mclg_power.empty()) +// if (!mclg_band.empty()) +// if (!mclg_lastname.empty()) +// if (!mclg_comment.empty()) +// if (!mclg_bearing.empty()) +// if (!mclg_longpath.empty()) +// if (!mclg_distance.empty()) +// if (!mclg_dxccnum.empty()) +// if (!mclg_dxccstr.empty()) + +} + +void parse_report(string str) +{ + size_t p; + mclg_rxhz = 0; + mclg_txhz = 0; + mclg_band.clear(); + mclg_mode.clear(); + mclg_power.clear(); + mclg_call.clear(); + mclg_dxccnum.clear(); + mclg_dxccstr.clear(); + mclg_city.clear(); + mclg_state.clear(); + mclg_firstname.clear(); + mclg_lastname.clear(); + mclg_comment.clear(); + mclg_bearing.clear(); + mclg_longpath.clear(); + mclg_distance.clear(); + + if ((p = str.find("RxMHz:")) != string::npos) + mclg_rxhz = get_freq(str.substr(p)); + if ((p = str.find("TxMHz:")) != string::npos) + mclg_txhz = get_freq(str.substr(p)); + if ((p = str.find("Mode:")) != string::npos) + mclg_mode = get_str(str.substr(p)); + if ((p = str.find("Call:")) != string::npos) + mclg_call = get_str(str.substr(p)); + if ((p = str.find("city:")) != string::npos) + mclg_city = get_str(str.substr(p)); + if ((p = str.find("state:")) != string::npos) + mclg_state = get_str(str.substr(p)); + if ((p = str.find("first_name:")) != string::npos) + mclg_firstname = get_str(str.substr(p)); + +// if ((p = mclg_str.find("dxcc_num:")) != string::npos) +// mclg_dxccnum = get_str(mclg_str.substr(p)); +// if ((p = mclg_str.find("dxcc_string:")) != string::npos) +// mclg_dxccstr = get_str(mclg_str.substr(p)); +// if ((p = mclg_str.find("Power:")) != string::npos) +// mclg_power = get_str(mclg_str.substr(p)); +// if ((p = mclg_str.find("Band:")) != string::npos) +// mclg_band = get_str(mclg_str.substr(p)); +// if ((p = mclg_str.find("last_name:")) != string::npos) +// mclg_lastname = get_str(mclg_str.substr(p)); +// if ((p = mclg_str.find("Comment:")) != string::npos) +// mclg_comment = get_str(mclg_str.substr(p)); +// if ((p = mclg_str.find("Bearing:")) != string::npos) +// mclg_bearing = get_str(mclg_str.substr(p)); +// if ((p = mclg_str.find("LongPath:")) != string::npos) +// mclg_longpath = get_str(mclg_str.substr(p)); +// if ((p = mclg_str.find("Distance:")) != string::npos) +// mclg_distance = get_str(mclg_str.substr(p)); + + show_mac_strings(); +} + +void parse_maclog() +{ + size_t p1, p2; + string str, srep; + static string sreport[20]; + int repnbr = 0; + while (!mclg_str.empty()) { + p1 = mclg_str.find("["); + if (p1 == string::npos) return; + if (p1 != 0) mclg_str.erase(0, p1); + p2 = mclg_str.find("]"); + if (p2 == string::npos) return; + + str = mclg_str.substr(0, p2 + 1); + srep = str; + srep.append("\n"); + if (repnbr < 20) { + sreport[repnbr] = srep; + REQ(maclogger_disp_report, sreport[repnbr].c_str()); + repnbr++; + } + + if (progdefaults.enable_maclogger_log) { + std::string pathname = TempDir; + pathname.append("maclogger_udp_strings.txt"); + FILE *maclog = fopen(pathname.c_str(), "a"); + fprintf(maclog, "%s", srep.c_str()); + fclose(maclog); + } + + if (progdefaults.capture_maclogger_radio && + (mclg_str.find("[Radio Report:") == 0)) parse_report(str); + + else if (progdefaults.capture_maclogger_spot_tune && + (mclg_str.find("[SpotTune:") == 0)) parse_report(str); + + else if (progdefaults.capture_maclogger_spot_report && + (mclg_str.find("[Spot Report:") == 0)) parse_report(str); + + else if (progdefaults.capture_maclogger_log && + (mclg_str.find("[Log Report:") == 0)) parse_report(str); + + else if (progdefaults.capture_maclogger_lookup && + (mclg_str.find("[Lookup Report") == 0)) parse_report(str); + + mclg_str.erase(0, p2 + 1); + + } +} + +//====================================================================== +// uncomment to use UDP test strings +// +// #define TESTSTRINGS 1 +// +//====================================================================== + +#ifdef TESTSTRINGS +string tstring[6] = { + "[Radio Report:RxMHz:24.96400, TxMHz:24.96400, Band:12M, Mode:USB, Power:5]", + "[SpotTune:RxMHz:28.49500, TxMHz:28.49600, Band:10M, Mode:USB]", + "[Log Report: Call:N2BJ, RxMHz:21.08580, TxMHz:21.08580, Band:15M, Mode:FSK, Power:5, dxcc_num:291, dxcc_string:United States, city:NEW LENOX, state:IL, first_name:Barry, last_name:COHEN]", + "[Spot Report: RxMHz:3.50300, TxMHz:3.50300, Band:80M, Mode:CW, Call:EP6T, dxcc_string:Iran, Comment:UP , TNX CARLO , GL]", + "[Rotor Report: Bearing:304.7, LongPath:0, Distance:0.0]", + "[Lookup Report:Call:YC8RBI, RxMHz:21.32500, Band:15M, Mode:USB, dxcc_num:327, dxcc_string:Indonesia, Bearing:328.1, city:SANGIHE ISLAND NORTH SULAWESI, state:(null), first_name:RICHARD, last_name:BYL ( ICHA )]" +}; +int tnbr = 0; +#endif + +void get_maclogger_udp() +{ + if(!maclogger_socket) return; + if (!progdefaults.connect_to_maclogger) return; + +#ifdef TESTSTRINGS + if (tnbr == 0) { + mclg_str = "bogus start chars dkoe13.chfff "; + for (int n = 0; n < 6; n++) mclg_str.append(tstring[n]); + mclg_str.append(" and garbage at the end"); + parse_maclog(); + tnbr = 1; + } +#else + char buffer[MACLOGGER_BUFFER_SIZE]; + size_t count = 0; + + memset(buffer, 0, sizeof(buffer)); + + try { + count = maclogger_socket->recvFrom( + (void *) buffer, + sizeof(buffer) - 1); + } catch (...) { + LOG_WARN("MAC_logger socket error"); + count = 0; + } + + if (count) { + mclg_str.append(buffer, count); + parse_maclog(); + } +#endif +} + +//====================================================================== +// +//====================================================================== +void *maclogger_loop(void *args) +{ + SET_THREAD_ID(MACLOGGER_TID); + + LOG_INFO("%s", "MAC_logger loop started. "); + + while(1) { + for (int i = 0; i < 100; i++) { + MilliSleep(10); + if (maclogger_exit) break; + } + if (maclogger_exit) break; + get_maclogger_udp(); + } + // exit the maclogger thread + SET_THREAD_CANCEL(); + return NULL; +} + +//====================================================================== +// +//====================================================================== +bool maclogger_start(void) +{ + maclogger_ip_address = "255.255.255.255"; + maclogger_ip_port = "9932"; + + try { + maclogger_socket = new Socket( + Address( maclogger_ip_address.c_str(), + maclogger_ip_port.c_str(), + "udp") ); + maclogger_socket->set_autoclose(true); + maclogger_socket->set_nonblocking(false); + maclogger_socket->bindUDP(); + } + catch (const SocketException& e) { + LOG_ERROR( + "Could not resolve %s: %s", + maclogger_ip_address.c_str(), + e.what() ); + return false; + } + + return true; +} + +//====================================================================== +// +//====================================================================== +void maclogger_init(void) +{ + maclogger_enabled = false; + maclogger_exit = false; + + if(!maclogger_start()) return; + + LOG_INFO("%s", "UDP Init - OK"); + + if (pthread_create(&maclogger_thread, NULL, maclogger_loop, NULL) < 0) { + LOG_ERROR("MACLOGGER maclogger_thread: pthread_create failed"); + return; + } + + LOG_INFO("MACLOGGER thread started"); + + maclogger_enabled = true; +} + +//====================================================================== +// +//====================================================================== +void maclogger_close(void) +{ + if (!maclogger_enabled) return; + + if(maclogger_socket) { + maclogger_socket->shut_down(); + maclogger_socket->close(); + } + + maclogger_exit = true; + pthread_join(maclogger_thread, NULL); + + LOG_INFO("%s", "MAC_logger loop terminated. "); + + maclogger_enabled = false; +#ifdef TESTSTRINGS + tnbr = 0; +#endif +} + diff --git a/src/main.cxx b/src/main.cxx index 39132dfb..2b8c2801 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -95,6 +95,7 @@ #include "Viewer.h" #include "kmlserver.h" #include "data_io.h" +#include "maclogger.h" #if USE_HAMLIB #include "rigclass.h" @@ -345,10 +346,13 @@ void delayed_startup(void *) FLRIG_start_flrig_thread(); data_io_enabled = DISABLED_IO; + arq_init(); kiss_init(); + if (progdefaults.connect_to_maclogger) maclogger_init(); data_io_enabled = progStatus.data_io_enabled; + toggle_io_port_selection(data_io_enabled); notify_start(); @@ -502,6 +506,10 @@ int main(int argc, char ** argv) cbq[i]->attach(i, "KISSSOCKET_TID"); break; + case MACLOGGER_TID: + cbq[i]->attach(i, "MACLOGGER_TID"); + break; + case FLMAIN_TID: cbq[i]->attach(i, "FLMAIN_TID"); break; @@ -764,6 +772,7 @@ void exit_process() { KmlServer::Exit(); arq_close(); kiss_close(); + maclogger_close(); XML_RPC_Server::stop(); if (progdefaults.usepskrep) diff --git a/src/misc/debug.cxx b/src/misc/debug.cxx index 22494c2d..fd46f4af 100644 --- a/src/misc/debug.cxx +++ b/src/misc/debug.cxx @@ -102,7 +102,8 @@ Fl_Menu_Item src_menu[] = { { _("Flrig I/O"), 0, 0, 0, FL_MENU_TOGGLE | FL_MENU_VALUE }, { _("RPC"), 0, 0, 0, FL_MENU_TOGGLE | FL_MENU_VALUE }, { _("Spotter"), 0, 0, 0, FL_MENU_TOGGLE | FL_MENU_VALUE }, - { _("KISS control"), 0, 0, 0, FL_MENU_TOGGLE | FL_MENU_VALUE | FL_MENU_DIVIDER }, + { _("KISS control"), 0, 0, 0, FL_MENU_TOGGLE | FL_MENU_VALUE }, + { _("Mac Logger"), 0, 0, 0, FL_MENU_TOGGLE | FL_MENU_VALUE | FL_MENU_DIVIDER }, { _("Other"), 0, 0, 0, FL_MENU_TOGGLE | FL_MENU_VALUE }, { 0 } }; diff --git a/src/qrunner/qrunner.cxx b/src/qrunner/qrunner.cxx index 5f26ae12..55225f60 100644 --- a/src/qrunner/qrunner.cxx +++ b/src/qrunner/qrunner.cxx @@ -47,6 +47,44 @@ # define QRUNNER_EAGAIN() ((errno = WSAGetLastError()) == WSAEWOULDBLOCK) #endif +const char *sztid[] = { + "INVALID_TID", + "TRX_TID", + "QRZ_TID", + "RIGCTL_TID", + "NORIGCTL_TID", + "EQSL_TID", + "ADIF_RW_TID", + "XMLRPC_TID", + "ARQ_TID", + "ARQSOCKET_TID", + "MACLOGGER_TID", + "KISS_TID", + "KISSSOCKET_TID", + "FLMAIN_TID" +}; + +static pthread_mutex_t mlog = PTHREAD_MUTEX_INITIALIZER; +void qrunner_debug(int tid, const char *name) +{ + // disabled ! + return; + + if (tid > ((int)sizeof(sztid)-1)) tid = 0; + else tid++; + + if (tid < 2) return; + + pthread_mutex_lock(&mlog); + FILE *fd = (FILE *)0; + fd = fopen("qrunner.txt", "a"); + if(fd) { + fprintf(fd, "%s, %s\n", sztid[tid], name); + fclose(fd); + } + pthread_mutex_unlock(&mlog); +} + qrunner::qrunner() : attached(false), inprog(false), drop_flag(false) { @@ -101,6 +139,7 @@ void qrunner::execute(int fd, void *arg) if (qr->inprog) return; + qr->inprog = true; size_t n = QRUNNER_READ(fd, rbuf, FIFO_SIZE); @@ -113,8 +152,9 @@ void qrunner::execute(int fd, void *arg) case 0: break; default: - while (n--) + while (n--) { qr->fifo->execute(); + } } qr->inprog = false;