PIPS
directory_menu.c File Reference
#include <xview/xview.h>
#include <xview/panel.h>
#include <sys/param.h>
#include <sys/stat.h>
#include "genC.h"
#include "misc.h"
#include "database.h"
#include "linear.h"
#include "ri.h"
#include "ri-util.h"
#include "pipsdbm.h"
#include "wpips.h"
+ Include dependency graph for directory_menu.c:

Go to the source code of this file.

Macros

#define MAXNAMELEN   MAXNAMLEN
 Generate a menu from the current directory to serve as a directory chooser. More...
 

Enumerations

enum  { MENU_PATH_DATA_HANDLER = 54829 , WPIPS_MAX_DIRECTORY_MENU_SIZE = 80 }
 

Functions

static bool accept_all_file_names (char *file_name __attribute__((unused)))
 Note the pedantic way to avoid the warning about unused file_name. More...
 
static Menu directory_gen_pullright (Menu_item menu_item, Menu_generate op)
 
static void generate_a_directory_menu_notify (Menu menu, Menu_item menu_item)
 
Menu generate_a_directory_menu (char *directory)
 

Macro Definition Documentation

◆ MAXNAMELEN

#define MAXNAMELEN   MAXNAMLEN

Generate a menu from the current directory to serve as a directory chooser.

To have SunOS 5.5 happy about MAXNAMELEN (in SunOS 4, it is already defined in sys/dirent.h): To have SunOS4 still working:

Definition at line 43 of file directory_menu.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
MENU_PATH_DATA_HANDLER 
WPIPS_MAX_DIRECTORY_MENU_SIZE 

Maximum size of the directory menu of the main frame:

Definition at line 56 of file directory_menu.c.

56  {MENU_PATH_DATA_HANDLER = 54829,
57 /* Maximum size of the directory menu of the main frame: */
59 };
@ MENU_PATH_DATA_HANDLER
@ WPIPS_MAX_DIRECTORY_MENU_SIZE
Maximum size of the directory menu of the main frame:

Function Documentation

◆ accept_all_file_names()

static bool accept_all_file_names ( char *file_name   __attribute__(unused))
static

Note the pedantic way to avoid the warning about unused file_name.

:-)

Definition at line 64 of file directory_menu.c.

65 {
66  return TRUE;
67 }

◆ directory_gen_pullright()

static Menu directory_gen_pullright ( Menu_item  menu_item,
Menu_generate  op 
)
static

First get the parent directory name that is the title:

Build the new directory name:

Well, there is already a menu... we've been already here. Free it first:

Free the associated directory name:

Then initialize it with a new directory menu:

A Menu-Generating procedure has to return the menu in any case:

Definition at line 71 of file directory_menu.c.

73 {
74  Menu menu;
75 
76  if (op == MENU_DISPLAY) {
77  char directory[MAXNAMELEN + 1];
78  char * parent_directory;
79  Menu parent = xv_get(menu_item, MENU_PARENT);
80 
81  debug(2, "directory_gen_pullright", "menu_item = %#x (%s), parent = %#x\n",
82  menu_item, (char *) xv_get(menu_item, MENU_STRING), parent);
83 
84  /* First get the parent directory name that is the title: */
85  parent_directory = (char *) xv_get(parent,
86  XV_KEY_DATA, MENU_PATH_DATA_HANDLER);
87  debug(2, "directory_gen_pullright", " parent_directory = %s\n",
88  parent_directory);
89 
90  /* Build the new directory name: */
91  (void) sprintf(directory, "%s/%s",
92  parent_directory,
93  (char *) xv_get(menu_item, MENU_STRING));
94 
95  if ((char *)(menu = (Menu) xv_get(menu_item, MENU_PULLRIGHT)) != NULL) {
96  /* Well, there is already a menu... we've been already here.
97  Free it first: */
98  /* Free the associated directory name: */
99  free((char *) xv_get(menu, XV_KEY_DATA, MENU_PATH_DATA_HANDLER));
100  xv_destroy(menu);
101  }
102 
103  /* Then initialize it with a new directory menu: */
104  menu = generate_a_directory_menu(directory);
105  }
106  else
107  /* A Menu-Generating procedure has to return the menu in any case: */
108  menu = (Menu)xv_get(menu_item, MENU_PULLRIGHT);
109 
110  return menu;
111 }
void free(void *)
GtkWidget * generate_a_directory_menu(char *directory)
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
#define MAXNAMELEN
Generate a menu from the current directory to serve as a directory chooser.

References debug(), free(), generate_a_directory_menu(), MAXNAMELEN, and MENU_PATH_DATA_HANDLER.

Referenced by generate_a_directory_menu().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ generate_a_directory_menu()

Menu generate_a_directory_menu ( char *  directory)

The string is not copied in MENU_TITLE_ITEM:

and furthermore MENU_TITLE_ITEM is write only, so add the info somewhere else:

Add its own notifying procedure:

Get all the files in the directory:

Generate a corresponding entry for each file:

Skip the "." directory:

The strdup'ed string will also be freed when the menu is discarded:

Since a menu item cannot be selected as an item, add an plain item with the same name. Not beautiful hack... :-(

Now recreate another item that will be the submenu:

The strdup'ed string will also be freed when the menu is discarded:

Put a right menu on each directory entry:

And disable non-subdirectory entry:

Definition at line 129 of file directory_menu.c.

130 {
131  gen_array_t file_list;
132  int file_list_length;
133  int return_code;
134  int i;
135  Menu menu;
136 
137  menu = (Menu) xv_create(
138  (int) NULL, MENU,
139  /* The string is *not* copied in MENU_TITLE_ITEM: */
140  MENU_TITLE_ITEM, strdup(directory),
141  /* and furthermore MENU_TITLE_ITEM is write
142  only, so add the info somewhere else: */
143  XV_KEY_DATA, MENU_PATH_DATA_HANDLER, strdup(directory),
144  /* Add its own notifying procedure: */
145  MENU_NOTIFY_PROC, generate_a_directory_menu_notify,
146  NULL);
147  pips_debug(2, "menu = %p (%s)\n", (void *) menu, directory);
148 
150  xv_set(menu, MENU_APPEND_ITEM,
151  xv_create(XV_NULL, MENUITEM,
152  MENU_STRING,
153  "* Close the current workspace before "
154  "changing directory *",
155  MENU_RELEASE,
156  MENU_INACTIVE, TRUE,
157  NULL),
158  NULL);
159  pips_user_warning("Close the current workspace before changing "
160  "directory.\n");
161  }
162  else
163  {
164  /* Get all the files in the directory: */
165  file_list = gen_array_make(0);
166  return_code = safe_list_files_in_directory(file_list,
167  directory,
168  ".*", directory_exists_p);
169  file_list_length = gen_array_nitems(file_list);
170 
171  if (return_code == -1 || file_list_length == 0)
172  xv_set(menu, MENU_APPEND_ITEM,
173  xv_create(XV_NULL, MENUITEM,
174  MENU_STRING,
175  "* No file in this directory or cannot be open *",
176  MENU_RELEASE,
177  MENU_INACTIVE, TRUE,
178  NULL),
179  NULL);
180  else if (file_list_length > WPIPS_MAX_DIRECTORY_MENU_SIZE) {
181  xv_set(menu, MENU_APPEND_ITEM,
182  xv_create(XV_NULL, MENUITEM,
183  MENU_STRING,
184  "* Too many files. Type directly in the Directory "
185  "line of the main panel *",
186  MENU_RELEASE,
187  MENU_INACTIVE, TRUE,
188  NULL),
189  NULL);
190  user_warning("generate_a_directory_menu",
191  "Too many files in the \"%s\" directory.\n", directory);
192  }
193  else
194  /* Generate a corresponding entry for each file: */
195  for(i = 0; i < file_list_length; i++)
196  {
197  string file_name = gen_array_item(file_list, i);
198  /* Skip the "." directory: */
199  if (strcmp(file_name, ".") != 0) {
200  struct stat buf;
201  char complete_file_name[MAXNAMELEN + 1];
202 
203  Menu_item menu_item =
204  xv_create(XV_NULL, MENUITEM,
205  MENU_STRING, strdup(file_name),
206  MENU_RELEASE,
207  /* The strdup'ed string will also be
208  freed when the menu is discarded: */
209  MENU_RELEASE_IMAGE,
210  NULL);
211 
212  (void) sprintf(complete_file_name, "%s/%s",
213  directory, file_name);
214  if (((stat(complete_file_name, &buf) == 0)
215  && (buf.st_mode & S_IFDIR))) {
216  /* Since a menu item cannot be selected as an item, add an
217  plain item with the same name. Not beautiful
218  hack... :-( */
219  xv_set(menu,
220  MENU_APPEND_ITEM, menu_item,
221  NULL);
222  /* Now recreate another item that will be the submenu: */
223  menu_item =
224  xv_create(XV_NULL, MENUITEM,
225  MENU_STRING, strdup(file_name),
226  MENU_RELEASE,
227  /* The strdup'ed string will also be
228  freed when the menu is discarded: */
229  MENU_RELEASE_IMAGE,
230  /* Put a right menu on each directory
231  entry: */
232  MENU_GEN_PULLRIGHT, directory_gen_pullright,
233  NULL);
234  pips_debug(2, " menu_item = %p (%s)\n",
235  (void *) menu_item, file_name);
236  }
237  else
238  /* And disable non-subdirectory entry: */
239  xv_set(menu_item, MENU_INACTIVE, TRUE, NULL);
240 
241  xv_set(menu, MENU_APPEND_ITEM, menu_item, NULL);
242  }
243  }
244  gen_array_full_free(file_list);
245  }
246  return menu;
247 }
size_t gen_array_nitems(const gen_array_t a)
Definition: array.c:131
void gen_array_full_free(gen_array_t a)
Definition: array.c:77
gen_array_t gen_array_make(size_t size)
declarations...
Definition: array.c:40
void * gen_array_item(const gen_array_t a, size_t i)
Definition: array.c:143
bool directory_exists_p(const char *name)
Definition: file.c:314
int safe_list_files_in_directory(gen_array_t files, string dir, string re, bool(*file_name_predicate)(const char *))
returns a sorted arg list of files matching regular expression re in directory 'dir' and with file_na...
Definition: file.c:250
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_user_warning
Definition: misc-local.h:146
#define user_warning(fn,...)
Definition: misc-local.h:262
string db_get_current_workspace_name(void)
the function is used to check that there is some current workspace...
Definition: workspace.c:82
char * strdup()
static char buf[BSZ]
Definition: split_file.c:157
static string file_name
static Menu directory_gen_pullright(Menu_item menu_item, Menu_generate op)
static void generate_a_directory_menu_notify(Menu menu, Menu_item menu_item)

References buf, db_get_current_workspace_name(), directory_exists_p(), directory_gen_pullright(), file_name, gen_array_full_free(), gen_array_item(), gen_array_make(), gen_array_nitems(), generate_a_directory_menu_notify(), MAXNAMELEN, MENU_PATH_DATA_HANDLER, pips_debug, pips_user_warning, safe_list_files_in_directory(), strdup(), user_warning, and WPIPS_MAX_DIRECTORY_MENU_SIZE.

+ Here is the call graph for this function:

◆ generate_a_directory_menu_notify()

static void generate_a_directory_menu_notify ( Menu  menu,
Menu_item  menu_item 
)
static

Definition at line 115 of file directory_menu.c.

116 {
117  char full_directory_name[MAXNAMELEN + 1];
118  char * directory_name = (char *) xv_get(menu_item, MENU_STRING);
119  char * parent_path_name =
120  (char *) xv_get(menu, XV_KEY_DATA, MENU_PATH_DATA_HANDLER);
121 
122  (void) sprintf(full_directory_name, "%s/%s",
123  parent_path_name, directory_name);
124  (void) end_directory_notify(full_directory_name);
125 }
success end_directory_notify(const char *dir)
Definition: gtk_select.c:103

References end_directory_notify(), MAXNAMELEN, and MENU_PATH_DATA_HANDLER.

Referenced by generate_a_directory_menu().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: