* plugins/symbol-browser/plugin.c,
[anjuta-git-plugin.git] / plugins / tools / variable.c
blob86c87f081a775b8aff78ea826406316565d2ca0c
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-project-manager.h>
36 #include <libanjuta/interfaces/ianjuta-editor.h>
37 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
38 #include <libanjuta/interfaces/ianjuta-file.h>
40 #include <libgnomevfs/gnome-vfs.h>
42 #include <glib/gi18n.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_URI,
55 ATP_FILE_MANAGER_CURRENT_DIRECTORY,
56 ATP_FILE_MANAGER_CURRENT_FULL_FILENAME,
57 ATP_FILE_MANAGER_CURRENT_FULL_FILENAME_WITHOUT_EXT,
58 ATP_FILE_MANAGER_CURRENT_FILENAME,
59 ATP_FILE_MANAGER_CURRENT_FILENAME_WITHOUT_EXT,
60 ATP_FILE_MANAGER_CURRENT_EXTENSION,
61 ATP_PROJECT_MANAGER_CURRENT_URI,
62 ATP_PROJECT_MANAGER_CURRENT_DIRECTORY,
63 ATP_PROJECT_MANAGER_CURRENT_FULL_FILENAME,
64 ATP_PROJECT_MANAGER_CURRENT_FULL_FILENAME_WITHOUT_EXT,
65 ATP_PROJECT_MANAGER_CURRENT_FILENAME,
66 ATP_PROJECT_MANAGER_CURRENT_FILENAME_WITHOUT_EXT,
67 ATP_PROJECT_MANAGER_CURRENT_EXTENSION,
68 ATP_EDITOR_CURRENT_FILENAME,
69 ATP_EDITOR_CURRENT_FILENAME_WITHOUT_EXT,
70 ATP_EDITOR_CURRENT_DIRECTORY,
71 ATP_EDITOR_CURRENT_SELECTION,
72 ATP_EDITOR_CURRENT_WORD,
73 ATP_EDITOR_CURRENT_LINE,
74 ATP_ASK_USER_STRING,
75 ATP_VARIABLE_COUNT
79 static const struct
81 char *name;
82 char *help;
83 ATPFlags flag;
84 } variable_list[] = {
85 {"project_root_uri", "project root URI", ATP_DEFAULT_VARIABLE},
86 {"project_root_directory", "project root path", ATP_DIRECTORY_VARIABLE },
87 {"file_manager_current_uri", "selected file manager URI", ATP_DEFAULT_VARIABLE },
88 {"file_manager_current_directory", "selected file manager directory", ATP_DIRECTORY_VARIABLE },
89 {"file_manager_current_full_filename", "selected file manager full file name", ATP_FILE_VARIABLE },
90 {"file_manager_current_full_filename_without_ext", "selected file manager full file name without extension", ATP_FILE_VARIABLE },
91 {"file_manager_current_filename", "selected file manager file name", ATP_FILE_VARIABLE },
92 {"file_manager_current_filename_without_ext", "selected file manager file name without extension", ATP_FILE_VARIABLE },
93 {"file_manager_current_extension", "selected file manager file extension", ATP_DEFAULT_VARIABLE },
94 {"project_manager_current_uri", "selected project manager URI", ATP_DEFAULT_VARIABLE },
95 {"project_manager_current_directory", "selected project manager directory", ATP_DIRECTORY_VARIABLE },
96 {"project_manager_current_full_filename", "selected project manager full file name", ATP_FILE_VARIABLE },
97 {"project_manager_current_full_filename_without_ext", "selected project manager full file name without extension", ATP_FILE_VARIABLE },
98 {"project_manager_current_filename", "selected project manager file name", ATP_FILE_VARIABLE },
99 {"project_manager_current_filename_without_ext", "selected project manager file name without extension", ATP_FILE_VARIABLE },
100 {"project_manager_current_extension", "selected project manager file extension", ATP_DEFAULT_VARIABLE },
101 {"editor_current_filename", "current edited file name", ATP_FILE_VARIABLE },
102 {"editor_current_filename_without_ext", "current edited file name without extension", ATP_FILE_VARIABLE },
103 {"editor_current_directory", "current edited file directory", ATP_DIRECTORY_VARIABLE },
104 {"editor_current_selection", "current selection in editor", ATP_FILE_VARIABLE },
105 {"editor_current_word", "current word in editor", ATP_FILE_VARIABLE },
106 {"editor_current_line", "current line in editor", ATP_FILE_VARIABLE },
107 {"ask_user_string", "ask the user to get additional parameters", ATP_INTERACTIVE_VARIABLE }
110 /* Helper functions
111 *---------------------------------------------------------------------------*/
113 /* Get path from uri */
114 static gchar*
115 get_path_from_uri (char* uri)
117 gchar* val;
118 if (uri == NULL) return NULL;
120 val = gnome_vfs_get_local_path_from_uri (uri);
121 g_free (uri);
123 return val;
126 /* Remove file name from a path */
127 static gchar*
128 remove_filename (char* path)
130 gchar *val;
132 if (path == NULL) return NULL;
134 val = g_path_get_dirname (path);
135 g_free (path);
137 return val;
140 /* Remove directory from a path */
141 static gchar*
142 remove_directory (char* path)
144 gchar *val;
146 if (path == NULL) return NULL;
148 val = g_path_get_basename (path);
149 g_free (path);
151 return val;
155 /* Remove directory and base filename from a path */
156 static gchar*
157 remove_all_but_extension (char* path)
159 gchar* ext;
160 gchar* dir;
162 if (path == NULL) return NULL;
164 dir = strrchr (path, G_DIR_SEPARATOR);
165 ext = strrchr (path, '.');
166 if ((ext != NULL) && ((dir == NULL) || (dir < ext)))
168 strcpy(path, ext + 1);
170 else
172 *path = '\0';
175 return path;
178 /* Remove extension from a filename */
179 static gchar*
180 remove_extension (char* path)
182 gchar* ext;
183 gchar* dir;
185 if (path == NULL) return NULL;
187 dir = strrchr (path, G_DIR_SEPARATOR);
188 ext = strrchr (path, '.');
189 if ((ext != NULL) && ((dir == NULL) || (dir < ext)))
191 *ext = '\0';
194 return path;
197 /* Get variable index from name
198 *---------------------------------------------------------------------------*/
200 static guint
201 atp_variable_get_id (const ATPVariable* this, const gchar* name)
203 guint i;
205 for (i = 0; i < ATP_VARIABLE_COUNT; ++i)
207 if (strcmp (variable_list[i].name, name) == 0) break;
210 return i;
213 static guint
214 atp_variable_get_id_from_name_part (const ATPVariable* this, const gchar* name, gsize length)
216 guint i;
218 for (i = 0; i < ATP_VARIABLE_COUNT; ++i)
220 if ((strncmp (variable_list[i].name, name, length) == 0)
221 && (variable_list[i].name[length] == '\0')) break;
224 return i;
227 /* Get Anjuta variables
228 *---------------------------------------------------------------------------*/
230 static gchar*
231 atp_variable_get_anjuta_variable (const ATPVariable *this, guint id)
233 gchar* string;
234 GValue value = {0,};
235 GError* err = NULL;
237 anjuta_shell_get_value (this->shell, variable_list[id].name, &value, &err);
238 if (err != NULL)
240 /* Value probably does not exist */
241 g_error_free (err);
243 return NULL;
245 else
247 string = G_VALUE_HOLDS (&value, G_TYPE_STRING) ? g_value_dup_string (&value) : NULL;
248 g_value_unset (&value);
251 return string;
254 static gchar*
255 atp_variable_get_project_manager_variable (const ATPVariable *this, guint id)
257 IAnjutaProjectManager *prjman;
258 gchar* val;
259 GError* err = NULL;
261 prjman = anjuta_shell_get_interface (this->shell, IAnjutaProjectManager, NULL);
263 if (prjman == NULL) return NULL;
265 switch (id)
267 case ATP_PROJECT_MANAGER_CURRENT_URI:
268 val = ianjuta_project_manager_get_selected (prjman, &err);
269 break;
270 default:
271 g_return_val_if_reached (NULL);
274 if (err != NULL)
276 g_error_free (err);
278 return NULL;
280 else
282 return val;
286 static IAnjutaEditor*
287 get_current_editor(IAnjutaDocumentManager* docman)
289 if (docman == NULL)
290 return NULL;
291 IAnjutaDocument* document = ianjuta_document_manager_get_current_document(docman, NULL);
292 if (IANJUTA_IS_EDITOR(document))
293 return IANJUTA_EDITOR(document);
294 else
295 return NULL;
298 static gchar*
299 atp_variable_get_editor_variable (const ATPVariable *this, guint id)
301 IAnjutaDocumentManager *docman;
302 IAnjutaEditor *ed;
303 gchar* val;
304 gchar* uri;
305 GError* err = NULL;
307 docman = anjuta_shell_get_interface (this->shell, IAnjutaDocumentManager, NULL);
308 ed = get_current_editor(docman);
310 if (ed == NULL) return NULL;
311 switch (id)
313 case ATP_EDITOR_CURRENT_SELECTION:
314 val = ianjuta_editor_selection_get (IANJUTA_EDITOR_SELECTION (ed),
315 &err);
316 break;
317 case ATP_EDITOR_CURRENT_WORD:
318 val = ianjuta_editor_get_current_word (ed, &err);
319 break;
320 case ATP_EDITOR_CURRENT_LINE:
321 val = g_strdup_printf ("%d", ianjuta_editor_get_lineno (ed, &err));
322 break;
323 case ATP_EDITOR_CURRENT_FILENAME:
324 val = g_strdup (ianjuta_document_get_filename (IANJUTA_DOCUMENT(ed), &err));
325 break;
326 case ATP_EDITOR_CURRENT_DIRECTORY:
327 uri = ianjuta_file_get_uri (IANJUTA_FILE (ed), &err);
328 val = remove_filename(get_path_from_uri(uri));
329 break;
330 default:
331 g_return_val_if_reached (NULL);
334 if (err != NULL)
336 g_error_free (err);
338 return NULL;
340 else
342 return val;
346 /* Access functions
347 *---------------------------------------------------------------------------*/
349 guint
350 atp_variable_get_count (const ATPVariable* this)
352 return ATP_VARIABLE_COUNT;
355 const gchar*
356 atp_variable_get_name (const ATPVariable* this, guint id)
358 return id >= ATP_VARIABLE_COUNT ? NULL : variable_list[id].name;
361 const gchar*
362 atp_variable_get_help (const ATPVariable* this, guint id)
364 return id >= ATP_VARIABLE_COUNT ? NULL : _(variable_list[id].help);
367 ATPFlags
368 atp_variable_get_flag (const ATPVariable* this, guint id)
370 return id >= ATP_VARIABLE_COUNT ? ATP_NO_VARIABLE : variable_list[id].flag;
373 gchar*
374 atp_variable_get_value (const ATPVariable* this, const gchar* name)
376 guint id;
378 id = atp_variable_get_id (this, name);
380 return atp_variable_get_value_from_id (this, id);
383 gchar*
384 atp_variable_get_value_from_name_part (const ATPVariable* this, const gchar* name, gsize length)
386 guint id;
388 id = atp_variable_get_id_from_name_part (this, name, length);
390 return atp_variable_get_value_from_id (this, id);
393 /* Return NULL only if the variable doesn't exist
394 * If not NULL, return value must be freed when not used */
395 gchar*
396 atp_variable_get_value_from_id (const ATPVariable* this, guint id)
398 char *val;
400 switch (id)
402 case ATP_PROJECT_ROOT_URI:
403 case ATP_FILE_MANAGER_CURRENT_URI:
404 val = atp_variable_get_anjuta_variable (this, id);
405 break;
406 case ATP_PROJECT_ROOT_DIRECTORY:
407 val = atp_variable_get_anjuta_variable (this, ATP_PROJECT_ROOT_URI);
408 val = get_path_from_uri (val);
409 break;
410 case ATP_FILE_MANAGER_CURRENT_DIRECTORY:
411 val = atp_variable_get_anjuta_variable (this, ATP_FILE_MANAGER_CURRENT_URI);
412 val = get_path_from_uri (val);
413 val = remove_filename (val);
414 break;
415 case ATP_FILE_MANAGER_CURRENT_FULL_FILENAME:
416 val = atp_variable_get_anjuta_variable (this, ATP_FILE_MANAGER_CURRENT_URI);
417 val = get_path_from_uri (val);
418 break;
419 case ATP_FILE_MANAGER_CURRENT_FULL_FILENAME_WITHOUT_EXT:
420 val = atp_variable_get_anjuta_variable (this, ATP_FILE_MANAGER_CURRENT_URI);
421 val = get_path_from_uri (val);
422 val = remove_extension (val);
423 break;
424 case ATP_FILE_MANAGER_CURRENT_FILENAME:
425 val = atp_variable_get_anjuta_variable (this, ATP_FILE_MANAGER_CURRENT_URI);
426 val = get_path_from_uri (val);
427 val = remove_directory (val);
428 break;
429 case ATP_FILE_MANAGER_CURRENT_FILENAME_WITHOUT_EXT:
430 val = atp_variable_get_anjuta_variable (this, ATP_FILE_MANAGER_CURRENT_URI);
431 val = get_path_from_uri (val);
432 val = remove_directory (val);
433 val = remove_extension (val);
434 break;
435 case ATP_FILE_MANAGER_CURRENT_EXTENSION:
436 val = atp_variable_get_anjuta_variable (this, ATP_FILE_MANAGER_CURRENT_URI);
437 val = get_path_from_uri (val);
438 val = remove_all_but_extension (val);
439 break;
440 case ATP_PROJECT_MANAGER_CURRENT_URI:
441 val = atp_variable_get_project_manager_variable (this, id);
442 break;
443 case ATP_PROJECT_MANAGER_CURRENT_DIRECTORY:
444 val = atp_variable_get_project_manager_variable (this, ATP_PROJECT_MANAGER_CURRENT_URI);
445 val = get_path_from_uri (val);
446 val = remove_filename (val);
447 break;
448 case ATP_PROJECT_MANAGER_CURRENT_FULL_FILENAME:
449 val = atp_variable_get_project_manager_variable (this, ATP_PROJECT_MANAGER_CURRENT_URI);
450 val = get_path_from_uri (val);
451 break;
452 case ATP_PROJECT_MANAGER_CURRENT_FULL_FILENAME_WITHOUT_EXT:
453 val = atp_variable_get_project_manager_variable (this, ATP_PROJECT_MANAGER_CURRENT_URI);
454 val = get_path_from_uri (val);
455 val = remove_extension (val);
456 break;
457 case ATP_PROJECT_MANAGER_CURRENT_FILENAME:
458 val = atp_variable_get_anjuta_variable (this, ATP_PROJECT_MANAGER_CURRENT_URI);
459 val = get_path_from_uri (val);
460 val = remove_directory (val);
461 break;
462 case ATP_PROJECT_MANAGER_CURRENT_FILENAME_WITHOUT_EXT:
463 val = atp_variable_get_anjuta_variable (this, ATP_PROJECT_MANAGER_CURRENT_URI);
464 val = get_path_from_uri (val);
465 val = remove_directory (val);
466 val = remove_extension (val);
467 break;
468 case ATP_PROJECT_MANAGER_CURRENT_EXTENSION:
469 val = atp_variable_get_anjuta_variable (this, ATP_PROJECT_MANAGER_CURRENT_URI);
470 val = get_path_from_uri (val);
471 val = remove_all_but_extension (val);
472 break;
473 case ATP_EDITOR_CURRENT_FILENAME_WITHOUT_EXT:
474 val = atp_variable_get_editor_variable (this, ATP_EDITOR_CURRENT_FILENAME);
475 val = remove_extension (val);
476 break;
477 case ATP_EDITOR_CURRENT_FILENAME:
478 case ATP_EDITOR_CURRENT_DIRECTORY:
479 case ATP_EDITOR_CURRENT_SELECTION:
480 case ATP_EDITOR_CURRENT_WORD:
481 case ATP_EDITOR_CURRENT_LINE:
482 val = atp_variable_get_editor_variable (this, id);
483 break;
484 case ATP_ASK_USER_STRING:
485 val = NULL;
486 anjuta_util_dialog_input (GTK_WINDOW (this->shell),
487 _("Command line parameters"), NULL, &val);
488 break;
489 default:
490 /* Variable does not exist */
491 return NULL;
494 /* Variable exist */
495 return val == NULL ? g_new0 (gchar, 1) : val;
498 /* Creation and Destruction
499 *---------------------------------------------------------------------------*/
501 ATPVariable*
502 atp_variable_construct (ATPVariable* this, AnjutaShell* shell)
504 this->shell = shell;
506 return this;
509 void
510 atp_variable_destroy (ATPVariable* this)