Updated Makefile.am files after make -f git.mk
[anjuta.git] / plugins / tools / variable.c
blobf94cec47f447ad664780b9f7c649cd6b8fbee61b
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 variable.c
4 Copyright (C) 2005 Sebastien Granjoux
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 * Keeps variables used by the tool plugin. This includes values defined
23 * by Anjuta in several flavour (by example file uri, path or just name) and
24 * other values ask at run time with a dialog.
25 * Each variable includes a short help message.
27 *---------------------------------------------------------------------------*/
29 #include <config.h>
31 #include "variable.h"
33 #include <libanjuta/anjuta-utils.h>
34 #include <libanjuta/interfaces/ianjuta-document-manager.h>
35 #include <libanjuta/interfaces/ianjuta-file-manager.h>
36 #include <libanjuta/interfaces/ianjuta-project-manager.h>
37 #include <libanjuta/interfaces/ianjuta-editor.h>
38 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
39 #include <libanjuta/interfaces/ianjuta-file.h>
41 #include <glib/gi18n.h>
42 #include <gio/gio.h>
44 #include <string.h>
46 /* List of variables understood by the tools editor and their values.
47 *---------------------------------------------------------------------------*/
49 /* enum and following variable_list table must be in the same order */
51 enum {
52 ATP_PROJECT_ROOT_URI = 0,
53 ATP_PROJECT_ROOT_DIRECTORY,
54 ATP_FILE_MANAGER_CURRENT_GFILE,
55 ATP_FILE_MANAGER_CURRENT_URI,
56 ATP_FILE_MANAGER_CURRENT_DIRECTORY,
57 ATP_FILE_MANAGER_CURRENT_FULL_FILENAME,
58 ATP_FILE_MANAGER_CURRENT_FULL_FILENAME_WITHOUT_EXT,
59 ATP_FILE_MANAGER_CURRENT_FILENAME,
60 ATP_FILE_MANAGER_CURRENT_FILENAME_WITHOUT_EXT,
61 ATP_FILE_MANAGER_CURRENT_EXTENSION,
62 ATP_PROJECT_MANAGER_CURRENT_URI,
63 ATP_PROJECT_MANAGER_CURRENT_DIRECTORY,
64 ATP_PROJECT_MANAGER_CURRENT_FULL_FILENAME,
65 ATP_PROJECT_MANAGER_CURRENT_FULL_FILENAME_WITHOUT_EXT,
66 ATP_PROJECT_MANAGER_CURRENT_FILENAME,
67 ATP_PROJECT_MANAGER_CURRENT_FILENAME_WITHOUT_EXT,
68 ATP_PROJECT_MANAGER_CURRENT_EXTENSION,
69 ATP_EDITOR_CURRENT_FILENAME,
70 ATP_EDITOR_CURRENT_FILENAME_WITHOUT_EXT,
71 ATP_EDITOR_CURRENT_DIRECTORY,
72 ATP_EDITOR_CURRENT_SELECTION,
73 ATP_EDITOR_CURRENT_WORD,
74 ATP_EDITOR_CURRENT_LINE,
75 ATP_ASK_USER_STRING,
76 ATP_VARIABLE_COUNT
80 static const struct
82 char *name;
83 char *help;
84 ATPFlags flag;
85 } variable_list[] = {
86 {IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI, N_("Project root URI"), ATP_DEFAULT_VARIABLE},
87 {"project_root_directory", N_("Project root path"), ATP_DIRECTORY_VARIABLE },
88 {IANJUTA_FILE_MANAGER_SELECTED_FILE, "File Manager file", ATP_NO_VARIABLE},
89 {"file_manager_current_uri", N_("Selected URI in the file manager plugin"), ATP_DEFAULT_VARIABLE },
90 {"file_manager_current_directory", N_("Selected directory in the file manager plugin"), ATP_DIRECTORY_VARIABLE },
91 {"file_manager_current_full_filename", N_("Selected full file name in the file manager plugin"), ATP_FILE_VARIABLE },
92 {"file_manager_current_full_filename_without_ext", N_("Selected full file name without extension in the file manager plugin"), ATP_FILE_VARIABLE },
93 {"file_manager_current_filename", N_("Selected file name in the file manager plugin"), ATP_FILE_VARIABLE },
94 {"file_manager_current_filename_without_ext", N_("Selected file name without extension in the file manager plugin"), ATP_FILE_VARIABLE },
95 {"file_manager_current_extension", N_("Selected file's extension in the file manager plugin"), ATP_DEFAULT_VARIABLE },
96 {"project_manager_current_uri", N_("Selected URI in the project manager plugin"), ATP_DEFAULT_VARIABLE },
97 {"project_manager_current_directory", N_("Selected directory in the project manager plugin"), ATP_DIRECTORY_VARIABLE },
98 {"project_manager_current_full_filename", N_("Selected full file name in the project manager plugin"), ATP_FILE_VARIABLE },
99 {"project_manager_current_full_filename_without_ext", N_("Selected full file name without extension in the project manager plugin"), ATP_FILE_VARIABLE },
100 {"project_manager_current_filename", N_("Selected file name in the project manager plugin"), ATP_FILE_VARIABLE },
101 {"project_manager_current_filename_without_ext", N_("Selected file name without extension in the project manager plugin"), ATP_FILE_VARIABLE },
102 {"project_manager_current_extension", N_("Selected file extension in the project manager plugin"), ATP_DEFAULT_VARIABLE },
103 {"editor_current_filename", N_("Currently edited file name"), ATP_FILE_VARIABLE },
104 {"editor_current_filename_without_ext", N_("Currently edited file name without extension"), ATP_FILE_VARIABLE },
105 {"editor_current_directory", N_("Currently edited file directory"), ATP_DIRECTORY_VARIABLE },
106 {"editor_current_selection", N_("Currently selected text in editor"), ATP_FILE_VARIABLE },
107 {"editor_current_word", N_("Current word in editor"), ATP_FILE_VARIABLE },
108 {"editor_current_line", N_("Current line in editor"), ATP_FILE_VARIABLE },
109 {"ask_user_string", N_("Ask the user to get additional parameters"), ATP_INTERACTIVE_VARIABLE }
112 /* Helper functions
113 *---------------------------------------------------------------------------*/
115 /* Get path from uri */
116 static gchar*
117 get_path_from_uri (char* uri)
119 gchar* val;
120 GFile *file;
122 if (uri == NULL) return NULL;
124 file = g_file_new_for_uri (uri);
125 g_free (uri);
126 val = g_file_get_path (file);
127 g_object_unref (file);
129 return val;
132 /* Remove file name from a path */
133 static gchar*
134 remove_filename (char* path)
136 gchar *val;
138 if (path == NULL) return NULL;
140 val = g_path_get_dirname (path);
141 g_free (path);
143 return val;
146 /* Remove directory from a path */
147 static gchar*
148 remove_directory (char* path)
150 gchar *val;
152 if (path == NULL) return NULL;
154 val = g_path_get_basename (path);
155 g_free (path);
157 return val;
161 /* Remove directory and base filename from a path */
162 static gchar*
163 remove_all_but_extension (char* path)
165 gchar* ext;
166 gchar* dir;
168 if (path == NULL) return NULL;
170 dir = strrchr (path, G_DIR_SEPARATOR);
171 ext = strrchr (path, '.');
172 if ((ext != NULL) && ((dir == NULL) || (dir < ext)))
174 strcpy(path, ext + 1);
176 else
178 *path = '\0';
181 return path;
184 /* Remove extension from a filename */
185 static gchar*
186 remove_extension (char* path)
188 gchar* ext;
189 gchar* dir;
191 if (path == NULL) return NULL;
193 dir = strrchr (path, G_DIR_SEPARATOR);
194 ext = strrchr (path, '.');
195 if ((ext != NULL) && ((dir == NULL) || (dir < ext)))
197 *ext = '\0';
200 return path;
203 /* Get variable index from name
204 *---------------------------------------------------------------------------*/
206 static guint
207 atp_variable_get_id (const ATPVariable* this, const gchar* name)
209 guint i;
211 for (i = 0; i < ATP_VARIABLE_COUNT; ++i)
213 if (strcmp (variable_list[i].name, name) == 0) break;
216 return i;
219 static guint
220 atp_variable_get_id_from_name_part (const ATPVariable* this, const gchar* name, gsize length)
222 guint i;
224 for (i = 0; i < ATP_VARIABLE_COUNT; ++i)
226 if ((strncmp (variable_list[i].name, name, length) == 0)
227 && (variable_list[i].name[length] == '\0')) break;
230 return i;
233 /* Get Anjuta variables
234 *---------------------------------------------------------------------------*/
236 static gpointer
237 atp_variable_get_anjuta_variable (const ATPVariable *this, guint id)
239 GValue value = {0,};
240 GError* err = NULL;
242 anjuta_shell_get_value (this->shell, variable_list[id].name, &value, &err);
243 if (err != NULL)
245 /* Value probably does not exist */
246 g_error_free (err);
248 return NULL;
250 else
252 gpointer ret;
254 if (G_VALUE_HOLDS (&value, G_TYPE_STRING))
256 ret = g_value_dup_string (&value);
258 else if (G_VALUE_HOLDS (&value, G_TYPE_FILE))
260 ret = g_value_dup_object (&value);
262 else
264 ret = NULL;
266 g_value_unset (&value);
268 return ret;
272 static gchar*
273 atp_variable_get_project_manager_variable (const ATPVariable *this, guint id)
275 IAnjutaProjectManager *prjman;
276 gchar* val = NULL;
277 GFile *file;
278 GError* err = NULL;
280 prjman = anjuta_shell_get_interface (this->shell, IAnjutaProjectManager, NULL);
282 if (prjman == NULL) return NULL;
284 switch (id)
286 case ATP_PROJECT_MANAGER_CURRENT_URI:
287 file = ianjuta_project_manager_get_selected (prjman, &err);
288 if (file != NULL)
290 val = g_file_get_uri (file);
291 g_object_unref (file);
293 break;
294 default:
295 g_return_val_if_reached (NULL);
298 if (err != NULL)
300 g_error_free (err);
302 return NULL;
304 else
306 return val;
310 static IAnjutaEditor*
311 get_current_editor(IAnjutaDocumentManager* docman)
313 if (docman == NULL)
314 return NULL;
315 IAnjutaDocument* document = ianjuta_document_manager_get_current_document(docman, NULL);
316 if (IANJUTA_IS_EDITOR(document))
317 return IANJUTA_EDITOR(document);
318 else
319 return NULL;
322 static gchar*
323 atp_variable_get_editor_variable (const ATPVariable *this, guint id)
325 IAnjutaDocumentManager *docman;
326 IAnjutaEditor *ed;
327 gchar* val;
328 gchar* path;
329 GFile* file;
330 GError* err = NULL;
332 docman = anjuta_shell_get_interface (this->shell, IAnjutaDocumentManager, NULL);
333 ed = get_current_editor(docman);
335 if (ed == NULL) return NULL;
336 switch (id)
338 case ATP_EDITOR_CURRENT_SELECTION:
339 val = ianjuta_editor_selection_get (IANJUTA_EDITOR_SELECTION (ed),
340 &err);
341 break;
342 case ATP_EDITOR_CURRENT_WORD:
343 val = ianjuta_editor_get_current_word (ed, &err);
344 break;
345 case ATP_EDITOR_CURRENT_LINE:
346 val = g_strdup_printf ("%d", ianjuta_editor_get_lineno (ed, &err));
347 break;
348 case ATP_EDITOR_CURRENT_FILENAME:
349 val = g_strdup (ianjuta_document_get_filename (IANJUTA_DOCUMENT(ed), &err));
350 break;
351 case ATP_EDITOR_CURRENT_DIRECTORY:
352 file = ianjuta_file_get_file (IANJUTA_FILE (ed), &err);
353 path = g_file_get_path (file);
354 val = remove_filename(path);
355 g_object_unref (file);
356 break;
357 default:
358 g_return_val_if_reached (NULL);
361 if (err != NULL)
363 g_error_free (err);
365 return NULL;
367 else
369 return val;
373 /* Access functions
374 *---------------------------------------------------------------------------*/
376 guint
377 atp_variable_get_count (const ATPVariable* this)
379 return ATP_VARIABLE_COUNT;
382 const gchar*
383 atp_variable_get_name (const ATPVariable* this, guint id)
385 return id >= ATP_VARIABLE_COUNT ? NULL : variable_list[id].name;
388 const gchar*
389 atp_variable_get_help (const ATPVariable* this, guint id)
391 return id >= ATP_VARIABLE_COUNT ? NULL : _(variable_list[id].help);
394 ATPFlags
395 atp_variable_get_flag (const ATPVariable* this, guint id)
397 return id >= ATP_VARIABLE_COUNT ? ATP_NO_VARIABLE : variable_list[id].flag;
400 gchar*
401 atp_variable_get_value (const ATPVariable* this, const gchar* name)
403 guint id;
405 id = atp_variable_get_id (this, name);
407 return atp_variable_get_value_from_id (this, id);
410 gchar*
411 atp_variable_get_value_from_name_part (const ATPVariable* this, const gchar* name, gsize length)
413 guint id;
415 id = atp_variable_get_id_from_name_part (this, name, length);
417 return atp_variable_get_value_from_id (this, id);
420 /* Return NULL only if the variable doesn't exist
421 * If not NULL, return value must be freed when not used */
422 gchar*
423 atp_variable_get_value_from_id (const ATPVariable* this, guint id)
425 gchar *val = NULL;
426 GFile *file;
428 switch (id)
430 case ATP_PROJECT_ROOT_URI:
431 val = atp_variable_get_anjuta_variable (this, id);
432 break;
433 case ATP_PROJECT_ROOT_DIRECTORY:
434 val = atp_variable_get_anjuta_variable (this, ATP_PROJECT_ROOT_URI);
435 val = get_path_from_uri (val);
436 break;
437 case ATP_FILE_MANAGER_CURRENT_URI:
438 file = atp_variable_get_anjuta_variable (this, ATP_FILE_MANAGER_CURRENT_GFILE);
439 if (file != NULL)
441 val = g_file_get_uri (file);
442 g_object_unref (file);
444 break;
445 case ATP_FILE_MANAGER_CURRENT_DIRECTORY:
446 file = atp_variable_get_anjuta_variable (this, ATP_FILE_MANAGER_CURRENT_GFILE);
447 if (file != NULL)
449 val = g_file_get_path (file);
450 g_object_unref (file);
451 val = remove_filename (val);
453 break;
454 case ATP_FILE_MANAGER_CURRENT_FULL_FILENAME:
455 file = atp_variable_get_anjuta_variable (this, ATP_FILE_MANAGER_CURRENT_GFILE);
456 if (file != NULL)
458 val = g_file_get_path (file);
459 g_object_unref (file);
461 break;
462 case ATP_FILE_MANAGER_CURRENT_FULL_FILENAME_WITHOUT_EXT:
463 file = atp_variable_get_anjuta_variable (this, ATP_FILE_MANAGER_CURRENT_GFILE);
464 if (file != NULL)
466 val = g_file_get_path (file);
467 g_object_unref (file);
468 val = remove_extension (val);
470 break;
471 case ATP_FILE_MANAGER_CURRENT_FILENAME:
472 file = atp_variable_get_anjuta_variable (this, ATP_FILE_MANAGER_CURRENT_GFILE);
473 if (file != NULL)
475 val = g_file_get_path (file);
476 g_object_unref (file);
477 val = remove_directory (val);
479 break;
480 case ATP_FILE_MANAGER_CURRENT_FILENAME_WITHOUT_EXT:
481 file = atp_variable_get_anjuta_variable (this, ATP_FILE_MANAGER_CURRENT_GFILE);
482 if (file != NULL)
484 val = g_file_get_path (file);
485 g_object_unref (file);
486 val = remove_directory (val);
487 val = remove_extension (val);
489 break;
490 case ATP_FILE_MANAGER_CURRENT_EXTENSION:
491 file = atp_variable_get_anjuta_variable (this, ATP_FILE_MANAGER_CURRENT_GFILE);
492 if (file != NULL)
494 val = g_file_get_path (file);
495 g_object_unref (file);
496 val = remove_all_but_extension (val);
498 break;
499 case ATP_PROJECT_MANAGER_CURRENT_URI:
500 val = atp_variable_get_project_manager_variable (this, id);
501 break;
502 case ATP_PROJECT_MANAGER_CURRENT_DIRECTORY:
503 val = atp_variable_get_project_manager_variable (this, ATP_PROJECT_MANAGER_CURRENT_URI);
504 val = get_path_from_uri (val);
505 val = remove_filename (val);
506 break;
507 case ATP_PROJECT_MANAGER_CURRENT_FULL_FILENAME:
508 val = atp_variable_get_project_manager_variable (this, ATP_PROJECT_MANAGER_CURRENT_URI);
509 val = get_path_from_uri (val);
510 break;
511 case ATP_PROJECT_MANAGER_CURRENT_FULL_FILENAME_WITHOUT_EXT:
512 val = atp_variable_get_project_manager_variable (this, ATP_PROJECT_MANAGER_CURRENT_URI);
513 val = get_path_from_uri (val);
514 val = remove_extension (val);
515 break;
516 case ATP_PROJECT_MANAGER_CURRENT_FILENAME:
517 val = atp_variable_get_anjuta_variable (this, ATP_PROJECT_MANAGER_CURRENT_URI);
518 val = get_path_from_uri (val);
519 val = remove_directory (val);
520 break;
521 case ATP_PROJECT_MANAGER_CURRENT_FILENAME_WITHOUT_EXT:
522 val = atp_variable_get_anjuta_variable (this, ATP_PROJECT_MANAGER_CURRENT_URI);
523 val = get_path_from_uri (val);
524 val = remove_directory (val);
525 val = remove_extension (val);
526 break;
527 case ATP_PROJECT_MANAGER_CURRENT_EXTENSION:
528 val = atp_variable_get_anjuta_variable (this, ATP_PROJECT_MANAGER_CURRENT_URI);
529 val = get_path_from_uri (val);
530 val = remove_all_but_extension (val);
531 break;
532 case ATP_EDITOR_CURRENT_FILENAME_WITHOUT_EXT:
533 val = atp_variable_get_editor_variable (this, ATP_EDITOR_CURRENT_FILENAME);
534 val = remove_extension (val);
535 break;
536 case ATP_EDITOR_CURRENT_FILENAME:
537 case ATP_EDITOR_CURRENT_DIRECTORY:
538 case ATP_EDITOR_CURRENT_SELECTION:
539 case ATP_EDITOR_CURRENT_WORD:
540 case ATP_EDITOR_CURRENT_LINE:
541 val = atp_variable_get_editor_variable (this, id);
542 break;
543 case ATP_ASK_USER_STRING:
544 val = NULL;
545 anjuta_util_dialog_input (GTK_WINDOW (this->shell),
546 _("Command line parameters"), NULL, &val);
547 break;
548 default:
549 /* Variable does not exist */
550 return NULL;
553 /* Variable exist */
554 return val == NULL ? g_new0 (gchar, 1) : val;
557 /* Creation and Destruction
558 *---------------------------------------------------------------------------*/
560 ATPVariable*
561 atp_variable_construct (ATPVariable* this, AnjutaShell* shell)
563 this->shell = shell;
565 return this;
568 void
569 atp_variable_destroy (ATPVariable* this)