/* * xlog - GTK+ logging program for amateur radio operators * Copyright (C) 2001 - 2002 Joop Stakenborg * * This program is free oftware; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * main.c - start of gtk main loop and initialization */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include "interface.h" #include "support.h" #include "callbacks_menu.h" #include "callbacks_qsoframe.h" #include "callbacks_mainwindow.h" #include "callbacks_clist.h" #include "types.h" #include "preferences.h" #include "log.h" #include "utils.h" #include "hamlib-utils.h" #include "dxcc.h" #include "remote.h" #include "history.h" #include "pixmaps/xlog.xpm" #if WANT_HAMLIB # include # include #endif GtkWidget *mainwindow, *mainnotebook; gchar *xlogdir; gint remotetimer = -1, clocktimer = -1, savetimer = -1; gchar **bandsplit, **modesplit, **qso = NULL; statetype state; glong msgid; GList *logwindowlist = NULL; GdkColormap *colormap; extern preferencestype preferences; extern remotetype remote; #if WANT_HAMLIB GList *riglist = NULL; gint hamlibtimer = -1; RIG *myrig; #endif /* command line options */ static void parsecommandline(int argc, char *argv[]) { gint i; gchar *versionstr; for (i = 1; i < argc; i++) { if (g_strncasecmp(argv[i], "--version", 9) == 0) { if (betaversion == 0) versionstr = g_strdup_printf(_("%s version %s\n"), g_basename(argv[0]), VERSION); else versionstr = g_strdup_printf(_("%s version %s beta %d\n"), g_basename(argv[0]), VERSION, betaversion); g_print(versionstr); g_free(versionstr); exit(0); } else if (g_strncasecmp(argv[i], "--help", 6) == 0) { g_print(_("Usage: %s [option]...\n"), g_basename(argv[0])); g_print(_(" --version Output version information and exit\n")); g_print(_(" --help Display this help and exit\n")); exit(0); } else { g_print(_("Unknown argument, type %s --help for a list of options\n"), g_basename(argv[0])); exit(1); } } } /* see if we can create the ~/.xlog directory */ static gboolean xlogdircheck(void) { GString *packagedir = g_string_new(""); struct stat statdir; gchar *labeltext; GtkWidget *setupdialog, *setuplabel; g_string_sprintf(packagedir, "%s.", G_DIR_SEPARATOR_S); g_string_append(packagedir, PACKAGE); setupdialog = create_setupdialog(); setuplabel = lookup_widget(setupdialog, "setuplabel"); xlogdir = g_strconcat(g_get_home_dir(), packagedir->str, NULL); if (stat(xlogdir, &statdir) == -1) { if (mkdir(xlogdir, S_IRUSR | S_IWUSR | S_IXUSR) == -1) g_error(_("Creating ~%s directory."), packagedir->str); else { labeltext = g_strdup_printf(_("Xlog has created %s,\n\ this is the directory where your log will be saved.\n\n\ You can change the default path for your logs\n\ in the preferences dialog."), xlogdir); gtk_label_set_text(GTK_LABEL(setuplabel), labeltext); g_free(labeltext); g_string_free(packagedir, TRUE); gtk_widget_show(setupdialog); return(FALSE); } } else if (!S_ISDIR(statdir.st_mode)) g_error(_("~%s is not a directory."), packagedir->str); g_string_free(packagedir, TRUE); return(TRUE); } /* defaults for program state */ static void setdefaultstate(void) { gchar **versionsplit; state.minorversion = 0; state.majorversion = 0; state.qsos = 0; state.countries = 0; state.prefixes = 0; /* the default ham lives in the gulf of guinea */ state.mylocation = g_strdup("0.0N0.0E"); state.controlkey = FALSE; state.rigfrequency = 0; state.rigmode = 0; state.rigrst = g_strdup("0"); state.rigpower = 0; state.scounter = 0; state.hlcounter = 0; state.tx = FALSE; state.statustimer = FALSE; state.shmid = -1; state.logwindows = 0; versionsplit = g_strsplit(preferences.version, ".", 0); state.majorversion = atoi(versionsplit[0]); state.minorversion = atoi(versionsplit[1]); g_strfreev(versionsplit); state.mylocation = setlocation(preferences.latitude, preferences.NS, preferences.longitude, preferences.EW); state.searchqso = 0; state.searchlog = 0; state.dupecheck = 0; state.notdupecheckmode = FALSE; state.notdupecheckband = FALSE; } /* the fun starts here */ gint main (int argc, char *argv[]) { GtkWidget *bandoptionmenu, *modeoptionmenu, *dateentry, *qsoframe, *dxccframe, *bandentry, *modeentry, *clockpixmap, *clocklabel, *clockhandlebox, * clockhbox, *mhzlabel, *mhzbutton, *frequencypixmap, *frequencylabel, *frequencyhbox, *frequencyhandlebox, *modelabel, *modebutton, *rstlabel, *rstbutton, *smeterhandlebox, *smeterhbox, *smeterdrawingarea, *smeterpixmap, *hpaned, *powerlabel, *powerbutton, *locatorframe, *unknownlabel1, *unknownlabel2; GdkPixmap *icon_pixmap; GdkBitmap *mask; gchar *xlogfile, *xlogbackupfile, *temp, *rcpath, *logstoload, **loglist = NULL; gint i; gboolean showmainwindow = TRUE, logsfromprefs = FALSE; GtkStyle *mainwindowstyle; GString *logs; logtype *logwindow; LOGDB *lp; #if WANT_HAMLIB gint rigid, retcode; #endif parsecommandline(argc, argv); gtk_set_locale(); gtk_init(&argc, &argv); add_pixmap_directory(PACKAGE_DATA_DIR G_DIR_SEPARATOR_S "pixmaps"); add_pixmap_directory(PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "pixmaps"); rcpath = g_strdup_printf("%s%sthemes%s%src", PACKAGE_DATA_DIR, G_DIR_SEPARATOR_S, G_DIR_SEPARATOR_S, PACKAGE); gtk_rc_parse(rcpath); g_free(rcpath); mainwindow = create_mainwindow(); showmainwindow = xlogdircheck(); loadpreferences(); loadhistory(); setdefaultstate(); colormap = gdk_colormap_get_system(); /* defaults for remote data */ remote.version = 0; remote.nr = 0; remote.program = g_strdup("unknow"); loaddxcc(); qso = g_new0(gchar *, 20); for (i = 0; i < 20; i++) qso[i] = g_new0(gchar, 100); /* logging should always be in GMT, shouldn't it? */ putenv("TZ=GMT"); tzset(); /* update the date field */ temp = getdate(); dateentry = lookup_widget(mainwindow, "dateentry"); gtk_entry_set_text(GTK_ENTRY(dateentry), temp); gtk_widget_grab_focus(GTK_WIDGET(dateentry)); /* read the logs */ mainnotebook = gtk_notebook_new(); gtk_widget_show (mainnotebook); hpaned = lookup_widget(mainwindow, "hpaned"); gtk_paned_pack2(GTK_PANED(hpaned), mainnotebook, TRUE, FALSE); /* check for multiple *.xlog */ if (g_strncasecmp(preferences.logstoload, "*", 1) == 0) logs = getlogs(preferences.savedir, 0); /* read all logs of type xlog */ else { /* read logs from preferences.logstoload */ logstoload = g_strdup(preferences.logstoload); g_strdelimit(logstoload, ",", '\n'); logs = g_string_new(logstoload); g_free(logstoload); logsfromprefs = TRUE; } if ((logs->len) > 0) /* flexible logs */ loglist = g_strsplit(logs->str, "\n", 0); else /* old log type */ { loglist = g_malloc0(3*sizeof(gchar)); loglist[0] = g_strdup("log"); } for (i = 0;; i++) { if (!loglist || (loglist[i] == NULL)) break; if (logsfromprefs) xlogfile = g_strconcat(preferences.savedir, G_DIR_SEPARATOR_S, loglist[i], ".xlog", NULL); else xlogfile = g_strconcat(preferences.savedir, G_DIR_SEPARATOR_S, loglist[i], NULL); if ((logs->len) > 0) lp = log_file_open(xlogfile, TYPE_FLOG); else lp = log_file_open(xlogfile, TYPE_OLD_LOG); if (!lp) /* create a new log */ lp = log_file_create("log.xlog", TYPE_FLOG, qso_field_nr, qso_fields, qso_widths); if (lp) { logwindow = openlog(lp, loglist[i], i); log_file_qso_foreach(lp, fillin_clist, logwindow); log_file_close(lp); logwindowlist = g_list_append(logwindowlist, logwindow); /* backup */ xlogbackupfile = g_strconcat(xlogfile, ".backup", NULL); savelog(logwindow, xlogbackupfile, TYPE_FLOG); g_free(xlogbackupfile); } g_free(xlogfile); } state.logwindows = i; g_strfreev(loglist); g_string_free(logs, TRUE); gtk_signal_connect(GTK_OBJECT(mainnotebook), "switch_page", GTK_SIGNAL_FUNC(on_mainnotebook_switch_page), NULL); /* first page has focus */ logwindow = g_list_nth_data(logwindowlist, 0); set_qsoframe(logwindow); /* we have to set the labels of the unknown fields, wether they are visible or not */ unknownlabel1 = lookup_widget(mainwindow, "unknownlabel1"); gtk_label_set_text(GTK_LABEL(unknownlabel1), preferences.freefield1); unknownlabel2 = lookup_widget(mainwindow, "unknownlabel2"); gtk_label_set_text(GTK_LABEL(unknownlabel2), preferences.freefield2); /* update the statusbar with some information */ temp = g_strdup_printf(_("%d QSO's, %d countries and %d prefixes loaded"), state.qsos, state.countries, state.prefixes); update_statusbar(temp); bandsplit = g_strsplit(preferences.bands, ",", 0); modesplit = g_strsplit(preferences.modes, ",", 0); /* clean up modes and bands, don't want any spaces */ deletespaces(bandsplit); deletespaces(modesplit); bandoptionmenu = lookup_widget(mainwindow, "bandoptionmenu"); /* set the menu strings for the bandoption menu */ updateoptionmenu(bandoptionmenu, bandsplit); modeoptionmenu = lookup_widget(mainwindow, "modeoptionmenu"); /* set the menu strings for the modeoption menu */ updateoptionmenu(modeoptionmenu, modesplit); /* either hide the editbox or the optionmenu */ bandentry = lookup_widget(mainwindow, "bandentry"); modeentry = lookup_widget(mainwindow, "modeentry"); if (preferences.modeseditbox == 0) gtk_widget_hide(modeentry); else gtk_widget_hide(modeoptionmenu); if (preferences.bandseditbox == 0) gtk_widget_hide(bandentry); else gtk_widget_hide(bandoptionmenu); /* set clock appearance */ clockpixmap = lookup_widget(mainwindow, "clockpixmap"); clocklabel = lookup_widget(mainwindow, "clocklabel"); clockhbox = lookup_widget(mainwindow, "clockhbox"); clockhandlebox = lookup_widget(mainwindow, "clockhandlebox"); setlabelstyle(clocklabel, preferences.themecolor, preferences.themefont); if (preferences.clock == 0) { /* no clock */ gtk_widget_hide(clocklabel); gtk_widget_hide(clockpixmap); gtk_widget_hide(clockhbox); gtk_widget_hide(clockhandlebox); } else { /* clock on statusbar */ gtk_widget_show(clocklabel); gtk_widget_show(clockpixmap); gtk_widget_show(clockhbox); gtk_widget_show(clockhandlebox); clocktimer = gtk_timeout_add(1000, (GtkFunction)updateclock, NULL); } /* set appearance of the QSO, DXCC and locator frame */ dxccframe = lookup_widget(mainwindow, "dxccframe"); setframestyle(dxccframe, preferences.themecolor, preferences.themefont); qsoframe = lookup_widget(mainwindow, "qsoframe"); setframestyle(qsoframe, preferences.themecolor, preferences.themefont); locatorframe = lookup_widget(mainwindow, "locatorframe"); setframestyle(locatorframe, preferences.themecolor, preferences.themefont); /* set up the message queue for remote data */ msgid = msgget((key_t)1238, 0666 | IPC_CREAT); if (msgid == -1) { temp = g_strdup_printf(_("Msgget failed: %s"), g_strerror(errno)); update_statusbar(temp); } else /* check for a message twice a second */ remotetimer = gtk_timeout_add(500, (GtkFunction)remote_entry, NULL); /* hamlib stuff */ mhzlabel = lookup_widget(mainwindow, "mhzlabel"); mhzbutton = lookup_widget(mainwindow, "mhzbutton"); modelabel = lookup_widget(mainwindow, "modelabel"); modebutton = lookup_widget(mainwindow, "modebutton"); rstlabel = lookup_widget(mainwindow, "rstlabel"); rstbutton = lookup_widget(mainwindow, "rstbutton"); frequencypixmap = lookup_widget(mainwindow, "frequencypixmap"); frequencylabel = lookup_widget(mainwindow, "frequencylabel"); frequencyhbox = lookup_widget(mainwindow, "frequencyhbox"); frequencyhandlebox = lookup_widget(mainwindow, "frequencyhandlebox"); smeterhandlebox = lookup_widget(mainwindow, "smeterhandlebox"); smeterhbox = lookup_widget(mainwindow, "smeterhbox"); smeterdrawingarea = lookup_widget(mainwindow, "smeterdrawingarea"); smeterpixmap = lookup_widget(mainwindow, "smeterpixmap"); powerlabel = lookup_widget(mainwindow, "powerlabel"); powerbutton = lookup_widget(mainwindow, "powerbutton"); #if WANT_HAMLIB /* need this to set popdown strings in prefs dialog */ rig_set_debug(RIG_DEBUG_ERR); riglist = riglist_get_list(); setlabelstyle(frequencylabel, preferences.themecolor, preferences.themefont); /* clickable buttons and events for hamlib */ gtk_signal_connect(GTK_OBJECT(mhzbutton), "clicked", GTK_SIGNAL_FUNC(on_mhzbutton_clicked), NULL); gtk_signal_connect(GTK_OBJECT(modebutton), "clicked", GTK_SIGNAL_FUNC(on_modebutton_clicked), NULL); gtk_signal_connect(GTK_OBJECT(rstbutton), "clicked", GTK_SIGNAL_FUNC(on_rstbutton_clicked), NULL); gtk_signal_connect(GTK_OBJECT(powerbutton), "clicked", GTK_SIGNAL_FUNC(on_powerbutton_clicked), NULL); gtk_signal_connect(GTK_OBJECT(smeterdrawingarea), "configure_event", GTK_SIGNAL_FUNC(on_smeterdrawingarea_configure_event), NULL); gtk_signal_connect(GTK_OBJECT(smeterdrawingarea), "expose_event", GTK_SIGNAL_FUNC(on_smeterdrawingarea_expose_event), NULL); gtk_signal_connect(GTK_OBJECT(mainwindow), "show", GTK_SIGNAL_FUNC(on_mainwindow_show), NULL); /* init rig if hamlib is enabled and show/hide some widgets */ if (preferences.hamlib > 0) { rigid = get_rigid(preferences.radio); myrig = rig_init(rigid); strncpy(myrig->state.rigport.pathname, preferences.device, FILPATHLEN); retcode = rig_open(myrig); /* check if the rig was opened OK */ if (retcode != RIG_OK) { temp = g_strdup_printf (_("An error occured while opening port %s: %s"), myrig->state.rigport.pathname, rigerror(retcode)); update_statusbar(temp); } else /* timeout for hamlib is 200ms, so have to give the timer a bigger value */ hamlibtimer = gtk_timeout_add(350, (GtkFunction)get_riginfo, NULL); } sethamlibwidgets(preferences.hamlib); #else gtk_widget_show(mhzlabel); gtk_widget_show(modelabel); gtk_widget_show(rstlabel); gtk_widget_hide(mhzbutton); gtk_widget_hide(modebutton); gtk_widget_hide(rstbutton); gtk_widget_hide(frequencypixmap); gtk_widget_hide(frequencyhbox); gtk_widget_hide(frequencyhandlebox); gtk_widget_hide(frequencylabel); gtk_widget_hide(smeterhandlebox); gtk_widget_hide(smeterhbox); gtk_widget_hide(smeterdrawingarea); gtk_widget_hide(smeterpixmap); #endif if (preferences.autosave > 0) savetimer = gtk_timeout_add(preferences.autosave*60*1000, (GtkFunction)autosave, NULL); /* set icon */ gtk_widget_realize(mainwindow); mainwindowstyle = gtk_widget_get_style(mainwindow); icon_pixmap = gdk_pixmap_create_from_xpm_d(mainwindow->window, &mask, &mainwindowstyle->bg[GTK_STATE_NORMAL], (gchar **) &xlog_xpm); gdk_window_set_icon(mainwindow->window, NULL, icon_pixmap, mask); g_free(temp); if (showmainwindow) { gtk_widget_show(mainwindow); /* position the main window */ gdk_window_move_resize(mainwindow->window, preferences.x, preferences.y, preferences.width, preferences.height); } gtk_main(); return 0; }