Commit 7820cd7f authored by Christian Hergert's avatar Christian Hergert
Browse files

build-tools: start on a build panel

parent 5d6305dd
......@@ -228,6 +228,7 @@ dnl ***********************************************************************
dnl Check for supported plugins
dnl ***********************************************************************
m4_include([plugins/autotools/configure.ac])
m4_include([plugins/build-tools/configure.ac])
m4_include([plugins/c-pack/configure.ac])
m4_include([plugins/clang/configure.ac])
m4_include([plugins/command-bar/configure.ac])
......@@ -484,6 +485,7 @@ echo ""
echo " Plugins"
echo ""
echo " Autotools ............................ : ${enable_autotools_plugin}"
echo " Build Tools .......................... : ${enable_build_tools_plugin}"
echo " C Language Pack ...................... : ${enable_c_pack_plugin}"
echo " Clang ................................ : ${enable_clang_plugin}"
echo " Command Bar .......................... : ${enable_command_bar_plugin}"
......
......@@ -175,3 +175,10 @@ editortweak box.indentation button {
editortweak box.indentation button label {
padding: 2px 12px 2px 12px;
}
box.build-status {
background-image: none;
background-color: shade(@theme_bg_color, 1.05);
}
......@@ -196,7 +196,7 @@ ide_build_system_new_finish (GAsyncResult *result,
/**
* ide_build_system_get_builder:
* @system: The #IdeBuildSystem to perform the build.
* @config: The configuration options for the build.
* @config: (nullable): The configuration options for the build.
* @device: The #IdeDevice the result should be able to run on.
*
* This function should return an #IdeBuilder that can be used to perform a
......@@ -213,11 +213,14 @@ ide_build_system_get_builder (IdeBuildSystem *system,
{
IdeBuildSystemInterface *iface;
IdeBuilder *ret = NULL;
g_autoptr(GKeyFile) local = NULL;
g_return_val_if_fail (IDE_IS_BUILD_SYSTEM (system), NULL);
g_return_val_if_fail (config, NULL);
g_return_val_if_fail (IDE_IS_DEVICE (device), NULL);
if (config == NULL)
config = local = g_key_file_new ();
iface = IDE_BUILD_SYSTEM_GET_IFACE (system);
if (iface->get_builder)
......
......@@ -23,6 +23,11 @@
G_DEFINE_ABSTRACT_TYPE (IdeBuilder, ide_builder, IDE_TYPE_OBJECT)
/**
* ide_builder_build_async:
* @result: (out) (transfer none): A location for an #IdeBuildResult.
*
*/
void
ide_builder_build_async (IdeBuilder *builder,
IdeBuilderBuildFlags flags,
......
SUBDIRS = \
autotools \
build-tools \
clang \
command-bar \
c-pack \
......
if ENABLE_BUILD_TOOLS_PLUGIN
DISTCLEANFILES =
BUILT_SOURCES =
CLEANFILES =
EXTRA_DIST = $(plugin_DATA)
plugindir = $(libdir)/gnome-builder/plugins
plugin_LTLIBRARIES = libbuild-tools-plugin.la
dist_plugin_DATA = build-tools.plugin
libbuild_tools_plugin_la_SOURCES = \
gbp-build-panel.c \
gbp-build-panel.h \
gbp-build-panel-row.c \
gbp-build-panel-row.h \
gbp-build-plugin.c \
gbp-build-workbench-addin.c \
gbp-build-workbench-addin.h \
$(NULL)
nodist_libbuild_tools_plugin_la_SOURCES = \
gbp-build-resources.c \
gbp-build-resources.h
libbuild_tools_plugin_la_CFLAGS = \
$(LIBIDE_CFLAGS) \
$(OPTIMIZE_CFLAGS) \
-I$(top_srcdir)/libide \
-I$(top_srcdir)/contrib/egg \
$(NULL)
libbuild_tools_plugin_la_LDFLAGS = \
$(OPTIMIZE_LDFLAGS) \
-avoid-version \
-module \
-export-regex peas_register_types \
$(NULL)
glib_resources_c = gbp-build-resources.c
glib_resources_h = gbp-build-resources.h
glib_resources_xml = gbp-build-tools.gresource.xml
glib_resources_namespace = gbp_build_tools
include $(top_srcdir)/build/autotools/Makefile.am.gresources
include $(top_srcdir)/plugins/Makefile.plugin
endif
-include $(top_srcdir)/git.mk
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/builder/plugins/build-tools-plugin">
</gresource>
</gresources>
[Plugin]
Module=build-tools-plugin
Name=Build Tools
Description=Build panel and command line tools
Authors=Christian Hergert <christian@hergert.me>
Copyright=Copyright © 2015 Christian Hergert
Depends=editor
Hidden=true
Builtin=true
# --enable-build-tools-plugin=yes/no
AC_ARG_ENABLE([build-tools-plugin],
[AS_HELP_STRING([--enable-build-tools-plugin=@<:@yes/no@:>@],
[Build with support for build tools and panels.])],
[enable_build_tools_plugin=$enableval],
[enable_build_tools_plugin=yes])
# for if ENABLE_BUILD_TOOLS_PLUGIN in Makefile.am
AM_CONDITIONAL(ENABLE_BUILD_TOOLS_PLUGIN, test x$enable_build_tools_plugin != xno)
# Ensure our makefile is generated by autoconf
AC_CONFIG_FILES([plugins/build-tools/Makefile])
/* gbp-build-panel-row.c
*
* Copyright (C) 2015 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/>.
*/
#include <ide.h>
#include "gbp-build-panel-row.h"
struct _GbpBuildPanelRow
{
GtkListBoxRow parent_instance;
GtkLabel *file_label;
GtkLabel *message_label;
IdeDiagnostic *diagnostic;
};
G_DEFINE_TYPE (GbpBuildPanelRow, gbp_build_panel_row, GTK_TYPE_LIST_BOX_ROW)
enum {
PROP_0,
PROP_DIAGNOSTIC,
LAST_PROP
};
static GParamSpec *properties [LAST_PROP];
static void
gbp_build_panel_row_set_diagnostic (GbpBuildPanelRow *self,
IdeDiagnostic *diagnostic)
{
gchar *text;
g_return_if_fail (GBP_IS_BUILD_PANEL_ROW (self));
g_return_if_fail (diagnostic != NULL);
text = ide_diagnostic_get_text_for_display (diagnostic);
gtk_label_set_label (self->message_label, text);
g_free (text);
}
static void
gbp_build_panel_row_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GbpBuildPanelRow *self = GBP_BUILD_PANEL_ROW(object);
switch (prop_id)
{
case PROP_DIAGNOSTIC:
g_value_set_boxed (value, self->diagnostic);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
}
static void
gbp_build_panel_row_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GbpBuildPanelRow *self = GBP_BUILD_PANEL_ROW(object);
switch (prop_id)
{
case PROP_DIAGNOSTIC:
gbp_build_panel_row_set_diagnostic (self, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
}
static void
gbp_build_panel_row_class_init (GbpBuildPanelRowClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gbp_build_panel_row_get_property;
object_class->set_property = gbp_build_panel_row_set_property;
properties [PROP_DIAGNOSTIC] =
g_param_spec_boxed ("diagnostic",
"Diagnostic",
"Diagnostic",
IDE_TYPE_DIAGNOSTIC,
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, LAST_PROP, properties);
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/builder/plugins/build-tools-plugin/gbp-build-panel-row.ui");
gtk_widget_class_set_css_name (widget_class, "buildpanelrow");
gtk_widget_class_bind_template_child (widget_class, GbpBuildPanelRow, file_label);
gtk_widget_class_bind_template_child (widget_class, GbpBuildPanelRow, message_label);
}
static void
gbp_build_panel_row_init (GbpBuildPanelRow *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
}
/* gbp-build-panel-row.h
*
* Copyright (C) 2015 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/>.
*/
#pragma once
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GBP_TYPE_BUILD_PANEL_ROW (gbp_build_panel_row_get_type())
G_DECLARE_FINAL_TYPE (GbpBuildPanelRow, gbp_build_panel_row, GBP, BUILD_PANEL_ROW, GObject)
G_END_DECLS
<interface>
<template class="GbpBuildPanelRow" parent="GtkListBoxRow">
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="visible">true</property>
<child>
<object class="GtkLabel" id="file_label">
<property name="visible">true</property>
<property name="xalign">0.0</property>
</object>
</child>
<child>
<object class="GtkLabel" id="message_label">
<property name="visible">true</property>
<property name="xalign">0.0</property>
</object>
</child>
</object>
</child>
</template>
</interface>
/* gbp-build-panel.c
*
* Copyright (C) 2015 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/>.
*/
#include <glib/gi18n.h>
#include "egg-binding-group.h"
#include "egg-signal-group.h"
#include "gbp-build-panel.h"
#include "gbp-build-panel-row.h"
struct _GbpBuildPanel
{
GtkBin parent_instance;
IdeBuildResult *result;
EggSignalGroup *signals;
EggBindingGroup *bindings;
IdeDevice *device;
GtkListBox *diagnostics;
GtkRevealer *status_revealer;
GtkLabel *status_label;
GtkLabel *running_time_label;
GtkMenuButton *device_button;
GtkLabel *device_label;
GtkListBox *devices;
GtkPopover *device_popover;
guint running_time_source;
};
G_DEFINE_TYPE (GbpBuildPanel, gbp_build_panel, GTK_TYPE_BIN)
enum {
PROP_0,
PROP_DEVICE,
PROP_DEVICE_MANAGER,
PROP_RESULT,
LAST_PROP
};
static GParamSpec *properties [LAST_PROP];
static GtkWidget *
create_device_row (gpointer item,
gpointer user_data)
{
GtkListBoxRow *row;
IdeDevice *device = item;
const gchar *type;
const gchar *name;
GtkLabel *label;
gchar *str;
g_assert (IDE_IS_DEVICE (device));
row = g_object_new (GTK_TYPE_LIST_BOX_ROW,
"visible", TRUE,
NULL);
g_object_set_data_full (G_OBJECT (row),
"IDE_DEVICE_ID",
g_strdup (ide_device_get_id (device)),
g_free);
name = ide_device_get_display_name (device);
type = ide_device_get_system_type (device);
str = g_strdup_printf ("%s (%s)", name, type);
label = g_object_new (GTK_TYPE_LABEL,
"label", str,
"xalign", 0.0f,
"visible", TRUE,
NULL);
gtk_container_add (GTK_CONTAINER (row), GTK_WIDGET (label));
g_free (str);
return GTK_WIDGET (row);
}
static void
gbp_build_panel_set_device (GbpBuildPanel *self,
IdeDevice *device)
{
g_return_if_fail (GBP_IS_BUILD_PANEL (self));
g_return_if_fail (!device || IDE_IS_DEVICE (device));
if (g_set_object (&self->device, device))
{
const gchar *name = NULL;
if (device != NULL)
name = ide_device_get_display_name (device);
gtk_label_set_label (self->device_label, name);
}
}
static void
gbp_build_panel_set_device_manager (GbpBuildPanel *self,
IdeDeviceManager *device_manager)
{
g_return_if_fail (GBP_IS_BUILD_PANEL (self));
g_return_if_fail (!device_manager || IDE_IS_DEVICE_MANAGER (device_manager));
gtk_list_box_bind_model (self->devices,
G_LIST_MODEL (device_manager),
create_device_row, NULL, NULL);
}
void
gbp_build_panel_add_error (GbpBuildPanel *self,
const gchar *message)
{
g_return_if_fail (GBP_IS_BUILD_PANEL (self));
g_return_if_fail (message != NULL);
}
static void
gbp_build_panel_diagnostic (GbpBuildPanel *self,
IdeDiagnostic *diagnostic,
IdeBuildResult *result)
{
GtkWidget *row;
g_assert (GBP_IS_BUILD_PANEL (self));
g_assert (diagnostic != NULL);
g_assert (IDE_IS_BUILD_RESULT (result));
row = g_object_new (GBP_TYPE_BUILD_PANEL_ROW,
"diagnostic", diagnostic,
"visible", TRUE,
NULL);
gtk_container_add (GTK_CONTAINER (self->diagnostics), row);
}
static gboolean
gbp_build_panel_update_running_time (GbpBuildPanel *self)
{
g_assert (GBP_IS_BUILD_PANEL (self));
if (self->result != NULL)
{
GTimeSpan span;
guint hours;
guint minutes;
guint seconds;
gchar *text;
span = ide_build_result_get_running_time (self->result);
hours = span / G_TIME_SPAN_HOUR;
minutes = (span % G_TIME_SPAN_HOUR) / G_TIME_SPAN_MINUTE;
seconds = (span % G_TIME_SPAN_MINUTE) / G_TIME_SPAN_SECOND;
text = g_strdup_printf ("%02u:%02u:%02u", hours, minutes, seconds);
gtk_label_set_label (self->running_time_label, text);
g_free (text);
}
return G_SOURCE_CONTINUE;
}
static void
gbp_build_panel_connect (GbpBuildPanel *self,
IdeBuildResult *result)
{
g_return_if_fail (GBP_IS_BUILD_PANEL (self));
g_return_if_fail (IDE_IS_BUILD_RESULT (result));
g_return_if_fail (self->result == NULL);
self->result = g_object_ref (result);
egg_signal_group_set_target (self->signals, result);
egg_binding_group_set_source (self->bindings, result);
if (ide_build_result_get_running (result))
{
gtk_label_set_label (self->running_time_label, NULL);
self->running_time_source =
g_timeout_add_seconds (1, (GSourceFunc)gbp_build_panel_update_running_time, self);
}
gtk_revealer_set_reveal_child (self->status_revealer, TRUE);
}
static void
gbp_build_panel_disconnect (GbpBuildPanel *self)
{
g_return_if_fail (GBP_IS_BUILD_PANEL (self));
gtk_revealer_set_reveal_child (self->status_revealer, FALSE);
egg_signal_group_set_target (self->signals, NULL);
egg_binding_group_set_source (self->bindings, NULL);
ide_clear_source (&self->running_time_source);
g_clear_object (&self->result);
}
void
gbp_build_panel_set_result (GbpBuildPanel *self,
IdeBuildResult *result)
{
g_return_if_fail (GBP_IS_BUILD_PANEL (self));
g_return_if_fail (!result || IDE_IS_BUILD_RESULT (result));
if (result != self->result)
{
if (self->result)
gbp_build_panel_disconnect (self);
if (result)
gbp_build_panel_connect (self, result);
}
}
static void
gbp_build_panel_notify_running (GbpBuildPanel *self,
GParamSpec *pspec,
IdeBuildResult *result)
{
g_assert (GBP_IS_BUILD_PANEL (self));
g_assert (IDE_IS_BUILD_RESULT (result));
if (!ide_build_result_get_running (result))
ide_clear_source (&self->running_time_source);
gbp_build_panel_update_running_time (self);
}
static void
gbp_build_panel_device_activated (GbpBuildPanel *self,
GtkListBoxRow *row,
GtkListBox *list_box)
{
const gchar *id;
g_assert (GBP_IS_BUILD_PANEL (self));
g_assert (GTK_IS_LIST_BOX_ROW (row));
g_assert (GTK_IS_LIST_BOX (list_box));
if ((id = g_object_get_data (G_OBJECT (row), "IDE_DEVICE_ID")))
ide_widget_action (GTK_WIDGET (self),
"build-tools", "device",
g_variant_new_string (id));
gtk_widget_hide (GTK_WIDGET (self->device_popover));
}
static void
gbp_build_panel_destroy (GtkWidget *widget)
{
GbpBuildPanel *self = (GbpBuildPanel *)widget;
if (self->result)
gbp_build_panel_disconnect (self);
g_clear_object