2005-11-22 12:26:26 +00:00
|
|
|
/*
|
|
|
|
* templates.c - this file is part of Geany, a fast and lightweight IDE
|
|
|
|
*
|
2010-01-01 22:55:18 +00:00
|
|
|
* Copyright 2005-2010 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
|
|
|
|
* Copyright 2006-2010 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)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-05-10 19:54:44 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2005-11-22 12:26:26 +00:00
|
|
|
*
|
2005-12-20 17:50:11 +00:00
|
|
|
* $Id$
|
2005-11-22 12:26:26 +00:00
|
|
|
*/
|
|
|
|
|
2007-02-24 11:41:56 +00:00
|
|
|
/*
|
|
|
|
* Templates to insert into the current document, or filetype templates to create a new
|
|
|
|
* document from.
|
|
|
|
*/
|
|
|
|
|
2005-11-22 12:26:26 +00:00
|
|
|
#include <time.h>
|
2007-01-06 15:03:53 +00:00
|
|
|
#include <string.h>
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
#include "geany.h"
|
|
|
|
|
|
|
|
#include "templates.h"
|
|
|
|
#include "support.h"
|
|
|
|
#include "utils.h"
|
2006-08-20 15:47:18 +00:00
|
|
|
#include "document.h"
|
2010-08-01 17:20:50 +00:00
|
|
|
#include "editor.h"
|
2007-08-15 15:37:21 +00:00
|
|
|
#include "filetypes.h"
|
2007-08-23 11:34:06 +00:00
|
|
|
#include "ui_utils.h"
|
2009-06-20 16:51:32 +00:00
|
|
|
#include "toolbar.h"
|
|
|
|
#include "geanymenubuttonaction.h"
|
2010-05-05 13:06:53 +00:00
|
|
|
#include "project.h"
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-09-17 19:58:04 +00:00
|
|
|
|
2008-05-16 12:08:39 +00:00
|
|
|
GeanyTemplatePrefs template_prefs;
|
|
|
|
|
2009-10-01 14:40:42 +00:00
|
|
|
static GtkWidget *new_with_template_menu = NULL; /* submenu used for both file menu and toolbar */
|
2008-05-13 17:18:14 +00:00
|
|
|
|
2010-06-16 15:26:04 +00:00
|
|
|
/* TODO: implement custom insertion templates instead? */
|
2006-09-17 19:58:04 +00:00
|
|
|
static gchar *templates[GEANY_MAX_TEMPLATES];
|
2009-08-12 11:19:54 +00:00
|
|
|
|
2009-09-30 17:40:10 +00:00
|
|
|
/* We should probably remove filetype templates support soon - users can use custom
|
|
|
|
* file templates instead. */
|
2008-05-07 11:34:38 +00:00
|
|
|
static gchar *ft_templates[GEANY_MAX_BUILT_IN_FILETYPES] = {NULL};
|
2006-09-17 19:58:04 +00:00
|
|
|
|
|
|
|
|
2010-01-24 14:52:46 +00:00
|
|
|
static void replace_static_values(GString *text);
|
2010-04-21 16:47:54 +00:00
|
|
|
static gchar *get_template_fileheader(GeanyFiletype *ft);
|
2010-04-22 13:01:45 +00:00
|
|
|
|
|
|
|
/* called by templates_replace_common */
|
2010-04-21 17:19:27 +00:00
|
|
|
static void templates_replace_default_dates(GString *text);
|
|
|
|
static void templates_replace_command(GString *text, const gchar *file_name,
|
|
|
|
const gchar *file_type, const gchar *func_name);
|
2010-01-24 14:52:46 +00:00
|
|
|
|
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* some simple macros to reduce code size and make the code readable */
|
2007-02-19 13:26:06 +00:00
|
|
|
#define TEMPLATES_GET_FILENAME(shortname) \
|
|
|
|
g_strconcat(app->configdir, \
|
|
|
|
G_DIR_SEPARATOR_S GEANY_TEMPLATES_SUBDIR G_DIR_SEPARATOR_S, shortname, NULL)
|
|
|
|
|
|
|
|
#define TEMPLATES_READ_FILE(fname, contents_ptr) \
|
|
|
|
g_file_get_contents(fname, contents_ptr, NULL, NULL);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
|
2010-06-09 12:27:58 +00:00
|
|
|
static void read_template(const gchar *name, gint id)
|
2009-06-21 21:19:18 +00:00
|
|
|
{
|
2010-06-09 12:27:58 +00:00
|
|
|
gchar *fname = TEMPLATES_GET_FILENAME(name);
|
|
|
|
|
|
|
|
/* try system if user template doesn't exist */
|
|
|
|
if (!g_file_test(fname, G_FILE_TEST_EXISTS))
|
|
|
|
setptr(fname, g_strconcat(app->datadir,
|
|
|
|
G_DIR_SEPARATOR_S GEANY_TEMPLATES_SUBDIR G_DIR_SEPARATOR_S, name, NULL));
|
|
|
|
|
|
|
|
TEMPLATES_READ_FILE(fname, &templates[id]);
|
|
|
|
|
|
|
|
/* FIXME: we should replace the line ends on insertion with doc pref, not on loading */
|
|
|
|
if (file_prefs.default_eol_character != SC_EOL_LF)
|
2009-06-21 21:19:18 +00:00
|
|
|
{
|
2010-06-09 12:27:58 +00:00
|
|
|
/* Replace the \n characters in the default template text by the proper
|
|
|
|
* platform-specific line ending characters. */
|
|
|
|
GString *tmp = g_string_new(templates[id]);
|
|
|
|
const gchar *eol_str = (file_prefs.default_eol_character == SC_EOL_CR) ? "\r" : "\r\n";
|
|
|
|
|
|
|
|
utils_string_replace_all(tmp, "\n", eol_str);
|
|
|
|
setptr(templates[id], tmp->str);
|
|
|
|
g_string_free(tmp, FALSE);
|
2009-06-21 21:19:18 +00:00
|
|
|
}
|
2010-06-09 12:27:58 +00:00
|
|
|
g_free(fname);
|
2009-06-21 21:19:18 +00:00
|
|
|
}
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2009-09-16 14:13:38 +00:00
|
|
|
|
2008-11-21 18:19:36 +00:00
|
|
|
/* FIXME the callers should use GStrings instead of char arrays */
|
|
|
|
static gchar *replace_all(gchar *text, const gchar *year, const gchar *date, const gchar *datetime)
|
|
|
|
{
|
|
|
|
GString *str;
|
|
|
|
|
2009-04-15 22:47:33 +00:00
|
|
|
if (text == NULL)
|
2008-11-21 18:19:36 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
str = g_string_new(text);
|
|
|
|
|
|
|
|
g_free(text);
|
2010-01-12 21:10:46 +00:00
|
|
|
templates_replace_valist(str,
|
|
|
|
"{year}", year,
|
|
|
|
"{date}", date,
|
|
|
|
"{datetime}", datetime,
|
|
|
|
NULL);
|
2008-11-21 18:19:36 +00:00
|
|
|
|
|
|
|
return g_string_free(str, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-01 17:20:50 +00:00
|
|
|
static void convert_eol_characters(GString *template, GeanyDocument *doc)
|
|
|
|
{
|
|
|
|
gint doc_eol_mode;
|
|
|
|
|
|
|
|
if (doc == NULL)
|
|
|
|
doc = document_get_current();
|
|
|
|
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
|
|
|
|
doc_eol_mode = editor_get_eol_char_mode(doc->editor);
|
|
|
|
utils_ensure_same_eol_characters(template, doc_eol_mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-10 18:27:23 +00:00
|
|
|
static void init_general_templates(const gchar *year, const gchar *date, const gchar *datetime)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2010-06-09 12:27:58 +00:00
|
|
|
guint id;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* read the contents */
|
2010-06-09 12:27:58 +00:00
|
|
|
read_template("fileheader", GEANY_TEMPLATE_FILEHEADER);
|
|
|
|
read_template("gpl", GEANY_TEMPLATE_GPL);
|
|
|
|
read_template("bsd", GEANY_TEMPLATE_BSD);
|
|
|
|
read_template("function", GEANY_TEMPLATE_FUNCTION);
|
|
|
|
read_template("changelog", GEANY_TEMPLATE_CHANGELOG);
|
|
|
|
|
|
|
|
/* FIXME: we should replace the dates on insertion, not on loading */
|
|
|
|
for (id = 0; id < GEANY_MAX_TEMPLATES; id++)
|
|
|
|
templates[id] = replace_all(templates[id], year, date, datetime);
|
2007-02-19 13:26:06 +00:00
|
|
|
}
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
|
2008-11-10 18:27:23 +00:00
|
|
|
static void init_ft_templates(const gchar *year, const gchar *date, const gchar *datetime)
|
2007-02-19 13:26:06 +00:00
|
|
|
{
|
|
|
|
filetype_id ft_id;
|
2006-07-09 14:41:53 +00:00
|
|
|
|
2008-05-07 11:34:38 +00:00
|
|
|
for (ft_id = 0; ft_id < GEANY_MAX_BUILT_IN_FILETYPES; ft_id++)
|
2007-02-19 13:26:06 +00:00
|
|
|
{
|
|
|
|
gchar *ext = filetypes_get_conf_extension(ft_id);
|
|
|
|
gchar *shortname = g_strconcat("filetype.", ext, NULL);
|
|
|
|
gchar *fname = TEMPLATES_GET_FILENAME(shortname);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2007-02-19 13:26:06 +00:00
|
|
|
TEMPLATES_READ_FILE(fname, &ft_templates[ft_id]);
|
2008-11-21 18:19:36 +00:00
|
|
|
ft_templates[ft_id] = replace_all(ft_templates[ft_id], year, date, datetime);
|
2007-02-19 13:26:06 +00:00
|
|
|
|
|
|
|
g_free(fname);
|
|
|
|
g_free(shortname);
|
|
|
|
g_free(ext);
|
|
|
|
}
|
|
|
|
}
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
|
2007-02-19 13:26:06 +00:00
|
|
|
static void
|
2009-10-01 11:06:08 +00:00
|
|
|
on_new_with_filetype_template(GtkMenuItem *menuitem, gpointer user_data)
|
2007-02-19 13:26:06 +00:00
|
|
|
{
|
2008-05-16 14:17:54 +00:00
|
|
|
GeanyFiletype *ft = user_data;
|
2007-09-03 16:09:53 +00:00
|
|
|
gchar *template = templates_get_template_new_file(ft);
|
|
|
|
|
|
|
|
document_new_file(NULL, ft, template);
|
|
|
|
g_free(template);
|
2007-02-19 13:26:06 +00:00
|
|
|
}
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2006-09-05 16:55:40 +00:00
|
|
|
|
2009-10-12 11:15:08 +00:00
|
|
|
/* TODO: remove filetype template support after 0.19 */
|
2009-10-01 11:56:04 +00:00
|
|
|
static gboolean create_new_filetype_items(void)
|
2007-02-19 13:26:06 +00:00
|
|
|
{
|
2009-03-31 14:32:03 +00:00
|
|
|
GSList *node;
|
2009-10-01 11:56:04 +00:00
|
|
|
gboolean ret = FALSE;
|
2009-10-12 11:15:08 +00:00
|
|
|
GtkWidget *menu = NULL;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2009-06-12 15:32:35 +00:00
|
|
|
foreach_slist(node, filetypes_by_title)
|
2007-02-19 13:26:06 +00:00
|
|
|
{
|
2009-06-12 15:32:35 +00:00
|
|
|
GeanyFiletype *ft = node->data;
|
2009-10-12 11:15:08 +00:00
|
|
|
GtkWidget *item;
|
2007-02-19 13:26:06 +00:00
|
|
|
|
2009-10-01 11:06:08 +00:00
|
|
|
if (ft->id >= GEANY_MAX_BUILT_IN_FILETYPES || ft_templates[ft->id] == NULL)
|
2007-02-19 13:26:06 +00:00
|
|
|
continue;
|
2008-12-06 11:10:06 +00:00
|
|
|
|
2009-10-12 11:15:08 +00:00
|
|
|
if (!menu)
|
|
|
|
{
|
|
|
|
item = gtk_menu_item_new_with_label(_("Old"));
|
|
|
|
menu = gtk_menu_new();
|
|
|
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
|
|
|
|
gtk_widget_show_all(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(new_with_template_menu), item);
|
|
|
|
}
|
|
|
|
item = gtk_menu_item_new_with_label(ft->title);
|
|
|
|
gtk_widget_show(item);
|
|
|
|
gtk_container_add(GTK_CONTAINER(menu), item);
|
|
|
|
g_signal_connect(item, "activate", G_CALLBACK(on_new_with_filetype_template), ft);
|
2009-10-01 11:56:04 +00:00
|
|
|
ret = TRUE;
|
2007-02-19 13:26:06 +00:00
|
|
|
}
|
2009-10-01 11:56:04 +00:00
|
|
|
return ret;
|
2007-02-19 13:26:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-21 17:19:27 +00:00
|
|
|
void templates_replace_common(GString *template, const gchar *fname,
|
|
|
|
GeanyFiletype *ft, const gchar *func_name)
|
2010-04-21 16:47:54 +00:00
|
|
|
{
|
|
|
|
gchar *shortname;
|
|
|
|
|
|
|
|
if (fname == NULL)
|
|
|
|
{
|
|
|
|
if (!ft->extension)
|
|
|
|
shortname = g_strdup(GEANY_STRING_UNTITLED);
|
|
|
|
else
|
|
|
|
shortname = g_strconcat(GEANY_STRING_UNTITLED, ".", ft->extension, NULL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
shortname = g_path_get_basename(fname);
|
|
|
|
|
|
|
|
templates_replace_valist(template,
|
|
|
|
"{filename}", shortname,
|
2010-05-05 13:06:53 +00:00
|
|
|
"{project}", app->project ? app->project->name : "",
|
|
|
|
"{description}", app->project ? app->project->description : "",
|
2010-04-21 16:47:54 +00:00
|
|
|
NULL);
|
|
|
|
g_free(shortname);
|
|
|
|
|
|
|
|
templates_replace_default_dates(template);
|
|
|
|
templates_replace_command(template, fname, ft->name, func_name);
|
|
|
|
/* Bug: command results could have {ob} {cb} strings in! */
|
|
|
|
/* replace braces last */
|
|
|
|
templates_replace_valist(template,
|
|
|
|
"{ob}", "{",
|
|
|
|
"{cb}", "}",
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-10 18:27:23 +00:00
|
|
|
static gchar *get_template_from_file(const gchar *locale_fname, const gchar *doc_filename,
|
|
|
|
GeanyFiletype *ft)
|
2008-05-13 17:18:14 +00:00
|
|
|
{
|
2008-11-21 18:19:36 +00:00
|
|
|
gchar *content;
|
|
|
|
GString *template = NULL;
|
2008-05-13 17:18:14 +00:00
|
|
|
|
2008-11-21 18:19:36 +00:00
|
|
|
g_file_get_contents(locale_fname, &content, NULL, NULL);
|
2008-05-13 17:18:14 +00:00
|
|
|
|
2009-04-15 22:47:33 +00:00
|
|
|
if (content != NULL)
|
2008-05-13 17:18:14 +00:00
|
|
|
{
|
|
|
|
gchar *file_header;
|
|
|
|
|
2008-11-21 18:19:36 +00:00
|
|
|
template = g_string_new(content);
|
2008-05-13 17:18:14 +00:00
|
|
|
|
2010-04-21 16:47:54 +00:00
|
|
|
file_header = get_template_fileheader(ft);
|
2010-01-12 21:10:46 +00:00
|
|
|
templates_replace_valist(template,
|
|
|
|
"{fileheader}", file_header,
|
|
|
|
NULL);
|
2010-04-21 16:47:54 +00:00
|
|
|
templates_replace_common(template, doc_filename, ft, NULL);
|
2008-11-10 18:27:23 +00:00
|
|
|
|
2010-01-12 21:10:46 +00:00
|
|
|
utils_free_pointers(2, file_header, content, NULL);
|
2009-09-30 14:39:47 +00:00
|
|
|
return g_string_free(template, FALSE);
|
2008-05-13 17:18:14 +00:00
|
|
|
}
|
2009-09-30 14:39:47 +00:00
|
|
|
return NULL;
|
2008-05-13 17:18:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_new_with_file_template(GtkMenuItem *menuitem, G_GNUC_UNUSED gpointer user_data)
|
|
|
|
{
|
|
|
|
gchar *fname = ui_menu_item_get_text(menuitem);
|
2008-05-16 14:17:54 +00:00
|
|
|
GeanyFiletype *ft;
|
2008-05-13 17:18:14 +00:00
|
|
|
gchar *template;
|
2009-09-30 14:39:47 +00:00
|
|
|
const gchar *extension = strrchr(fname, '.'); /* easy way to get the file extension */
|
2008-11-10 18:27:23 +00:00
|
|
|
gchar *new_filename = g_strconcat(GEANY_STRING_UNTITLED, extension, NULL);
|
2009-09-30 14:39:47 +00:00
|
|
|
gchar *path;
|
2008-05-13 17:18:14 +00:00
|
|
|
|
|
|
|
ft = filetypes_detect_from_extension(fname);
|
|
|
|
setptr(fname, utils_get_locale_from_utf8(fname));
|
2009-09-30 14:39:47 +00:00
|
|
|
|
2008-05-13 17:18:14 +00:00
|
|
|
/* fname is just the basename from the menu item, so prepend the custom files path */
|
2009-09-30 14:39:47 +00:00
|
|
|
path = g_build_path(G_DIR_SEPARATOR_S, app->configdir, GEANY_TEMPLATES_SUBDIR,
|
|
|
|
"files", fname, NULL);
|
|
|
|
template = get_template_from_file(path, new_filename, ft);
|
|
|
|
if (!template)
|
|
|
|
{
|
|
|
|
/* try the system path */
|
2009-10-01 16:43:32 +00:00
|
|
|
g_free(path);
|
2009-09-30 14:39:47 +00:00
|
|
|
path = g_build_path(G_DIR_SEPARATOR_S, app->datadir, GEANY_TEMPLATES_SUBDIR,
|
|
|
|
"files", fname, NULL);
|
|
|
|
template = get_template_from_file(path, new_filename, ft);
|
|
|
|
}
|
2009-10-01 16:39:38 +00:00
|
|
|
if (template)
|
|
|
|
document_new_file(new_filename, ft, template);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setptr(fname, utils_get_utf8_from_locale(fname));
|
|
|
|
ui_set_statusbar(TRUE, _("Could not find file '%s'."), fname);
|
|
|
|
}
|
2008-05-13 17:18:14 +00:00
|
|
|
g_free(template);
|
2009-10-01 16:39:38 +00:00
|
|
|
g_free(path);
|
2008-11-10 18:27:23 +00:00
|
|
|
g_free(new_filename);
|
2009-10-01 16:39:38 +00:00
|
|
|
g_free(fname);
|
2008-05-13 17:18:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-10-01 11:56:04 +00:00
|
|
|
static void add_file_item(const gchar *fname, GtkWidget *menu)
|
2008-05-13 17:18:14 +00:00
|
|
|
{
|
2009-10-01 14:40:42 +00:00
|
|
|
GtkWidget *tmp_button;
|
2008-05-13 17:18:14 +00:00
|
|
|
gchar *label;
|
|
|
|
|
2009-10-01 11:56:04 +00:00
|
|
|
g_return_if_fail(fname);
|
|
|
|
g_return_if_fail(menu);
|
2008-05-13 17:18:14 +00:00
|
|
|
|
2009-10-01 11:56:04 +00:00
|
|
|
label = utils_get_utf8_from_locale(fname);
|
2008-05-13 17:18:14 +00:00
|
|
|
|
2009-06-20 16:51:32 +00:00
|
|
|
tmp_button = gtk_menu_item_new_with_label(label);
|
|
|
|
gtk_widget_show(tmp_button);
|
2009-10-01 11:56:04 +00:00
|
|
|
gtk_container_add(GTK_CONTAINER(menu), tmp_button);
|
2009-06-20 16:51:32 +00:00
|
|
|
g_signal_connect(tmp_button, "activate", G_CALLBACK(on_new_with_file_template), NULL);
|
|
|
|
|
2008-12-06 11:10:06 +00:00
|
|
|
g_free(label);
|
2008-05-13 17:18:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-29 11:39:35 +00:00
|
|
|
static gboolean add_custom_template_items(void)
|
2008-05-13 17:18:14 +00:00
|
|
|
{
|
2009-11-04 14:47:07 +00:00
|
|
|
GSList *list = utils_get_config_files(GEANY_TEMPLATES_SUBDIR G_DIR_SEPARATOR_S "files");
|
|
|
|
GSList *node;
|
2008-05-13 17:18:14 +00:00
|
|
|
|
2009-10-12 10:53:39 +00:00
|
|
|
foreach_slist(node, list)
|
|
|
|
{
|
|
|
|
gchar *fname = node->data;
|
|
|
|
|
|
|
|
add_file_item(fname, new_with_template_menu);
|
|
|
|
g_free(fname);
|
|
|
|
}
|
2008-05-13 17:18:14 +00:00
|
|
|
g_slist_free(list);
|
2009-09-30 14:39:47 +00:00
|
|
|
return list != NULL;
|
2008-05-13 17:18:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-10-01 14:40:42 +00:00
|
|
|
static void create_file_template_menu(void)
|
2008-05-13 17:18:14 +00:00
|
|
|
{
|
2009-10-01 14:40:42 +00:00
|
|
|
GtkWidget *sep = NULL;
|
2008-05-13 17:18:14 +00:00
|
|
|
|
2009-10-01 14:40:42 +00:00
|
|
|
new_with_template_menu = gtk_menu_new();
|
2009-06-20 16:51:32 +00:00
|
|
|
|
2009-09-29 12:10:17 +00:00
|
|
|
if (add_custom_template_items())
|
2009-10-01 11:56:04 +00:00
|
|
|
{
|
2009-10-01 14:40:42 +00:00
|
|
|
sep = gtk_separator_menu_item_new();
|
|
|
|
gtk_container_add(GTK_CONTAINER(new_with_template_menu), sep);
|
2009-10-01 11:56:04 +00:00
|
|
|
}
|
2009-10-01 14:40:42 +00:00
|
|
|
if (create_new_filetype_items() && sep)
|
2008-05-13 17:18:14 +00:00
|
|
|
{
|
2009-10-01 14:40:42 +00:00
|
|
|
gtk_widget_show(sep);
|
2008-05-13 17:18:14 +00:00
|
|
|
}
|
2009-10-01 14:40:42 +00:00
|
|
|
/* unless the file menu is showing, menu should be in the toolbar widget */
|
2009-06-20 16:51:32 +00:00
|
|
|
geany_menu_button_action_set_menu(GEANY_MENU_BUTTON_ACTION(
|
2009-10-01 14:40:42 +00:00
|
|
|
toolbar_get_action_by_name("New")), new_with_template_menu);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-10-27 17:27:24 +00:00
|
|
|
static void on_file_menu_show(GtkWidget *item)
|
2009-10-01 14:40:42 +00:00
|
|
|
{
|
|
|
|
geany_menu_button_action_set_menu(
|
|
|
|
GEANY_MENU_BUTTON_ACTION(toolbar_get_action_by_name("New")), NULL);
|
|
|
|
item = ui_lookup_widget(main_widgets.window, "menu_new_with_template1");
|
|
|
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), new_with_template_menu);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-10-27 17:27:24 +00:00
|
|
|
static void on_file_menu_hide(GtkWidget *item)
|
2009-10-01 14:40:42 +00:00
|
|
|
{
|
|
|
|
item = ui_lookup_widget(main_widgets.window, "menu_new_with_template1");
|
|
|
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), NULL);
|
|
|
|
geany_menu_button_action_set_menu(
|
|
|
|
GEANY_MENU_BUTTON_ACTION(toolbar_get_action_by_name("New")), new_with_template_menu);
|
2008-05-13 17:18:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-06 12:45:19 +00:00
|
|
|
/* reload templates if any file in the templates path is saved */
|
|
|
|
static void on_document_save(G_GNUC_UNUSED GObject *object, GeanyDocument *doc)
|
|
|
|
{
|
|
|
|
const gchar *path = utils_build_path(app->configdir, GEANY_TEMPLATES_SUBDIR, NULL);
|
|
|
|
|
|
|
|
g_return_if_fail(NZV(doc->real_path));
|
|
|
|
|
|
|
|
if (strncmp(doc->real_path, path, strlen(path)) == 0)
|
|
|
|
{
|
|
|
|
/* reload templates */
|
|
|
|
templates_free_templates();
|
|
|
|
templates_init();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-07 13:21:32 +00:00
|
|
|
/* warning: also called when reloading template settings */
|
2007-02-19 13:26:06 +00:00
|
|
|
void templates_init(void)
|
|
|
|
{
|
2008-07-13 11:51:00 +00:00
|
|
|
gchar *year = utils_get_date_time(template_prefs.year_format, NULL);
|
|
|
|
gchar *date = utils_get_date_time(template_prefs.date_format, NULL);
|
2008-11-10 18:27:23 +00:00
|
|
|
gchar *datetime = utils_get_date_time(template_prefs.datetime_format, NULL);
|
2010-05-07 13:21:32 +00:00
|
|
|
static gboolean init_done = FALSE;
|
2007-02-19 13:26:06 +00:00
|
|
|
|
2008-11-10 18:27:23 +00:00
|
|
|
init_general_templates(year, date, datetime);
|
|
|
|
init_ft_templates(year, date, datetime);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
|
|
|
g_free(date);
|
2008-11-16 17:55:05 +00:00
|
|
|
g_free(datetime);
|
2005-11-22 12:26:26 +00:00
|
|
|
g_free(year);
|
2008-05-13 17:18:14 +00:00
|
|
|
|
2009-10-01 14:40:42 +00:00
|
|
|
create_file_template_menu();
|
2009-10-27 17:27:24 +00:00
|
|
|
/* we hold our own ref for the menu as it has no parent whilst being moved */
|
2009-10-01 14:40:42 +00:00
|
|
|
g_object_ref(new_with_template_menu);
|
2009-10-27 17:27:24 +00:00
|
|
|
|
2010-05-07 13:21:32 +00:00
|
|
|
/* only connect signals to persistent objects once */
|
|
|
|
if (!init_done)
|
|
|
|
{
|
|
|
|
GtkWidget *item;
|
|
|
|
/* reparent the template menu as needed */
|
|
|
|
item = ui_lookup_widget(main_widgets.window, "file1");
|
|
|
|
item = gtk_menu_item_get_submenu(GTK_MENU_ITEM(item));
|
|
|
|
g_signal_connect(item, "show", G_CALLBACK(on_file_menu_show), NULL);
|
|
|
|
g_signal_connect(item, "hide", G_CALLBACK(on_file_menu_hide), NULL);
|
2010-05-06 12:45:19 +00:00
|
|
|
|
2010-05-07 13:21:32 +00:00
|
|
|
g_signal_connect(geany_object, "document-save", G_CALLBACK(on_document_save), NULL);
|
|
|
|
}
|
|
|
|
init_done = TRUE;
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-06 15:03:53 +00:00
|
|
|
/* indent is used to make some whitespace between comment char and real start of the line
|
|
|
|
* e.g. indent = 8 prints " * here comes the text of the line"
|
|
|
|
* indent is meant to be the whole amount of characters before the real line content follows, i.e.
|
|
|
|
* 6 characters are filled with whitespace when the comment characters include " *" */
|
2010-07-31 15:31:30 +00:00
|
|
|
static void make_comment_block(GString *comment_text, gint filetype_idx, guint indent)
|
2006-11-14 16:03:25 +00:00
|
|
|
{
|
2010-04-25 17:43:39 +00:00
|
|
|
gchar *frame_start; /* to add before comment_text */
|
|
|
|
gchar *frame_end; /* to add after comment_text */
|
|
|
|
const gchar *line_prefix; /* to add before every line in comment_text */
|
2007-01-06 15:03:53 +00:00
|
|
|
gchar *tmp;
|
|
|
|
gchar *prefix;
|
|
|
|
gchar **lines;
|
2009-02-10 21:11:25 +00:00
|
|
|
guint i, len;
|
2010-07-31 15:31:30 +00:00
|
|
|
gint template_eol_mode;
|
|
|
|
const gchar *template_eol_char;
|
2009-07-18 14:45:43 +00:00
|
|
|
GeanyFiletype *ft = filetypes_index(filetype_idx);
|
2007-01-06 15:03:53 +00:00
|
|
|
|
2010-07-31 15:31:30 +00:00
|
|
|
g_return_if_fail(comment_text != NULL);
|
|
|
|
g_return_if_fail(ft != NULL);
|
|
|
|
|
|
|
|
template_eol_mode = utils_get_line_endings(comment_text->str, comment_text->len);
|
|
|
|
template_eol_char = utils_get_eol_char(template_eol_mode);
|
2006-11-14 16:03:25 +00:00
|
|
|
|
2009-07-18 14:45:43 +00:00
|
|
|
if (NZV(ft->comment_open))
|
|
|
|
{
|
|
|
|
if (NZV(ft->comment_close))
|
2007-01-06 15:03:53 +00:00
|
|
|
{
|
2010-07-31 15:31:30 +00:00
|
|
|
frame_start = g_strconcat(ft->comment_open, template_eol_char, NULL);
|
|
|
|
frame_end = g_strconcat(ft->comment_close, template_eol_char, NULL);
|
2007-01-06 15:03:53 +00:00
|
|
|
line_prefix = "";
|
|
|
|
}
|
2009-07-18 14:45:43 +00:00
|
|
|
else
|
2007-01-06 15:03:53 +00:00
|
|
|
{
|
2009-07-18 14:45:43 +00:00
|
|
|
frame_start = NULL;
|
|
|
|
frame_end = NULL;
|
|
|
|
line_prefix = ft->comment_open;
|
2007-01-06 15:03:53 +00:00
|
|
|
}
|
2009-07-18 14:45:43 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{ /* use C-like multi-line comments as fallback */
|
2010-07-31 15:31:30 +00:00
|
|
|
frame_start = g_strconcat("/*", template_eol_char, NULL);
|
|
|
|
frame_end = g_strconcat("*/", template_eol_char, NULL);
|
2009-07-18 14:45:43 +00:00
|
|
|
line_prefix = "";
|
|
|
|
}
|
2006-11-14 16:03:25 +00:00
|
|
|
|
2009-07-18 14:45:43 +00:00
|
|
|
/* do some magic to nicely format C-like multi-line comments */
|
|
|
|
if (NZV(frame_start) && frame_start[1] == '*')
|
|
|
|
{
|
|
|
|
/* prefix the string with a space */
|
|
|
|
setptr(frame_end, g_strconcat(" ", frame_end, NULL));
|
|
|
|
line_prefix = " *";
|
2006-11-14 16:03:25 +00:00
|
|
|
}
|
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* construct the real prefix with given amount of whitespace */
|
2007-01-06 15:03:53 +00:00
|
|
|
i = (indent > strlen(line_prefix)) ? (indent - strlen(line_prefix)) : strlen(line_prefix);
|
|
|
|
tmp = g_strnfill(i, ' ');
|
|
|
|
prefix = g_strconcat(line_prefix, tmp, NULL);
|
|
|
|
g_free(tmp);
|
2006-11-14 16:03:25 +00:00
|
|
|
|
2008-02-27 13:17:29 +00:00
|
|
|
/* add line_prefix to every line of comment_text */
|
2010-07-31 15:31:30 +00:00
|
|
|
lines = g_strsplit(comment_text->str, template_eol_char, -1);
|
2009-02-10 21:11:25 +00:00
|
|
|
len = g_strv_length(lines) - 1;
|
|
|
|
for (i = 0; i < len; i++)
|
2006-11-14 16:03:25 +00:00
|
|
|
{
|
2007-01-06 15:03:53 +00:00
|
|
|
tmp = lines[i];
|
|
|
|
lines[i] = g_strconcat(prefix, tmp, NULL);
|
|
|
|
g_free(tmp);
|
|
|
|
}
|
2010-07-31 15:31:30 +00:00
|
|
|
tmp = g_strjoinv(template_eol_char, lines);
|
2006-11-14 16:03:25 +00:00
|
|
|
|
2010-07-31 15:31:30 +00:00
|
|
|
/* clear old contents */
|
|
|
|
g_string_erase(comment_text, 0, -1);
|
|
|
|
|
|
|
|
/* add frame_end */
|
2009-07-18 14:45:43 +00:00
|
|
|
if (frame_start != NULL)
|
2010-07-31 15:31:30 +00:00
|
|
|
g_string_append(comment_text, frame_start);
|
|
|
|
/* add the new main content */
|
|
|
|
g_string_append(comment_text, tmp);
|
|
|
|
/* add frame_start */
|
|
|
|
if (frame_end != NULL)
|
|
|
|
g_string_append(comment_text, frame_end);
|
2006-11-14 16:03:25 +00:00
|
|
|
|
2009-10-15 16:15:28 +00:00
|
|
|
utils_free_pointers(4, prefix, tmp, frame_start, frame_end, NULL);
|
2007-01-06 15:03:53 +00:00
|
|
|
g_strfreev(lines);
|
2006-11-14 16:03:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-24 14:52:46 +00:00
|
|
|
gchar *templates_get_template_licence(GeanyDocument *doc, gint licence_type)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2010-01-24 14:52:46 +00:00
|
|
|
GString *template;
|
|
|
|
|
|
|
|
g_return_val_if_fail(doc != NULL, NULL);
|
|
|
|
g_return_val_if_fail(licence_type == GEANY_TEMPLATE_GPL || licence_type == GEANY_TEMPLATE_BSD, NULL);
|
|
|
|
|
|
|
|
template = g_string_new(templates[licence_type]);
|
|
|
|
replace_static_values(template);
|
|
|
|
templates_replace_default_dates(template);
|
|
|
|
templates_replace_command(template, DOC_FILENAME(doc), doc->file_type->name, NULL);
|
2007-01-06 15:03:53 +00:00
|
|
|
|
2010-07-31 15:31:30 +00:00
|
|
|
make_comment_block(template, FILETYPE_ID(doc->file_type), 8);
|
2010-08-01 17:20:50 +00:00
|
|
|
convert_eol_characters(template, doc);
|
2010-01-24 14:52:46 +00:00
|
|
|
|
2010-07-31 15:31:30 +00:00
|
|
|
return g_string_free(template, FALSE);
|
2007-01-06 15:03:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-21 16:47:54 +00:00
|
|
|
static gchar *get_template_fileheader(GeanyFiletype *ft)
|
2007-01-06 15:03:53 +00:00
|
|
|
{
|
2010-01-24 14:52:46 +00:00
|
|
|
GString *template = g_string_new(templates[GEANY_TEMPLATE_FILEHEADER]);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2010-04-21 16:47:54 +00:00
|
|
|
filetypes_load_config(ft->id, FALSE); /* load any user extension setting */
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2010-01-24 14:52:46 +00:00
|
|
|
templates_replace_valist(template,
|
|
|
|
"{gpl}", templates[GEANY_TEMPLATE_GPL],
|
|
|
|
"{bsd}", templates[GEANY_TEMPLATE_BSD],
|
|
|
|
NULL);
|
2006-11-14 16:03:25 +00:00
|
|
|
|
2010-04-21 16:47:54 +00:00
|
|
|
/* we don't replace other wildcards here otherwise they would get done twice for files */
|
2010-07-31 15:31:30 +00:00
|
|
|
make_comment_block(template, ft->id, 8);
|
|
|
|
return g_string_free(template, FALSE);
|
2006-11-14 16:03:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-21 16:47:54 +00:00
|
|
|
/* TODO change the signature to take a GeanyDocument? this would break plugin API/ABI */
|
|
|
|
gchar *templates_get_template_fileheader(gint filetype_idx, const gchar *fname)
|
|
|
|
{
|
|
|
|
GeanyFiletype *ft = filetypes[filetype_idx];
|
|
|
|
gchar *str = get_template_fileheader(ft);
|
|
|
|
GString *template = g_string_new(str);
|
|
|
|
|
|
|
|
g_free(str);
|
|
|
|
templates_replace_common(template, fname, ft, NULL);
|
2010-08-01 17:20:50 +00:00
|
|
|
convert_eol_characters(template, NULL);
|
2010-04-21 16:47:54 +00:00
|
|
|
return g_string_free(template, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-16 14:17:54 +00:00
|
|
|
gchar *templates_get_template_new_file(GeanyFiletype *ft)
|
2006-11-14 16:03:25 +00:00
|
|
|
{
|
2010-01-24 14:52:46 +00:00
|
|
|
GString *ft_template;
|
2006-11-14 16:03:25 +00:00
|
|
|
gchar *file_header = NULL;
|
|
|
|
|
2010-01-24 14:52:46 +00:00
|
|
|
g_return_val_if_fail(ft != NULL, NULL);
|
2009-10-01 11:06:08 +00:00
|
|
|
g_return_val_if_fail(ft->id < GEANY_MAX_BUILT_IN_FILETYPES, NULL);
|
|
|
|
|
2010-01-24 14:52:46 +00:00
|
|
|
ft_template = g_string_new(ft_templates[ft->id]);
|
2008-05-07 13:54:21 +00:00
|
|
|
if (FILETYPE_ID(ft) == GEANY_FILETYPES_NONE)
|
2010-01-24 14:52:46 +00:00
|
|
|
{
|
|
|
|
replace_static_values(ft_template);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ /* file template only used for new files */
|
2010-04-21 16:47:54 +00:00
|
|
|
file_header = get_template_fileheader(ft);
|
2010-01-24 14:52:46 +00:00
|
|
|
templates_replace_valist(ft_template, "{fileheader}", file_header, NULL);
|
|
|
|
}
|
2010-04-21 16:47:54 +00:00
|
|
|
templates_replace_common(ft_template, NULL, ft, NULL);
|
2010-08-01 17:20:50 +00:00
|
|
|
convert_eol_characters(ft_template, NULL);
|
2006-11-14 16:03:25 +00:00
|
|
|
|
|
|
|
g_free(file_header);
|
2010-01-24 14:52:46 +00:00
|
|
|
return g_string_free(ft_template, FALSE);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-24 14:52:46 +00:00
|
|
|
gchar *templates_get_template_function(GeanyDocument *doc, const gchar *func_name)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2010-01-24 14:52:46 +00:00
|
|
|
GString *text;
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2010-01-24 14:52:46 +00:00
|
|
|
func_name = (func_name != NULL) ? func_name : "";
|
|
|
|
text = g_string_new(templates[GEANY_TEMPLATE_FUNCTION]);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2010-01-24 14:52:46 +00:00
|
|
|
templates_replace_valist(text, "{functionname}", func_name, NULL);
|
|
|
|
templates_replace_default_dates(text);
|
|
|
|
templates_replace_command(text, DOC_FILENAME(doc), doc->file_type->name, func_name);
|
2007-01-06 15:03:53 +00:00
|
|
|
|
2010-07-31 15:31:30 +00:00
|
|
|
make_comment_block(text, doc->file_type->id, 3);
|
2010-08-01 17:20:50 +00:00
|
|
|
convert_eol_characters(text, doc);
|
2010-01-24 14:52:46 +00:00
|
|
|
|
2010-07-31 15:31:30 +00:00
|
|
|
return g_string_free(text, FALSE);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
2007-01-06 15:03:53 +00:00
|
|
|
|
2010-01-24 14:52:46 +00:00
|
|
|
gchar *templates_get_template_changelog(GeanyDocument *doc)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2010-01-24 14:52:46 +00:00
|
|
|
GString *result = g_string_new(templates[GEANY_TEMPLATE_CHANGELOG]);
|
2010-04-25 17:43:39 +00:00
|
|
|
const gchar *file_type_name = (doc != NULL) ? doc->file_type->name : "";
|
2009-07-23 16:01:45 +00:00
|
|
|
|
2010-01-24 14:52:46 +00:00
|
|
|
replace_static_values(result);
|
|
|
|
templates_replace_default_dates(result);
|
|
|
|
templates_replace_command(result, DOC_FILENAME(doc), file_type_name, NULL);
|
2010-08-01 17:20:50 +00:00
|
|
|
convert_eol_characters(result, doc);
|
2005-11-22 12:26:26 +00:00
|
|
|
|
2010-01-24 14:52:46 +00:00
|
|
|
return g_string_free(result, FALSE);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void templates_free_templates(void)
|
|
|
|
{
|
|
|
|
gint i;
|
2008-06-30 15:59:00 +00:00
|
|
|
GList *children, *item;
|
|
|
|
|
2010-05-15 13:14:38 +00:00
|
|
|
/* disconnect the menu from the action widget, so destroying the items below doesn't
|
|
|
|
* trigger rebuilding of the menu on each item destroy */
|
|
|
|
geany_menu_button_action_set_menu(
|
|
|
|
GEANY_MENU_BUTTON_ACTION(toolbar_get_action_by_name("New")), NULL);
|
|
|
|
|
2005-11-22 12:26:26 +00:00
|
|
|
for (i = 0; i < GEANY_MAX_TEMPLATES; i++)
|
|
|
|
{
|
|
|
|
g_free(templates[i]);
|
|
|
|
}
|
2008-06-30 15:59:00 +00:00
|
|
|
for (i = 0; i < GEANY_MAX_BUILT_IN_FILETYPES; i++)
|
|
|
|
{
|
|
|
|
g_free(ft_templates[i]);
|
|
|
|
}
|
|
|
|
/* destroy "New with template" sub menu items (in case we want to reload the templates) */
|
|
|
|
children = gtk_container_get_children(GTK_CONTAINER(new_with_template_menu));
|
2009-06-20 16:51:32 +00:00
|
|
|
foreach_list(item, children)
|
2008-06-30 15:59:00 +00:00
|
|
|
{
|
|
|
|
gtk_widget_destroy(GTK_WIDGET(item->data));
|
|
|
|
}
|
2009-10-12 16:31:38 +00:00
|
|
|
g_list_free(children);
|
|
|
|
|
2010-02-07 18:19:25 +00:00
|
|
|
g_object_unref(new_with_template_menu);
|
2009-10-01 14:40:42 +00:00
|
|
|
new_with_template_menu = NULL;
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-12 21:10:46 +00:00
|
|
|
static void replace_static_values(GString *text)
|
2005-11-22 12:26:26 +00:00
|
|
|
{
|
2008-11-21 18:19:36 +00:00
|
|
|
utils_string_replace_all(text, "{version}", template_prefs.version);
|
|
|
|
utils_string_replace_all(text, "{initial}", template_prefs.initials);
|
|
|
|
utils_string_replace_all(text, "{developer}", template_prefs.developer);
|
|
|
|
utils_string_replace_all(text, "{mail}", template_prefs.mail);
|
|
|
|
utils_string_replace_all(text, "{company}", template_prefs.company);
|
|
|
|
utils_string_replace_all(text, "{untitled}", GEANY_STRING_UNTITLED);
|
|
|
|
utils_string_replace_all(text, "{geanyversion}", "Geany " VERSION);
|
2005-11-22 12:26:26 +00:00
|
|
|
}
|
2007-06-14 13:10:51 +00:00
|
|
|
|
2010-01-12 21:10:46 +00:00
|
|
|
|
|
|
|
/* Replaces all static template wildcards (version, mail, company, name, ...)
|
|
|
|
* plus those wildcard, value pairs which are passed, e.g.
|
|
|
|
*
|
|
|
|
* templates_replace_valist(text, "{some_wildcard}", "some value",
|
|
|
|
* "{another_wildcard}", "another value", NULL);
|
|
|
|
*
|
|
|
|
* The argument list must be terminated with NULL. */
|
2010-04-22 13:01:45 +00:00
|
|
|
void templates_replace_valist(GString *text, const gchar *first_wildcard, ...)
|
2010-01-12 21:10:46 +00:00
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
const gchar *key, *value;
|
|
|
|
|
|
|
|
g_return_if_fail(text != NULL);
|
|
|
|
|
|
|
|
va_start(args, first_wildcard);
|
|
|
|
|
|
|
|
key = first_wildcard;
|
|
|
|
value = va_arg(args, gchar*);
|
|
|
|
|
|
|
|
while (key != NULL)
|
|
|
|
{
|
|
|
|
utils_string_replace_all(text, key, value);
|
|
|
|
|
|
|
|
key = va_arg(args, gchar*);
|
2010-01-24 14:52:46 +00:00
|
|
|
if (key == NULL || text == NULL)
|
2010-01-12 21:10:46 +00:00
|
|
|
break;
|
|
|
|
value = va_arg(args, gchar*);
|
|
|
|
}
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
replace_static_values(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-21 17:19:27 +00:00
|
|
|
static void templates_replace_default_dates(GString *text)
|
2010-01-12 21:10:46 +00:00
|
|
|
{
|
|
|
|
gchar *year = utils_get_date_time(template_prefs.year_format, NULL);
|
|
|
|
gchar *date = utils_get_date_time(template_prefs.date_format, NULL);
|
|
|
|
gchar *datetime = utils_get_date_time(template_prefs.datetime_format, NULL);
|
|
|
|
|
2010-01-24 14:52:46 +00:00
|
|
|
g_return_if_fail(text != NULL);
|
|
|
|
|
2010-01-12 21:10:46 +00:00
|
|
|
templates_replace_valist(text,
|
|
|
|
"{year}", year,
|
|
|
|
"{date}", date,
|
|
|
|
"{datetime}", datetime,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
utils_free_pointers(3, year, date, datetime, NULL);
|
|
|
|
}
|
2010-01-24 14:52:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
static gchar *run_command(const gchar *command, const gchar *file_name,
|
|
|
|
const gchar *file_type, const gchar *func_name)
|
|
|
|
{
|
|
|
|
gchar *result = NULL;
|
|
|
|
gchar **argv;
|
|
|
|
|
|
|
|
if (g_shell_parse_argv(command, NULL, &argv, NULL))
|
|
|
|
{
|
|
|
|
GError *error = NULL;
|
|
|
|
gchar **env;
|
|
|
|
|
|
|
|
file_name = (file_name != NULL) ? file_name : "";
|
|
|
|
file_type = (file_type != NULL) ? file_type : "";
|
|
|
|
func_name = (func_name != NULL) ? func_name : "";
|
|
|
|
|
|
|
|
env = utils_copy_environment(NULL,
|
|
|
|
"GEANY_FILENAME", file_name,
|
|
|
|
"GEANY_FILETYPE", file_type,
|
|
|
|
"GEANY_FUNCNAME", func_name,
|
|
|
|
NULL);
|
2010-01-31 22:08:58 +00:00
|
|
|
if (! utils_spawn_sync(NULL, argv, env, G_SPAWN_SEARCH_PATH,
|
2010-01-24 14:52:46 +00:00
|
|
|
NULL, NULL, &result, NULL, NULL, &error))
|
|
|
|
{
|
|
|
|
g_warning("templates_replace_command: %s", error->message);
|
|
|
|
g_error_free(error);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
g_strfreev(argv);
|
|
|
|
g_strfreev(env);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-21 17:19:27 +00:00
|
|
|
static void templates_replace_command(GString *text, const gchar *file_name,
|
2010-01-24 14:52:46 +00:00
|
|
|
const gchar *file_type, const gchar *func_name)
|
|
|
|
{
|
|
|
|
gchar *match = NULL;
|
|
|
|
gchar *wildcard = NULL;
|
|
|
|
gchar *cmd;
|
|
|
|
gchar *result;
|
|
|
|
|
|
|
|
g_return_if_fail(text != NULL);
|
|
|
|
|
|
|
|
while ((match = strstr(text->str, "{command:")) != NULL)
|
|
|
|
{
|
|
|
|
cmd = match;
|
|
|
|
while (*match != '}' && *match != '\0')
|
|
|
|
match++;
|
|
|
|
|
|
|
|
wildcard = g_strndup(cmd, match - cmd + 1);
|
|
|
|
cmd = g_strndup(wildcard + 9, strlen(wildcard) - 10);
|
|
|
|
|
|
|
|
result = run_command(cmd, file_name, file_type, func_name);
|
|
|
|
if (result != NULL)
|
|
|
|
{
|
2010-10-02 14:36:12 +00:00
|
|
|
result = g_strstrip(result);
|
2010-01-24 14:52:46 +00:00
|
|
|
utils_string_replace_first(text, wildcard, result);
|
|
|
|
g_free(result);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
utils_string_replace_first(text, wildcard, "");
|
|
|
|
|
|
|
|
g_free(wildcard);
|
|
|
|
g_free(cmd);
|
|
|
|
}
|
|
|
|
}
|