1 /* gbp-todo-workspace-addin.c
2 *
3 * Copyright 2017-2019 Christian Hergert <chergert@redhat.com>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: GPL-3.0-or-later
19 */
20
21 #define G_LOG_DOMAIN "gbp-todo-workspace-addin"
22
23 #include <libide-editor.h>
24 #include <glib/gi18n.h>
25
26 #include "gbp-todo-workspace-addin.h"
27 #include "gbp-todo-panel.h"
28
29 struct _GbpTodoWorkspaceAddin
30 {
31 GObject parent_instance;
32
33 GbpTodoPanel *panel;
34 GbpTodoModel *model;
35 GCancellable *cancellable;
36 GFile *workdir;
37
38 guint has_presented : 1;
39 guint is_global_mining : 1;
40 };
41
42 static void
gbp_todo_workspace_addin_mine_cb(GObject * object,GAsyncResult * result,gpointer user_data)43 gbp_todo_workspace_addin_mine_cb (GObject *object,
44 GAsyncResult *result,
45 gpointer user_data)
46 {
47 GbpTodoModel *model = (GbpTodoModel *)object;
48 g_autoptr(GbpTodoWorkspaceAddin) self = user_data;
49 g_autoptr(GError) error = NULL;
50
51 g_assert (GBP_IS_TODO_WORKSPACE_ADDIN (self));
52 g_assert (G_IS_ASYNC_RESULT (result));
53 g_assert (GBP_IS_TODO_MODEL (model));
54
55 /* We only do this once, safe to re-clear on per-file mining */
56 self->is_global_mining = FALSE;
57
58 if (!gbp_todo_model_mine_finish (model, result, &error))
59 g_warning ("todo: %s", error->message);
60
61 if (self->panel != NULL)
62 gbp_todo_panel_make_ready (self->panel);
63 }
64
65 static void
gbp_todo_workspace_addin_presented_cb(GbpTodoWorkspaceAddin * self,GbpTodoPanel * panel)66 gbp_todo_workspace_addin_presented_cb (GbpTodoWorkspaceAddin *self,
67 GbpTodoPanel *panel)
68 {
69 g_assert (GBP_IS_TODO_WORKSPACE_ADDIN (self));
70 g_assert (GBP_IS_TODO_PANEL (panel));
71
72 if (self->has_presented)
73 return;
74
75 self->has_presented = TRUE;
76 self->is_global_mining = TRUE;
77
78 gbp_todo_model_mine_async (self->model,
79 self->workdir,
80 self->cancellable,
81 gbp_todo_workspace_addin_mine_cb,
82 g_object_ref (self));
83 }
84
85 static void
gbp_todo_workspace_addin_buffer_saved(GbpTodoWorkspaceAddin * self,IdeBuffer * buffer,IdeBufferManager * bufmgr)86 gbp_todo_workspace_addin_buffer_saved (GbpTodoWorkspaceAddin *self,
87 IdeBuffer *buffer,
88 IdeBufferManager *bufmgr)
89 {
90 GFile *file;
91
92 g_assert (GBP_IS_TODO_WORKSPACE_ADDIN (self));
93 g_assert (self->model != NULL);
94 g_assert (IDE_IS_BUFFER (buffer));
95 g_assert (IDE_IS_BUFFER_MANAGER (bufmgr));
96
97 if (!self->has_presented || self->is_global_mining)
98 return;
99
100 file = ide_buffer_get_file (buffer);
101 gbp_todo_model_mine_async (self->model,
102 file,
103 self->cancellable,
104 gbp_todo_workspace_addin_mine_cb,
105 g_object_ref (self));
106 }
107
108 static void
gbp_todo_workspace_addin_load(IdeWorkspaceAddin * addin,IdeWorkspace * workspace)109 gbp_todo_workspace_addin_load (IdeWorkspaceAddin *addin,
110 IdeWorkspace *workspace)
111 {
112 GbpTodoWorkspaceAddin *self = (GbpTodoWorkspaceAddin *)addin;
113 IdeEditorSidebar *sidebar;
114 IdeBufferManager *bufmgr;
115 IdeSurface *editor;
116 IdeContext *context;
117 IdeVcs *vcs;
118 GFile *workdir;
119
120 g_assert (GBP_IS_TODO_WORKSPACE_ADDIN (self));
121 g_assert (IDE_IS_WORKSPACE (workspace));
122
123 self->cancellable = g_cancellable_new ();
124
125 context = ide_workspace_get_context (workspace);
126 vcs = ide_vcs_from_context (context);
127 workdir = ide_vcs_get_workdir (vcs);
128 bufmgr = ide_buffer_manager_from_context (context);
129 editor = ide_workspace_get_surface_by_name (workspace, "editor");
130 sidebar = ide_editor_surface_get_sidebar (IDE_EDITOR_SURFACE (editor));
131
132 self->workdir = g_object_ref (workdir);
133
134 g_signal_connect_object (bufmgr,
135 "buffer-saved",
136 G_CALLBACK (gbp_todo_workspace_addin_buffer_saved),
137 self,
138 G_CONNECT_SWAPPED);
139
140 self->model = gbp_todo_model_new (vcs);
141
142 self->panel = g_object_new (GBP_TYPE_TODO_PANEL,
143 "model", self->model,
144 "visible", TRUE,
145 NULL);
146 g_signal_connect_object (self->panel,
147 "presented",
148 G_CALLBACK (gbp_todo_workspace_addin_presented_cb),
149 self,
150 G_CONNECT_SWAPPED);
151 g_signal_connect (self->panel,
152 "destroy",
153 G_CALLBACK (gtk_widget_destroyed),
154 &self->panel);
155 ide_editor_sidebar_add_section (sidebar,
156 "todo",
157 _("TODO/FIXMEs"),
158 "emblem-ok-symbolic",
159 NULL, NULL,
160 GTK_WIDGET (self->panel),
161 200);
162 }
163
164 static void
gbp_todo_workspace_addin_unload(IdeWorkspaceAddin * addin,IdeWorkspace * workspace)165 gbp_todo_workspace_addin_unload (IdeWorkspaceAddin *addin,
166 IdeWorkspace *workspace)
167 {
168 GbpTodoWorkspaceAddin *self = (GbpTodoWorkspaceAddin *)addin;
169 IdeBufferManager *bufmgr;
170 IdeContext *context;
171
172 g_assert (GBP_IS_TODO_WORKSPACE_ADDIN (self));
173 g_assert (IDE_IS_WORKSPACE (workspace));
174
175 g_cancellable_cancel (self->cancellable);
176 g_clear_object (&self->cancellable);
177
178 context = ide_widget_get_context (GTK_WIDGET (workspace));
179 bufmgr = ide_buffer_manager_from_context (context);
180
181 g_signal_handlers_disconnect_by_func (bufmgr,
182 G_CALLBACK (gbp_todo_workspace_addin_buffer_saved),
183 self);
184
185 if (self->panel != NULL)
186 gtk_widget_destroy (GTK_WIDGET (self->panel));
187
188 g_assert (self->panel == NULL);
189
190 g_clear_object (&self->model);
191 g_clear_object (&self->workdir);
192 }
193
194 static void
workspace_addin_iface_init(IdeWorkspaceAddinInterface * iface)195 workspace_addin_iface_init (IdeWorkspaceAddinInterface *iface)
196 {
197 iface->load = gbp_todo_workspace_addin_load;
198 iface->unload = gbp_todo_workspace_addin_unload;
199 }
200
G_DEFINE_FINAL_TYPE_WITH_CODE(GbpTodoWorkspaceAddin,gbp_todo_workspace_addin,G_TYPE_OBJECT,G_IMPLEMENT_INTERFACE (IDE_TYPE_WORKSPACE_ADDIN,workspace_addin_iface_init))201 G_DEFINE_FINAL_TYPE_WITH_CODE (GbpTodoWorkspaceAddin, gbp_todo_workspace_addin, G_TYPE_OBJECT,
202 G_IMPLEMENT_INTERFACE (IDE_TYPE_WORKSPACE_ADDIN,
203 workspace_addin_iface_init))
204
205 static void
206 gbp_todo_workspace_addin_class_init (GbpTodoWorkspaceAddinClass *klass)
207 {
208 }
209
210 static void
gbp_todo_workspace_addin_init(GbpTodoWorkspaceAddin * self)211 gbp_todo_workspace_addin_init (GbpTodoWorkspaceAddin *self)
212 {
213 }
214