diff --git a/res/gtk/connection-form.blp b/res/gtk/connection-form.blp index 309687f..3bab371 100644 --- a/res/gtk/connection-form.blp +++ b/res/gtk/connection-form.blp @@ -1,300 +1,322 @@ using Gtk 4.0; using Adw 1; -template $PsequelConnectionForm : Gtk.Box { +template $PsequelConnectionForm : Adw.Bin { - orientation: vertical; - hexpand: true; - vexpand: true; + child: WindowHandle { + Box { + orientation: vertical; + hexpand: true; + vexpand: true; + Adw.HeaderBar header { + styles ["flat"] - - Adw.HeaderBar header { - styles ["flat"] - - [title] - Label { - label: ""; - } - - // Dupplicate primary_menu in query-view.blp. - // Update both if you change something - [end] - MenuButton { - icon-name: "open-menu-symbolic"; - menu-model: primary_menu; - } - } - - Adw.Clamp { - valign: center; - maximum-size: 800; - Box { - orientation: vertical; - styles ["connection-form", "frame"] - // vexpand: true; - spacing: 4; - - Label { - margin-top: 20; - margin-bottom: 40; - styles ["title-0"] - - label: "Connect with Psequel"; - } - - Box { - spacing: 8; - + [title] Label { - label: "URL:"; - } - - Entry url_entry { - placeholder-text: "postgres://..."; - hexpand: true; - activate => $on_entry_activated(); - changed => $on_url_entry_changed(); - } + label: ""; } - Label err_label { - styles ["secondary"] - height-request: 48; - valign: start; - label: " "; + // Dupplicate primary_menu in query-view.blp. + // Update both if you change something + [end] + MenuButton { + icon-name: "open-menu-symbolic"; + menu-model: primary_menu; } - - CenterBox { - margin-top: 0; - margin-bottom: 24; - [start] - Box { - orientation: vertical; - hexpand: true; - valign: center; - margin-start: 8; - margin-end: 8; - Separator { - - } - } - [center] - Label { - styles ["title-3"] - label: "OR"; - } - [end] + } + + Adw.Clamp { + valign: start; + hexpand: true; + vexpand: true; + maximum-size: 800; Box { orientation: vertical; - hexpand: true; - valign: center; - margin-start: 8; - margin-end: 8; - Separator { - - } - } - } - - Grid { - - hexpand: true; - vexpand: true; - row-homogeneous: true; - row-spacing: 8; - column-spacing: 8; - margin-start: 4; - margin-end: 4; - - Label { - halign: end; - label: "Name:"; - - layout { - row: 0; - column: 0; - column-span: 3; - } - } - - Label { - halign: end; - label: "Host:"; + styles ["connection-form"] + // vexpand: true; + spacing: 4; - layout { - row: 1; - column: 0; - column-span: 3; - } - } - - Label { - halign: end; - label: "User:"; - - layout { - row: 2; - column: 0; - column-span: 3; - } - } - - Label { - halign: end; - label: "Password:"; - - layout { - row: 3; - column: 0; - column-span: 3; - } - } - - Label { - halign: end; - label: "Database:"; - - layout { - row: 4; - column: 0; - column-span: 3; + Label { + margin-top: 20; + margin-bottom: 40; + styles ["title-0"] + + label: "Connect with Psequel"; } - } - - Entry name_entry { - placeholder-text: "Connection name"; - hexpand: true; - activate => $on_entry_activated(); - layout { - row: 0; - column: 3; - column-span: 7; - } - } - - Entry host_entry { - placeholder-text: "localhost"; - activate => $on_entry_activated(); + Box { + spacing: 8; - layout { - row: 1; - column: 3; - column-span: 5; + Label { + label: "URL:"; + } + + Entry url_entry { + placeholder-text: "postgres://..."; + hexpand: true; + activate => $on_entry_activated(); + changed => $on_url_entry_changed(); + } } - } - - Label { - label: "Port"; - halign: end; - layout { - row: 1; - column: 8; + + Label err_label { + styles ["secondary"] + height-request: 48; + valign: start; + label: " "; } - } - - Entry port_entry { - placeholder-text: "5432"; - activate => $on_entry_activated(); - layout { - row: 1; - column: 9; - column-span: 1; + CenterBox { + margin-top: 0; + margin-bottom: 24; + [start] + Box { + orientation: vertical; + hexpand: true; + valign: center; + margin-start: 8; + margin-end: 8; + Separator { + + } + } + [center] + Label { + styles ["title-3"] + label: "OR"; + } + [end] + Box { + orientation: vertical; + hexpand: true; + valign: center; + margin-start: 8; + margin-end: 8; + Separator { + + } + } } - } - - Entry user_entry { - placeholder-text: "postgres"; - activate => $on_entry_activated(); - layout { - row: 2; - column: 3; - column-span: 7; - } - } - - PasswordEntry password_entry { - placeholder-text: ""; - show-peek-icon: true; - activate => $on_entry_activated(); - - layout { - row: 3; - column: 3; - column-span: 7; - } - } - + Grid { - Entry database_entry { - placeholder-text: "postgres"; - activate => $on_entry_activated(); + hexpand: true; + vexpand: true; + row-homogeneous: true; + row-spacing: 8; + column-spacing: 8; + margin-start: 4; + margin-end: 4; - layout { - row: 4; - column: 3; - column-span: 7; - } - } - - Label { - label: "SSL:"; - halign: end; - layout { - row: 5; - column: 0; - column-span: 3; - } + Label { + halign: end; + label: "Name:"; + + layout { + row: 0; + column: 0; + column-span: 3; + } + } + + Label { + halign: end; + label: "Host:"; + + layout { + row: 1; + column: 0; + column-span: 3; + } + } + + Label { + halign: end; + label: "User:"; + + layout { + row: 2; + column: 0; + column-span: 3; + } + } + + Label { + halign: end; + label: "Password:"; + + layout { + row: 3; + column: 0; + column-span: 3; + } + } + + Label { + halign: end; + label: "Database:"; + + layout { + row: 4; + column: 0; + column-span: 3; + } + } + + Entry name_entry { + placeholder-text: "Connection name"; + hexpand: true; + activate => $on_entry_activated(); + + layout { + row: 0; + column: 3; + column-span: 7; + } + } + + Entry host_entry { + placeholder-text: "localhost"; + activate => $on_entry_activated(); + + layout { + row: 1; + column: 3; + column-span: 5; + } + } + + Label { + label: "Port"; + halign: end; + layout { + row: 1; + column: 8; + } + } + + Entry port_entry { + placeholder-text: "5432"; + activate => $on_entry_activated(); + + layout { + row: 1; + column: 9; + column-span: 1; + } + } + + Entry user_entry { + placeholder-text: "postgres"; + activate => $on_entry_activated(); + + layout { + row: 2; + column: 3; + column-span: 7; + } + } + + PasswordEntry password_entry { + placeholder-text: ""; + show-peek-icon: true; + activate => $on_entry_activated(); + + layout { + row: 3; + column: 3; + column-span: 7; + } + } + + + Entry database_entry { + placeholder-text: "postgres"; + activate => $on_entry_activated(); + + layout { + row: 4; + column: 3; + column-span: 7; + } + } + + Label { + label: "SSL:"; + halign: end; + layout { + row: 5; + column: 0; + column-span: 3; + } + } + + Box { + orientation: horizontal; + Box { + valign: center; + orientation: vertical; + Switch ssl_switch {} + } + layout { + row: 5; + column: 3; + } + } } Box { - orientation: horizontal; - Box { - valign: center; - orientation: vertical; - Switch ssl_switch {} - } - layout { - row: 5; - column: 3; + + margin-top: 20; + margin-bottom: 10; + + Label status_label { + label: ""; + halign: start; + hexpand: true; } - } - } - - Box { - margin-top: 20; - margin-bottom: 10; - - Label status_label { - label: ""; - halign: start; - hexpand: true; - } + Box { - Box { + spacing: 8; - spacing: 8; + Spinner spinner { + + } - Spinner spinner { - + Button connect_btn { + styles ["suggested-action"] + label: "Connect"; + clicked => $on_connect_clicked(); + } + } } - Button connect_btn { - styles ["suggested-action"] - label: "Connect"; - clicked => $on_connect_clicked(); - } } } - } - } + }; } menu primary_menu { + section { + item { + label: _("_New Window"); + action: "app.new-window"; + } + } + section { + item { + label: _("_Import Connections"); + action: "app.import"; + } + + item { + label: _("_Export Connections"); + action: "app.export"; + } + } + section { item { label: _("_Preferences"); diff --git a/res/gtk/connection-recent.blp b/res/gtk/connection-recent.blp index 5d86e82..70312ad 100644 --- a/res/gtk/connection-recent.blp +++ b/res/gtk/connection-recent.blp @@ -20,21 +20,7 @@ template $PsequelConnectionSidebar : Gtk.Box { spacing: 4; hexpand: true; halign: end; - - Button { - styles ["flat", "big-icon", "linked"] - icon-name: "document-export-symbolic"; - tooltip-text: "Import Connection"; - clicked => $on_import_connection(); - } - Button { - styles ["flat", "big-icon", "linked"] - icon-name: "document-import-symbolic"; - tooltip-text: "Export Connection"; - clicked => $on_export_connection(); - } - Button { tooltip-text: "Add new connection"; @@ -42,13 +28,6 @@ template $PsequelConnectionSidebar : Gtk.Box { icon-name: "plus-large-symbolic"; clicked => $on_add_connection(); } - - Button { - tooltip-text: "Remove selected connection"; - styles ["flat"] - icon-name: "minus-large-symbolic"; - clicked => $on_remove_btn_clicked(); - } } } diff --git a/res/gtk/query-view.blp b/res/gtk/query-view.blp index 37a64de..896e3d5 100644 --- a/res/gtk/query-view.blp +++ b/res/gtk/query-view.blp @@ -270,6 +270,12 @@ template $PsequelQueryView : Adw.Bin { menu primary_menu { section { + + item { + label: _("_New Window"); + action: "app.new-window"; + } + item { label: _("_Preferences"); action: "app.preferences"; diff --git a/src/application.vala b/src/application.vala index a061dc1..563fa8f 100644 --- a/src/application.vala +++ b/src/application.vala @@ -28,6 +28,7 @@ namespace Psequel { private PreferencesWindow preference; + private AppSignals app_signals; public Application () { Object (application_id: "me.ppvan.psequel", flags: ApplicationFlags.DEFAULT_FLAGS); @@ -37,19 +38,18 @@ namespace Psequel { ActionEntry[] action_entries = { { "about", this.on_about_action }, { "preferences", this.on_preferences_action }, + { "new-window", this.on_new_window }, { "quit", this.quit } }; this.add_action_entries (action_entries, this); - this.set_accels_for_action ("app.quit", {"q"}); + this.set_accels_for_action ("app.quit", { "q" }); } public override void activate () { base.activate (); - var win = this.active_window; - if (win == null) { - win = new Psequel.Window (this); - } - win.present (); + + var window = new_window (); + window.present (); } public override void startup () { @@ -71,9 +71,10 @@ namespace Psequel { return_if_reached (); } - query_service = new QueryService (background); + app_signals = new AppSignals (); + app.app_signals = app_signals; + // query_service = new QueryService (background); table_list = new ObservableArrayList (); - signals = new AppSignals (); load_user_data (); }; @@ -103,6 +104,7 @@ namespace Psequel { /* register needed types, allow me to ref a template inside a template */ private static void ensure_types () { + typeof (WindowSignals).ensure (); typeof (Psequel.ConnectionView).ensure (); typeof (Psequel.ConnectionSidebar).ensure (); typeof (Psequel.ConnectionForm).ensure (); @@ -138,6 +140,12 @@ namespace Psequel { about.present (); } + private void on_new_window () { + var window = new_window (); + window.present (); + } + + private void on_preferences_action () { if (this.preference == null) { @@ -149,5 +157,16 @@ namespace Psequel { } this.preference.present (); } + + private Window new_window () { + var signals = new WindowSignals (); + var window = new Window (this); + var query_service = new QueryService (ResourceManager.instance ().background); + window.signals = (owned)signals; + window.query_service = (owned)query_service; + app_signals.window_ready (); + + return window; + } } } \ No newline at end of file diff --git a/src/models/utils.vala b/src/models/utils.vala index f11e68f..02f2db3 100644 --- a/src/models/utils.vala +++ b/src/models/utils.vala @@ -183,4 +183,16 @@ namespace Psequel { assert_not_reached (); } } + + public Window get_parrent_window (Gtk.Widget widget) { + var window = widget.get_root (); + + if (window is Gtk.Window) { + return (Window) window; + } else { + warning ("Widget %s root is not a window", widget.name); + + assert_not_reached (); + } + } } \ No newline at end of file diff --git a/src/services/query_service.vala b/src/services/query_service.vala index 95cb59f..ff4cc9c 100644 --- a/src/services/query_service.vala +++ b/src/services/query_service.vala @@ -121,7 +121,6 @@ namespace Psequel { public async Relation exec_query_params (string query, Variant[] params) throws PsequelError { - debug (params[0].get_string ()); var result = yield exec_query_params_internal (query, params); diff --git a/src/services/resource_manager.vala b/src/services/resource_manager.vala index 3e80007..1f9af37 100644 --- a/src/services/resource_manager.vala +++ b/src/services/resource_manager.vala @@ -6,10 +6,7 @@ namespace Psequel { public class ResourceManager : Object { - /** - * Application specific signals. - */ - public AppSignals signals; + public AppSignals app_signals; /** * Recent connections info in last sessions. diff --git a/src/services/signal.vala b/src/services/signal.vala index 7d37b0c..7f9a091 100644 --- a/src/services/signal.vala +++ b/src/services/signal.vala @@ -1,10 +1,15 @@ namespace Psequel { /** - * Application signals to comnicate between components. + * Window signals to comnicate between components. */ - public class AppSignals { + public class WindowSignals : Object { + /* Target connection in connection list changed */ + public signal void selection_changed (Connection conn); + + /* Request a db connection by click connect context menu */ + public signal void request_database_conn (Connection conn); /** * Emit when the table list changed. */ @@ -22,9 +27,24 @@ namespace Psequel { public signal void request_database (Connection conn); public signal void database_connected (); /** - * Should only init onces by the resource manager. Should be single on but i'm lazy + * Tied to one window and created by window. */ + public WindowSignals () { + Object (); + } + + public int number {get; set;} + } + + /** + * Application signals. + */ + public class AppSignals : Object { + + public signal void window_ready (); + public AppSignals () { + Object (); } } } \ No newline at end of file diff --git a/src/ui/connection/connection_form.vala b/src/ui/connection/connection_form.vala index 1796ceb..1adc7ed 100644 --- a/src/ui/connection/connection_form.vala +++ b/src/ui/connection/connection_form.vala @@ -1,12 +1,12 @@ namespace Psequel { [GtkTemplate (ui = "/me/ppvan/psequel/gtk/connection-form.ui")] - public class ConnectionForm : Gtk.Box { + public class ConnectionForm : Adw.Bin { BindingGroup binddings; private unowned QueryService query_service; - private unowned AppSignals signals; + private unowned WindowSignals signals; private Connection _conn; public Connection mapped_conn { @@ -26,9 +26,7 @@ namespace Psequel { } construct { - // init service - query_service = ResourceManager.instance ().query_service; - signals = ResourceManager.instance ().signals; + debug ("[CONTRUCT] %s", this.name); // Create group to maped the entry widget to connection data. this.binddings = new BindingGroup (); @@ -37,13 +35,25 @@ namespace Psequel { } private void setup_signals () { - ConnectionSidebar.signals.selection_changed.connect ((conn) => { - mapped_conn = conn; - }); - ConnectionSidebar.signals.request_database_conn.connect ((conn) => { - mapped_conn = conn; - connect_btn.clicked (); + + // signals can only be connected after the window is ready. + // because widget access window to get signals. + ResourceManager.instance ().app_signals.window_ready.connect (() => { + var window = get_parrent_window (this); + signals = window.signals; + + signals.selection_changed.connect ((conn) => { + mapped_conn = conn; + }); + + signals.request_database_conn.connect ((conn) => { + mapped_conn = conn; + connect_btn.clicked (); + }); + + query_service = window.query_service; }); + } private void set_up_bindings (BindingGroup group) { diff --git a/src/ui/connection/connection_recent.vala b/src/ui/connection/connection_recent.vala index be3c370..dd67018 100644 --- a/src/ui/connection/connection_recent.vala +++ b/src/ui/connection/connection_recent.vala @@ -5,21 +5,6 @@ namespace Psequel { [GtkTemplate (ui = "/me/ppvan/psequel/gtk/connection-recent.ui")] public class ConnectionSidebar : Gtk.Box { - /* Learn from Svelte ~ write store */ - public class InnerSignal { - /* Target connection in connection list changed */ - public signal void selection_changed (Connection conn); - - /* Request a db connection by click connect context menu */ - public signal void request_database_conn (Connection conn); - } - - public static InnerSignal signals; - - static construct { - signals = new InnerSignal (); - } - const ActionEntry[] ACTION_ENTRIES = { { "connect", on_connect_connection }, @@ -27,8 +12,18 @@ namespace Psequel { { "delete", on_remove_connection }, }; + // Import and export require access to this.model but also have to visible in app menu. + // So, it's on application action maps + const ActionEntry[] APP_ACTIONS = { + { "import", on_import_connection }, + { "export", on_export_connection }, + }; + private Application app; - private ObservableArrayList model; + + /* This is null ultil window ready event, which after contruct block */ + private unowned WindowSignals signals; + private unowned ObservableArrayList model; public ConnectionSidebar (ConnectionView parent) { @@ -36,23 +31,37 @@ namespace Psequel { } construct { + debug ("[CONTRUCT] %s", this.name); this.app = ResourceManager.instance ().app; - setup_bindings (); - setup_action (); + this.model = ResourceManager.instance ().recent_connections; + + setup_signals (); + } + + private void setup_signals () { + // signals can only be connected after the window is ready. + // because widget access window to get signals. + ResourceManager.instance ().app_signals.window_ready.connect (() => { + signals = get_parrent_window (this).signals; + this.setup_bindings (); + this.setup_action (); + }); } private void setup_action () { + debug ("setup_action"); + var action_group = new SimpleActionGroup (); action_group.add_action_entries (ACTION_ENTRIES, this); - insert_action_group ("conn", action_group); + this.insert_action_group ("conn", action_group); + + app.add_action_entries (APP_ACTIONS, this); } public void setup_bindings () { debug ("setup bindings"); - this.model = ResourceManager.instance ().recent_connections; - // Auto create a conn and focus it on first install. if (model.size == 0) { model.add (new Connection ()); @@ -79,7 +88,7 @@ namespace Psequel { return; } - // Emit connection changed for any one subcribe to it. + // Emit connection changed for any one subcribe to it. signals.selection_changed (conn_row.conn_data); debug ("mapped widget binding to another row"); @@ -97,12 +106,6 @@ namespace Psequel { conn_list.select_row (last_row); } - // On remove, remove selected connection and select pos - 1. - [GtkCallback] - public void on_remove_btn_clicked (Gtk.Button btn) { - remove_connection (); - } - private Gtk.ListBoxRow row_factory (Object item) { if (item is Connection) { @@ -115,14 +118,12 @@ namespace Psequel { } } - [GtkCallback] - private void on_import_connection (Gtk.Button btn) { + private void on_import_connection () { debug ("Importting connections"); open_file_dialog.begin ("Import Connections"); } - [GtkCallback] - private void on_export_connection (Gtk.Button btn) { + private void on_export_connection () { debug ("Exporting connections"); save_file_dialog.begin ("Export Connections"); } @@ -185,6 +186,12 @@ namespace Psequel { private async void open_file_dialog (string title = "Open File") { var filter = new Gtk.FileFilter (); filter.add_mime_type ("application/json"); + + var window = (Window) app.active_window; + + debug (this.name); + + var file_dialog = new Gtk.FileDialog () { modal = true, initial_folder = File.new_for_path (Environment.get_home_dir ()), @@ -194,7 +201,6 @@ namespace Psequel { }; uint8[] contents; - var window = (Window) app.active_window; try { var file = yield file_dialog.open (window, null); @@ -290,7 +296,6 @@ namespace Psequel { model.insert (dupp, pos + 1); } - private void request_connect_database () { var selected = conn_list.get_selected_row (); // Selection mode must be browse (only 1 selection) diff --git a/src/ui/connection/connection_view.vala b/src/ui/connection/connection_view.vala index fb92744..8938fd2 100644 --- a/src/ui/connection/connection_view.vala +++ b/src/ui/connection/connection_view.vala @@ -19,6 +19,7 @@ namespace Psequel { // Connect event. construct { + debug ("[CONTRUCT] %s", this.name); } diff --git a/src/ui/preferences_window.vala b/src/ui/preferences_window.vala index b609f62..1875e31 100644 --- a/src/ui/preferences_window.vala +++ b/src/ui/preferences_window.vala @@ -11,6 +11,7 @@ namespace Psequel { } construct { + debug ("[CONTRUCT] %s", this.name); settings = ResourceManager.instance ().settings; setup_binding (); defaults (); diff --git a/src/ui/query/query_editor.vala b/src/ui/query/query_editor.vala index 88fbb66..c74daf1 100644 --- a/src/ui/query/query_editor.vala +++ b/src/ui/query/query_editor.vala @@ -15,13 +15,20 @@ namespace Psequel { } construct { + debug ("[CONTRUCT] %s", this.name); debug ("Contruct view"); - query_service = ResourceManager.instance ().query_service; lang_manager = LanguageManager.get_default (); style_manager = StyleSchemeManager.get_default (); default_setttings (); + setup_signals (); + } + + private void setup_signals () { + ResourceManager.instance ().app_signals.window_ready.connect (() => { + query_service = get_parrent_window (this).query_service; + }); } diff --git a/src/ui/query/query_results.vala b/src/ui/query/query_results.vala index 153d6a9..554d287 100644 --- a/src/ui/query/query_results.vala +++ b/src/ui/query/query_results.vala @@ -19,7 +19,7 @@ namespace Psequel { } construct { - + debug ("[CONTRUCT] %s", this.name); stack.visible_child_name = EMPTY; spinner.spinning = false; model = new ObservableArrayList (); diff --git a/src/ui/query/query_view.vala b/src/ui/query/query_view.vala index e59345d..998f53b 100644 --- a/src/ui/query/query_view.vala +++ b/src/ui/query/query_view.vala @@ -11,14 +11,13 @@ namespace Psequel { public const string QUERY_EDITOR = "query-editor"; private unowned QueryService query_service; - private unowned AppSignals signals; + private unowned WindowSignals signals; private SchemaService schema_service; private ObservableArrayList schemas; private Schema _current_schema; - - private Schema current_schema { + public Schema current_schema { get { return _current_schema; } @@ -40,18 +39,14 @@ namespace Psequel { } construct { - query_service = ResourceManager.instance ().query_service; - signals = ResourceManager.instance ().signals; - - schema_service = new SchemaService (query_service); - schemas = new ObservableArrayList (); + debug ("[CONTRUCT] %s", this.name); var exp = new Gtk.PropertyExpression (typeof (Gtk.StringObject), null, "string"); tbname_filter = new Gtk.StringFilter (exp); vname_filter = new Gtk.StringFilter (exp); + setup_signals (); set_up_schema (); - connect_signals (); } @@ -71,8 +66,8 @@ namespace Psequel { var schema_list = yield schema_service.schema_list (); // Clear last item. - schema_dropdown.model = null; + schemas.clear (); for (int i = 0; i < schema_list.length; i++) { var cur_schema = yield schema_service.load_schema (schema_list[i]); @@ -153,23 +148,27 @@ namespace Psequel { this.schema_dropdown.set_model (schemas); } - private void connect_signals () { - // signals.table_list_changed.connect (() => { - // debug ("Handle table_list_changed."); - // reload_tables.begin (); - // }); + private void setup_signals () { + // signals can only be connected after the window is ready. + // because widget access window to get signals. + ResourceManager.instance ().app_signals.window_ready.connect (() => { + var window = get_parrent_window (this); - // signals.views_list_changed.connect (() => { - // debug ("Handle views_list_changed."); - // reload_views.begin (); - // }); + signals = window.signals; - signals.database_connected.connect (() => { - debug ("Handle database_connected."); - reload_schema.begin (); - }); + signals.database_connected.connect (() => { + debug ("Handle database_connected."); + reload_schema.begin (); + }); + + schema_dropdown.notify["selected"].connect (schema_changed); + + query_service = window.query_service; + debug ("Query: %p", query_service); - schema_dropdown.notify["selected"].connect (schema_changed); + schema_service = new SchemaService (query_service); + schemas = new ObservableArrayList (); + }); } [GtkCallback] @@ -234,9 +233,9 @@ namespace Psequel { var vname = current_schema.viewnames[row.get_index ()]; debug ("Emit view_selected"); - // Idle.add_once (() => { - // stack.visible_child_name = TABLE_DATA; - // }); + // Idle.add_once (() => { + // stack.visible_child_name = TABLE_DATA; + // }); signals.view_selected_changed (vname.string); } diff --git a/src/ui/query/table_data_view.vala b/src/ui/query/table_data_view.vala index 69d7604..b8e8b74 100644 --- a/src/ui/query/table_data_view.vala +++ b/src/ui/query/table_data_view.vala @@ -4,7 +4,7 @@ namespace Psequel { [GtkTemplate (ui = "/me/ppvan/psequel/gtk/table-data-view.ui")] public class TableData : Gtk.Box { - private AppSignals signals; + private unowned WindowSignals signals; private QueryService query_service; private ObservableArrayList model; @@ -20,13 +20,13 @@ namespace Psequel { } construct { - query_service = ResourceManager.instance ().query_service; - signals = ResourceManager.instance ().signals; + debug ("[CONTRUCT] %s", this.name); model = new ObservableArrayList (); var setting = ResourceManager.instance ().settings; setting.bind ("query-limit", this, "query-limit", SettingsBindFlags.DEFAULT); - connect_signal (); + + setup_signals (); } @@ -69,24 +69,34 @@ namespace Psequel { status_label.label = @"Rows $begin - $end"; } - private void connect_signal () { - this.signals.table_selected_changed.connect ((tbname) => { - this.tbname = tbname; - this.filter_entry.set_text (""); - load_data.begin (schema.name, tbname); - }); + private void setup_signals () { - this.signals.view_selected_changed.connect ((vname) => { - this.tbname = vname; - this.filter_entry.set_text (""); - load_data.begin (schema.name, vname); - }); + // signals can only be connected after the window is ready. + // because widget access window to get signals. + ResourceManager.instance ().app_signals.window_ready.connect (() => { + signals = get_parrent_window (this).signals; + + signals.table_selected_changed.connect ((tbname) => { + this.tbname = tbname; + this.filter_entry.set_text (""); + load_data.begin (schema.name, tbname); + }); - this.signals.schema_changed.connect ((schema) => { - this.schema = schema; + signals.view_selected_changed.connect ((vname) => { + this.tbname = vname; + this.filter_entry.set_text (""); + load_data.begin (schema.name, vname); + }); + + signals.schema_changed.connect ((schema) => { + this.schema = schema; + }); + + query_service = get_parrent_window (this).query_service; }); } + [GtkCallback] private void filter_query (Gtk.Button btn) { var where_clause = filter_entry.get_text (); diff --git a/src/ui/table/table_cols.vala b/src/ui/table/table_cols.vala index 8464ae2..7c391b2 100644 --- a/src/ui/table/table_cols.vala +++ b/src/ui/table/table_cols.vala @@ -45,6 +45,7 @@ namespace Psequel { } construct { + debug ("[CONTRUCT] %s", this.name); setup_name_col (); setup_datatype_col (); setup_nullable_col (); diff --git a/src/ui/table/table_fk.vala b/src/ui/table/table_fk.vala index 879f9a2..cbe2279 100644 --- a/src/ui/table/table_fk.vala +++ b/src/ui/table/table_fk.vala @@ -44,6 +44,7 @@ namespace Psequel { } construct { + debug ("[CONTRUCT] %s", this.name); setup_name_col (); setup_table_columns_col (); setup_fk_tbname_col (); diff --git a/src/ui/table/table_index.vala b/src/ui/table/table_index.vala index 0de9be3..bfa57ec 100644 --- a/src/ui/table/table_index.vala +++ b/src/ui/table/table_index.vala @@ -44,6 +44,7 @@ namespace Psequel { } construct { + debug ("[CONTRUCT] %s", this.name); setup_name_col (); setup_indexcolumns_col (); setup_indextype_col (); diff --git a/src/ui/table/table_structure_view.vala b/src/ui/table/table_structure_view.vala index 6ebbd89..affbda3 100644 --- a/src/ui/table/table_structure_view.vala +++ b/src/ui/table/table_structure_view.vala @@ -3,7 +3,7 @@ namespace Psequel { [GtkTemplate (ui = "/me/ppvan/psequel/gtk/table-structure-view.ui")] public class TableStructure : Gtk.Box { - private AppSignals signals; + private unowned WindowSignals signals; private Schema _cur_schema; @@ -30,24 +30,34 @@ namespace Psequel { } construct { - signals = ResourceManager.instance ().signals; + debug ("[CONTRUCT] %s", this.name); + setup_signals (); + } + private void setup_signals () { - signals.schema_changed.connect ((schema) => { - debug ("%s", schema.name); - cur_schema = schema; + // signals can only be connected after the window is ready. + // because widget access window to get signals. + ResourceManager.instance ().app_signals.window_ready.connect (() => { + signals = get_parrent_window (this).signals; - columns.table = " "; - indexes.table = " "; - foreign_keys.table = " "; + signals.schema_changed.connect ((schema) => { + debug ("%s", schema.name); + cur_schema = schema; + + columns.table = " "; + indexes.table = " "; + foreign_keys.table = " "; + }); + + signals.table_selected_changed.connect ((tbname) => { + debug ("Handle table_selected_changed: %s", tbname); + columns.table = tbname; + indexes.table = tbname; + foreign_keys.table = tbname; + }); }); - signals.table_selected_changed.connect ((tbname) => { - debug ("Handle table_selected_changed: %s", tbname); - columns.table = tbname; - indexes.table = tbname; - foreign_keys.table = tbname; - }); } diff --git a/src/ui/window.vala b/src/ui/window.vala index b97ef87..235229d 100644 --- a/src/ui/window.vala +++ b/src/ui/window.vala @@ -25,13 +25,16 @@ namespace Psequel { [GtkTemplate (ui = "/me/ppvan/psequel/gtk/window.ui")] public class Window : Adw.ApplicationWindow { - private AppSignals signals; + public WindowSignals signals {get; set; default = null;} + public QueryService query_service {get; set; default = null;} public Window (Application app) { Object (application: app); } construct { + debug ("[CONTRUCT] %s", this.name); + with (ResourceManager.instance ()) { settings.bind ("window-width", this, "default-width", SettingsBindFlags.DEFAULT); @@ -39,10 +42,16 @@ namespace Psequel { "default-height", SettingsBindFlags.DEFAULT); } - this.signals = ResourceManager.instance ().signals; + setup_signals (); + } - signals.database_connected.connect (() => { - navigate_to (Views.QUERY); + private void setup_signals () { + // signals can only be connected after the window is ready. + // because widget access window to get signals. + ResourceManager.instance ().app_signals.window_ready.connect (() => { + signals.database_connected.connect (() => { + navigate_to (Views.QUERY); + }); }); } @@ -50,6 +59,9 @@ namespace Psequel { * Navigate to the stack view. */ public void navigate_to (string view_name) { + + debug ("OK"); + var child = stack.get_child_by_name (view_name); if (child == null) { @@ -58,7 +70,6 @@ namespace Psequel { debug ("navigate_to %s", view_name); stack.visible_child = child; } - } public void add_toast (Adw.Toast toast) {