Merge pull request #43 from gergelypolonkai/chart-db
Save charts in a database instead of separate files
This commit is contained in:
commit
82c8b193a1
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -0,0 +1,3 @@
|
||||
[submodule "libgd"]
|
||||
path = libgd
|
||||
url = git://git.gnome.org/libgd.git
|
@ -1,5 +1,5 @@
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
SUBDIRS = src po data help
|
||||
ACLOCAL_AMFLAGS = -I m4 -I libgd ${ACLOCAL_FLAGS}
|
||||
SUBDIRS = libgd src po data help
|
||||
|
||||
EXTRA_DIST = config.rpath ChangeLog
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
ACLOCAL_FLAGS="-I libgd $ACLOCAL_FLAGS"
|
||||
|
||||
PKG_NAME="astrognome"
|
||||
|
||||
(test -f $srcdir/configure.ac \
|
||||
@ -18,5 +20,7 @@ which gnome-autogen.sh || {
|
||||
exit 1
|
||||
}
|
||||
|
||||
git submodule update --init --recursive
|
||||
|
||||
REQUIRED_AUTOMAKE_VERSION=1.9 . gnome-autogen.sh
|
||||
|
||||
|
@ -35,10 +35,16 @@ PKG_CHECK_MODULES([GTK], [gtk+-3.0 >= 3.8])
|
||||
PKG_CHECK_MODULES([LIBXML], [libxml-2.0])
|
||||
PKG_CHECK_MODULES([LIBXSLT], [libexslt])
|
||||
PKG_CHECK_MODULES([WEBKIT], [webkit2gtk-3.0])
|
||||
PKG_CHECK_MODULES([GDA], [libgda-5.0 libgda-sqlite-5.0])
|
||||
PKG_CHECK_MODULES([SWE_GLIB], [swe-glib >= 2.1.0])
|
||||
|
||||
LIBGD_INIT([
|
||||
main-view
|
||||
])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
libgd/Makefile
|
||||
src/Makefile
|
||||
help/Makefile
|
||||
po/Makefile.in
|
||||
|
1
libgd
Submodule
1
libgd
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 62f9b8b92599b38d986bd26d5780edd400d318c9
|
@ -18,6 +18,7 @@ astrognome_source_files = \
|
||||
ag-chart.c \
|
||||
ag-settings.c \
|
||||
ag-preferences.c \
|
||||
ag-db.c \
|
||||
astrognome.c \
|
||||
$(NULL)
|
||||
|
||||
@ -26,11 +27,11 @@ EXTRA_DIST = \
|
||||
ag.gresource.xml \
|
||||
$(NULL)
|
||||
|
||||
AM_CPPFLAGS = -DG_LOG_DOMAIN=\"Astrognome\" -DLOCALEDIR=\"$(localedir)\" -DPKGDATADIR=\"$(pkgdatadir)\"
|
||||
AM_CPPFLAGS = -DG_LOG_DOMAIN=\"Astrognome\" -DLOCALEDIR=\"$(localedir)\" -DPKGDATADIR=\"$(pkgdatadir)\" -I$(top_srcdir)/libgd
|
||||
bin_PROGRAMS = astrognome
|
||||
|
||||
astrognome_SOURCES = $(astrognome_source_files) $(BUILT_SOURCES)
|
||||
astrognome_LDADD = $(SWE_GLIB_LIBS) $(GTK_LIBS) $(LIBXML_LIBS) $(LIBXSLT_LIBS) $(WEBKIT_LIBS)
|
||||
astrognome_LDADD = $(SWE_GLIB_LIBS) $(GTK_LIBS) $(LIBXML_LIBS) $(LIBXSLT_LIBS) $(WEBKIT_LIBS) $(GDA_LIBS) $(top_builddir)/libgd/libgd.la
|
||||
astrognome_LDFLAGS = -rdynamic
|
||||
astrognome_CFLAGS = $(SWE_GLIB_CFLAGS) $(CFLAGS) $(GTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBXSLT_CFLAGS) $(WEBKIT_CFLAGS) -Wall
|
||||
astrognome_CFLAGS = $(SWE_GLIB_CFLAGS) $(CFLAGS) $(GTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBXSLT_CFLAGS) $(WEBKIT_CFLAGS) $(GDA_CFLAGS) -Wall
|
||||
|
||||
|
98
src/ag-app.c
98
src/ag-app.c
@ -68,7 +68,10 @@ ag_app_create_window(AgApp *app)
|
||||
static void
|
||||
new_window_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
{
|
||||
ag_app_create_window(AG_APP(user_data));
|
||||
AgWindow *window = AG_WINDOW(ag_app_create_window(AG_APP(user_data)));
|
||||
|
||||
ag_window_load_chart_list(window);
|
||||
ag_window_change_tab(window, "list");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -130,12 +133,11 @@ quit_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
}
|
||||
|
||||
static void
|
||||
ag_app_open_chart(AgApp *app, GFile *file)
|
||||
ag_app_import_chart(AgApp *app, GFile *file)
|
||||
{
|
||||
GtkWidget *window;
|
||||
AgChart *chart;
|
||||
GError *err = NULL;
|
||||
gchar *uri;
|
||||
|
||||
if ((chart = ag_chart_load_from_file(file, &err)) == NULL) {
|
||||
g_print("Error: '%s'\n", err->message);
|
||||
@ -146,14 +148,12 @@ ag_app_open_chart(AgApp *app, GFile *file)
|
||||
window = ag_app_create_window(app);
|
||||
ag_window_set_chart(AG_WINDOW(window), chart);
|
||||
ag_window_update_from_chart(AG_WINDOW(window));
|
||||
uri = g_file_get_uri(file);
|
||||
ag_window_set_uri(AG_WINDOW(window), uri);
|
||||
g_free(uri);
|
||||
g_action_group_activate_action(G_ACTION_GROUP(window), "save", NULL);
|
||||
ag_window_change_tab(AG_WINDOW(window), "chart");
|
||||
}
|
||||
|
||||
static void
|
||||
open_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
ag_app_import_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
{
|
||||
gint response;
|
||||
GtkWidget *fs;
|
||||
@ -163,7 +163,7 @@ open_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
NULL,
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||
_("_Open"), GTK_RESPONSE_ACCEPT,
|
||||
_("_Import"), GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fs), filter_all);
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fs), filter_chart);
|
||||
@ -190,7 +190,7 @@ open_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
}
|
||||
|
||||
file = g_file_new_for_commandline_arg(data);
|
||||
ag_app_open_chart(AG_APP(user_data), file);
|
||||
ag_app_import_chart(AG_APP(user_data), file);
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,13 +245,13 @@ help_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data)
|
||||
}
|
||||
|
||||
static GActionEntry app_entries[] = {
|
||||
{ "new-window", new_window_cb, NULL, NULL, NULL },
|
||||
{ "preferences", preferences_cb, NULL, NULL, NULL },
|
||||
{ "about", about_cb, NULL, NULL, NULL },
|
||||
{ "quit", quit_cb, NULL, NULL, NULL },
|
||||
{ "raise", raise_cb, NULL, NULL, NULL },
|
||||
{ "open", open_cb, NULL, NULL, NULL },
|
||||
{ "help", help_cb, NULL, NULL, NULL },
|
||||
{ "new-window", new_window_cb, NULL, NULL, NULL },
|
||||
{ "preferences", preferences_cb, NULL, NULL, NULL },
|
||||
{ "about", about_cb, NULL, NULL, NULL },
|
||||
{ "quit", quit_cb, NULL, NULL, NULL },
|
||||
{ "raise", raise_cb, NULL, NULL, NULL },
|
||||
{ "import", ag_app_import_cb, NULL, NULL, NULL },
|
||||
{ "help", help_cb, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
@ -348,12 +348,15 @@ startup(GApplication *gapp)
|
||||
}
|
||||
|
||||
static void
|
||||
ag_app_open(GApplication *gapp, GFile **files, gint n_files, const gchar *hint)
|
||||
ag_app_import(GApplication *gapp,
|
||||
GFile **files,
|
||||
gint n_files,
|
||||
const gchar *hint)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < n_files; i++) {
|
||||
ag_app_open_chart(AG_APP(gapp), files[i]);
|
||||
ag_app_import_chart(AG_APP(gapp), files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -441,7 +444,49 @@ ag_app_class_init(AgAppClass *klass)
|
||||
GApplicationClass *application_class = G_APPLICATION_CLASS(klass);
|
||||
|
||||
application_class->startup = startup;
|
||||
application_class->open = ag_app_open;
|
||||
application_class->open = ag_app_import;
|
||||
}
|
||||
|
||||
gint
|
||||
ag_app_buttoned_dialog(GtkWidget *window,
|
||||
GtkMessageType message_type,
|
||||
const gchar *message,
|
||||
const gchar *first_button_text,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
const gchar *button_text;
|
||||
gint response_id;
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_message_dialog_new(
|
||||
GTK_WINDOW(window),
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
message_type,
|
||||
GTK_BUTTONS_NONE,
|
||||
"%s",
|
||||
message
|
||||
);
|
||||
|
||||
if (first_button_text) {
|
||||
button_text = first_button_text;
|
||||
|
||||
va_start(ap, first_button_text);
|
||||
response_id = va_arg(ap, gint);
|
||||
gtk_dialog_add_button(GTK_DIALOG(dialog), button_text, response_id);
|
||||
|
||||
while ((button_text = va_arg(ap, gchar *)) != NULL) {
|
||||
response_id = va_arg(ap, gint);
|
||||
gtk_dialog_add_button(GTK_DIALOG(dialog), button_text, response_id);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
response_id = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
|
||||
return response_id;
|
||||
}
|
||||
|
||||
void
|
||||
@ -451,21 +496,18 @@ ag_app_message_dialog(GtkWidget *window,
|
||||
{
|
||||
gchar *msg;
|
||||
va_list args;
|
||||
GtkWidget *dialog;
|
||||
|
||||
va_start(args, fmt);
|
||||
msg = g_strdup_vprintf(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
dialog = gtk_message_dialog_new(
|
||||
GTK_WINDOW(window),
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
ag_app_buttoned_dialog(
|
||||
window,
|
||||
message_type,
|
||||
GTK_BUTTONS_OK,
|
||||
"%s",
|
||||
msg
|
||||
msg,
|
||||
_("Close"), GTK_RESPONSE_CLOSE,
|
||||
NULL
|
||||
);
|
||||
|
||||
g_free(msg);
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
@ -47,6 +47,11 @@ void ag_app_run_action(AgApp *app,
|
||||
gboolean is_remote,
|
||||
const AstrognomeOptions *options);
|
||||
|
||||
gint ag_app_buttoned_dialog(GtkWidget *window,
|
||||
GtkMessageType message_type,
|
||||
const gchar *message,
|
||||
const gchar *first_button_text, ...);
|
||||
|
||||
void ag_app_message_dialog(GtkWidget *window,
|
||||
GtkMessageType message_type,
|
||||
gchar *fmt, ...);
|
||||
|
118
src/ag-chart.c
118
src/ag-chart.c
@ -10,6 +10,7 @@
|
||||
#include <locale.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "ag-db.h"
|
||||
#include "ag-chart.h"
|
||||
|
||||
typedef struct _AgChartPrivate {
|
||||
@ -921,6 +922,70 @@ ag_chart_load_from_file(GFile *file, GError **err)
|
||||
return chart;
|
||||
}
|
||||
|
||||
AgChart *
|
||||
ag_chart_new_from_db_save(AgDbSave *save_data, GError **err)
|
||||
{
|
||||
GsweTimestamp *timestamp;
|
||||
gchar *house_system_enum_name;
|
||||
GTypeClass *house_system_class;
|
||||
GEnumValue *enum_value;
|
||||
GsweHouseSystem house_system;
|
||||
AgChart *chart;
|
||||
|
||||
if (save_data == NULL) {
|
||||
g_set_error(
|
||||
err,
|
||||
AG_CHART_ERROR, AG_CHART_ERROR_EMPTY_RECORD,
|
||||
"Invalid chart"
|
||||
);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
house_system_enum_name = g_utf8_strdown(save_data->house_system, -1);
|
||||
house_system_class = g_type_class_ref(GSWE_TYPE_HOUSE_SYSTEM);
|
||||
|
||||
if ((enum_value = g_enum_get_value_by_nick(
|
||||
G_ENUM_CLASS(house_system_class),
|
||||
house_system_enum_name
|
||||
)) == NULL) {
|
||||
g_free(house_system_enum_name);
|
||||
g_set_error(
|
||||
err,
|
||||
AG_CHART_ERROR, AG_CHART_ERROR_INVALID_HOUSE_SYSTEM,
|
||||
"Invalid house system: '%s'",
|
||||
save_data->house_system
|
||||
);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_free(house_system_enum_name);
|
||||
|
||||
house_system = enum_value->value;
|
||||
|
||||
timestamp = gswe_timestamp_new_from_gregorian_full(
|
||||
save_data->year, save_data->month, save_data->day,
|
||||
save_data->hour, save_data->minute, save_data->second, 0,
|
||||
save_data->timezone
|
||||
);
|
||||
|
||||
chart = ag_chart_new_full(
|
||||
timestamp,
|
||||
save_data->longitude,
|
||||
save_data->latitude,
|
||||
save_data->altitude,
|
||||
house_system
|
||||
);
|
||||
|
||||
ag_chart_set_name(chart, save_data->name);
|
||||
ag_chart_set_country(chart, save_data->country);
|
||||
ag_chart_set_city(chart, save_data->city);
|
||||
ag_chart_set_note(chart, save_data->note);
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
static xmlDocPtr
|
||||
create_save_doc(AgChart *chart)
|
||||
{
|
||||
@ -1475,3 +1540,56 @@ const gchar *ag_chart_get_note(AgChart *chart)
|
||||
return priv->note;
|
||||
}
|
||||
|
||||
AgDbSave *
|
||||
ag_chart_get_db_save(AgChart *chart, gint db_id)
|
||||
{
|
||||
GsweCoordinates *coords;
|
||||
AgChartPrivate *priv = ag_chart_get_instance_private(chart);
|
||||
AgDbSave *save_data = g_new0(AgDbSave, 1);
|
||||
GsweTimestamp *timestamp = gswe_moment_get_timestamp(GSWE_MOMENT(chart));
|
||||
GEnumClass *house_system_class;
|
||||
GEnumValue *house_system_enum;
|
||||
|
||||
save_data->db_id = db_id;
|
||||
|
||||
save_data->name = g_strdup(priv->name);
|
||||
save_data->country = g_strdup(priv->country);
|
||||
save_data->city = g_strdup(priv->city);
|
||||
coords = gswe_moment_get_coordinates(GSWE_MOMENT(chart));
|
||||
save_data->longitude = coords->longitude;
|
||||
save_data->latitude = coords->latitude;
|
||||
save_data->altitude = coords->altitude;
|
||||
g_free(coords);
|
||||
save_data->year = gswe_timestamp_get_gregorian_year(
|
||||
timestamp,
|
||||
NULL
|
||||
);
|
||||
save_data->month = gswe_timestamp_get_gregorian_month(
|
||||
timestamp,
|
||||
NULL
|
||||
);
|
||||
save_data->day = gswe_timestamp_get_gregorian_day(timestamp, NULL);
|
||||
save_data->hour = gswe_timestamp_get_gregorian_hour(
|
||||
timestamp,
|
||||
NULL
|
||||
);
|
||||
save_data->minute = gswe_timestamp_get_gregorian_minute(
|
||||
timestamp,
|
||||
NULL
|
||||
);
|
||||
save_data->second = gswe_timestamp_get_gregorian_second(
|
||||
timestamp,
|
||||
NULL
|
||||
);
|
||||
save_data->timezone = gswe_timestamp_get_gregorian_timezone(timestamp);
|
||||
house_system_class = g_type_class_ref(GSWE_TYPE_HOUSE_SYSTEM);
|
||||
house_system_enum = g_enum_get_value(
|
||||
house_system_class,
|
||||
gswe_moment_get_house_system(GSWE_MOMENT(chart))
|
||||
);
|
||||
save_data->house_system = g_strdup(house_system_enum->value_nick);
|
||||
g_type_class_unref(house_system_class);
|
||||
save_data->note = g_strdup(priv->note);
|
||||
|
||||
return save_data;
|
||||
}
|
||||
|
@ -2,13 +2,18 @@
|
||||
#define __AG_CHART_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <swe-glib.h>
|
||||
|
||||
#include "ag-db.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
AG_CHART_ERROR_LIBXML,
|
||||
AG_CHART_ERROR_CORRUPT_FILE,
|
||||
AG_CHART_ERROR_EMPTY_RECORD,
|
||||
AG_CHART_ERROR_INVALID_HOUSE_SYSTEM,
|
||||
} AgChartError;
|
||||
|
||||
#define AG_TYPE_CHART (ag_chart_get_type())
|
||||
@ -46,6 +51,8 @@ AgChart *ag_chart_new_full(GsweTimestamp *timestamp,
|
||||
AgChart *ag_chart_load_from_file(GFile *file,
|
||||
GError **err);
|
||||
|
||||
AgChart *ag_chart_new_from_db_save(AgDbSave *save_data, GError **err);
|
||||
|
||||
void ag_chart_save_to_file(AgChart *chart,
|
||||
GFile *file,
|
||||
GError **err);
|
||||
@ -79,6 +86,8 @@ void ag_chart_set_note(AgChart *chart, const gchar *note);
|
||||
|
||||
const gchar *ag_chart_get_note(AgChart *chart);
|
||||
|
||||
AgDbSave *ag_chart_get_db_save(AgChart *chart, gint db_id);
|
||||
|
||||
#define AG_CHART_ERROR (ag_chart_error_quark())
|
||||
GQuark ag_chart_error_quark(void);
|
||||
|
||||
|
1134
src/ag-db.c
Normal file
1134
src/ag-db.c
Normal file
File diff suppressed because it is too large
Load Diff
78
src/ag-db.h
Normal file
78
src/ag-db.h
Normal file
@ -0,0 +1,78 @@
|
||||
#ifndef __AG_DB_H__
|
||||
#define __AG_DB_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define AG_TYPE_DB (ag_db_get_type())
|
||||
#define AG_DB(o) (G_TYPE_CHECK_INSTANCE_CAST((o), \
|
||||
AG_TYPE_DB, \
|
||||
AgDb))
|
||||
#define AG_DB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), \
|
||||
AG_TYPE_DB, \
|
||||
AgDbClass))
|
||||
#define AG_IS_DB(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), AG_TYPE_DB))
|
||||
#define AG_IS_DB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), AG_TYPE_DB))
|
||||
#define AG_DB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), \
|
||||
AG_TYPE_DB, \
|
||||
AgDbClass))
|
||||
|
||||
typedef struct _AgDb AgDb;
|
||||
typedef struct _AgDbClass AgDbClass;
|
||||
|
||||
struct _AgDb {
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
struct _AgDbClass {
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
typedef struct _AgDbSave {
|
||||
gint db_id;
|
||||
gchar *name;
|
||||
gchar *country;
|
||||
gchar *city;
|
||||
gdouble longitude;
|
||||
gdouble latitude;
|
||||
gdouble altitude;
|
||||
gint year;
|
||||
guint month;
|
||||
guint day;
|
||||
guint hour;
|
||||
guint minute;
|
||||
guint second;
|
||||
gdouble timezone;
|
||||
gchar *house_system;
|
||||
gchar *note;
|
||||
} AgDbSave;
|
||||
|
||||
typedef enum {
|
||||
AG_DB_ERROR_NO_CHART,
|
||||
AG_DB_ERROR_DATABASE_ERROR,
|
||||
} AgDbError;
|
||||
|
||||
GType ag_db_get_type(void) G_GNUC_CONST;
|
||||
|
||||
AgDb *ag_db_get(void);
|
||||
|
||||
void ag_db_save_data_free(AgDbSave *save_data);
|
||||
|
||||
gboolean ag_db_save_chart(AgDb *db,
|
||||
AgDbSave *save_data,
|
||||
GError **err);
|
||||
|
||||
GList *ag_db_get_chart_list(AgDb *db, GError **err);
|
||||
|
||||
AgDbSave *ag_db_get_chart_data_by_id(AgDb *db, guint row_id, GError **err);
|
||||
|
||||
gboolean ag_db_save_identical(const AgDbSave *a, const AgDbSave *b);
|
||||
|
||||
#define AG_DB_ERROR (ag_db_error_quark())
|
||||
GQuark ag_db_error_quark(void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __AG_DB_H__ */
|
389
src/ag-window.c
389
src/ag-window.c
@ -4,6 +4,7 @@
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
#include <webkit2/webkit2.h>
|
||||
#include <libgd/gd-main-view.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <swe-glib.h>
|
||||
@ -12,9 +13,12 @@
|
||||
#include "ag-window.h"
|
||||
#include "ag-chart.h"
|
||||
#include "ag-settings.h"
|
||||
#include "ag-db.h"
|
||||
|
||||
struct _AgWindowPrivate {
|
||||
GtkWidget *header_bar;
|
||||
GtkWidget *menubutton_revealer;
|
||||
GtkWidget *new_back_stack;
|
||||
GtkWidget *stack;
|
||||
GtkWidget *name;
|
||||
GtkWidget *north_lat;
|
||||
@ -32,6 +36,7 @@ struct _AgWindowPrivate {
|
||||
GtkWidget *timezone;
|
||||
GtkWidget *house_system;
|
||||
|
||||
GtkWidget *tab_list;
|
||||
GtkWidget *tab_chart;
|
||||
GtkWidget *tab_edit;
|
||||
GtkWidget *current_tab;
|
||||
@ -42,10 +47,11 @@ struct _AgWindowPrivate {
|
||||
|
||||
AgSettings *settings;
|
||||
AgChart *chart;
|
||||
gchar *uri;
|
||||
gboolean aspect_table_populated;
|
||||
GtkTextBuffer *note_buffer;
|
||||
GtkListStore *house_system_model;
|
||||
GtkListStore *db_chart_data;
|
||||
AgDbSave *saved_data;
|
||||
};
|
||||
|
||||
G_DEFINE_QUARK(ag_window_error_quark, ag_window_error);
|
||||
@ -86,19 +92,101 @@ ag_window_view_menu_action(GSimpleAction *action,
|
||||
g_variant_unref(state);
|
||||
}
|
||||
|
||||
static void
|
||||
ag_window_close_action(GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gboolean
|
||||
ag_window_can_close(AgWindow *window, gboolean display_dialog)
|
||||
{
|
||||
AgWindow *window = user_data;
|
||||
AgWindowPrivate *priv = ag_window_get_instance_private(window);
|
||||
gint db_id = (priv->saved_data)
|
||||
? priv->saved_data->db_id
|
||||
: -1;
|
||||
AgDbSave *save_data = NULL;
|
||||
AgDb *db = ag_db_get();
|
||||
GError *err = NULL;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
// TODO: Save unsaved changes!
|
||||
gtk_widget_destroy(GTK_WIDGET(window));
|
||||
if (priv->chart) {
|
||||
save_data = ag_chart_get_db_save(priv->chart, db_id);
|
||||
|
||||
if (
|
||||
!ag_db_save_identical(priv->saved_data, save_data)
|
||||
|| !(priv->saved_data)
|
||||
|| (priv->saved_data->db_id == -1)
|
||||
) {
|
||||
g_debug("Save is needed!");
|
||||
|
||||
if (display_dialog) {
|
||||
gint response;
|
||||
|
||||
response = ag_app_buttoned_dialog(
|
||||
GTK_WIDGET(window),
|
||||
GTK_MESSAGE_QUESTION,
|
||||
_("Chart is not saved. Do you want to save it?"),
|
||||
_("Save and close"), GTK_RESPONSE_YES,
|
||||
_("Close without saving"), GTK_RESPONSE_NO,
|
||||
_("Return to chart"), GTK_RESPONSE_CANCEL,
|
||||
NULL
|
||||
);
|
||||
|
||||
switch (response) {
|
||||
case GTK_RESPONSE_YES:
|
||||
if (!ag_db_save_chart(db, save_data, &err)) {
|
||||
ag_app_message_dialog(
|
||||
GTK_WIDGET(window),
|
||||
GTK_MESSAGE_ERROR,
|
||||
"Unable to save chart: %s",
|
||||
err->message
|
||||
);
|
||||
|
||||
ret = FALSE;
|
||||
} else {
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case GTK_RESPONSE_NO:
|
||||
ret = TRUE;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = FALSE;
|
||||
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ag_db_save_data_free(save_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ag_window_delete_event_callback(AgWindow *window,
|
||||
GdkEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
return (!ag_window_can_close(window, TRUE));
|
||||
}
|
||||
|
||||
static void
|
||||
ag_window_save_as(AgWindow *window, GError **err)
|
||||
ag_window_close_action(GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
AgWindow *window = AG_WINDOW(user_data);
|
||||
|
||||
if (ag_window_can_close(window, TRUE)) {
|
||||
gtk_widget_destroy(GTK_WIDGET(window));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ag_window_export(AgWindow *window, GError **err)
|
||||
{
|
||||
gchar *name;
|
||||
gchar *file_name;
|
||||
@ -146,7 +234,7 @@ ag_window_save_as(AgWindow *window, GError **err)
|
||||
file_name = g_strdup_printf("%s.agc", name);
|
||||
g_free(name);
|
||||
|
||||
fs = gtk_file_chooser_dialog_new(_("Save Chart"),
|
||||
fs = gtk_file_chooser_dialog_new(_("Export Chart"),
|
||||
GTK_WINDOW(window),
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||
@ -175,42 +263,43 @@ ag_window_save_action(GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
gchar *uri;
|
||||
AgWindow *window = AG_WINDOW(user_data);
|
||||
GError *err = NULL;
|
||||
AgWindowPrivate *priv = ag_window_get_instance_private(window);
|
||||
AgDb *db = ag_db_get();
|
||||
GError *err;
|
||||
gint old_id;
|
||||
AgDbSave *save_data;
|
||||
|
||||
recalculate_chart(window);
|
||||
uri = ag_window_get_uri(window);
|
||||
|
||||
if (uri != NULL) {
|
||||
GFile *file = g_file_new_for_uri(uri);
|
||||
g_free(uri);
|
||||
if (!ag_window_can_close(window, FALSE)) {
|
||||
old_id = (priv->saved_data) ? priv->saved_data->db_id : -1;
|
||||
save_data = ag_chart_get_db_save(priv->chart, old_id);
|
||||
|
||||
ag_chart_save_to_file(priv->chart, file, &err);
|
||||
} else {
|
||||
ag_window_save_as(window, &err);
|
||||
}
|
||||
if (!ag_db_save_chart(db, save_data, &err)) {
|
||||
ag_app_message_dialog(
|
||||
GTK_WIDGET(window),
|
||||
GTK_MESSAGE_ERROR,
|
||||
_("Unable to save: %s"),
|
||||
err->message
|
||||
);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
ag_app_message_dialog(
|
||||
GTK_WIDGET(window),
|
||||
GTK_MESSAGE_ERROR,
|
||||
"%s", err->message
|
||||
);
|
||||
ag_db_save_data_free(priv->saved_data);
|
||||
priv->saved_data = save_data;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ag_window_save_as_action(GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
ag_window_export_action(GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
AgWindow *window = AG_WINDOW(user_data);
|
||||
GError *err = NULL;
|
||||
|
||||
recalculate_chart(window);
|
||||
ag_window_save_as(window, &err);
|
||||
ag_window_export(window, &err);
|
||||
|
||||
if (err) {
|
||||
ag_app_message_dialog(
|
||||
@ -874,6 +963,14 @@ ag_window_tab_changed_cb(GtkStack *stack, GParamSpec *pspec, AgWindow *window)
|
||||
gtk_widget_set_size_request(active_tab, 600, 600);
|
||||
}
|
||||
|
||||
if (strcmp("list", active_tab_name) == 0) {
|
||||
gtk_revealer_set_reveal_child(GTK_REVEALER(priv->menubutton_revealer), FALSE);
|
||||
gtk_stack_set_visible_child_name(GTK_STACK(priv->new_back_stack), "new");
|
||||
} else {
|
||||
gtk_revealer_set_reveal_child(GTK_REVEALER(priv->menubutton_revealer), TRUE);
|
||||
gtk_stack_set_visible_child_name(GTK_STACK(priv->new_back_stack), "back");
|
||||
}
|
||||
|
||||
// If we are coming from the Edit tab, let’s assume the chart data has
|
||||
// changed. This is a bad idea, though, it should be checked instead!
|
||||
// (TODO)
|
||||
@ -900,14 +997,68 @@ ag_window_change_tab_action(GSimpleAction *action,
|
||||
g_action_change_state(G_ACTION(action), parameter);
|
||||
}
|
||||
|
||||
static void
|
||||
ag_window_new_chart_action(GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
AgWindow *window = AG_WINDOW(user_data);
|
||||
AgWindowPrivate *priv = ag_window_get_instance_private(window);
|
||||
|
||||
if (priv->chart) {
|
||||
ag_app_message_dialog(
|
||||
GTK_WIDGET(window),
|
||||
GTK_MESSAGE_ERROR,
|
||||
"This window already has a chart. " \
|
||||
"This should not happen, " \
|
||||
"please consider issuing a bug report!"
|
||||
);
|
||||
|
||||
gtk_stack_set_visible_child_name(GTK_STACK(priv->stack), "chart");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_stack_set_visible_child_name(GTK_STACK(priv->stack), "edit");
|
||||
}
|
||||
|
||||
static void
|
||||
ag_window_back_action(GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
AgWindow *window = AG_WINDOW(user_data);
|
||||
AgWindowPrivate *priv = ag_window_get_instance_private(window);
|
||||
|
||||
if (ag_window_can_close(window, TRUE)) {
|
||||
g_clear_object(&(priv->chart));
|
||||
ag_db_save_data_free(priv->saved_data);
|
||||
priv->saved_data = NULL;
|
||||
|
||||
ag_window_load_chart_list(window);
|
||||
gtk_stack_set_visible_child_name(GTK_STACK(priv->stack), "list");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ag_window_refresh_action(GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
ag_window_load_chart_list(AG_WINDOW(user_data));
|
||||
}
|
||||
|
||||
static GActionEntry win_entries[] = {
|
||||
{ "close", ag_window_close_action, NULL, NULL, NULL },
|
||||
{ "save", ag_window_save_action, NULL, NULL, NULL },
|
||||
{ "save-as", ag_window_save_as_action, NULL, NULL, NULL },
|
||||
{ "export", ag_window_export_action, NULL, NULL, NULL },
|
||||
{ "export-svg", ag_window_export_svg_action, NULL, NULL, NULL },
|
||||
{ "view-menu", ag_window_view_menu_action, NULL, "false", NULL },
|
||||
{ "gear-menu", ag_window_gear_menu_action, NULL, "false", NULL },
|
||||
{ "change-tab", ag_window_change_tab_action, "s", "'edit'", NULL },
|
||||
{ "new-chart", ag_window_new_chart_action, NULL, NULL, NULL },
|
||||
{ "back", ag_window_back_action, NULL, NULL, NULL },
|
||||
{ "refresh", ag_window_refresh_action, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
@ -972,6 +1123,70 @@ ag_window_set_default_house_system(GtkTreeModel *model,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
ag_window_list_item_activated_cb(GdMainView *view,
|
||||
const gchar *id,
|
||||
const GtkTreePath *path,
|
||||
AgWindow *window)
|
||||
{
|
||||
guint row_id = atoi(id);
|
||||
AgWindowPrivate *priv = ag_window_get_instance_private(window);
|
||||
AgDb *db = ag_db_get();
|
||||
GError *err = NULL;
|
||||
|
||||
if (priv->saved_data != NULL) {
|
||||
ag_app_message_dialog(
|
||||
GTK_WIDGET(window),
|
||||
GTK_MESSAGE_ERROR,
|
||||
"Window chart is not saved. " \
|
||||
"This is a bug, it should not happen here. " \
|
||||
"Please consider opening a bug report!"
|
||||
);
|
||||
|
||||
ag_window_change_tab(window, "chart");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((priv->saved_data = ag_db_get_chart_data_by_id(
|
||||
db,
|
||||
row_id,
|
||||
&err)) == NULL) {
|
||||
ag_app_message_dialog(
|
||||
GTK_WIDGET(window),
|
||||
GTK_MESSAGE_ERROR,
|
||||
"Could not open chart."
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->chart) {
|
||||
g_object_unref(priv->chart);
|
||||
priv->chart = NULL;
|
||||
}
|
||||
|
||||
if ((priv->chart = ag_chart_new_from_db_save(
|
||||
priv->saved_data,
|
||||
&err
|
||||
)) == NULL) {
|
||||
ag_app_message_dialog(
|
||||
GTK_WIDGET(window),
|
||||
GTK_MESSAGE_ERROR,
|
||||
"Error: %s",
|
||||
err->message
|
||||
);
|
||||
ag_db_save_data_free(priv->saved_data);
|
||||
priv->saved_data = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ag_window_update_from_chart(window);
|
||||
|
||||
ag_window_change_tab(window, "chart");
|
||||
}
|
||||
|
||||
static void
|
||||
ag_window_init(AgWindow *window)
|
||||
{
|
||||
@ -1021,8 +1236,29 @@ ag_window_init(AgWindow *window)
|
||||
NULL
|
||||
);
|
||||
|
||||
gtk_stack_set_visible_child_name(GTK_STACK(priv->stack), "edit");
|
||||
priv->current_tab = priv->tab_edit;
|
||||
priv->tab_list = GTK_WIDGET(gd_main_view_new(GD_MAIN_VIEW_ICON));
|
||||
gtk_stack_add_titled(
|
||||
GTK_STACK(priv->stack),
|
||||
priv->tab_list,
|
||||
"list",
|
||||
"Chart list"
|
||||
);
|
||||
|
||||
gd_main_view_set_selection_mode(GD_MAIN_VIEW(priv->tab_list), FALSE);
|
||||
gd_main_view_set_model(
|
||||
GD_MAIN_VIEW(priv->tab_list),
|
||||
GTK_TREE_MODEL(priv->db_chart_data)
|
||||
);
|
||||
g_signal_connect(
|
||||
priv->tab_list,
|
||||
"item-activated",
|
||||
G_CALLBACK(ag_window_list_item_activated_cb),
|
||||
window
|
||||
);
|
||||
|
||||
gtk_stack_set_visible_child_name(GTK_STACK(priv->stack), "list");
|
||||
priv->current_tab = priv->tab_list;
|
||||
|
||||
g_object_set(
|
||||
priv->year_adjust,
|
||||
"lower", (gdouble)G_MININT,
|
||||
@ -1031,7 +1267,6 @@ ag_window_init(AgWindow *window)
|
||||
);
|
||||
|
||||
priv->chart = NULL;
|
||||
priv->uri = NULL;
|
||||
|
||||
g_action_map_add_action_entries(
|
||||
G_ACTION_MAP(window),
|
||||
@ -1071,6 +1306,21 @@ ag_window_class_init(AgWindowClass *klass)
|
||||
AgWindow,
|
||||
header_bar
|
||||
);
|
||||
gtk_widget_class_bind_template_child_private(
|
||||
widget_class,
|
||||
AgWindow,
|
||||
new_back_stack
|
||||
);
|
||||
gtk_widget_class_bind_template_child_private(
|
||||
widget_class,
|
||||
AgWindow,
|
||||
menubutton_revealer
|
||||
);
|
||||
gtk_widget_class_bind_template_child_private(
|
||||
widget_class,
|
||||
AgWindow,
|
||||
db_chart_data
|
||||
);
|
||||
gtk_widget_class_bind_template_child_private(widget_class, AgWindow, name);
|
||||
gtk_widget_class_bind_template_child_private(widget_class, AgWindow, year);
|
||||
gtk_widget_class_bind_template_child_private(widget_class, AgWindow, month);
|
||||
@ -1236,9 +1486,12 @@ ag_window_set_chart(AgWindow *window, AgChart *chart)
|
||||
g_clear_object(&(priv->chart));
|
||||
}
|
||||
|
||||
ag_db_save_data_free(priv->saved_data);
|
||||
|
||||
priv->chart = chart;
|
||||
g_signal_connect(priv->chart, "changed", G_CALLBACK(chart_changed), window);
|
||||
g_object_ref(chart);
|
||||
priv->saved_data = ag_chart_get_db_save(chart, -1);
|
||||
}
|
||||
|
||||
AgChart *
|
||||
@ -1249,26 +1502,6 @@ ag_window_get_chart(AgWindow *window)
|
||||
return priv->chart;
|
||||
}
|
||||
|
||||
void
|
||||
ag_window_set_uri(AgWindow *window, const gchar *uri)
|
||||
{
|
||||
AgWindowPrivate *priv = ag_window_get_instance_private(window);
|
||||
|
||||
if (priv->uri != NULL) {
|
||||
g_free(priv->uri);
|
||||
}
|
||||
|
||||
priv->uri = g_strdup(uri);
|
||||
}
|
||||
|
||||
gchar *
|
||||
ag_window_get_uri(AgWindow *window)
|
||||
{
|
||||
AgWindowPrivate *priv = ag_window_get_instance_private(window);
|
||||
|
||||
return g_strdup(priv->uri);
|
||||
}
|
||||
|
||||
void
|
||||
ag_window_settings_restore(GtkWindow *window, GSettings *settings)
|
||||
{
|
||||
@ -1343,3 +1576,51 @@ ag_window_name_changed_cb(GtkEntry *name_entry, AgWindow *window)
|
||||
|
||||
gtk_header_bar_set_subtitle(GTK_HEADER_BAR(priv->header_bar), name);
|
||||
}
|
||||
|
||||
static void
|
||||
ag_window_add_chart_to_list(AgDbSave *save_data, AgWindow *window)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
AgWindowPrivate *priv = ag_window_get_instance_private(window);
|
||||
gchar *id = g_strdup_printf("%d", save_data->db_id);
|
||||
|
||||
gtk_list_store_append(priv->db_chart_data, &iter);
|
||||
gtk_list_store_set(
|
||||
priv->db_chart_data, &iter,
|
||||
0, id, /* ID */
|
||||
1, NULL, /* URI */
|
||||
2, save_data->name, /* Primary text */
|
||||
3, NULL, /* Secondary text */
|
||||
4, NULL, /* Icon */
|
||||
5, 0, /* mtime */
|
||||
6, FALSE, /* Selected */
|
||||
7, 0, /* Pulse */
|
||||
-1
|
||||
);
|
||||
g_free(id);
|
||||
}
|
||||
|
||||
static void
|
||||
ag_window_clear_chart_list(AgWindow *window)
|
||||
{
|
||||
AgWindowPrivate *priv = ag_window_get_instance_private(window);
|
||||
|
||||
gtk_list_store_clear(priv->db_chart_data);
|
||||
}
|
||||
|
||||
gboolean
|
||||
ag_window_load_chart_list(AgWindow *window)
|
||||
{
|
||||
AgDb *db = ag_db_get();
|
||||
GError *err = NULL;
|
||||
GList *chart_list = ag_db_get_chart_list(db, &err);
|
||||
|
||||
ag_window_clear_chart_list(window);
|
||||
/* With only a few charts, this should be fine. Maybe implementing lazy
|
||||
* loading would be a better idea. See:
|
||||
* http://blogs.gnome.org/ebassi/documentation/lazy-loading/
|
||||
*/
|
||||
g_list_foreach(chart_list, (GFunc)ag_window_add_chart_to_list, window);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -50,11 +50,6 @@ AgChart *ag_window_get_chart(AgWindow *window);
|
||||
|
||||
void ag_window_update_from_chart(AgWindow *window);
|
||||
|
||||
void ag_window_set_uri(AgWindow *window,
|
||||
const gchar *uri);
|
||||
|
||||
gchar *ag_window_get_uri(AgWindow *window);
|
||||
|
||||
void ag_window_settings_restore(GtkWindow *window,
|
||||
GSettings *settings);
|
||||
|
||||
@ -63,6 +58,8 @@ void ag_window_settings_save(GtkWindow *window,
|
||||
|
||||
void ag_window_change_tab(AgWindow *window, const gchar *tab_name);
|
||||
|
||||
gboolean ag_window_load_chart_list(AgWindow *window);
|
||||
|
||||
#define AG_WINDOW_ERROR (ag_window_error_quark())
|
||||
|
||||
GQuark ag_window_error_quark(void);
|
||||
|
@ -38,9 +38,9 @@
|
||||
<attribute name="accel"><Primary>s</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Save as…</attribute>
|
||||
<attribute name="action">win.save-as</attribute>
|
||||
<attribute name="accel"><Primary><Shift>s</attribute>
|
||||
<attribute name="label" translatable="yes">Export…</attribute>
|
||||
<attribute name="action">win.export</attribute>
|
||||
<attribute name="accel"><Primary><Shift>e</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
@ -116,11 +116,32 @@
|
||||
</object>
|
||||
<object class="GtkTextBuffer" id="note_buffer">
|
||||
</object>
|
||||
<object class="GtkListStore" id="db_chart_data">
|
||||
<columns>
|
||||
<!-- column-name id -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name uri -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name name -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name secondary-text -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name icon -->
|
||||
<column type="GdkPixbuf"/>
|
||||
<!-- column-name mtime -->
|
||||
<column type="gint64"/>
|
||||
<!-- column-name selected -->
|
||||
<column type="gboolean"/>
|
||||
<!-- column-name pulse -->
|
||||
<column type="guint"/>
|
||||
</columns>
|
||||
</object>
|
||||
<template class="AgWindow" parent="GtkApplicationWindow">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="has_focus">False</property>
|
||||
<property name="is_focus">False</property>
|
||||
<property name="icon_name">astrognome</property>
|
||||
<signal name="delete-event" handler="ag_window_delete_event_callback" swapped="no"/>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header_bar">
|
||||
<property name="visible">True</property>
|
||||
@ -128,6 +149,82 @@
|
||||
<property name="vexpand">False</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<property name="title" translatable="yes">Astrognome</property>
|
||||
<child>
|
||||
<object class="GtkStack" id="new_back_stack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="new_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="action_name">win.new-chart</property>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkImage" id="new_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon_name">document-new-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="refresh_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="action_name">win.refresh</property>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkImage" id="refresh_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon_name">view-refresh-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">new</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="back_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="action_name">win.back</property>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkImage" id="back_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon_name">go-previous-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">back</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box">
|
||||
<property name="visible">True</property>
|
||||
@ -139,44 +236,60 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<object class="GtkRevealer" id="menubutton_revealer">
|
||||
<property name="visible">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="action_name">win.gear-menu</property>
|
||||
<property name="menu_model">gear_menu</property>
|
||||
<property name="use_popover">False</property>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
</style>
|
||||
<property name="reveal_child">False</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="gear_image">
|
||||
<object class="GtkBox" id="menubutton_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon_name">emblem-system-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="action_name">win.view-menu</property>
|
||||
<property name="menu_model">view_menu</property>
|
||||
<property name="use_popover">False</property>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkImage" id="view_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon_name">document-properties-symbolic</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="action_name">win.view-menu</property>
|
||||
<property name="menu_model">view_menu</property>
|
||||
<property name="use_popover">False</property>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkImage" id="view_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon_name">document-properties-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="action_name">win.gear-menu</property>
|
||||
<property name="menu_model">gear_menu</property>
|
||||
<property name="use_popover">False</property>
|
||||
<style>
|
||||
<class name="image-button"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkImage" id="gear_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon_name">emblem-system-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -9,8 +9,8 @@
|
||||
<attribute name="accel"><Primary>n</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Open</attribute>
|
||||
<attribute name="action">app.open</attribute>
|
||||
<attribute name="label" translatable="yes">Import</attribute>
|
||||
<attribute name="action">app.import</attribute>
|
||||
<attribute name="accel"><Primary>o</attribute>
|
||||
</item>
|
||||
</section>
|
||||
|
Loading…
Reference in New Issue
Block a user