233 lines
7.1 KiB
C
233 lines
7.1 KiB
C
|
/* ide-run-button.c
|
||
|
*
|
||
|
* Copyright 2016-2019 Christian Hergert <chergert@redhat.com>
|
||
|
*
|
||
|
* This program is free software: you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation, either version 3 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*
|
||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||
|
*/
|
||
|
|
||
|
#define G_LOG_DOMAIN "ide-run-button"
|
||
|
|
||
|
#include "config.h"
|
||
|
|
||
|
#include <dazzle.h>
|
||
|
#include <glib/gi18n.h>
|
||
|
#include <libide-foundry.h>
|
||
|
|
||
|
#include "ide-gui-global.h"
|
||
|
#include "ide-run-button.h"
|
||
|
|
||
|
#include "ide-run-manager-private.h"
|
||
|
|
||
|
struct _IdeRunButton
|
||
|
{
|
||
|
GtkBox parent_instance;
|
||
|
|
||
|
GtkButton *button;
|
||
|
GtkImage *button_image;
|
||
|
DzlMenuButton *menu_button;
|
||
|
GtkShortcutsShortcut *run_shortcut;
|
||
|
GtkLabel *run_tooltip_message;
|
||
|
DzlShortcutTooltip *tooltip;
|
||
|
|
||
|
char *run_handler_icon_name;
|
||
|
};
|
||
|
|
||
|
G_DEFINE_FINAL_TYPE (IdeRunButton, ide_run_button, GTK_TYPE_BOX)
|
||
|
|
||
|
static void
|
||
|
ide_run_button_handler_set (IdeRunButton *self,
|
||
|
GParamSpec *pspec,
|
||
|
IdeRunManager *run_manager)
|
||
|
{
|
||
|
const GList *list;
|
||
|
const GList *iter;
|
||
|
const gchar *handler;
|
||
|
|
||
|
g_assert (IDE_IS_RUN_BUTTON (self));
|
||
|
g_assert (IDE_IS_RUN_MANAGER (run_manager));
|
||
|
|
||
|
handler = ide_run_manager_get_handler (run_manager);
|
||
|
list = _ide_run_manager_get_handlers (run_manager);
|
||
|
|
||
|
for (iter = list; iter; iter = iter->next)
|
||
|
{
|
||
|
const IdeRunHandlerInfo *info = iter->data;
|
||
|
|
||
|
if (g_strcmp0 (info->id, handler) == 0)
|
||
|
{
|
||
|
self->run_handler_icon_name = g_strdup (info->icon_name);
|
||
|
g_object_set (self->button_image, "icon-name", info->icon_name, NULL);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
on_run_busy_state_changed_cb (IdeRunButton *self,
|
||
|
GParamSpec *pspec,
|
||
|
IdeRunManager *run_manager)
|
||
|
{
|
||
|
const char *icon_name;
|
||
|
const char *action_name;
|
||
|
|
||
|
g_assert (IDE_IS_RUN_BUTTON (self));
|
||
|
g_assert (IDE_IS_RUN_MANAGER (run_manager));
|
||
|
|
||
|
if (!ide_run_manager_get_busy (run_manager))
|
||
|
{
|
||
|
icon_name = self->run_handler_icon_name;
|
||
|
action_name = "run-manager.run";
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
icon_name = "builder-run-stop-symbolic";
|
||
|
action_name = "run-manager.stop";
|
||
|
}
|
||
|
|
||
|
g_object_set (self->button_image, "icon-name", icon_name, NULL);
|
||
|
gtk_actionable_set_action_name (GTK_ACTIONABLE (self->button), action_name);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ide_run_button_load (IdeRunButton *self,
|
||
|
IdeContext *context)
|
||
|
{
|
||
|
IdeRunManager *run_manager;
|
||
|
|
||
|
g_assert (IDE_IS_RUN_BUTTON (self));
|
||
|
g_assert (IDE_IS_CONTEXT (context));
|
||
|
|
||
|
run_manager = ide_run_manager_from_context (context);
|
||
|
|
||
|
g_signal_connect_object (run_manager,
|
||
|
"notify::busy",
|
||
|
G_CALLBACK (on_run_busy_state_changed_cb),
|
||
|
self,
|
||
|
G_CONNECT_SWAPPED);
|
||
|
|
||
|
g_signal_connect_object (run_manager,
|
||
|
"notify::handler",
|
||
|
G_CALLBACK (ide_run_button_handler_set),
|
||
|
self,
|
||
|
G_CONNECT_SWAPPED);
|
||
|
|
||
|
ide_run_button_handler_set (self, NULL, run_manager);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ide_run_button_context_set (GtkWidget *widget,
|
||
|
IdeContext *context)
|
||
|
{
|
||
|
IdeRunButton *self = (IdeRunButton *)widget;
|
||
|
|
||
|
g_assert (IDE_IS_RUN_BUTTON (self));
|
||
|
g_assert (!context || IDE_IS_CONTEXT (context));
|
||
|
|
||
|
if (context != NULL)
|
||
|
ide_run_button_load (self, context);
|
||
|
}
|
||
|
|
||
|
static gboolean
|
||
|
ide_run_button_query_tooltip (IdeRunButton *self,
|
||
|
gint x,
|
||
|
gint y,
|
||
|
gboolean keyboard_tooltip,
|
||
|
GtkTooltip *tooltip,
|
||
|
GtkButton *button)
|
||
|
{
|
||
|
IdeRunManager *run_manager;
|
||
|
const GList *list;
|
||
|
const GList *iter;
|
||
|
const gchar *handler;
|
||
|
IdeContext *context;
|
||
|
|
||
|
g_assert (IDE_IS_RUN_BUTTON (self));
|
||
|
g_assert (GTK_IS_TOOLTIP (tooltip));
|
||
|
g_assert (GTK_IS_BUTTON (button));
|
||
|
|
||
|
context = ide_widget_get_context (GTK_WIDGET (self));
|
||
|
run_manager = ide_run_manager_from_context (context);
|
||
|
handler = ide_run_manager_get_handler (run_manager);
|
||
|
list = _ide_run_manager_get_handlers (run_manager);
|
||
|
|
||
|
if (ide_run_manager_get_busy (run_manager))
|
||
|
{
|
||
|
gtk_tooltip_set_text (tooltip, _("Stop running"));
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
for (iter = list; iter; iter = iter->next)
|
||
|
{
|
||
|
const IdeRunHandlerInfo *info = iter->data;
|
||
|
|
||
|
if (g_strcmp0 (info->id, handler) == 0)
|
||
|
{
|
||
|
gboolean enabled;
|
||
|
/* Figure out if the run action is enabled. If it
|
||
|
* is not, then we should inform the user that
|
||
|
* the project cannot be run yet because the
|
||
|
* build pipeline is not yet configured. */
|
||
|
g_action_group_query_action (G_ACTION_GROUP (run_manager),
|
||
|
"run",
|
||
|
&enabled,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL);
|
||
|
|
||
|
if (!enabled)
|
||
|
{
|
||
|
gtk_tooltip_set_custom (tooltip, GTK_WIDGET (self->run_tooltip_message));
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/* The shortcut tooltip will set this up after us */
|
||
|
dzl_shortcut_tooltip_set_accel (self->tooltip, info->accel);
|
||
|
dzl_shortcut_tooltip_set_title (self->tooltip, info->title);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ide_run_button_class_init (IdeRunButtonClass *klass)
|
||
|
{
|
||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||
|
|
||
|
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/libide-gui/ui/ide-run-button.ui");
|
||
|
gtk_widget_class_bind_template_child (widget_class, IdeRunButton, button);
|
||
|
gtk_widget_class_bind_template_child (widget_class, IdeRunButton, button_image);
|
||
|
gtk_widget_class_bind_template_child (widget_class, IdeRunButton, menu_button);
|
||
|
gtk_widget_class_bind_template_child (widget_class, IdeRunButton, run_shortcut);
|
||
|
gtk_widget_class_bind_template_child (widget_class, IdeRunButton, run_tooltip_message);
|
||
|
gtk_widget_class_bind_template_child (widget_class, IdeRunButton, tooltip);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ide_run_button_init (IdeRunButton *self)
|
||
|
{
|
||
|
gtk_widget_init_template (GTK_WIDGET (self));
|
||
|
|
||
|
g_signal_connect_object (self->button,
|
||
|
"query-tooltip",
|
||
|
G_CALLBACK (ide_run_button_query_tooltip),
|
||
|
self,
|
||
|
G_CONNECT_SWAPPED);
|
||
|
|
||
|
ide_widget_set_context_handler (self, ide_run_button_context_set);
|
||
|
}
|