/** * Read QTH file and add data to list store. * @param liststore The GtkListStore where the data should be stored. * @param filename The full name of the qth file. * @return 1 if read is successful, 0 if an error occurs. * * The function uses the gtk-sat-data infrastructure to read the qth * data from the specified file. * * There is a little challenge here. First, we want to read the data from * the .qth files and store them in the list store. To do this we use a * qth_t structure, which can be populated using gtk_sat_data_read_qth. * Then, when the configuration is finished and the user presses "OK", we * want to write all the data back to the .qth files. To do that, we create * an up-to-date qth_t data structure and pass it to the gtk_sat_data_write_qth * function, which will take care of updating the GKeyFile data structure and * writing the contents to the .qth file. */ static guint read_qth_file(GtkListStore * liststore, gchar * filename) { GtkTreeIter item; /* new item added to the list store */ qth_t *qth; /* qth data structure */ gchar *defqth; gboolean is_default = FALSE; gchar *fname; gint dispalt; /* displayed altitude */ if ((qth = g_try_new0(qth_t, 1)) == NULL) { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s:%d: Failed to allocate memory!\n"), __FILE__, __LINE__); return FALSE; } /* read data from file */ if (!qth_data_read(filename, qth)) { g_free(qth); return FALSE; } /* calculate QRA locator */ gint retcode; qth->qra = g_malloc(7); retcode = longlat2locator(qth->lon, qth->lat, qth->qra, 3); if (retcode != RIG_OK) { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s:%d: Could not convert (%.2f,%.2f) to QRA."), __FILE__, __LINE__, qth->lat, qth->lon); qth->qra[0] = '\0'; } else { qth->qra[6] = '\0'; sat_log_log(SAT_LOG_LEVEL_DEBUG, _("%s:%d: QRA locator is %s"), __FILE__, __LINE__, qth->qra); } /* is this the default qth? */ defqth = sat_cfg_get_str(SAT_CFG_STR_DEF_QTH); if (g_str_has_suffix(filename, defqth)) { is_default = TRUE; sat_log_log(SAT_LOG_LEVEL_INFO, _("%s:%d: This appears to be the default QTH."), __FILE__, __LINE__); } g_free(defqth); /* check wehter we are using imperial or metric system; in case of imperial we have to convert altitude from meters to feet. note: the internat data are always kept in metric and only the displayed numbers are converted. Therefore, we use a dedicated var 'dispalt' */ /* NO, ONLY DISPLAY WIDGETS WILL BE AFFECTED BY THIS SETTING */ if (sat_cfg_get_bool(SAT_CFG_BOOL_USE_IMPERIAL)) { dispalt = (gint) M_TO_FT(qth->alt); } else { dispalt = (gint) qth->alt; } /* strip file name; we don't need the whole path */ fname = g_path_get_basename(filename); /* we now have all necessary data in the qth_t structure; add the data to the list store */ gtk_list_store_append(liststore, &item); gtk_list_store_set(liststore, &item, QTH_LIST_COL_NAME, qth->name, QTH_LIST_COL_LOC, qth->loc, QTH_LIST_COL_DESC, qth->desc, QTH_LIST_COL_LAT, qth->lat, QTH_LIST_COL_LON, qth->lon, QTH_LIST_COL_ALT, dispalt, QTH_LIST_COL_QRA, qth->qra, QTH_LIST_COL_WX, qth->wx, QTH_LIST_COL_DEF, is_default, QTH_LIST_COL_TYPE, qth->type, QTH_LIST_COL_GPSD_SERVER, qth->gpsd_server, QTH_LIST_COL_GPSD_PORT, qth->gpsd_port, -1); g_free(fname); /* we are finished with this qth, free it */ qth_data_free(qth); return TRUE; }
/** \brief Read QTH data from file. * \param filename The file to read from. * \param qth Pointer to a qth_t data structure where the data will be stored. * \return FALSE if an error occurred, TRUE otherwise. * * \note The function uses the new key=value file parser from glib. */ gint qth_data_read(const gchar *filename, qth_t *qth) { GError *error = NULL; gchar *buff; gchar **buffv; qth->data = g_key_file_new(); g_key_file_set_list_separator(qth->data, ';'); /* bail out with error message if data can not be read */ if (!g_key_file_load_from_file(qth->data, filename, G_KEY_FILE_KEEP_COMMENTS, &error)) { g_key_file_free(qth->data); qth->data = NULL; sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s: Could not load data from %s (%s)"), __FUNCTION__, filename, error->message); return FALSE; } /* send a debug message, then read data */ sat_log_log(SAT_LOG_LEVEL_DEBUG, _("%s: QTH data: %s"), __FUNCTION__, filename); /*** FIXME: should check that strings are UTF-8? */ /* QTH Name */ buff = g_path_get_basename(filename); buffv = g_strsplit(buff, ".qth", 0); qth->name = g_strdup(buffv[0]); g_free(buff); g_strfreev(buffv); /* g_key_file_get_string (qth->data, */ /* QTH_CFG_MAIN_SECTION, */ /* QTH_CFG_NAME_KEY, */ /* &error); */ if (error != NULL) { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s: Error reading QTH name (%s)."), __FUNCTION__, error->message); qth->name = g_strdup(_("ERROR")); g_clear_error(&error); } /* QTH location */ qth->loc = g_key_file_get_string(qth->data, QTH_CFG_MAIN_SECTION, QTH_CFG_LOC_KEY, &error); if (error != NULL) { sat_log_log(SAT_LOG_LEVEL_INFO, _("%s: QTH has no location (%s)."), __FUNCTION__, error->message); qth->loc = g_strdup(""); g_clear_error(&error); } /* QTH description */ qth->desc = g_key_file_get_string(qth->data, QTH_CFG_MAIN_SECTION, QTH_CFG_DESC_KEY, &error); if ((qth->desc == NULL) || (error != NULL)) { sat_log_log(SAT_LOG_LEVEL_INFO, _("%s: QTH has no description."), __FUNCTION__); qth->desc = g_strdup(""); g_clear_error(&error); } /* Weather station */ qth->wx = g_key_file_get_string(qth->data, QTH_CFG_MAIN_SECTION, QTH_CFG_WX_KEY, &error); if ((qth->wx == NULL) || (error != NULL)) { sat_log_log(SAT_LOG_LEVEL_INFO, _("%s: QTH has no weather station."), __FUNCTION__); qth->wx = g_strdup(""); g_clear_error(&error); } /* QTH Latitude */ buff = g_key_file_get_string(qth->data, QTH_CFG_MAIN_SECTION, QTH_CFG_LAT_KEY, &error); if (error != NULL) { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s: Error reading QTH latitude (%s)."), __FUNCTION__, error->message); g_clear_error(&error); if (buff != NULL) g_free(buff); qth->lat = 0.0; } else { qth->lat = g_ascii_strtod(buff, NULL); g_free(buff); } /* QTH Longitude */ buff = g_key_file_get_string(qth->data, QTH_CFG_MAIN_SECTION, QTH_CFG_LON_KEY, &error); if (error != NULL) { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s: Error reading QTH longitude (%s)."), __FUNCTION__, error->message); g_clear_error(&error); if (buff != NULL) g_free(buff); qth->lon = 0.0; } else { qth->lon = g_ascii_strtod(buff, NULL); g_free(buff); } /* QTH Altitude */ qth->alt = g_key_file_get_integer(qth->data, QTH_CFG_MAIN_SECTION, QTH_CFG_ALT_KEY, &error); if (error != NULL) { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s: Error reading QTH altitude (%s)."), __FUNCTION__, error->message); g_clear_error(&error); if (buff != NULL) g_free(buff); qth->alt = 0; } else { } /* QTH Type */ qth->type = g_key_file_get_integer(qth->data, QTH_CFG_MAIN_SECTION, QTH_CFG_TYPE_KEY, &error); if (error != NULL) { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s: Error reading QTH type (%s)."), __FUNCTION__, error->message); g_clear_error(&error); qth->type = QTH_STATIC_TYPE; } /* GPSD Port */ qth->gpsd_port = g_key_file_get_integer(qth->data, QTH_CFG_MAIN_SECTION, QTH_CFG_GPSD_PORT_KEY, &error); if (error != NULL) { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s: Error reading QTH type (%s)."), __FUNCTION__, error->message); g_clear_error(&error); /*if not set put it on the default port */ qth->gpsd_port = 2947; } /* GPSD Server */ qth->gpsd_server = g_key_file_get_string(qth->data, QTH_CFG_MAIN_SECTION, QTH_CFG_GPSD_SERVER_KEY, &error); if ((qth->gpsd_server == NULL) || (error != NULL)) { sat_log_log(SAT_LOG_LEVEL_INFO, _("%s: QTH has no GPSD Server."), __FUNCTION__); qth->gpsd_server = g_strdup(""); g_clear_error(&error); } /* set QRA based on data */ if (longlat2locator(qth->lon, qth->lat, qth->qra, 2) != RIG_OK) { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s: Could not set QRA for %s at %f, %f."), __FUNCTION__, qth->name, qth->lon, qth->lat); } qth_validate(qth); /* Now, send debug message and return */ sat_log_log(SAT_LOG_LEVEL_INFO, _("%s: QTH data: %s, %.4f, %.4f, %d"), __FUNCTION__, qth->name, qth->lat, qth->lon, qth->alt); return TRUE; }
int main (int argc, char *argv[]) { char recodedloc[13], *loc1, *loc2, sign; double lon1, lat1, lon2, lat2; double distance, az, mmm, sec; int deg, min, retcode, loc_len, nesw = 0; if (argc < 2) { fprintf(stderr, "Usage: %s <locator1> <precision> [<locator2>]\n", argv[0]); exit(1); } loc1 = argv[1]; loc_len = argc > 2 ? atoi(argv[2]) : strlen(loc1)/2; loc2 = argc > 3 ? argv[3] : NULL; printf("Locator1:\t%s\n", loc1); /* hamlib function to convert maidenhead to decimal degrees */ retcode = locator2longlat(&lon1, &lat1, loc1); if (retcode != RIG_OK) { fprintf(stderr, "locator2longlat() failed with malformed input.\n"); exit(2); } /* hamlib function to convert decimal degrees to deg, min, sec */ retcode = dec2dms(lon1, °, &min, &sec, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dms() failed, invalid paramter address.\n"); exit(2); } if (nesw == 1) sign = '-'; else sign = '\0'; printf(" Longitude:\t%f\t%c%d %d' %.2f\"\n", lon1, sign, deg, min, sec); /* hamlib function to convert deg, min, sec to decimal degrees */ lon1 = dms2dec(deg, min, sec, nesw); printf(" Recoded lon:\t%f\n", lon1); /* hamlib function to convert decimal degrees to deg decimal minutes */ retcode = dec2dmmm(lon1, °, &mmm, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dmmm() failed, invalid paramter address.\n"); exit(2); } if (nesw == 1) sign = '-'; else sign = '\0'; printf(" GPS lon:\t%f\t%c%d %.3f'\n", lon1, sign, deg, mmm); /* hamlib function to convert deg, decimal min to decimal degrees */ lon1 = dmmm2dec(deg, mmm, nesw); printf(" Recoded GPS:\t%f\n", lon1); /* hamlib function to convert decimal degrees to deg, min, sec */ retcode = dec2dms(lat1, °, &min, &sec, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dms() failed, invalid paramter address.\n"); exit(2); } if (nesw == 1) sign = '-'; else sign = '\0'; printf(" Latitude:\t%f\t%c%d %d' %.2f\"\n", lat1, sign, deg, min, sec); /* hamlib function to convert deg, min, sec to decimal degrees */ lat1 = dms2dec(deg, min, sec, nesw); printf(" Recoded lat:\t%f\n", lat1); /* hamlib function to convert decimal degrees to deg decimal minutes */ retcode = dec2dmmm(lat1, °, &mmm, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dmmm() failed, invalid paramter address.\n"); exit(2); } if (nesw == 1) sign = '-'; else sign = '\0'; printf(" GPS lat:\t%f\t%c%d %.3f'\n", lat1, sign, deg, mmm); /* hamlib function to convert deg, decimal min to decimal degrees */ lat1 = dmmm2dec(deg, mmm, nesw); printf(" Recoded GPS:\t%f\n", lat1); /* hamlib function to convert decimal degrees to maidenhead */ retcode = longlat2locator(lon1, lat1, recodedloc, loc_len); if (retcode != RIG_OK) { fprintf(stderr, "longlat2locator() failed, precision out of range.\n"); exit(2); } printf(" Recoded:\t%s\n", recodedloc); if (loc2 == NULL) exit(0); /* Now work on the second locator */ printf("\nLocator2:\t%s\n", loc2); retcode = locator2longlat(&lon2, &lat2, loc2); if (retcode != RIG_OK) { fprintf(stderr, "locator2longlat() failed with malformed input.\n"); exit(2); } /* hamlib function to convert decimal degrees to deg, min, sec */ retcode = dec2dms(lon2, °, &min, &sec, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dms() failed, invalid paramter address.\n"); exit(2); } if (nesw == 1) sign = '-'; else sign = '\0'; printf(" Longitude:\t%f\t%c%d %d' %.2f\"\n", lon2, sign, deg, min, sec); /* hamlib function to convert deg, min, sec to decimal degrees */ lon2 = dms2dec(deg, min, sec, nesw); printf(" Recoded lon:\t%f\n", lon2); /* hamlib function to convert decimal degrees to deg decimal minutes */ retcode = dec2dmmm(lon2, °, &mmm, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dmmm() failed, invalid paramter address.\n"); exit(2); } if (nesw == 1) sign = '-'; else sign = '\0'; printf(" GPS lon:\t%f\t%c%d %.3f'\n", lon2, sign, deg, mmm); /* hamlib function to convert deg, decimal min to decimal degrees */ lon2 = dmmm2dec(deg, mmm, nesw); printf(" Recoded GPS:\t%f\n", lon2); /* hamlib function to convert decimal degrees to deg, min, sec */ retcode = dec2dms(lat2, °, &min, &sec, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dms() failed, invalid paramter address.\n"); exit(2); } if (nesw == 1) sign = '-'; else sign = '\0'; printf(" Latitude:\t%f\t%c%d %d' %.2f\"\n", lat2, sign, deg, min, sec); /* hamlib function to convert deg, min, sec to decimal degrees */ lat2 = dms2dec(deg, min, sec, nesw); printf(" Recoded lat:\t%f\n", lat2); /* hamlib function to convert decimal degrees to deg decimal minutes */ retcode = dec2dmmm(lat2, °, &mmm, &nesw); if (retcode != RIG_OK) { fprintf(stderr, "dec2dmmm() failed, invalid paramter address.\n"); exit(2); } if (nesw == 1) sign = '-'; else sign = '\0'; printf(" GPS lat:\t%f\t%c%d %.3f'\n", lat2, sign, deg, mmm); /* hamlib function to convert deg, decimal min to decimal degrees */ lat2 = dmmm2dec(deg, mmm, nesw); printf(" Recoded GPS:\t%f\n", lat2); /* hamlib function to convert decimal degrees to maidenhead */ retcode = longlat2locator(lon2, lat2, recodedloc, loc_len); if (retcode != RIG_OK) { fprintf(stderr, "longlat2locator() failed, precision out of range.\n"); exit(2); } printf(" Recoded:\t%s\n", recodedloc); retcode = qrb(lon1, lat1, lon2, lat2, &distance, &az); if (retcode != RIG_OK) { fprintf(stderr, "QRB error: %d\n", retcode); exit(2); } dec2dms(az, °, &min, &sec, &nesw); printf("\nDistance: %.6fkm\n", distance); if (nesw == 1) sign = '-'; else sign = '\0'; /* Beware printf() rounding error! */ printf("Bearing: %.2f, %c%d %d' %.2f\"\n", az, sign, deg, min, sec); exit(0); }
/** \brief Update the qth data by whatever method is appropriate. * \param qth the qth data structure to update * \param qth the time at which the qth is to be computed. this may be ignored by gps updates. */ gboolean qth_data_update(qth_t * qth, gdouble t) { gboolean retval = FALSE; #ifdef HAS_LIBGPS guint num_loops = 0; #endif switch (qth->type) { case QTH_STATIC_TYPE: /* never changes */ break; case QTH_GPSD_TYPE: if (((t - qth->gpsd_update) > 30.0 / 86400.0) && (t - qth->gpsd_connected > 30.0 / 86400.0)) { /* if needed restart the gpsd interface */ qth_data_update_stop(qth); qth_data_update_init(qth); qth->gpsd_connected = t; } if (qth->gps_data != NULL) { #ifdef HAS_LIBGPS switch (GPSD_API_MAJOR_VERSION) { case 4: #if GPSD_API_MAJOR_VERSION==4 while (gps_waiting(qth->gps_data) == TRUE) { /* this is a watchdog in case there is a problem with the gpsd code. */ /* if the server was up and has failed then gps_waiting in 2.92 confirmed */ /* will return 1 (supposedly fixed in later versions.) */ /* if we do not do this as a while loop, the gpsd packets can backup */ /* and no longer be in sync with the gps receiver */ num_loops++; if (num_loops > 1000) { retval = FALSE; break; } if (gps_poll(qth->gps_data) == 0) { /* handling packet_set inline with http://gpsd.berlios.de/client-howto.html */ if (qth->gps_data->set & PACKET_SET) { if (qth->gps_data->fix.mode >= MODE_2D) { if (qth->lat != qth->gps_data->fix.latitude) { qth->lat = qth->gps_data->fix.latitude; retval = TRUE; } if (qth->lon != qth->gps_data->fix.longitude) { qth->lon = qth->gps_data->fix.longitude; retval = TRUE; } } if (qth->gps_data->fix.mode == MODE_3D) { if (qth->alt != qth->gps_data->fix.altitude) { qth->alt = qth->gps_data->fix.altitude; retval = TRUE; } } else { if (qth->alt != 0) { qth->alt = 0; retval = TRUE; } } } } } #endif break; case 5: #if GPSD_API_MAJOR_VERSION==5 while (gps_waiting(qth->gps_data, 0) == 1) { /* see comment from above */ /* hopefully not needed but does not hurt anything. */ num_loops++; if (num_loops > 1000) { retval = FALSE; break; } if (gps_read(qth->gps_data) == 0) { /* handling packet_set inline with http://gpsd.berlios.de/client-howto.html */ if (qth->gps_data->set & PACKET_SET) { if (qth->gps_data->fix.mode >= MODE_2D) { if (qth->lat != qth->gps_data->fix.latitude) { qth->lat = qth->gps_data->fix.latitude; retval = TRUE; } if (qth->lon != qth->gps_data->fix.longitude) { qth->lon = qth->gps_data->fix.longitude; retval = TRUE; } } if (qth->gps_data->fix.mode == MODE_3D) { if (qth->alt != qth->gps_data->fix.altitude) { qth->alt = qth->gps_data->fix.altitude; retval = TRUE; } } else { if (qth->alt != 0) { qth->alt = 0; retval = TRUE; } } } } } #endif break; default: break; } #endif if (retval == TRUE) { qth->gpsd_update = t; } } break; default: break; } /* check that data is valid */ qth_validate(qth); /* update qra */ if (longlat2locator(qth->lon, qth->lat, qth->qra, 2) != RIG_OK) { sat_log_log(SAT_LOG_LEVEL_ERROR, _("%s: Could not set QRA for %s at %f, %f."), __FUNCTION__, qth->name, qth->lon, qth->lat); } return retval; }
/** \brief Show details about a satellite pass. * \param parent The parent widget. * \param satname The name of the satellite. * \param qth Pointer to the QTH data. * \param pass The pass info. * \param toplevel The toplevel window or NULL. * * This function creates a dialog window containing a notebook with three pages: * 1. A list showing the details of a pass * 2. Polar plot of the pass * 3. Az/El plot of the pass * * Reference to the parent widget is needed to acquire the correct top-level * window, otherwise simply using the main window would bring that to front * covering any possible module windows. This would be unfortunate in the case * of fullscreen modules. * */ void show_pass (const gchar *satname, qth_t *qth, pass_t *pass, GtkWidget *toplevel) { GtkWidget *dialog; /* the dialogue window */ GtkWidget *notebook; /* the notebook widet */ GtkWidget *list; GtkListStore *liststore; GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeIter item; GtkWidget *swin; /* scrolled window containing the list view */ GtkWidget *polar; /* polar plot */ GtkWidget *azel; /* Az/El plot */ GtkWidget *hbox; /* hbox used in tab headers */ GtkWidget *image; /* icon used in tab header */ gchar *title; guint flags; guint i, num; pass_detail_t *detail; gchar *buff; gint retcode; gdouble doppler; gdouble delay; gdouble loss; obs_astro_t astro; gdouble ra,dec; /* get columns flags */ flags = sat_cfg_get_int (SAT_CFG_INT_PRED_SINGLE_COL); /* create list */ list = gtk_tree_view_new (); gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (list), TRUE); for (i = 0; i < SINGLE_PASS_COL_NUMBER; i++) { renderer = gtk_cell_renderer_text_new (); g_object_set (G_OBJECT (renderer), "xalign", SINGLE_PASS_COL_XALIGN[i], NULL); column = gtk_tree_view_column_new_with_attributes (_(SINGLE_PASS_COL_TITLE[i]), renderer, "text", i, NULL); gtk_tree_view_insert_column (GTK_TREE_VIEW (list), column, -1); /* only aligns the headers */ gtk_tree_view_column_set_alignment (column, 0.5); /* set cell data function; allows to format data before rendering */ check_and_set_single_cell_renderer (column, renderer, i); /* hide columns that have not been specified */ if (!(flags & (1 << i))) { gtk_tree_view_column_set_visible (column, FALSE); } } /* create and fill model */ liststore = gtk_list_store_new (SINGLE_PASS_COL_NUMBER, G_TYPE_DOUBLE, // time G_TYPE_DOUBLE, // az G_TYPE_DOUBLE, // el G_TYPE_DOUBLE, // ra G_TYPE_DOUBLE, // dec G_TYPE_DOUBLE, // range G_TYPE_DOUBLE, // range rate G_TYPE_DOUBLE, // lat G_TYPE_DOUBLE, // lon G_TYPE_STRING, // SSP G_TYPE_DOUBLE, // footprint G_TYPE_DOUBLE, // alt G_TYPE_DOUBLE, // vel G_TYPE_DOUBLE, // doppler G_TYPE_DOUBLE, // loss G_TYPE_DOUBLE, // delay G_TYPE_DOUBLE, // ma G_TYPE_DOUBLE, // phase G_TYPE_STRING); // visibility /* add rows to list store */ num = g_slist_length (pass->details); for (i = 0; i < num; i++) { detail = PASS_DETAIL(g_slist_nth_data (pass->details, i)); gtk_list_store_append (liststore, &item); gtk_list_store_set (liststore, &item, SINGLE_PASS_COL_TIME, detail->time, SINGLE_PASS_COL_AZ, detail->az, SINGLE_PASS_COL_EL, detail->el, SINGLE_PASS_COL_RANGE, detail->range, SINGLE_PASS_COL_RANGE_RATE, detail->range_rate, SINGLE_PASS_COL_LAT, detail->lat, SINGLE_PASS_COL_LON, detail->lon, SINGLE_PASS_COL_FOOTPRINT, detail->footprint, SINGLE_PASS_COL_ALT, detail->alt, SINGLE_PASS_COL_VEL, detail->velo, SINGLE_PASS_COL_MA, detail->ma, SINGLE_PASS_COL_PHASE, detail->phase, -1); /* SINGLE_PASS_COL_RA */ /* SINGLE_PASS_COL_DEC */ if (flags & (SINGLE_PASS_FLAG_RA | SINGLE_PASS_FLAG_DEC)) { Calc_RADec (detail->time, detail->az, detail->el, qth, &astro); ra = Degrees(astro.ra); dec = Degrees(astro.dec); gtk_list_store_set (liststore, &item, SINGLE_PASS_COL_RA, ra, SINGLE_PASS_COL_DEC, dec, -1); } /* SINGLE_PASS_COL_SSP */ if (flags & SINGLE_PASS_FLAG_SSP) { buff = g_try_malloc (7); retcode = longlat2locator (detail->lon, detail->lat, buff, 3); if (retcode == RIG_OK) { buff[6] = '\0'; gtk_list_store_set (liststore, &item, SINGLE_PASS_COL_SSP, buff, -1); } g_free (buff); } /* SINGLE_PASS_COL_DOPPLER */ if (flags & SINGLE_PASS_FLAG_DOPPLER) { doppler = -100.0e06 * (detail->range_rate / 299792.4580); // Hz gtk_list_store_set (liststore, &item, SINGLE_PASS_COL_DOPPLER, doppler, -1); } /* SINGLE_PASS_COL_LOSS */ if (flags & SINGLE_PASS_FLAG_LOSS) { loss = 72.4 + 20.0*log10(detail->range); // dB gtk_list_store_set (liststore, &item, SINGLE_PASS_COL_LOSS, loss, -1); } /* SINGLE_PASS_COL_DELAY */ if (flags & SINGLE_PASS_FLAG_DELAY) { delay = detail->range / 299.7924580; // msec gtk_list_store_set (liststore, &item, SINGLE_PASS_COL_DELAY, delay, -1); } /* SINGLE_PASS_COL_VIS */ if (flags & SINGLE_PASS_FLAG_VIS) { buff = g_strdup_printf ("%c", vis_to_chr (detail->vis)); gtk_list_store_set (liststore, &item, SINGLE_PASS_COL_VIS, buff, -1); g_free (buff); } } /* connect model to tree view */ gtk_tree_view_set_model (GTK_TREE_VIEW (list), GTK_TREE_MODEL (liststore)); g_object_unref (liststore); /* scrolled window */ swin = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_container_add (GTK_CONTAINER (swin), list); /* create notebook and add pages */ notebook = gtk_notebook_new (); image = gtk_image_new_from_stock (GTK_STOCK_JUSTIFY_FILL, GTK_ICON_SIZE_MENU); hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("Data")), FALSE, TRUE, 5); gtk_widget_show_all (hbox); gtk_notebook_append_page (GTK_NOTEBOOK (notebook), swin, hbox); /* polar plot */ polar = gtk_polar_plot_new (qth, pass); buff = icon_file_name ("gpredict-polar-small.png"); image = gtk_image_new_from_file (buff); g_free (buff); hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("Polar")), FALSE, TRUE, 5); gtk_widget_show_all (hbox); gtk_notebook_append_page (GTK_NOTEBOOK (notebook), polar, hbox); /* Az/El plot */ azel = gtk_azel_plot_new (qth, pass); buff = icon_file_name ("gpredict-azel-small.png"); image = gtk_image_new_from_file (buff); g_free (buff); hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("Az/El")), FALSE, TRUE, 5); gtk_widget_show_all (hbox); gtk_notebook_append_page (GTK_NOTEBOOK (notebook), azel, hbox); /* create dialog */ title = g_strdup_printf (_("Pass details for %s (orbit %d)"), satname, pass->orbit); /* use NULL as parent to avoid conflict when using undocked windows as parents. */ dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (toplevel), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_PRINT, RESPONSE_PRINT, GTK_STOCK_SAVE, RESPONSE_SAVE, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); g_free (title); /* Make Close button default */ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE); /* window icon */ buff = icon_file_name ("gpredict-sat-list.png"); gtk_window_set_icon_from_file (GTK_WINDOW (dialog), buff, NULL); g_free (buff); /* allow interaction with other windows */ gtk_window_set_modal (GTK_WINDOW (dialog), FALSE); g_object_set_data (G_OBJECT (dialog), "sat", (gpointer) satname); g_object_set_data (G_OBJECT (dialog), "qth", qth); g_object_set_data (G_OBJECT (dialog), "pass", pass); g_signal_connect (dialog, "response", G_CALLBACK (single_pass_response), NULL); g_signal_connect (dialog, "destroy", G_CALLBACK (single_pass_dialog_destroy), NULL); g_signal_connect (dialog, "delete_event", G_CALLBACK (single_pass_dialog_delete), NULL); gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area(GTK_DIALOG(dialog))), notebook); gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 300); gtk_widget_show_all (dialog); }