2005-11-22 12:26:26 +00:00
|
|
|
/*
|
|
|
|
* build.c - this file is part of Geany, a fast and lightweight IDE
|
|
|
|
*
|
2007-01-14 17:36:42 +00:00
|
|
|
* Copyright 2005-2007 Enrico Tröger <enrico.troeger@uvena.de>
|
2007-01-14 17:09:17 +00:00
|
|
|
* Copyright 2006-2007 Nick Treleaven <nick.treleaven@btinternet.com>
|
2005-11-22 12:26:26 +00:00
|
|
|
*
|
|
|
|
* 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 2 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, write to the Free Software
|
2006-06-13 19:37:21 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2005-11-22 12:26:26 +00:00
|
|
|
*
|
2006-01-03 12:39:25 +00:00
|
|
|
* $Id$
|
2005-11-22 12:26:26 +00:00
|
|
|
*/
|
|
|
|
|
2007-02-24 11:41:56 +00:00
|
|
|
/*
|
|
|
|
* Build commands and menu items.
|
|
|
|
*/
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-07-20 21:16:12 +00:00
|
|
|
#include "geany.h"
|
2005-11-22 12:26:26 +00:00
|
|
|
#include "build.h"
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <errno.h>
|
2007-04-16 15:58:34 +00:00
|
|
|
#include <glib/gstdio.h>
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
#ifdef G_OS_UNIX
|
|
|
|
# include <sys/types.h>
|
|
|
|
# include <sys/wait.h>
|
2006-11-14 01:27:12 +00:00
|
|
|
# include <signal.h>
|
2005-11-22 12:26:26 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "support.h"
|
|
|
|
#include "utils.h"
|
2006-09-08 13:40:30 +00:00
|
|
|
#include "ui_utils.h"
|
2005-11-22 12:26:26 +00:00
|
|
|
#include "dialogs.h"
|
|
|
|
#include "msgwindow.h"
|
2006-06-13 19:37:21 +00:00
|
|
|
#include "document.h"
|
2006-10-18 19:35:42 +00:00
|
|
|
#include "keybindings.h"
|
2006-12-10 21:29:04 +00:00
|
|
|
#include "vte.h"
|
2007-03-01 11:38:14 +00:00
|
|
|
#include "project.h"
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
|
2006-11-11 18:51:33 +00:00
|
|
|
BuildInfo build_info = {GBO_COMPILE, 0, NULL, GEANY_FILETYPES_ALL, NULL};
|
|
|
|
|
2006-11-29 10:29:34 +00:00
|
|
|
static struct
|
|
|
|
{
|
|
|
|
GPid pid;
|
|
|
|
gint file_type_id;
|
|
|
|
} run_info = {0, GEANY_FILETYPES_ALL};
|
|
|
|
|
2007-03-03 13:14:41 +00:00
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
static const gchar RUN_SCRIPT_CMD[] = "./geany_run_script.bat";
|
|
|
|
#else
|
|
|
|
static const gchar RUN_SCRIPT_CMD[] = "./geany_run_script.sh";
|
|
|
|
#endif
|
|
|
|
|
2006-11-11 18:51:33 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
LATEX_CMD_TO_DVI,
|
|
|
|
LATEX_CMD_TO_PDF,
|
|
|
|
LATEX_CMD_VIEW_DVI,
|
|
|
|
LATEX_CMD_VIEW_PDF
|
|
|
|
};
|
2006-10-16 14:15:04 +00:00
|
|
|
|
2006-11-30 15:42:52 +00:00
|
|
|
static BuildMenuItems default_menu_items =
|
2006-12-08 15:50:10 +00:00
|
|
|
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
2006-11-30 15:42:52 +00:00
|
|
|
static BuildMenuItems latex_menu_items =
|
2006-12-08 15:50:10 +00:00
|
|
|
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
2006-11-30 15:42:52 +00:00
|
|
|
|
2006-10-16 14:15:04 +00:00
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
static gboolean build_iofunc(GIOChannel *ioc, GIOCondition cond, gpointer data);
|
2007-03-03 16:54:04 +00:00
|
|
|
static gboolean build_create_shellscript(const gchar *fname, const gchar *cmd, gboolean autoclose);
|
2007-03-01 11:38:14 +00:00
|
|
|
static GPid build_spawn_cmd(gint idx, const gchar *cmd, const gchar *dir);
|
2006-11-11 18:51:33 +00:00
|
|
|
static void on_make_target_dialog_response(GtkDialog *dialog, gint response, gpointer user_data);
|
|
|
|
static void on_make_target_entry_activate(GtkEntry *entry, gpointer user_data);
|
|
|
|
static void set_stop_button(gboolean stop);
|
|
|
|
static void build_exit_cb(GPid child_pid, gint status, gpointer user_data);
|
2006-11-29 10:29:34 +00:00
|
|
|
static void run_exit_cb(GPid child_pid, gint status, gpointer user_data);
|
2007-03-24 12:40:20 +00:00
|
|
|
static void
|
|
|
|
on_build_arguments_activate (GtkMenuItem *menuitem,
|
|
|
|
gpointer user_data);
|
2006-11-29 10:29:34 +00:00
|
|
|
|
2006-11-17 17:49:16 +00:00
|
|
|
#ifndef G_OS_WIN32
|
2006-11-29 10:29:34 +00:00
|
|
|
static void kill_process(GPid *pid);
|
2006-11-17 17:49:16 +00:00
|
|
|
#endif
|
2006-04-27 18:06:35 +00:00
|
|
|
|
2006-12-08 15:50:10 +00:00
|
|
|
|
2006-10-16 14:41:57 +00:00
|
|
|
void build_finalize()
|
|
|
|
{
|
|
|
|
g_free(build_info.dir);
|
|
|
|
g_free(build_info.custom_target);
|
2006-11-30 15:42:52 +00:00
|
|
|
|
|
|
|
if (default_menu_items.menu != NULL && GTK_IS_WIDGET(default_menu_items.menu))
|
|
|
|
gtk_widget_destroy(default_menu_items.menu);
|
|
|
|
if (latex_menu_items.menu != NULL && GTK_IS_WIDGET(latex_menu_items.menu))
|
|
|
|
gtk_widget_destroy(latex_menu_items.menu);
|
2006-10-16 14:41:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-24 12:40:20 +00:00
|
|
|
static GPid build_compile_tex_file(gint idx, gint mode)
|
2006-01-11 18:44:52 +00:00
|
|
|
{
|
2007-02-28 17:24:22 +00:00
|
|
|
const gchar *cmd = NULL;
|
2006-01-11 18:44:52 +00:00
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
if (idx < 0 || doc_list[idx].file_name == NULL) return (GPid) 1;
|
2006-06-29 14:00:09 +00:00
|
|
|
|
2006-11-11 18:51:33 +00:00
|
|
|
if (mode == LATEX_CMD_TO_DVI)
|
|
|
|
{
|
2007-02-28 17:24:22 +00:00
|
|
|
cmd = doc_list[idx].file_type->programs->compiler;
|
2006-11-11 18:51:33 +00:00
|
|
|
build_info.type = GBO_COMPILE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-02-28 17:24:22 +00:00
|
|
|
cmd = doc_list[idx].file_type->programs->linker;
|
2006-11-11 18:51:33 +00:00
|
|
|
build_info.type = GBO_BUILD;
|
|
|
|
}
|
2006-01-11 18:44:52 +00:00
|
|
|
|
2007-03-01 11:38:14 +00:00
|
|
|
return build_spawn_cmd(idx, cmd, NULL);
|
2006-01-11 18:44:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-24 12:40:20 +00:00
|
|
|
static GPid build_view_tex_file(gint idx, gint mode)
|
2006-01-18 12:11:44 +00:00
|
|
|
{
|
2006-11-11 18:51:33 +00:00
|
|
|
gchar **argv, **term_argv;
|
2006-04-27 18:06:35 +00:00
|
|
|
gchar *executable = NULL;
|
|
|
|
gchar *view_file = NULL;
|
|
|
|
gchar *locale_filename = NULL;
|
|
|
|
gchar *cmd_string = NULL;
|
|
|
|
gchar *locale_cmd_string = NULL;
|
2006-11-11 18:51:33 +00:00
|
|
|
gchar *locale_term_cmd;
|
|
|
|
gint term_argv_len, i;
|
2006-01-18 12:11:44 +00:00
|
|
|
GError *error = NULL;
|
|
|
|
struct stat st;
|
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
if (idx < 0 || doc_list[idx].file_name == NULL) return (GPid) 1;
|
|
|
|
|
2006-11-29 10:29:34 +00:00
|
|
|
run_info.file_type_id = GEANY_FILETYPES_LATEX;
|
2006-11-11 18:51:33 +00:00
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
executable = utils_remove_ext_from_filename(doc_list[idx].file_name);
|
2006-11-11 18:51:33 +00:00
|
|
|
view_file = g_strconcat(executable, (mode == LATEX_CMD_VIEW_DVI) ? ".dvi" : ".pdf", NULL);
|
2006-04-27 18:06:35 +00:00
|
|
|
|
|
|
|
// try convert in locale for stat()
|
2006-08-13 09:07:10 +00:00
|
|
|
locale_filename = utils_get_locale_from_utf8(view_file);
|
2006-01-18 12:11:44 +00:00
|
|
|
|
|
|
|
// check wether view_file exists
|
2007-04-16 15:58:34 +00:00
|
|
|
if (g_stat(locale_filename, &st) != 0)
|
2006-01-18 12:11:44 +00:00
|
|
|
{
|
|
|
|
msgwin_status_add(_("Failed to view %s (make sure it is already compiled)"), view_file);
|
2007-03-03 13:14:41 +00:00
|
|
|
utils_free_pointers(executable, view_file, locale_filename, NULL);
|
2006-11-11 18:51:33 +00:00
|
|
|
|
2006-01-18 12:11:44 +00:00
|
|
|
return (GPid) 1;
|
|
|
|
}
|
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
// replace %f and %e in the run_cmd string
|
2006-11-11 18:51:33 +00:00
|
|
|
cmd_string = g_strdup((mode == LATEX_CMD_VIEW_DVI) ?
|
|
|
|
g_strdup(doc_list[idx].file_type->programs->run_cmd) :
|
2006-04-27 18:06:35 +00:00
|
|
|
g_strdup(doc_list[idx].file_type->programs->run_cmd2));
|
|
|
|
cmd_string = utils_str_replace(cmd_string, "%f", view_file);
|
|
|
|
cmd_string = utils_str_replace(cmd_string, "%e", executable);
|
2006-06-29 14:00:09 +00:00
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
// try convert in locale
|
2006-08-13 09:07:10 +00:00
|
|
|
locale_cmd_string = utils_get_locale_from_utf8(cmd_string);
|
2006-04-27 18:06:35 +00:00
|
|
|
|
2006-11-11 18:51:33 +00:00
|
|
|
/* get the terminal path */
|
|
|
|
locale_term_cmd = utils_get_locale_from_utf8(app->tools_term_cmd);
|
|
|
|
// split the term_cmd, so arguments will work too
|
|
|
|
term_argv = g_strsplit(locale_term_cmd, " ", -1);
|
|
|
|
term_argv_len = g_strv_length(term_argv);
|
2006-09-22 12:05:18 +00:00
|
|
|
|
2006-11-11 18:51:33 +00:00
|
|
|
// check that terminal exists (to prevent misleading error messages)
|
|
|
|
if (term_argv[0] != NULL)
|
|
|
|
{
|
|
|
|
gchar *tmp = term_argv[0];
|
|
|
|
// g_find_program_in_path checks tmp exists and is executable
|
|
|
|
term_argv[0] = g_find_program_in_path(tmp);
|
|
|
|
g_free(tmp);
|
|
|
|
}
|
|
|
|
if (term_argv[0] == NULL)
|
|
|
|
{
|
|
|
|
msgwin_status_add(
|
|
|
|
_("Could not find terminal '%s' "
|
|
|
|
"(check path for Terminal tool setting in Preferences)"), app->tools_term_cmd);
|
|
|
|
|
2007-01-14 17:09:17 +00:00
|
|
|
utils_free_pointers(executable, view_file, locale_filename, cmd_string, locale_cmd_string,
|
2007-03-03 13:14:41 +00:00
|
|
|
locale_term_cmd, NULL);
|
2006-11-11 18:51:33 +00:00
|
|
|
g_strfreev(term_argv);
|
|
|
|
return (GPid) 1;
|
|
|
|
}
|
2006-01-18 12:11:44 +00:00
|
|
|
|
2007-03-03 13:14:41 +00:00
|
|
|
// (RUN_SCRIPT_CMD should be ok in UTF8 without converting in locale because it contains no umlauts)
|
2007-03-03 16:54:04 +00:00
|
|
|
if (! build_create_shellscript(RUN_SCRIPT_CMD, locale_cmd_string, TRUE))
|
2006-11-11 18:51:33 +00:00
|
|
|
{
|
2007-03-05 12:13:09 +00:00
|
|
|
msgwin_status_add(_("Failed to execute \"%s\" (start-script could not be created)"),
|
2007-03-05 12:44:02 +00:00
|
|
|
executable);
|
2007-01-14 17:09:17 +00:00
|
|
|
utils_free_pointers(executable, view_file, locale_filename, cmd_string, locale_cmd_string,
|
2007-03-05 12:44:02 +00:00
|
|
|
locale_term_cmd, NULL);
|
2006-11-11 18:51:33 +00:00
|
|
|
g_strfreev(term_argv);
|
|
|
|
return (GPid) 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
argv = g_new0(gchar *, term_argv_len + 3);
|
|
|
|
for (i = 0; i < term_argv_len; i++)
|
|
|
|
{
|
|
|
|
argv[i] = g_strdup(term_argv[i]);
|
|
|
|
}
|
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
// command line arguments for cmd.exe
|
|
|
|
argv[term_argv_len ] = g_strdup("/Q /C");
|
2007-03-03 13:14:41 +00:00
|
|
|
argv[term_argv_len + 1] = g_path_get_basename(RUN_SCRIPT_CMD);
|
2006-11-11 18:51:33 +00:00
|
|
|
#else
|
|
|
|
argv[term_argv_len ] = g_strdup("-e");
|
2007-03-03 13:14:41 +00:00
|
|
|
argv[term_argv_len + 1] = g_strdup(RUN_SCRIPT_CMD);
|
2006-09-11 11:13:36 +00:00
|
|
|
#endif
|
2006-11-11 18:51:33 +00:00
|
|
|
argv[term_argv_len + 2] = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (! g_spawn_async_with_pipes(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
|
2006-11-29 10:29:34 +00:00
|
|
|
NULL, NULL, &(run_info.pid), NULL, NULL, NULL, &error))
|
2006-01-18 12:11:44 +00:00
|
|
|
{
|
|
|
|
geany_debug("g_spawn_async_with_pipes() failed: %s", error->message);
|
|
|
|
msgwin_status_add(_("Process failed (%s)"), error->message);
|
2006-04-27 18:06:35 +00:00
|
|
|
|
2007-01-14 17:09:17 +00:00
|
|
|
utils_free_pointers(executable, view_file, locale_filename, cmd_string, locale_cmd_string,
|
2007-03-03 13:14:41 +00:00
|
|
|
locale_term_cmd, NULL);
|
2006-01-18 12:11:44 +00:00
|
|
|
g_strfreev(argv);
|
2006-11-11 18:51:33 +00:00
|
|
|
g_strfreev(term_argv);
|
2006-01-18 12:11:44 +00:00
|
|
|
g_error_free(error);
|
|
|
|
error = NULL;
|
|
|
|
return (GPid) 0;
|
|
|
|
}
|
|
|
|
|
2006-11-29 10:29:34 +00:00
|
|
|
if (run_info.pid > 0)
|
2006-11-11 18:51:33 +00:00
|
|
|
{
|
|
|
|
//setpgid(0, getppid());
|
2006-11-29 10:29:34 +00:00
|
|
|
g_child_watch_add(run_info.pid, (GChildWatchFunc) run_exit_cb, NULL);
|
|
|
|
build_menu_update(idx);
|
2006-11-11 18:51:33 +00:00
|
|
|
}
|
|
|
|
|
2007-01-14 17:09:17 +00:00
|
|
|
utils_free_pointers(executable, view_file, locale_filename, cmd_string, locale_cmd_string,
|
2007-03-03 13:14:41 +00:00
|
|
|
locale_term_cmd, NULL);
|
2006-01-18 12:11:44 +00:00
|
|
|
g_strfreev(argv);
|
2006-11-11 18:51:33 +00:00
|
|
|
g_strfreev(term_argv);
|
2006-04-27 18:06:35 +00:00
|
|
|
|
2006-11-29 10:29:34 +00:00
|
|
|
return run_info.pid;
|
2006-01-18 12:11:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-02-28 17:24:22 +00:00
|
|
|
// get curfile.o in locale encoding from document::file_name
|
2006-10-16 14:15:04 +00:00
|
|
|
static gchar *get_object_filename(gint idx)
|
|
|
|
{
|
|
|
|
gchar *locale_filename, *short_file, *noext, *object_file;
|
|
|
|
|
|
|
|
if (doc_list[idx].file_name == NULL) return NULL;
|
|
|
|
|
|
|
|
locale_filename = utils_get_locale_from_utf8(doc_list[idx].file_name);
|
|
|
|
|
|
|
|
short_file = g_path_get_basename(locale_filename);
|
|
|
|
g_free(locale_filename);
|
|
|
|
|
|
|
|
noext = utils_remove_ext_from_filename(short_file);
|
|
|
|
g_free(short_file);
|
|
|
|
|
|
|
|
object_file = g_strdup_printf("%s.o", noext);
|
|
|
|
g_free(noext);
|
2006-10-24 18:02:38 +00:00
|
|
|
|
2006-10-16 14:15:04 +00:00
|
|
|
return object_file;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-24 12:40:20 +00:00
|
|
|
static GPid build_make_file(gint idx, gint build_opts)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2007-02-28 17:24:22 +00:00
|
|
|
GString *cmdstr;
|
2007-03-01 11:38:14 +00:00
|
|
|
const gchar *dir = NULL;
|
2007-02-28 17:24:22 +00:00
|
|
|
GPid pid;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
if (idx < 0 || doc_list[idx].file_name == NULL) return (GPid) 1;
|
2006-06-29 14:00:09 +00:00
|
|
|
|
2007-02-28 17:24:22 +00:00
|
|
|
cmdstr = g_string_new(app->tools_make_cmd);
|
|
|
|
g_string_append_c(cmdstr, ' ');
|
2006-10-24 18:02:38 +00:00
|
|
|
|
2006-10-16 14:15:04 +00:00
|
|
|
if (build_opts == GBO_MAKE_OBJECT)
|
|
|
|
{
|
2007-02-28 17:24:22 +00:00
|
|
|
gchar *tmp;
|
|
|
|
|
|
|
|
build_info.type = build_opts;
|
|
|
|
tmp = get_object_filename(idx);
|
|
|
|
g_string_append(cmdstr, tmp);
|
|
|
|
g_free(tmp);
|
2006-10-16 14:15:04 +00:00
|
|
|
}
|
2006-10-16 14:41:57 +00:00
|
|
|
else if (build_opts == GBO_MAKE_CUSTOM && build_info.custom_target)
|
2007-02-28 17:24:22 +00:00
|
|
|
{
|
2006-11-11 18:51:33 +00:00
|
|
|
build_info.type = GBO_MAKE_CUSTOM;
|
2007-02-28 17:24:22 +00:00
|
|
|
g_string_append(cmdstr, build_info.custom_target);
|
2007-03-01 11:38:14 +00:00
|
|
|
dir = project_get_make_dir();
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
2006-10-16 14:15:04 +00:00
|
|
|
else // GBO_MAKE_ALL
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2006-11-11 18:51:33 +00:00
|
|
|
build_info.type = GBO_MAKE_ALL;
|
2007-02-28 17:24:22 +00:00
|
|
|
g_string_append(cmdstr, "all");
|
2007-03-01 11:38:14 +00:00
|
|
|
dir = project_get_make_dir();
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
2007-03-01 11:38:14 +00:00
|
|
|
pid = build_spawn_cmd(idx, cmdstr->str, dir); // if dir is NULL, idx filename is used
|
2007-02-28 17:24:22 +00:00
|
|
|
g_string_free(cmdstr, TRUE);
|
|
|
|
return pid;
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-24 12:40:20 +00:00
|
|
|
static GPid build_compile_file(gint idx)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2007-02-28 17:24:22 +00:00
|
|
|
const gchar *cmd;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
if (idx < 0 || doc_list[idx].file_name == NULL) return (GPid) 1;
|
|
|
|
|
2007-02-28 17:24:22 +00:00
|
|
|
cmd = doc_list[idx].file_type->programs->compiler;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-11-11 18:51:33 +00:00
|
|
|
build_info.type = GBO_COMPILE;
|
2007-03-01 11:38:14 +00:00
|
|
|
return build_spawn_cmd(idx, cmd, NULL);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-24 12:40:20 +00:00
|
|
|
static GPid build_link_file(gint idx)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2007-02-28 17:24:22 +00:00
|
|
|
GString *cmdstr;
|
|
|
|
GPid pid;
|
2006-04-27 18:06:35 +00:00
|
|
|
gchar *executable = NULL;
|
|
|
|
gchar *object_file, *locale_filename;
|
2005-11-22 12:26:26 +00:00
|
|
|
struct stat st, st2;
|
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
if (idx < 0 || doc_list[idx].file_name == NULL) return (GPid) 1;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-08-13 09:07:10 +00:00
|
|
|
locale_filename = utils_get_locale_from_utf8(doc_list[idx].file_name);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
executable = utils_remove_ext_from_filename(locale_filename);
|
2007-02-03 17:01:44 +00:00
|
|
|
// check for filename extension and abort if filename doesn't have one
|
|
|
|
if (utils_str_equal(locale_filename, executable))
|
|
|
|
{
|
|
|
|
msgwin_status_add(_("Command stopped because the current file has no extension."));
|
|
|
|
utils_beep();
|
2007-02-03 17:49:03 +00:00
|
|
|
utils_free_pointers(locale_filename, executable, NULL);
|
2007-02-03 17:01:44 +00:00
|
|
|
return (GPid) 1;
|
|
|
|
}
|
|
|
|
|
2005-11-22 12:26:26 +00:00
|
|
|
object_file = g_strdup_printf("%s.o", executable);
|
|
|
|
|
|
|
|
// check wether object file (file.o) exists
|
2007-04-16 15:58:34 +00:00
|
|
|
if (g_stat(object_file, &st) == 0)
|
2005-11-22 12:26:26 +00:00
|
|
|
{ // check wether src is newer than object file
|
2007-04-16 15:58:34 +00:00
|
|
|
if (g_stat(locale_filename, &st2) == 0)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
|
|
|
if (st2.st_mtime > st.st_mtime)
|
|
|
|
{
|
2006-04-27 18:06:35 +00:00
|
|
|
// set object_file to NULL, so the source file will be used for linking,
|
|
|
|
// more precisely then we compile and link instead of just linking
|
2005-11-22 12:26:26 +00:00
|
|
|
g_free(object_file);
|
|
|
|
object_file = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-10-25 14:38:48 +00:00
|
|
|
dialogs_show_msgbox(GTK_MESSAGE_ERROR,
|
2006-11-11 18:51:33 +00:00
|
|
|
_("Something very strange is occurred, could not stat %s (%s)."),
|
|
|
|
doc_list[idx].file_name, g_strerror(errno));
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-28 17:24:22 +00:00
|
|
|
cmdstr = g_string_new(doc_list[idx].file_type->programs->linker);
|
|
|
|
g_string_append_c(cmdstr, ' ');
|
|
|
|
|
2006-07-09 14:41:53 +00:00
|
|
|
if (doc_list[idx].file_type->id == GEANY_FILETYPES_D)
|
|
|
|
{ // the dmd compiler needs -of instead of -o and it accepts no whitespace after -of
|
|
|
|
gchar *tmp = g_path_get_basename(executable);
|
|
|
|
|
2007-02-28 17:24:22 +00:00
|
|
|
g_string_append(cmdstr, "-of");
|
|
|
|
g_string_append(cmdstr, tmp);
|
2006-07-09 14:41:53 +00:00
|
|
|
g_free(tmp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-02-28 17:24:22 +00:00
|
|
|
gchar *tmp = g_path_get_basename(executable);
|
|
|
|
|
|
|
|
g_string_append(cmdstr, "-o");
|
|
|
|
g_string_append_c(cmdstr, ' ');
|
|
|
|
g_string_append(cmdstr, tmp);
|
|
|
|
g_free(tmp);
|
2006-07-09 14:41:53 +00:00
|
|
|
}
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
g_free(executable);
|
|
|
|
g_free(object_file);
|
2006-04-27 18:06:35 +00:00
|
|
|
g_free(locale_filename);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-11-11 18:51:33 +00:00
|
|
|
build_info.type = GBO_BUILD;
|
2007-03-01 11:38:14 +00:00
|
|
|
pid = build_spawn_cmd(idx, cmdstr->str, NULL);
|
2007-02-28 17:24:22 +00:00
|
|
|
g_string_free(cmdstr, TRUE);
|
|
|
|
return pid;
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-23 12:55:37 +00:00
|
|
|
/* If linking, clear all error indicators in all documents.
|
|
|
|
* Otherwise, just clear error indicators in document idx. */
|
|
|
|
static void clear_errors(gint idx)
|
|
|
|
{
|
|
|
|
switch (build_info.type)
|
|
|
|
{
|
|
|
|
case GBO_COMPILE:
|
|
|
|
case GBO_MAKE_OBJECT:
|
|
|
|
document_clear_indicators(idx);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GBO_BUILD:
|
|
|
|
case GBO_MAKE_ALL:
|
|
|
|
case GBO_MAKE_CUSTOM:
|
|
|
|
{
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
for (i = 0; i < doc_array->len; i++)
|
|
|
|
{
|
|
|
|
if (doc_list[i].is_valid)
|
|
|
|
document_clear_indicators(i);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-01 11:38:14 +00:00
|
|
|
/* dir is the UTF-8 working directory to run cmd in. It can be NULL to use the
|
|
|
|
* idx document directory */
|
|
|
|
static GPid build_spawn_cmd(gint idx, const gchar *cmd, const gchar *dir)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
|
|
|
GError *error = NULL;
|
2007-02-01 14:42:25 +00:00
|
|
|
gchar **argv;
|
2005-11-22 12:26:26 +00:00
|
|
|
gchar *working_dir;
|
2006-04-27 18:06:35 +00:00
|
|
|
gchar *utf8_working_dir;
|
2005-11-22 12:26:26 +00:00
|
|
|
gchar *cmd_string;
|
2006-04-27 18:06:35 +00:00
|
|
|
gchar *utf8_cmd_string;
|
|
|
|
gchar *locale_filename;
|
|
|
|
gchar *executable;
|
|
|
|
gchar *tmp;
|
2005-11-22 12:26:26 +00:00
|
|
|
gint stdout_fd;
|
|
|
|
gint stderr_fd;
|
|
|
|
|
2007-02-01 14:42:25 +00:00
|
|
|
g_return_val_if_fail(DOC_IDX_VALID(idx), (GPid) 1);
|
2006-08-14 15:02:52 +00:00
|
|
|
|
2007-04-23 12:55:37 +00:00
|
|
|
clear_errors(idx);
|
2006-06-29 14:00:09 +00:00
|
|
|
|
2006-08-13 09:07:10 +00:00
|
|
|
locale_filename = utils_get_locale_from_utf8(doc_list[idx].file_name);
|
2006-04-27 18:06:35 +00:00
|
|
|
executable = utils_remove_ext_from_filename(locale_filename);
|
2006-06-29 14:00:09 +00:00
|
|
|
|
2007-02-28 17:24:22 +00:00
|
|
|
cmd_string = g_strdup(cmd);
|
2006-04-27 18:06:35 +00:00
|
|
|
// replace %f and %e in the command string
|
|
|
|
tmp = g_path_get_basename(locale_filename);
|
|
|
|
cmd_string = utils_str_replace(cmd_string, "%f", tmp);
|
|
|
|
g_free(tmp);
|
|
|
|
tmp = g_path_get_basename(executable);
|
|
|
|
cmd_string = utils_str_replace(cmd_string, "%e", tmp);
|
|
|
|
g_free(tmp);
|
|
|
|
g_free(executable);
|
2006-06-29 14:00:09 +00:00
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
argv = g_new0(gchar *, 4);
|
2005-11-22 12:26:26 +00:00
|
|
|
argv[0] = g_strdup("/bin/sh");
|
|
|
|
argv[1] = g_strdup("-c");
|
|
|
|
argv[2] = cmd_string;
|
|
|
|
argv[3] = NULL;
|
|
|
|
|
2007-03-01 11:38:14 +00:00
|
|
|
utf8_cmd_string = utils_get_utf8_from_locale(cmd_string);
|
|
|
|
utf8_working_dir = (dir != NULL) ? g_strdup(dir) :
|
|
|
|
g_path_get_dirname(doc_list[idx].file_name);
|
|
|
|
working_dir = utils_get_locale_from_utf8(utf8_working_dir);
|
|
|
|
|
2005-11-22 12:26:26 +00:00
|
|
|
gtk_list_store_clear(msgwindow.store_compiler);
|
|
|
|
gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_COMPILER);
|
2007-03-01 11:38:14 +00:00
|
|
|
msgwin_compiler_add_fmt(COLOR_BLUE, _("%s (in directory: %s)"), utf8_cmd_string, utf8_working_dir);
|
|
|
|
g_free(utf8_working_dir);
|
|
|
|
g_free(utf8_cmd_string);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-08-14 15:02:52 +00:00
|
|
|
// set the build info for the message window
|
2006-11-15 17:07:15 +00:00
|
|
|
g_free(build_info.dir);
|
|
|
|
build_info.dir = g_strdup(working_dir);
|
|
|
|
build_info.file_type_id = FILETYPE_ID(doc_list[idx].file_type);
|
2006-08-14 15:02:52 +00:00
|
|
|
|
2005-11-22 12:26:26 +00:00
|
|
|
if (! g_spawn_async_with_pipes(working_dir, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
|
2006-11-11 18:51:33 +00:00
|
|
|
NULL, NULL, &(build_info.pid), NULL, &stdout_fd, &stderr_fd, &error))
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2006-01-18 12:11:44 +00:00
|
|
|
geany_debug("g_spawn_async_with_pipes() failed: %s", error->message);
|
2005-11-22 12:26:26 +00:00
|
|
|
msgwin_status_add(_("Process failed (%s)"), error->message);
|
|
|
|
g_strfreev(argv);
|
|
|
|
g_error_free(error);
|
2006-03-02 23:28:52 +00:00
|
|
|
g_free(working_dir);
|
2006-04-27 18:06:35 +00:00
|
|
|
g_free(locale_filename);
|
2005-11-22 12:26:26 +00:00
|
|
|
error = NULL;
|
|
|
|
return (GPid) 0;
|
|
|
|
}
|
|
|
|
|
2006-11-11 18:51:33 +00:00
|
|
|
if (build_info.pid > 0)
|
|
|
|
{
|
|
|
|
g_child_watch_add(build_info.pid, (GChildWatchFunc) build_exit_cb, NULL);
|
2006-11-29 10:29:34 +00:00
|
|
|
build_menu_update(idx);
|
2006-11-11 18:51:33 +00:00
|
|
|
}
|
|
|
|
|
2005-11-22 12:26:26 +00:00
|
|
|
// use GIOChannels to monitor stdout and stderr
|
2006-07-13 14:30:44 +00:00
|
|
|
utils_set_up_io_channel(stdout_fd, G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
|
2007-03-01 21:45:43 +00:00
|
|
|
TRUE, build_iofunc, GINT_TO_POINTER(0));
|
2006-07-13 14:30:44 +00:00
|
|
|
utils_set_up_io_channel(stderr_fd, G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
|
2007-03-01 21:45:43 +00:00
|
|
|
TRUE, build_iofunc, GINT_TO_POINTER(1));
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
g_strfreev(argv);
|
|
|
|
g_free(working_dir);
|
2006-04-27 18:06:35 +00:00
|
|
|
g_free(locale_filename);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-11-11 18:51:33 +00:00
|
|
|
return build_info.pid;
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-03 13:14:41 +00:00
|
|
|
// Returns: NULL if there was an error, or the working directory the script was created in.
|
|
|
|
static gchar *prepare_run_script(gint idx)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2006-02-01 20:21:34 +00:00
|
|
|
gchar *long_executable = NULL;
|
|
|
|
gchar *check_executable = NULL;
|
2006-04-27 18:06:35 +00:00
|
|
|
gchar *utf8_check_executable = NULL;
|
|
|
|
gchar *locale_filename = NULL;
|
|
|
|
gchar *cmd = NULL;
|
2006-02-01 20:21:34 +00:00
|
|
|
gchar *executable = NULL;
|
2007-03-03 13:14:41 +00:00
|
|
|
gchar *working_dir = NULL;
|
2006-12-10 21:29:04 +00:00
|
|
|
gboolean autoclose = FALSE;
|
2005-11-22 12:26:26 +00:00
|
|
|
struct stat st;
|
2007-03-03 13:14:41 +00:00
|
|
|
gboolean result = FALSE;
|
|
|
|
gchar *tmp;
|
2006-04-27 18:06:35 +00:00
|
|
|
|
2006-08-13 09:07:10 +00:00
|
|
|
locale_filename = utils_get_locale_from_utf8(doc_list[idx].file_name);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
long_executable = utils_remove_ext_from_filename(locale_filename);
|
2006-09-11 11:13:36 +00:00
|
|
|
#ifdef G_OS_WIN32
|
2007-03-03 13:34:15 +00:00
|
|
|
tmp = long_executable;
|
2006-09-11 11:13:36 +00:00
|
|
|
long_executable = g_strconcat(long_executable, ".exe", NULL);
|
2007-03-03 13:34:15 +00:00
|
|
|
g_free(tmp);
|
2006-09-11 11:13:36 +00:00
|
|
|
#endif
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
// only check for existing executable, if executable is required by %e
|
|
|
|
if (strstr(doc_list[idx].file_type->programs->run_cmd, "%e") != NULL)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2006-04-27 18:06:35 +00:00
|
|
|
// add .class extension for JAVA source files (only for stat)
|
|
|
|
if (doc_list[idx].file_type->id == GEANY_FILETYPES_JAVA)
|
2006-09-11 11:13:36 +00:00
|
|
|
{
|
|
|
|
#ifdef G_OS_WIN32
|
2007-03-03 16:54:04 +00:00
|
|
|
gchar *tmp;
|
2006-09-11 11:13:36 +00:00
|
|
|
// there is already the extension .exe, so first remove it and then add .class
|
2007-03-03 16:54:04 +00:00
|
|
|
tmp = utils_remove_ext_from_filename(long_executable);
|
|
|
|
check_executable = g_strconcat(tmp, ".class", NULL);
|
|
|
|
g_free(tmp);
|
2006-09-11 11:13:36 +00:00
|
|
|
#else
|
2006-04-27 18:06:35 +00:00
|
|
|
check_executable = g_strconcat(long_executable, ".class", NULL);
|
2006-09-11 11:13:36 +00:00
|
|
|
#endif
|
|
|
|
}
|
2006-04-27 18:06:35 +00:00
|
|
|
else
|
|
|
|
check_executable = g_strdup(long_executable);
|
2006-06-29 14:00:09 +00:00
|
|
|
|
2007-02-01 14:42:25 +00:00
|
|
|
// check for filename extension and abort if filename doesn't have one
|
|
|
|
if (utils_str_equal(locale_filename, check_executable))
|
|
|
|
{
|
|
|
|
msgwin_status_add(_("Command stopped because the current file has no extension."));
|
|
|
|
utils_beep();
|
2007-02-03 17:01:44 +00:00
|
|
|
goto free_strings;
|
2007-02-01 14:42:25 +00:00
|
|
|
}
|
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
// check whether executable exists
|
2007-04-16 15:58:34 +00:00
|
|
|
if (g_stat(check_executable, &st) != 0)
|
2006-04-27 18:06:35 +00:00
|
|
|
{
|
2007-03-03 17:02:57 +00:00
|
|
|
utf8_check_executable = utils_get_utf8_from_locale(check_executable);
|
2006-04-27 18:06:35 +00:00
|
|
|
msgwin_status_add(_("Failed to execute %s (make sure it is already built)"),
|
|
|
|
utf8_check_executable);
|
|
|
|
goto free_strings;
|
|
|
|
}
|
2006-02-01 20:21:34 +00:00
|
|
|
}
|
2006-06-29 14:00:09 +00:00
|
|
|
|
2005-11-22 12:26:26 +00:00
|
|
|
executable = g_path_get_basename(long_executable);
|
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
working_dir = g_path_get_dirname(locale_filename);
|
2005-11-22 12:26:26 +00:00
|
|
|
if (chdir(working_dir) != 0)
|
|
|
|
{
|
2006-04-27 18:06:35 +00:00
|
|
|
gchar *utf8_working_dir = NULL;
|
2006-08-13 09:07:10 +00:00
|
|
|
utf8_working_dir = utils_get_utf8_from_locale(working_dir);
|
2006-06-29 14:00:09 +00:00
|
|
|
|
2007-03-03 13:14:41 +00:00
|
|
|
msgwin_status_add(_("Failed to change the working directory to %s"), utf8_working_dir);
|
2006-04-27 18:06:35 +00:00
|
|
|
g_free(utf8_working_dir);
|
2006-02-01 20:21:34 +00:00
|
|
|
goto free_strings;
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
2006-06-29 14:00:09 +00:00
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
// replace %f and %e in the run_cmd string
|
|
|
|
cmd = g_strdup(doc_list[idx].file_type->programs->run_cmd);
|
|
|
|
tmp = g_path_get_basename(locale_filename);
|
|
|
|
cmd = utils_str_replace(cmd, "%f", tmp);
|
|
|
|
g_free(tmp);
|
|
|
|
cmd = utils_str_replace(cmd, "%e", executable);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-12-10 21:29:04 +00:00
|
|
|
#ifdef HAVE_VTE
|
|
|
|
if (vte_info.load_vte && vc != NULL && vc->run_in_vte)
|
|
|
|
autoclose = TRUE; // don't wait for user input at the end of script when we are running in VTE
|
|
|
|
#endif
|
|
|
|
|
2007-03-03 13:14:41 +00:00
|
|
|
// (RUN_SCRIPT_CMD should be ok in UTF8 without converting in locale because it contains no umlauts)
|
2007-03-03 16:54:04 +00:00
|
|
|
if (! build_create_shellscript(RUN_SCRIPT_CMD, cmd, autoclose))
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2007-03-05 12:44:02 +00:00
|
|
|
utf8_check_executable = utils_get_utf8_from_locale(check_executable);
|
2007-03-05 12:13:09 +00:00
|
|
|
msgwin_status_add(_("Failed to execute \"%s\" (start-script could not be created)"),
|
2006-04-27 18:06:35 +00:00
|
|
|
utf8_check_executable);
|
2007-03-03 13:14:41 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
result = TRUE;
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
2007-03-03 13:14:41 +00:00
|
|
|
free_strings:
|
|
|
|
g_free(executable);
|
|
|
|
g_free(cmd);
|
|
|
|
g_free(locale_filename);
|
|
|
|
g_free(utf8_check_executable);
|
|
|
|
g_free(check_executable);
|
|
|
|
g_free(long_executable);
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
return working_dir;
|
|
|
|
|
|
|
|
g_free(working_dir);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-05 12:13:09 +00:00
|
|
|
static gchar *prepare_project_run_script()
|
|
|
|
{
|
|
|
|
GeanyProject *project = app->project;
|
|
|
|
gboolean autoclose = FALSE;
|
|
|
|
gchar *working_dir;
|
|
|
|
gchar *cmd;
|
|
|
|
|
|
|
|
if (project == NULL || project->run_cmd == NULL) return NULL;
|
|
|
|
g_return_val_if_fail(project->base_path != NULL, NULL);
|
|
|
|
|
|
|
|
working_dir = utils_get_locale_from_utf8(project->base_path);
|
|
|
|
if (chdir(working_dir) != 0)
|
|
|
|
{
|
|
|
|
msgwin_status_add(_("Failed to change the working directory to %s"), project->base_path);
|
|
|
|
g_free(working_dir);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_VTE
|
|
|
|
if (vte_info.load_vte && vc != NULL && vc->run_in_vte)
|
|
|
|
autoclose = TRUE; // don't wait for user input at the end of script when we are running in VTE
|
|
|
|
#endif
|
|
|
|
cmd = utils_get_locale_from_utf8(project->run_cmd);
|
|
|
|
|
|
|
|
// (RUN_SCRIPT_CMD should be ok in UTF8 without converting in locale because it contains no umlauts)
|
|
|
|
if (! build_create_shellscript(RUN_SCRIPT_CMD, cmd, autoclose))
|
|
|
|
{
|
|
|
|
msgwin_status_add(_("Failed to execute \"%s\" (start-script could not be created)"),
|
|
|
|
project->run_cmd);
|
|
|
|
g_free(working_dir);
|
|
|
|
g_free(cmd);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
g_free(cmd);
|
|
|
|
return working_dir;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-24 12:40:20 +00:00
|
|
|
static GPid build_run_cmd(gint idx)
|
2007-03-03 13:14:41 +00:00
|
|
|
{
|
2007-03-05 12:13:09 +00:00
|
|
|
GeanyProject *project = app->project;
|
2007-03-03 13:14:41 +00:00
|
|
|
gchar *working_dir;
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
if (! DOC_IDX_VALID(idx) || doc_list[idx].file_name == NULL) return (GPid) 1;
|
|
|
|
|
2007-03-05 12:13:09 +00:00
|
|
|
if (project != NULL && project->run_cmd != NULL && *project->run_cmd != 0)
|
|
|
|
working_dir = prepare_project_run_script();
|
|
|
|
else
|
|
|
|
working_dir = prepare_run_script(idx);
|
|
|
|
|
2007-03-03 13:14:41 +00:00
|
|
|
if (working_dir == NULL)
|
|
|
|
{
|
|
|
|
return (GPid) 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
run_info.file_type_id = FILETYPE_ID(doc_list[idx].file_type);
|
|
|
|
|
2006-12-10 21:29:04 +00:00
|
|
|
#ifdef HAVE_VTE
|
|
|
|
if (vte_info.load_vte && vc != NULL && vc->run_in_vte)
|
2006-04-27 18:06:35 +00:00
|
|
|
{
|
2007-03-03 13:14:41 +00:00
|
|
|
gchar *vte_cmd = g_strconcat(RUN_SCRIPT_CMD, "\n", NULL);
|
2006-12-10 21:29:04 +00:00
|
|
|
// change into current directory if it is not done by default
|
|
|
|
if (! vc->follow_path) vte_cwd(doc_list[idx].file_name, TRUE);
|
2007-03-03 13:14:41 +00:00
|
|
|
vte_send_cmd(vte_cmd);
|
2006-12-10 21:29:04 +00:00
|
|
|
|
|
|
|
// show the VTE
|
|
|
|
gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_VTE);
|
|
|
|
gtk_widget_grab_focus(vc->vte);
|
2006-12-13 16:41:25 +00:00
|
|
|
msgwin_show_hide(TRUE);
|
2006-12-10 21:29:04 +00:00
|
|
|
|
|
|
|
run_info.pid = 1;
|
|
|
|
|
2007-03-03 13:14:41 +00:00
|
|
|
g_free(vte_cmd);
|
2006-04-27 18:06:35 +00:00
|
|
|
}
|
2006-12-10 21:29:04 +00:00
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
2007-03-03 13:14:41 +00:00
|
|
|
gchar *locale_term_cmd = NULL;
|
|
|
|
gchar **term_argv = NULL;
|
|
|
|
guint term_argv_len, i;
|
|
|
|
gchar **argv = NULL;
|
|
|
|
|
|
|
|
/* get the terminal path */
|
|
|
|
locale_term_cmd = utils_get_locale_from_utf8(app->tools_term_cmd);
|
|
|
|
// split the term_cmd, so arguments will work too
|
|
|
|
term_argv = g_strsplit(locale_term_cmd, " ", -1);
|
|
|
|
term_argv_len = g_strv_length(term_argv);
|
|
|
|
|
|
|
|
// check that terminal exists (to prevent misleading error messages)
|
|
|
|
if (term_argv[0] != NULL)
|
|
|
|
{
|
|
|
|
gchar *tmp = term_argv[0];
|
|
|
|
// g_find_program_in_path checks tmp exists and is executable
|
|
|
|
term_argv[0] = g_find_program_in_path(tmp);
|
|
|
|
g_free(tmp);
|
|
|
|
}
|
|
|
|
if (term_argv[0] == NULL)
|
|
|
|
{
|
|
|
|
msgwin_status_add(
|
|
|
|
_("Could not find terminal '%s' "
|
|
|
|
"(check path for Terminal tool setting in Preferences)"), app->tools_term_cmd);
|
|
|
|
run_info.pid = (GPid) 1;
|
|
|
|
goto free_strings;
|
|
|
|
}
|
|
|
|
|
2006-12-10 21:29:04 +00:00
|
|
|
argv = g_new0(gchar *, term_argv_len + 3);
|
|
|
|
for (i = 0; i < term_argv_len; i++)
|
|
|
|
{
|
|
|
|
argv[i] = g_strdup(term_argv[i]);
|
|
|
|
}
|
2006-09-11 11:13:36 +00:00
|
|
|
#ifdef G_OS_WIN32
|
2006-12-10 21:29:04 +00:00
|
|
|
// command line arguments for cmd.exe
|
|
|
|
argv[term_argv_len ] = g_strdup("/Q /C");
|
2007-03-03 13:14:41 +00:00
|
|
|
argv[term_argv_len + 1] = g_path_get_basename(RUN_SCRIPT_CMD);
|
2006-09-11 11:13:36 +00:00
|
|
|
#else
|
2006-12-10 21:29:04 +00:00
|
|
|
argv[term_argv_len ] = g_strdup("-e");
|
2007-03-03 13:14:41 +00:00
|
|
|
argv[term_argv_len + 1] = g_strdup(RUN_SCRIPT_CMD);
|
2006-09-11 11:13:36 +00:00
|
|
|
#endif
|
2006-12-10 21:29:04 +00:00
|
|
|
argv[term_argv_len + 2] = NULL;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-12-10 21:29:04 +00:00
|
|
|
if (! g_spawn_async_with_pipes(working_dir, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
|
|
|
|
NULL, NULL, &(run_info.pid), NULL, NULL, NULL, &error))
|
|
|
|
{
|
|
|
|
geany_debug("g_spawn_async_with_pipes() failed: %s", error->message);
|
|
|
|
msgwin_status_add(_("Process failed (%s)"), error->message);
|
2007-03-03 13:14:41 +00:00
|
|
|
unlink(RUN_SCRIPT_CMD);
|
2006-12-10 21:29:04 +00:00
|
|
|
g_error_free(error);
|
|
|
|
error = NULL;
|
2007-03-03 13:14:41 +00:00
|
|
|
run_info.pid = (GPid) 0;
|
2006-12-10 21:29:04 +00:00
|
|
|
}
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-12-10 21:29:04 +00:00
|
|
|
if (run_info.pid > 0)
|
|
|
|
{
|
|
|
|
g_child_watch_add(run_info.pid, (GChildWatchFunc) run_exit_cb, NULL);
|
|
|
|
build_menu_update(idx);
|
|
|
|
}
|
2007-03-03 13:14:41 +00:00
|
|
|
free_strings:
|
|
|
|
g_strfreev(argv);
|
|
|
|
g_strfreev(term_argv);
|
|
|
|
g_free(locale_term_cmd);
|
2006-11-11 18:51:33 +00:00
|
|
|
}
|
2006-02-10 20:58:08 +00:00
|
|
|
|
2005-11-22 12:26:26 +00:00
|
|
|
g_free(working_dir);
|
2007-03-03 13:14:41 +00:00
|
|
|
return run_info.pid;
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-27 18:06:35 +00:00
|
|
|
static gboolean build_iofunc(GIOChannel *ioc, GIOCondition cond, gpointer data)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
|
|
|
if (cond & (G_IO_IN | G_IO_PRI))
|
|
|
|
{
|
|
|
|
//GIOStatus s;
|
2006-12-30 16:16:59 +00:00
|
|
|
gchar *msg, *dir = NULL;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
while (g_io_channel_read_line(ioc, &msg, NULL, NULL, NULL) && msg)
|
|
|
|
{
|
|
|
|
//if (s != G_IO_STATUS_NORMAL && s != G_IO_STATUS_EOF) break;
|
2006-09-08 10:20:15 +00:00
|
|
|
gint color;
|
2007-01-04 11:49:14 +00:00
|
|
|
gchar *tmp;
|
|
|
|
|
2006-09-08 10:20:15 +00:00
|
|
|
color = (GPOINTER_TO_INT(data)) ? COLOR_DARK_RED : COLOR_BLACK;
|
|
|
|
g_strstrip(msg);
|
2006-06-27 15:29:33 +00:00
|
|
|
|
2007-01-04 11:49:14 +00:00
|
|
|
if (build_parse_make_dir(msg, &tmp))
|
|
|
|
{
|
2006-12-30 16:16:59 +00:00
|
|
|
if (dir != NULL)
|
|
|
|
g_free(dir);
|
2007-01-04 11:49:14 +00:00
|
|
|
dir = tmp;
|
2006-12-30 16:16:59 +00:00
|
|
|
}
|
|
|
|
|
2006-06-27 15:29:33 +00:00
|
|
|
if (app->pref_editor_use_indicators)
|
|
|
|
{
|
|
|
|
gchar *filename;
|
|
|
|
gint line;
|
2006-12-30 16:16:59 +00:00
|
|
|
|
|
|
|
msgwin_parse_compiler_error_line(msg, dir, &filename, &line);
|
2006-09-08 10:20:15 +00:00
|
|
|
if (line != -1 && filename != NULL)
|
2006-06-13 19:37:21 +00:00
|
|
|
{
|
2006-06-27 15:29:33 +00:00
|
|
|
gint idx = document_find_by_filename(filename, FALSE);
|
2006-09-08 10:20:15 +00:00
|
|
|
document_set_indicator(idx, line - 1); // will check valid idx
|
|
|
|
color = COLOR_RED; // error message parsed on the line
|
2006-06-13 19:37:21 +00:00
|
|
|
}
|
2006-06-27 15:29:33 +00:00
|
|
|
g_free(filename);
|
2006-06-13 19:37:21 +00:00
|
|
|
}
|
2006-12-08 15:50:10 +00:00
|
|
|
msgwin_compiler_add(color, msg);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
g_free(msg);
|
|
|
|
}
|
2006-12-30 16:16:59 +00:00
|
|
|
|
|
|
|
if (dir != NULL)
|
|
|
|
g_free(dir);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-04 11:49:14 +00:00
|
|
|
gboolean build_parse_make_dir(const gchar *string, gchar **prefix)
|
2006-12-30 16:16:59 +00:00
|
|
|
{
|
2007-01-04 11:49:14 +00:00
|
|
|
const gchar *pos;
|
2006-12-30 16:16:59 +00:00
|
|
|
|
|
|
|
*prefix = NULL;
|
|
|
|
|
2007-01-04 11:49:14 +00:00
|
|
|
if (string == NULL)
|
2006-12-30 16:16:59 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2007-01-04 11:49:14 +00:00
|
|
|
if ((pos = strstr(string, "Entering directory")) != NULL)
|
2006-12-30 16:16:59 +00:00
|
|
|
{
|
2007-01-04 11:49:14 +00:00
|
|
|
gsize len;
|
|
|
|
gchar *input;
|
2006-12-30 16:16:59 +00:00
|
|
|
|
2007-01-04 11:49:14 +00:00
|
|
|
// get the start of the path
|
|
|
|
pos = strstr(string, "/");
|
2006-12-30 16:16:59 +00:00
|
|
|
|
2007-01-04 11:49:14 +00:00
|
|
|
if (pos == NULL)
|
2006-12-30 16:16:59 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2007-01-04 11:49:14 +00:00
|
|
|
input = g_strdup(pos);
|
2006-12-30 16:16:59 +00:00
|
|
|
|
2007-01-04 11:49:14 +00:00
|
|
|
// kill the ' at the end of the path
|
|
|
|
len = strlen(input);
|
|
|
|
input[len - 1] = '\0';
|
|
|
|
input = g_realloc(input, len); // shorten by 1
|
|
|
|
*prefix = input;
|
2006-12-30 16:16:59 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-12-09 13:06:50 +00:00
|
|
|
#ifndef G_OS_WIN32
|
2006-11-27 11:32:45 +00:00
|
|
|
static void show_build_result_message(gboolean failure)
|
|
|
|
{
|
|
|
|
gchar *msg;
|
|
|
|
|
|
|
|
if (failure)
|
|
|
|
{
|
|
|
|
msg = _("Compilation failed.");
|
2007-01-21 18:22:14 +00:00
|
|
|
msgwin_compiler_add(COLOR_DARK_RED, msg);
|
2006-11-27 11:32:45 +00:00
|
|
|
// If msgwindow is hidden, user will want to display it to see the error
|
|
|
|
if (! app->msgwindow_visible)
|
|
|
|
{
|
|
|
|
gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_COMPILER);
|
2006-12-13 16:41:25 +00:00
|
|
|
msgwin_show_hide(TRUE);
|
2006-11-27 11:32:45 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
if (gtk_notebook_get_current_page(GTK_NOTEBOOK(msgwindow.notebook)) != MSG_COMPILER)
|
|
|
|
ui_set_statusbar("%s", msg);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
msg = _("Compilation finished successfully.");
|
2007-01-21 18:22:14 +00:00
|
|
|
msgwin_compiler_add(COLOR_BLUE, msg);
|
2006-11-27 11:32:45 +00:00
|
|
|
if (! app->msgwindow_visible ||
|
|
|
|
gtk_notebook_get_current_page(GTK_NOTEBOOK(msgwindow.notebook)) != MSG_COMPILER)
|
|
|
|
ui_set_statusbar("%s", msg);
|
|
|
|
}
|
|
|
|
}
|
2006-12-09 13:06:50 +00:00
|
|
|
#endif
|
2006-11-27 11:32:45 +00:00
|
|
|
|
|
|
|
|
2006-10-18 19:35:42 +00:00
|
|
|
static void build_exit_cb(GPid child_pid, gint status, gpointer user_data)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
|
|
|
#ifdef G_OS_UNIX
|
2006-11-29 10:29:34 +00:00
|
|
|
gboolean failure = FALSE;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-11-29 10:29:34 +00:00
|
|
|
if (WIFEXITED(status))
|
|
|
|
{
|
|
|
|
if (WEXITSTATUS(status) != EXIT_SUCCESS)
|
2006-11-11 18:51:33 +00:00
|
|
|
failure = TRUE;
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
2006-11-29 10:29:34 +00:00
|
|
|
else if (WIFSIGNALED(status))
|
|
|
|
{
|
|
|
|
// the terminating signal: WTERMSIG (status));
|
|
|
|
failure = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // any other failure occured
|
|
|
|
failure = TRUE;
|
|
|
|
}
|
|
|
|
show_build_result_message(failure);
|
|
|
|
#endif
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-11-29 10:29:34 +00:00
|
|
|
utils_beep();
|
2005-11-22 12:26:26 +00:00
|
|
|
g_spawn_close_pid(child_pid);
|
2006-11-11 18:51:33 +00:00
|
|
|
|
|
|
|
build_info.pid = 0;
|
2006-11-29 10:29:34 +00:00
|
|
|
// enable build items again
|
|
|
|
build_menu_update(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void run_exit_cb(GPid child_pid, gint status, gpointer user_data)
|
|
|
|
{
|
|
|
|
g_spawn_close_pid(child_pid);
|
|
|
|
|
|
|
|
run_info.pid = 0;
|
2006-11-11 18:51:33 +00:00
|
|
|
// reset the stop button and menu item to the original meaning
|
2006-11-29 10:29:34 +00:00
|
|
|
build_menu_update(-1);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-05 12:13:09 +00:00
|
|
|
// write a little shellscript to call the executable (similar to anjuta_launcher but "internal")
|
2007-03-03 16:54:04 +00:00
|
|
|
static gboolean build_create_shellscript(const gchar *fname, const gchar *cmd, gboolean autoclose)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
|
|
|
FILE *fp;
|
2006-09-11 11:13:36 +00:00
|
|
|
gchar *str;
|
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
gchar *tmp;
|
|
|
|
#endif
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
fp = fopen(fname, "w");
|
|
|
|
if (! fp) return FALSE;
|
|
|
|
|
2006-09-11 11:13:36 +00:00
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
tmp = g_path_get_basename(fname);
|
2006-11-11 18:51:33 +00:00
|
|
|
str = g_strdup_printf("%s\n\n%s\ndel %s\n", cmd, (autoclose) ? "" : "pause", tmp);
|
2006-09-11 11:13:36 +00:00
|
|
|
g_free(tmp);
|
|
|
|
#else
|
2005-11-22 12:26:26 +00:00
|
|
|
str = g_strdup_printf(
|
2006-04-27 18:06:35 +00:00
|
|
|
"#!/bin/sh\n\n%s\n\necho \"\n\n------------------\n(program exited with code: $?)\" \
|
2007-01-19 15:45:43 +00:00
|
|
|
\n\n%s\nrm $0\n", cmd, (autoclose) ? "" :
|
2006-12-10 21:29:04 +00:00
|
|
|
"\necho \"Press return to continue\"\n#to be more compatible with shells like dash\ndummy_var=\"\"\nread dummy_var");
|
2006-09-11 11:13:36 +00:00
|
|
|
#endif
|
|
|
|
|
2005-11-22 12:26:26 +00:00
|
|
|
fputs(str, fp);
|
|
|
|
g_free(str);
|
|
|
|
|
2006-09-11 11:13:36 +00:00
|
|
|
#ifndef G_OS_WIN32
|
2005-11-22 12:26:26 +00:00
|
|
|
if (chmod(fname, 0700) != 0)
|
|
|
|
{
|
|
|
|
unlink(fname);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2006-09-11 11:13:36 +00:00
|
|
|
#endif
|
2005-11-22 12:26:26 +00:00
|
|
|
fclose(fp);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-18 19:35:42 +00:00
|
|
|
#define GEANY_ADD_WIDGET_ACCEL(gkey, menuitem) \
|
|
|
|
if (keys[(gkey)]->key != 0) \
|
|
|
|
gtk_widget_add_accelerator(menuitem, "activate", accel_group, \
|
|
|
|
keys[(gkey)]->key, keys[(gkey)]->mods, GTK_ACCEL_VISIBLE)
|
|
|
|
|
2006-11-30 15:42:52 +00:00
|
|
|
static void create_build_menu_gen(BuildMenuItems *menu_items)
|
2006-10-18 19:35:42 +00:00
|
|
|
{
|
|
|
|
GtkWidget *menu, *item = NULL, *image, *separator;
|
|
|
|
GtkAccelGroup *accel_group = gtk_accel_group_new();
|
|
|
|
GtkTooltips *tooltips = GTK_TOOLTIPS(lookup_widget(app->window, "tooltips"));
|
|
|
|
|
|
|
|
menu = gtk_menu_new();
|
|
|
|
|
|
|
|
#ifndef G_OS_WIN32
|
2006-11-30 15:42:52 +00:00
|
|
|
// compile the code
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("_Compile"));
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
gtk_tooltips_set_tip(tooltips, item, _("Compiles the current file"), NULL);
|
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_COMPILE, item);
|
|
|
|
image = gtk_image_new_from_stock("gtk-convert", GTK_ICON_SIZE_MENU);
|
|
|
|
gtk_widget_show(image);
|
|
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
|
|
|
|
g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_compile_activate), NULL);
|
|
|
|
menu_items->item_compile = item;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
2006-11-30 15:42:52 +00:00
|
|
|
// build the code
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("_Build"));
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
gtk_tooltips_set_tip(tooltips, item,
|
|
|
|
_("Builds the current file (generate an executable file)"), NULL);
|
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_LINK, item);
|
|
|
|
g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_build_activate), NULL);
|
|
|
|
menu_items->item_link = item;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
2006-11-30 15:42:52 +00:00
|
|
|
item = gtk_separator_menu_item_new();
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
2006-10-18 19:35:42 +00:00
|
|
|
|
|
|
|
// build the code with make all
|
2006-12-12 12:12:20 +00:00
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("_Make All"));
|
2006-10-18 19:35:42 +00:00
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
gtk_tooltips_set_tip(tooltips, item, _("Builds the current file with the "
|
|
|
|
"make tool and the default target"), NULL);
|
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_MAKE, item);
|
|
|
|
g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_make_activate),
|
|
|
|
GINT_TO_POINTER(GBO_MAKE_ALL));
|
2006-11-30 15:42:52 +00:00
|
|
|
menu_items->item_make_all = item;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
|
|
|
// build the code with make custom
|
2006-12-12 12:12:20 +00:00
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("Make Custom _Target"));
|
2006-10-18 19:35:42 +00:00
|
|
|
gtk_widget_show(item);
|
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_MAKEOWNTARGET, item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
gtk_tooltips_set_tip(tooltips, item, _("Builds the current file with the "
|
|
|
|
"make tool and the specified target"), NULL);
|
|
|
|
g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_make_activate),
|
|
|
|
GINT_TO_POINTER(GBO_MAKE_CUSTOM));
|
2006-11-30 15:42:52 +00:00
|
|
|
menu_items->item_make_custom = item;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
|
|
|
// build the code with make object
|
2006-12-12 12:12:20 +00:00
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("Make _Object"));
|
2006-10-18 19:35:42 +00:00
|
|
|
gtk_widget_show(item);
|
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_MAKEOBJECT, item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
gtk_tooltips_set_tip(tooltips, item, _("Compiles the current file using the "
|
|
|
|
"make tool"), NULL);
|
|
|
|
g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_make_activate),
|
|
|
|
GINT_TO_POINTER(GBO_MAKE_OBJECT));
|
2006-11-30 15:42:52 +00:00
|
|
|
menu_items->item_make_object = item;
|
2006-10-18 19:35:42 +00:00
|
|
|
#endif
|
|
|
|
|
2006-11-30 15:42:52 +00:00
|
|
|
item = gtk_separator_menu_item_new();
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
2006-10-18 19:35:42 +00:00
|
|
|
|
2006-12-08 15:50:10 +00:00
|
|
|
// next error
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("_Next Error"));
|
|
|
|
gtk_widget_show(item);
|
2006-12-09 17:03:03 +00:00
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_NEXTERROR, item);
|
2006-12-08 15:50:10 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_next_error), NULL);
|
|
|
|
menu_items->item_next_error = item;
|
|
|
|
|
|
|
|
item = gtk_separator_menu_item_new();
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
|
2006-11-30 15:42:52 +00:00
|
|
|
// execute the code
|
|
|
|
item = gtk_image_menu_item_new_from_stock("gtk-execute", accel_group);
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
gtk_tooltips_set_tip(tooltips, item, _("Run or view the current file"), NULL);
|
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_RUN, item);
|
|
|
|
g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_execute_activate), NULL);
|
|
|
|
menu_items->item_exec = item;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
2006-11-30 15:42:52 +00:00
|
|
|
separator = gtk_separator_menu_item_new();
|
|
|
|
gtk_widget_show(separator);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), separator);
|
|
|
|
gtk_widget_set_sensitive(separator, FALSE);
|
2006-10-18 19:35:42 +00:00
|
|
|
|
2006-11-30 15:42:52 +00:00
|
|
|
// arguments
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("_Set Includes and Arguments"));
|
|
|
|
gtk_widget_show(item);
|
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_OPTIONS, item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
gtk_tooltips_set_tip(tooltips, item,
|
|
|
|
_("Sets the includes and library paths for the compiler and "
|
|
|
|
"the program arguments for execution"), NULL);
|
|
|
|
image = gtk_image_new_from_stock("gtk-preferences", GTK_ICON_SIZE_MENU);
|
|
|
|
gtk_widget_show(image);
|
|
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
|
|
|
|
g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_arguments_activate), NULL);
|
|
|
|
menu_items->item_set_args = item;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
2006-11-30 15:42:52 +00:00
|
|
|
menu_items->menu = menu;
|
|
|
|
g_object_ref((gpointer)menu_items->menu); // to hold it after removing
|
2006-10-18 19:35:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-30 15:42:52 +00:00
|
|
|
static void create_build_menu_tex(BuildMenuItems *menu_items)
|
2006-10-18 19:35:42 +00:00
|
|
|
{
|
|
|
|
GtkWidget *menu, *item, *image, *separator;
|
|
|
|
GtkAccelGroup *accel_group = gtk_accel_group_new();
|
|
|
|
GtkTooltips *tooltips = GTK_TOOLTIPS(lookup_widget(app->window, "tooltips"));
|
|
|
|
|
|
|
|
menu = gtk_menu_new();
|
|
|
|
|
|
|
|
#ifndef G_OS_WIN32
|
|
|
|
// DVI
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("LaTeX -> DVI"));
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
gtk_tooltips_set_tip(tooltips, item, _("Compiles the current file into a DVI file"), NULL);
|
2006-12-09 17:03:03 +00:00
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_COMPILE, item);
|
2006-10-18 19:35:42 +00:00
|
|
|
image = gtk_image_new_from_stock("gtk-convert", GTK_ICON_SIZE_MENU);
|
|
|
|
gtk_widget_show(image);
|
|
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
|
2006-11-11 18:51:33 +00:00
|
|
|
g_signal_connect((gpointer) item, "activate",
|
|
|
|
G_CALLBACK(on_build_tex_activate), GINT_TO_POINTER(LATEX_CMD_TO_DVI));
|
2006-11-30 15:42:52 +00:00
|
|
|
menu_items->item_compile = item;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
|
|
|
// PDF
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("LaTeX -> PDF"));
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
gtk_tooltips_set_tip(tooltips, item, _("Compiles the current file into a PDF file"), NULL);
|
2006-12-09 17:03:03 +00:00
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_LINK, item);
|
2006-10-18 19:35:42 +00:00
|
|
|
image = gtk_image_new_from_stock("gtk-convert", GTK_ICON_SIZE_MENU);
|
|
|
|
gtk_widget_show(image);
|
|
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
|
2006-11-11 18:51:33 +00:00
|
|
|
g_signal_connect((gpointer) item, "activate",
|
|
|
|
G_CALLBACK(on_build_tex_activate), GINT_TO_POINTER(LATEX_CMD_TO_PDF));
|
2006-11-30 15:42:52 +00:00
|
|
|
menu_items->item_link = item;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
2006-12-08 15:50:10 +00:00
|
|
|
item = gtk_separator_menu_item_new();
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
2006-10-18 19:35:42 +00:00
|
|
|
|
|
|
|
// build the code with make all
|
2006-12-12 12:12:20 +00:00
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("_Make All"));
|
2006-10-18 19:35:42 +00:00
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
gtk_tooltips_set_tip(tooltips, item, _("Builds the current file with the "
|
|
|
|
"make tool and the default target"), NULL);
|
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_MAKE, item);
|
|
|
|
g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_make_activate),
|
|
|
|
GINT_TO_POINTER(GBO_MAKE_ALL));
|
2006-11-30 15:42:52 +00:00
|
|
|
menu_items->item_make_all = item;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
|
|
|
// build the code with make custom
|
2006-12-12 12:12:20 +00:00
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("Make Custom _Target"));
|
2006-10-18 19:35:42 +00:00
|
|
|
gtk_widget_show(item);
|
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_MAKEOWNTARGET, item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
gtk_tooltips_set_tip(tooltips, item, _("Builds the current file with the "
|
|
|
|
"make tool and the specified target"), NULL);
|
|
|
|
g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_make_activate),
|
|
|
|
GINT_TO_POINTER(GBO_MAKE_CUSTOM));
|
2006-11-30 15:42:52 +00:00
|
|
|
menu_items->item_make_custom = item;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
2006-12-08 15:50:10 +00:00
|
|
|
item = gtk_separator_menu_item_new();
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
2006-10-18 19:35:42 +00:00
|
|
|
#endif
|
|
|
|
|
2006-12-08 15:50:10 +00:00
|
|
|
// next error
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("_Next Error"));
|
|
|
|
gtk_widget_show(item);
|
2006-12-09 17:03:03 +00:00
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_NEXTERROR, item);
|
2006-12-08 15:50:10 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_next_error), NULL);
|
|
|
|
menu_items->item_next_error = item;
|
|
|
|
|
|
|
|
item = gtk_separator_menu_item_new();
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
|
2006-10-18 19:35:42 +00:00
|
|
|
// DVI view
|
2006-12-12 12:12:20 +00:00
|
|
|
#define LATEX_VIEW_DVI_LABEL _("View DVI File") // used later again
|
2006-11-11 18:51:33 +00:00
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(LATEX_VIEW_DVI_LABEL);
|
2006-10-18 19:35:42 +00:00
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
2006-12-09 17:03:03 +00:00
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_RUN, item);
|
2007-03-05 12:44:02 +00:00
|
|
|
gtk_tooltips_set_tip(tooltips, item, _("Compile and view the current file"), NULL);
|
2006-10-18 19:35:42 +00:00
|
|
|
image = gtk_image_new_from_stock("gtk-find", GTK_ICON_SIZE_MENU);
|
|
|
|
gtk_widget_show(image);
|
|
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
|
2006-11-11 18:51:33 +00:00
|
|
|
g_signal_connect((gpointer) item, "activate",
|
|
|
|
G_CALLBACK(on_build_execute_activate), GINT_TO_POINTER(LATEX_CMD_VIEW_DVI));
|
2006-11-30 15:42:52 +00:00
|
|
|
menu_items->item_exec = item;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
|
|
|
// PDF view
|
2006-12-12 12:12:20 +00:00
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("View PDF File"));
|
2006-10-18 19:35:42 +00:00
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
2006-12-09 17:03:03 +00:00
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_RUN2, item);
|
2007-03-05 12:44:02 +00:00
|
|
|
gtk_tooltips_set_tip(tooltips, item, _("Compile and view the current file"), NULL);
|
2006-10-18 19:35:42 +00:00
|
|
|
image = gtk_image_new_from_stock("gtk-find", GTK_ICON_SIZE_MENU);
|
|
|
|
gtk_widget_show(image);
|
|
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
|
2006-11-11 18:51:33 +00:00
|
|
|
g_signal_connect((gpointer) item, "activate",
|
|
|
|
G_CALLBACK(on_build_execute_activate), GINT_TO_POINTER(LATEX_CMD_VIEW_PDF));
|
2006-11-30 15:42:52 +00:00
|
|
|
menu_items->item_exec2 = item;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
|
|
|
// separator
|
|
|
|
separator = gtk_separator_menu_item_new();
|
|
|
|
gtk_widget_show(separator);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), separator);
|
|
|
|
gtk_widget_set_sensitive(separator, FALSE);
|
|
|
|
|
|
|
|
// arguments
|
|
|
|
item = gtk_image_menu_item_new_with_mnemonic(_("Set Arguments"));
|
|
|
|
gtk_widget_show(item);
|
2006-12-09 17:03:03 +00:00
|
|
|
GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_OPTIONS, item);
|
2006-10-18 19:35:42 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
gtk_tooltips_set_tip(tooltips, item,
|
|
|
|
_("Sets the program paths and arguments"), NULL);
|
|
|
|
image = gtk_image_new_from_stock("gtk-preferences", GTK_ICON_SIZE_MENU);
|
|
|
|
gtk_widget_show(image);
|
|
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
|
2006-11-29 10:29:34 +00:00
|
|
|
g_signal_connect((gpointer) item, "activate",
|
2006-11-30 15:42:52 +00:00
|
|
|
G_CALLBACK(on_build_arguments_activate), filetypes[GEANY_FILETYPES_LATEX]);
|
|
|
|
menu_items->item_set_args = item;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
|
|
|
gtk_window_add_accel_group(GTK_WINDOW(app->window), accel_group);
|
|
|
|
|
2006-11-30 15:42:52 +00:00
|
|
|
menu_items->menu = menu;
|
|
|
|
g_object_ref((gpointer)menu_items->menu); // to hold it after removing
|
2006-10-18 19:35:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-24 12:40:20 +00:00
|
|
|
static void
|
|
|
|
on_includes_arguments_tex_dialog_response (GtkDialog *dialog,
|
|
|
|
gint response,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
filetype *ft = user_data;
|
|
|
|
g_return_if_fail(ft != NULL);
|
|
|
|
|
|
|
|
if (response == GTK_RESPONSE_ACCEPT)
|
|
|
|
{
|
|
|
|
const gchar *newstr;
|
|
|
|
struct build_programs *programs = ft->programs;
|
|
|
|
|
|
|
|
newstr = gtk_entry_get_text(
|
|
|
|
GTK_ENTRY(lookup_widget(GTK_WIDGET(dialog), "tex_entry1")));
|
|
|
|
if (! utils_str_equal(newstr, programs->compiler))
|
|
|
|
{
|
|
|
|
if (programs->compiler) g_free(programs->compiler);
|
|
|
|
programs->compiler = g_strdup(newstr);
|
|
|
|
programs->modified = TRUE;
|
|
|
|
}
|
|
|
|
newstr = gtk_entry_get_text(
|
|
|
|
GTK_ENTRY(lookup_widget(GTK_WIDGET(dialog), "tex_entry2")));
|
|
|
|
if (! utils_str_equal(newstr, programs->linker))
|
|
|
|
{
|
|
|
|
if (programs->linker) g_free(programs->linker);
|
|
|
|
programs->linker = g_strdup(newstr);
|
|
|
|
programs->modified = TRUE;
|
|
|
|
}
|
|
|
|
newstr = gtk_entry_get_text(
|
|
|
|
GTK_ENTRY(lookup_widget(GTK_WIDGET(dialog), "tex_entry3")));
|
|
|
|
if (! utils_str_equal(newstr, programs->run_cmd))
|
|
|
|
{
|
|
|
|
if (programs->run_cmd) g_free(programs->run_cmd);
|
|
|
|
programs->run_cmd = g_strdup(newstr);
|
|
|
|
programs->modified = TRUE;
|
|
|
|
}
|
|
|
|
newstr = gtk_entry_get_text(
|
|
|
|
GTK_ENTRY(lookup_widget(GTK_WIDGET(dialog), "tex_entry4")));
|
|
|
|
if (! utils_str_equal(newstr, programs->run_cmd2))
|
|
|
|
{
|
|
|
|
if (programs->run_cmd2) g_free(programs->run_cmd2);
|
|
|
|
programs->run_cmd2 = g_strdup(newstr);
|
|
|
|
programs->modified = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void show_includes_arguments_tex()
|
|
|
|
{
|
|
|
|
GtkWidget *dialog, *label, *entries[4], *vbox, *table;
|
|
|
|
gint idx = document_get_cur_idx();
|
|
|
|
gint response;
|
|
|
|
filetype *ft = NULL;
|
|
|
|
|
|
|
|
if (DOC_IDX_VALID(idx)) ft = doc_list[idx].file_type;
|
|
|
|
g_return_if_fail(ft != NULL);
|
|
|
|
|
|
|
|
dialog = gtk_dialog_new_with_buttons(_("Set Arguments"), GTK_WINDOW(app->window),
|
|
|
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
|
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
|
|
|
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
|
|
|
|
vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog));
|
|
|
|
|
|
|
|
label = gtk_label_new(_("Set programs and options for compiling and viewing (La)TeX files."));
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(vbox), label);
|
|
|
|
|
|
|
|
table = gtk_table_new(4, 2, FALSE);
|
|
|
|
gtk_table_set_row_spacings(GTK_TABLE(table), 6);
|
|
|
|
gtk_container_add(GTK_CONTAINER(vbox), table);
|
|
|
|
|
|
|
|
// LaTeX -> DVI args
|
|
|
|
if (ft->programs->compiler != NULL)
|
|
|
|
{
|
|
|
|
label = gtk_label_new(_("DVI creation:"));
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
|
|
|
|
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
|
|
|
|
GTK_FILL, GTK_FILL | GTK_EXPAND, 6, 0);
|
|
|
|
|
|
|
|
entries[0] = gtk_entry_new();
|
|
|
|
gtk_entry_set_width_chars(GTK_ENTRY(entries[0]), 30);
|
|
|
|
if (ft->programs->compiler)
|
|
|
|
{
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(entries[0]), ft->programs->compiler);
|
|
|
|
}
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(table), entries[0], 1, 2, 0, 1);
|
|
|
|
g_object_set_data_full(G_OBJECT(dialog), "tex_entry1",
|
|
|
|
gtk_widget_ref(entries[0]), (GDestroyNotify)gtk_widget_unref);
|
|
|
|
}
|
|
|
|
|
|
|
|
// LaTeX -> PDF args
|
|
|
|
if (ft->programs->linker != NULL)
|
|
|
|
{
|
|
|
|
label = gtk_label_new(_("PDF creation:"));
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
|
|
|
|
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
|
|
|
|
GTK_FILL, GTK_FILL | GTK_EXPAND, 6, 0);
|
|
|
|
|
|
|
|
entries[1] = gtk_entry_new();
|
|
|
|
gtk_entry_set_width_chars(GTK_ENTRY(entries[1]), 30);
|
|
|
|
if (ft->programs->linker)
|
|
|
|
{
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(entries[1]), ft->programs->linker);
|
|
|
|
}
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(table), entries[1], 1, 2, 1, 2);
|
|
|
|
g_object_set_data_full(G_OBJECT(dialog), "tex_entry2",
|
|
|
|
gtk_widget_ref(entries[1]), (GDestroyNotify)gtk_widget_unref);
|
|
|
|
}
|
|
|
|
|
|
|
|
// View LaTeX -> DVI args
|
|
|
|
if (ft->programs->run_cmd != NULL)
|
|
|
|
{
|
|
|
|
label = gtk_label_new(_("DVI preview:"));
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
|
|
|
|
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3,
|
|
|
|
GTK_FILL, GTK_FILL | GTK_EXPAND, 6, 0);
|
|
|
|
|
|
|
|
entries[2] = gtk_entry_new();
|
|
|
|
gtk_entry_set_width_chars(GTK_ENTRY(entries[2]), 30);
|
|
|
|
if (ft->programs->run_cmd)
|
|
|
|
{
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(entries[2]), ft->programs->run_cmd);
|
|
|
|
}
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(table), entries[2], 1, 2, 2, 3);
|
|
|
|
g_object_set_data_full(G_OBJECT(dialog), "tex_entry3",
|
|
|
|
gtk_widget_ref(entries[2]), (GDestroyNotify)gtk_widget_unref);
|
|
|
|
}
|
|
|
|
|
|
|
|
// View LaTeX -> PDF args
|
|
|
|
if (ft->programs->run_cmd2 != NULL)
|
|
|
|
{
|
|
|
|
label = gtk_label_new(_("PDF preview:"));
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
|
|
|
|
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4,
|
|
|
|
GTK_FILL, GTK_FILL | GTK_EXPAND, 6, 0);
|
|
|
|
|
|
|
|
entries[3] = gtk_entry_new();
|
|
|
|
gtk_entry_set_width_chars(GTK_ENTRY(entries[3]), 30);
|
|
|
|
if (ft->programs->run_cmd2)
|
|
|
|
{
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(entries[3]), ft->programs->run_cmd2);
|
|
|
|
}
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(table), entries[3], 1, 2, 3, 4);
|
|
|
|
g_object_set_data_full(G_OBJECT(dialog), "tex_entry4",
|
|
|
|
gtk_widget_ref(entries[3]), (GDestroyNotify)gtk_widget_unref);
|
|
|
|
}
|
|
|
|
|
|
|
|
label = gtk_label_new(_("%f will be replaced by the current filename, e.g. test_file.c\n"
|
|
|
|
"%e will be replaced by the filename without extension, e.g. test_file"));
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(vbox), label);
|
|
|
|
|
|
|
|
gtk_widget_show_all(dialog);
|
|
|
|
// run modally to prevent user changing idx filetype
|
|
|
|
response = gtk_dialog_run(GTK_DIALOG(dialog));
|
|
|
|
// call the callback manually
|
|
|
|
on_includes_arguments_tex_dialog_response(GTK_DIALOG(dialog), response, ft);
|
|
|
|
|
|
|
|
gtk_widget_destroy(dialog);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_includes_arguments_dialog_response (GtkDialog *dialog,
|
|
|
|
gint response,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
filetype *ft = user_data;
|
|
|
|
|
|
|
|
g_return_if_fail(ft != NULL);
|
|
|
|
|
|
|
|
if (response == GTK_RESPONSE_ACCEPT)
|
|
|
|
{
|
|
|
|
const gchar *newstr;
|
|
|
|
struct build_programs *programs = ft->programs;
|
|
|
|
|
|
|
|
if (ft->actions->can_compile)
|
|
|
|
{
|
|
|
|
newstr = gtk_entry_get_text(
|
|
|
|
GTK_ENTRY(lookup_widget(GTK_WIDGET(dialog), "includes_entry1")));
|
|
|
|
if (! utils_str_equal(newstr, programs->compiler))
|
|
|
|
{
|
|
|
|
if (programs->compiler) g_free(programs->compiler);
|
|
|
|
programs->compiler = g_strdup(newstr);
|
|
|
|
programs->modified = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ft->actions->can_link)
|
|
|
|
{
|
|
|
|
newstr = gtk_entry_get_text(
|
|
|
|
GTK_ENTRY(lookup_widget(GTK_WIDGET(dialog), "includes_entry2")));
|
|
|
|
if (! utils_str_equal(newstr, programs->linker))
|
|
|
|
{
|
|
|
|
if (programs->linker) g_free(programs->linker);
|
|
|
|
programs->linker = g_strdup(newstr);
|
|
|
|
programs->modified = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ft->actions->can_exec)
|
|
|
|
{
|
|
|
|
newstr = gtk_entry_get_text(
|
|
|
|
GTK_ENTRY(lookup_widget(GTK_WIDGET(dialog), "includes_entry3")));
|
|
|
|
if (! utils_str_equal(newstr, programs->run_cmd))
|
|
|
|
{
|
|
|
|
if (programs->run_cmd) g_free(programs->run_cmd);
|
|
|
|
programs->run_cmd = g_strdup(newstr);
|
|
|
|
programs->modified = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void show_includes_arguments_gen()
|
|
|
|
{
|
|
|
|
GtkWidget *dialog, *label, *entries[3], *vbox;
|
|
|
|
GtkWidget *ft_table = NULL;
|
|
|
|
gint row = 0;
|
|
|
|
gint idx = document_get_cur_idx();
|
|
|
|
gint response;
|
|
|
|
filetype *ft = NULL;
|
|
|
|
|
|
|
|
if (DOC_IDX_VALID(idx)) ft = doc_list[idx].file_type;
|
|
|
|
g_return_if_fail(ft != NULL);
|
|
|
|
|
|
|
|
dialog = gtk_dialog_new_with_buttons(_("Set Includes and Arguments"), GTK_WINDOW(app->window),
|
|
|
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
|
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
|
|
|
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
|
|
|
|
vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog));
|
|
|
|
|
|
|
|
label = gtk_label_new(_("Set the commands for building and running programs."));
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(vbox), label);
|
|
|
|
|
|
|
|
if (ft->actions->can_compile || ft->actions->can_link || ft->actions->can_exec)
|
|
|
|
{
|
|
|
|
GtkWidget *align, *frame;
|
|
|
|
gchar *frame_title = g_strconcat(ft->title, _(" commands"), NULL);
|
|
|
|
|
|
|
|
frame = ui_frame_new_with_alignment(frame_title, &align);
|
|
|
|
gtk_container_add(GTK_CONTAINER(vbox), frame);
|
|
|
|
g_free(frame_title);
|
|
|
|
|
|
|
|
ft_table = gtk_table_new(3, 2, FALSE);
|
|
|
|
gtk_table_set_row_spacings(GTK_TABLE(ft_table), 6);
|
|
|
|
gtk_container_add(GTK_CONTAINER(align), ft_table);
|
|
|
|
row = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// include-args
|
|
|
|
if (ft->actions->can_compile)
|
|
|
|
{
|
|
|
|
label = gtk_label_new(_("Compile:"));
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
|
|
|
|
gtk_table_attach(GTK_TABLE(ft_table), label, 0, 1, row, row + 1,
|
|
|
|
GTK_FILL, GTK_FILL | GTK_EXPAND, 6, 0);
|
|
|
|
|
|
|
|
entries[0] = gtk_entry_new();
|
|
|
|
gtk_entry_set_width_chars(GTK_ENTRY(entries[0]), 30);
|
|
|
|
if (ft->programs->compiler)
|
|
|
|
{
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(entries[0]), ft->programs->compiler);
|
|
|
|
}
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(ft_table), entries[0], 1, 2, row, row + 1);
|
|
|
|
row++;
|
|
|
|
|
|
|
|
g_object_set_data_full(G_OBJECT(dialog), "includes_entry1",
|
|
|
|
gtk_widget_ref(entries[0]), (GDestroyNotify)gtk_widget_unref);
|
|
|
|
}
|
|
|
|
|
|
|
|
// lib-args
|
|
|
|
if (ft->actions->can_link)
|
|
|
|
{
|
|
|
|
label = gtk_label_new(_("Build:"));
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
|
|
|
|
gtk_table_attach(GTK_TABLE(ft_table), label, 0, 1, row, row + 1,
|
|
|
|
GTK_FILL, GTK_FILL | GTK_EXPAND, 6, 0);
|
|
|
|
|
|
|
|
entries[1] = gtk_entry_new();
|
|
|
|
gtk_entry_set_width_chars(GTK_ENTRY(entries[1]), 30);
|
|
|
|
if (ft->programs->linker)
|
|
|
|
{
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(entries[1]), ft->programs->linker);
|
|
|
|
}
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(ft_table), entries[1], 1, 2, row, row + 1);
|
|
|
|
row++;
|
|
|
|
|
|
|
|
g_object_set_data_full(G_OBJECT(dialog), "includes_entry2",
|
|
|
|
gtk_widget_ref(entries[1]), (GDestroyNotify)gtk_widget_unref);
|
|
|
|
}
|
|
|
|
|
|
|
|
// program-args
|
|
|
|
if (ft->actions->can_exec)
|
|
|
|
{
|
|
|
|
label = gtk_label_new(_("Execute:"));
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
|
|
|
|
gtk_table_attach(GTK_TABLE(ft_table), label, 0, 1, row, row + 1,
|
|
|
|
GTK_FILL, GTK_FILL | GTK_EXPAND, 6, 0);
|
|
|
|
|
|
|
|
entries[2] = gtk_entry_new();
|
|
|
|
gtk_entry_set_width_chars(GTK_ENTRY(entries[2]), 30);
|
|
|
|
if (ft->programs->run_cmd)
|
|
|
|
{
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(entries[2]), ft->programs->run_cmd);
|
|
|
|
}
|
|
|
|
gtk_table_attach_defaults(GTK_TABLE(ft_table), entries[2], 1, 2, row, row + 1);
|
|
|
|
row++;
|
|
|
|
|
|
|
|
g_object_set_data_full(G_OBJECT(dialog), "includes_entry3",
|
|
|
|
gtk_widget_ref(entries[2]), (GDestroyNotify)gtk_widget_unref);
|
|
|
|
}
|
|
|
|
|
|
|
|
label = gtk_label_new(_("%f will be replaced by the current filename, e.g. test_file.c\n"
|
|
|
|
"%e will be replaced by the filename without extension, e.g. test_file"));
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
|
|
|
|
gtk_container_add(GTK_CONTAINER(vbox), label);
|
|
|
|
|
|
|
|
gtk_widget_show_all(dialog);
|
|
|
|
// run modally to prevent user changing idx filetype
|
|
|
|
response = gtk_dialog_run(GTK_DIALOG(dialog));
|
|
|
|
// call the callback manually
|
|
|
|
on_includes_arguments_dialog_response(GTK_DIALOG(dialog), response, ft);
|
|
|
|
|
|
|
|
gtk_widget_destroy(dialog);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_build_arguments_activate (GtkMenuItem *menuitem,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
if (user_data && FILETYPE_ID((filetype*) user_data) == GEANY_FILETYPES_LATEX)
|
|
|
|
show_includes_arguments_tex();
|
|
|
|
else
|
|
|
|
show_includes_arguments_gen();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-18 19:35:42 +00:00
|
|
|
static gboolean is_c_header(const gchar *fname)
|
|
|
|
{
|
|
|
|
gchar *ext = NULL;
|
|
|
|
|
|
|
|
if (fname)
|
|
|
|
{
|
|
|
|
ext = strrchr(fname, '.');
|
|
|
|
}
|
|
|
|
return (ext == NULL) ? FALSE : (*(ext + 1) == 'h'); // match *.h*
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-30 15:42:52 +00:00
|
|
|
/* Call this whenever build menu items need to be enabled/disabled.
|
|
|
|
* Uses current document (if there is one) when idx == -1 */
|
2006-10-18 19:35:42 +00:00
|
|
|
void build_menu_update(gint idx)
|
|
|
|
{
|
|
|
|
filetype *ft;
|
2006-12-08 15:50:10 +00:00
|
|
|
gboolean have_path, can_build, can_make, can_run, can_set_args, have_errors;
|
2006-11-30 15:42:52 +00:00
|
|
|
BuildMenuItems *menu_items;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
2006-11-29 10:29:34 +00:00
|
|
|
if (idx == -1)
|
|
|
|
idx = document_get_cur_idx();
|
|
|
|
if (idx == -1 ||
|
|
|
|
(FILETYPE_ID(doc_list[idx].file_type) == GEANY_FILETYPES_ALL &&
|
|
|
|
doc_list[idx].file_name == NULL))
|
2006-10-18 19:35:42 +00:00
|
|
|
{
|
|
|
|
gtk_widget_set_sensitive(lookup_widget(app->window, "menu_build1"), FALSE);
|
|
|
|
gtk_menu_item_remove_submenu(GTK_MENU_ITEM(lookup_widget(app->window, "menu_build1")));
|
|
|
|
gtk_widget_set_sensitive(app->compile_button, FALSE);
|
|
|
|
gtk_widget_set_sensitive(app->run_button, FALSE);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gtk_widget_set_sensitive(lookup_widget(app->window, "menu_build1"), TRUE);
|
|
|
|
|
|
|
|
ft = doc_list[idx].file_type;
|
2006-11-30 15:42:52 +00:00
|
|
|
g_return_if_fail(ft != NULL);
|
2006-10-18 19:35:42 +00:00
|
|
|
|
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
// disable compile and link under Windows until it is implemented
|
2006-12-09 13:06:50 +00:00
|
|
|
ft->actions->can_compile = FALSE;
|
|
|
|
ft->actions->can_link = FALSE;
|
2006-10-18 19:35:42 +00:00
|
|
|
#endif
|
|
|
|
|
2006-12-08 15:50:10 +00:00
|
|
|
menu_items = build_get_menu_items(ft->id);
|
2006-11-29 10:29:34 +00:00
|
|
|
/* Note: don't remove the submenu first because it can now cause an X hang if
|
|
|
|
* the menu is already open when called from build_exit_cb(). */
|
2006-10-18 19:35:42 +00:00
|
|
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(lookup_widget(app->window, "menu_build1")),
|
2006-11-30 15:42:52 +00:00
|
|
|
menu_items->menu);
|
2006-10-18 19:35:42 +00:00
|
|
|
|
|
|
|
have_path = (doc_list[idx].file_name != NULL);
|
2006-11-29 10:29:34 +00:00
|
|
|
|
2006-12-09 13:06:50 +00:00
|
|
|
can_make = have_path && build_info.pid <= (GPid) 1;
|
2006-11-29 10:29:34 +00:00
|
|
|
|
|
|
|
// disable compile and link for C/C++ header files
|
|
|
|
if (ft->id == GEANY_FILETYPES_C || ft->id == GEANY_FILETYPES_CPP)
|
|
|
|
can_build = can_make && ! is_c_header(doc_list[idx].file_name);
|
|
|
|
else
|
|
|
|
can_build = can_make;
|
|
|
|
|
2006-11-30 15:42:52 +00:00
|
|
|
if (menu_items->item_compile)
|
|
|
|
gtk_widget_set_sensitive(menu_items->item_compile, can_build && ft->actions->can_compile);
|
|
|
|
if (menu_items->item_link)
|
|
|
|
gtk_widget_set_sensitive(menu_items->item_link, can_build && ft->actions->can_link);
|
|
|
|
if (menu_items->item_make_all)
|
|
|
|
gtk_widget_set_sensitive(menu_items->item_make_all, can_make);
|
|
|
|
if (menu_items->item_make_custom)
|
|
|
|
gtk_widget_set_sensitive(menu_items->item_make_custom, can_make);
|
|
|
|
if (menu_items->item_make_object)
|
|
|
|
gtk_widget_set_sensitive(menu_items->item_make_object, can_make);
|
|
|
|
|
2006-12-09 13:06:50 +00:00
|
|
|
can_run = have_path && run_info.pid <= (GPid) 1;
|
2006-11-30 15:42:52 +00:00
|
|
|
/* can_run only applies item_exec2
|
|
|
|
* item_exec is enabled for both run and stop commands */
|
|
|
|
if (menu_items->item_exec)
|
|
|
|
gtk_widget_set_sensitive(menu_items->item_exec, have_path && ft->actions->can_exec);
|
|
|
|
if (menu_items->item_exec2)
|
|
|
|
gtk_widget_set_sensitive(menu_items->item_exec2, can_run && ft->actions->can_exec);
|
|
|
|
|
|
|
|
can_set_args =
|
|
|
|
((ft->actions->can_compile ||
|
|
|
|
ft->actions->can_link ||
|
|
|
|
ft->actions->can_exec) &&
|
|
|
|
FILETYPE_ID(ft) != GEANY_FILETYPES_ALL);
|
|
|
|
if (menu_items->item_set_args)
|
|
|
|
gtk_widget_set_sensitive(menu_items->item_set_args, can_set_args);
|
|
|
|
|
|
|
|
gtk_widget_set_sensitive(app->compile_button, can_build && ft->actions->can_compile);
|
|
|
|
gtk_widget_set_sensitive(app->run_button, have_path && ft->actions->can_exec);
|
2006-11-29 10:29:34 +00:00
|
|
|
|
|
|
|
// show the stop command if a program is running, otherwise show run command
|
2006-12-09 13:06:50 +00:00
|
|
|
set_stop_button(run_info.pid > (GPid) 1);
|
2006-12-08 15:50:10 +00:00
|
|
|
|
|
|
|
have_errors = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(msgwindow.store_compiler),
|
|
|
|
NULL) > 0;
|
|
|
|
gtk_widget_set_sensitive(menu_items->item_next_error, have_errors);
|
2006-11-29 10:29:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Call build_menu_update() instead of calling this directly.
|
|
|
|
static void set_stop_button(gboolean stop)
|
|
|
|
{
|
|
|
|
GtkStockItem sitem;
|
|
|
|
GtkWidget *menuitem =
|
2006-12-08 15:50:10 +00:00
|
|
|
build_get_menu_items(run_info.file_type_id)->item_exec;
|
2006-11-29 10:29:34 +00:00
|
|
|
|
2006-12-07 16:09:45 +00:00
|
|
|
if (stop && utils_str_equal(
|
2006-11-29 10:29:34 +00:00
|
|
|
gtk_tool_button_get_stock_id(GTK_TOOL_BUTTON(app->run_button)), "gtk-stop")) return;
|
2006-12-07 16:09:45 +00:00
|
|
|
if (! stop && utils_str_equal(
|
2006-11-29 10:29:34 +00:00
|
|
|
gtk_tool_button_get_stock_id(GTK_TOOL_BUTTON(app->run_button)), "gtk-execute")) return;
|
|
|
|
|
|
|
|
// use the run button also as stop button
|
|
|
|
if (stop)
|
|
|
|
{
|
|
|
|
gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(app->run_button), "gtk-stop");
|
|
|
|
|
|
|
|
if (menuitem != NULL)
|
2006-10-18 19:35:42 +00:00
|
|
|
{
|
2006-11-29 10:29:34 +00:00
|
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem),
|
|
|
|
gtk_image_new_from_stock("gtk-stop", GTK_ICON_SIZE_MENU));
|
|
|
|
gtk_stock_lookup("gtk-stop", &sitem);
|
|
|
|
gtk_label_set_text_with_mnemonic(GTK_LABEL(gtk_bin_get_child(GTK_BIN(menuitem))),
|
|
|
|
sitem.label);
|
2006-10-18 19:35:42 +00:00
|
|
|
}
|
2006-11-29 10:29:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(app->run_button), "gtk-execute");
|
|
|
|
|
|
|
|
if (menuitem != NULL)
|
2006-10-18 19:35:42 +00:00
|
|
|
{
|
2006-11-29 10:29:34 +00:00
|
|
|
// LaTeX hacks ;-(
|
|
|
|
if (run_info.file_type_id == GEANY_FILETYPES_LATEX)
|
|
|
|
{
|
|
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem),
|
|
|
|
gtk_image_new_from_stock("gtk-find", GTK_ICON_SIZE_MENU));
|
|
|
|
gtk_label_set_text_with_mnemonic(GTK_LABEL(gtk_bin_get_child(GTK_BIN(menuitem))),
|
|
|
|
LATEX_VIEW_DVI_LABEL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem),
|
|
|
|
gtk_image_new_from_stock("gtk-execute", GTK_ICON_SIZE_MENU));
|
|
|
|
|
|
|
|
gtk_stock_lookup("gtk-execute", &sitem);
|
|
|
|
gtk_label_set_text_with_mnemonic(GTK_LABEL(gtk_bin_get_child(GTK_BIN(menuitem))),
|
|
|
|
sitem.label);
|
|
|
|
}
|
2006-10-18 19:35:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-12-08 15:50:10 +00:00
|
|
|
/* Creates the relevant build menu if necessary.
|
2007-01-03 16:21:44 +00:00
|
|
|
* If filetype_idx is -1, the current filetype is used, or GEANY_FILETYPES_ALL */
|
|
|
|
BuildMenuItems *build_get_menu_items(gint filetype_idx)
|
2006-11-30 15:42:52 +00:00
|
|
|
{
|
|
|
|
BuildMenuItems *items;
|
|
|
|
|
2007-01-03 16:21:44 +00:00
|
|
|
if (filetype_idx == -1)
|
2006-12-08 15:50:10 +00:00
|
|
|
{
|
|
|
|
gint idx = document_get_cur_idx();
|
|
|
|
filetype *ft = NULL;
|
|
|
|
|
|
|
|
if (DOC_IDX_VALID(idx))
|
|
|
|
ft = doc_list[idx].file_type;
|
2007-01-03 16:21:44 +00:00
|
|
|
filetype_idx = FILETYPE_ID(ft);
|
2006-12-08 15:50:10 +00:00
|
|
|
}
|
|
|
|
|
2007-01-03 16:21:44 +00:00
|
|
|
if (filetype_idx == GEANY_FILETYPES_LATEX)
|
2006-11-30 15:42:52 +00:00
|
|
|
{
|
|
|
|
items = &latex_menu_items;
|
|
|
|
if (items->menu == NULL)
|
|
|
|
create_build_menu_tex(items);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
items = &default_menu_items;
|
|
|
|
if (items->menu == NULL)
|
|
|
|
create_build_menu_gen(items);
|
|
|
|
}
|
|
|
|
return items;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-18 19:35:42 +00:00
|
|
|
void
|
|
|
|
on_build_compile_activate (GtkMenuItem *menuitem,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
gint idx = document_get_cur_idx();
|
2006-11-11 18:51:33 +00:00
|
|
|
|
|
|
|
if (! DOC_IDX_VALID(idx)) return;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
|
|
|
if (doc_list[idx].changed) document_save_file(idx, FALSE);
|
|
|
|
|
|
|
|
if (doc_list[idx].file_type->id == GEANY_FILETYPES_LATEX)
|
2006-11-11 18:51:33 +00:00
|
|
|
build_compile_tex_file(idx, 0);
|
2006-10-18 19:35:42 +00:00
|
|
|
else
|
2006-11-11 18:51:33 +00:00
|
|
|
build_compile_file(idx);
|
2006-10-18 19:35:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
on_build_tex_activate (GtkMenuItem *menuitem,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
gint idx = document_get_cur_idx();
|
|
|
|
|
|
|
|
if (doc_list[idx].changed) document_save_file(idx, FALSE);
|
|
|
|
|
|
|
|
switch (GPOINTER_TO_INT(user_data))
|
|
|
|
{
|
2006-11-11 18:51:33 +00:00
|
|
|
case LATEX_CMD_TO_DVI:
|
|
|
|
case LATEX_CMD_TO_PDF:
|
|
|
|
build_compile_tex_file(idx, GPOINTER_TO_INT(user_data)); break;
|
|
|
|
case LATEX_CMD_VIEW_DVI:
|
|
|
|
case LATEX_CMD_VIEW_PDF:
|
|
|
|
build_view_tex_file(idx, GPOINTER_TO_INT(user_data)); break;
|
2006-10-18 19:35:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
on_build_build_activate (GtkMenuItem *menuitem,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
gint idx = document_get_cur_idx();
|
2006-11-11 18:51:33 +00:00
|
|
|
|
|
|
|
if (! DOC_IDX_VALID(idx)) return;
|
2006-10-18 19:35:42 +00:00
|
|
|
|
|
|
|
if (doc_list[idx].changed) document_save_file(idx, FALSE);
|
|
|
|
|
|
|
|
if (doc_list[idx].file_type->id == GEANY_FILETYPES_LATEX)
|
2006-11-11 18:51:33 +00:00
|
|
|
build_compile_tex_file(idx, 1);
|
2006-10-18 19:35:42 +00:00
|
|
|
else
|
2006-11-11 18:51:33 +00:00
|
|
|
build_link_file(idx);
|
2006-10-18 19:35:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
on_build_make_activate (GtkMenuItem *menuitem,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
gint idx = document_get_cur_idx();
|
|
|
|
gint build_opts = GPOINTER_TO_INT(user_data);
|
|
|
|
|
|
|
|
g_return_if_fail(DOC_IDX_VALID(idx) && doc_list[idx].file_name != NULL);
|
|
|
|
|
|
|
|
switch (build_opts)
|
|
|
|
{
|
|
|
|
case GBO_MAKE_CUSTOM:
|
|
|
|
{
|
2006-12-12 12:12:20 +00:00
|
|
|
dialogs_show_input(_("Make Custom Target"),
|
2006-10-18 19:35:42 +00:00
|
|
|
_("Enter custom options here, all entered text is passed to the make command."),
|
|
|
|
build_info.custom_target,
|
|
|
|
G_CALLBACK(on_make_target_dialog_response),
|
|
|
|
G_CALLBACK(on_make_target_entry_activate));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GBO_MAKE_OBJECT:
|
|
|
|
// fall through
|
|
|
|
case GBO_MAKE_ALL:
|
|
|
|
{
|
|
|
|
if (doc_list[idx].changed) document_save_file(idx, FALSE);
|
|
|
|
|
2006-11-11 18:51:33 +00:00
|
|
|
build_make_file(idx, build_opts);
|
2006-10-18 19:35:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
on_build_execute_activate (GtkMenuItem *menuitem,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
gint idx = document_get_cur_idx();
|
|
|
|
|
2006-11-11 18:51:33 +00:00
|
|
|
// make the process "stopable"
|
2006-11-29 10:29:34 +00:00
|
|
|
if (run_info.pid > (GPid) 1)
|
2006-10-18 19:35:42 +00:00
|
|
|
{
|
2006-11-17 17:49:16 +00:00
|
|
|
// on Windows there is no PID returned (resp. it is a handle), currently unsupported
|
|
|
|
#ifndef G_OS_WIN32
|
2006-11-29 10:29:34 +00:00
|
|
|
kill_process(&run_info.pid);
|
2006-11-17 17:49:16 +00:00
|
|
|
#endif
|
2006-11-11 18:51:33 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (doc_list[idx].file_type->id == GEANY_FILETYPES_LATEX)
|
|
|
|
{ // run LaTeX file
|
2006-10-18 19:35:42 +00:00
|
|
|
if (build_view_tex_file(idx, GPOINTER_TO_INT(user_data)) == (GPid) 0)
|
|
|
|
{
|
|
|
|
msgwin_status_add(_("Failed to execute the view program"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (doc_list[idx].file_type->id == GEANY_FILETYPES_HTML)
|
2006-11-11 18:51:33 +00:00
|
|
|
{ // run HTML file
|
2006-10-18 19:35:42 +00:00
|
|
|
gchar *uri = g_strconcat("file:///", g_path_skip_root(doc_list[idx].file_name), NULL);
|
|
|
|
utils_start_browser(uri);
|
|
|
|
g_free(uri);
|
|
|
|
}
|
|
|
|
else
|
2006-11-11 18:51:33 +00:00
|
|
|
{ // run everything else
|
|
|
|
|
2006-10-18 19:35:42 +00:00
|
|
|
// save the file only if the run command uses it
|
|
|
|
if (doc_list[idx].changed &&
|
|
|
|
strstr(doc_list[idx].file_type->programs->run_cmd, "%f") != NULL)
|
|
|
|
document_save_file(idx, FALSE);
|
2006-11-11 18:51:33 +00:00
|
|
|
|
2006-10-18 19:35:42 +00:00
|
|
|
if (build_run_cmd(idx) == (GPid) 0)
|
|
|
|
{
|
|
|
|
msgwin_status_add(_("Failed to execute the terminal program"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_make_target_dialog_response (GtkDialog *dialog,
|
|
|
|
gint response,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
if (response == GTK_RESPONSE_ACCEPT)
|
|
|
|
{
|
|
|
|
gint idx = document_get_cur_idx();
|
|
|
|
|
|
|
|
if (doc_list[idx].changed) document_save_file(idx, FALSE);
|
|
|
|
|
|
|
|
g_free(build_info.custom_target);
|
|
|
|
build_info.custom_target = g_strdup(gtk_entry_get_text(GTK_ENTRY(user_data)));
|
|
|
|
|
2006-11-11 18:51:33 +00:00
|
|
|
build_make_file(idx, GBO_MAKE_CUSTOM);
|
2006-10-18 19:35:42 +00:00
|
|
|
}
|
|
|
|
gtk_widget_destroy(GTK_WIDGET(dialog));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_make_target_entry_activate (GtkEntry *entry,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
on_make_target_dialog_response(GTK_DIALOG(user_data), GTK_RESPONSE_ACCEPT, entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-17 17:49:16 +00:00
|
|
|
#ifndef G_OS_WIN32
|
2006-11-29 10:29:34 +00:00
|
|
|
static void kill_process(GPid *pid)
|
2006-11-11 18:51:33 +00:00
|
|
|
{
|
|
|
|
/* SIGQUIT is not the best signal to use because it causes a core dump (this should not
|
|
|
|
* perforce necessary for just killing a process). But we must use a signal which we can
|
|
|
|
* ignore because the main process get it too, it is declared to ignore in main.c. */
|
|
|
|
|
2007-02-25 13:08:01 +00:00
|
|
|
gint result;
|
|
|
|
|
|
|
|
g_return_if_fail(*pid > 1);
|
2006-11-11 18:51:33 +00:00
|
|
|
|
2006-11-29 10:29:34 +00:00
|
|
|
result = kill(*pid, SIGQUIT);
|
2006-11-11 18:51:33 +00:00
|
|
|
|
2007-02-25 13:08:01 +00:00
|
|
|
if (result != 0)
|
2006-11-11 18:51:33 +00:00
|
|
|
msgwin_status_add(_("Process could not be stopped (%s)."), g_strerror(errno));
|
|
|
|
else
|
|
|
|
{
|
2006-11-29 10:29:34 +00:00
|
|
|
*pid = 0;
|
|
|
|
build_menu_update(-1);
|
2006-11-11 18:51:33 +00:00
|
|
|
}
|
|
|
|
}
|
2006-11-17 17:49:16 +00:00
|
|
|
#endif
|
2006-11-11 18:51:33 +00:00
|
|
|
|
|
|
|
|
2006-12-08 15:50:10 +00:00
|
|
|
void
|
|
|
|
on_build_next_error (GtkMenuItem *menuitem,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
2007-03-12 12:13:45 +00:00
|
|
|
if (ui_tree_view_find_next(GTK_TREE_VIEW(msgwindow.tree_compiler),
|
2006-12-08 15:50:10 +00:00
|
|
|
msgwin_goto_compiler_file_line))
|
2007-03-12 12:13:45 +00:00
|
|
|
{
|
|
|
|
gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_COMPILER);
|
|
|
|
}
|
|
|
|
else
|
2006-12-08 15:50:10 +00:00
|
|
|
ui_set_statusbar(_("No more build errors."));
|
|
|
|
}
|
|
|
|
|
|
|
|
|