- mmcatmap.conf may be stuck into /pandora/mmenu on SD cards, in order to specify category mapping conf stuff (or random conf overrides)
- now includes a directory browser/launcher
- default is on (shows a tab for each non-empty dir in /media)
- could just make one tab for /media .. *shrug*
- may be disabled
- may specify all sorts of tabs to open by using a searchpath
- can run pnd-files (will work in the normal way)
- can run non-pnd files (will set CWD and run them without exiting minimenu)
- can browse up and down the dir tree
cache_findpath /media/mmcblk[12]p?/pandora/appdata/mmenu.pvwcache # where to look for cached preview pics
[categories]
-do_all_cat 1 # if >0, will show an All category; if 0, skip it, just your cats.
-# Normally for mmenu, an encountered category is just used as is. 5 cats exist, you get 5 tabs.
-# If map_on is >0, then category transforms will occur
-# @NEWCAT oldcat1:oldcat2 <- means oldcat1, if found, will map to NEWCAT. "@" is discarded.
-# NOTE: FreeDesktop rules do not allow categories with spaces in the name; if needed, I can add it with quoting.
-# If map_default_on is set (>0), then any unmapped categories will be forced into the default category bucket (map_default_cat.)
-# If map_default_on is off (=0), then unmapped categories will become their own categories as normal.
-# Should probably still have an @ line to create the default category, since creating the cats comes before assigning defaults
-# NOTE: Individual app overrides occur at the time of app scanning, so before this category mapping occurs and thus is effected
-map_on 0 # if >0, will do category mapping at all; if 0, don't do any of this.
-map_default_on 0 # if >0, any unmapped category will get forced to map_default_cat; set to 0 to leave unmapped cats alone
-map_default_cat Spam # see map_default_on
-# NOTE: List the categories in reverse order to how you wish them in the tab list; last one shows up as first tab
-@Woogle Audio
-@Jimmy Game
-@Spam
+catmap_searchpath /media/*/pandora/mmenu:/etc/pandora/mmenu:./minimenu
+catmap_confname mmcatmap.conf
+do_all_cat 1 # if >0, will show an All category; if 0, skip it, just your cats.
+
+[filesystem]
+do_browser 1 # if >0, will allow filesystem browsing somehow
+tab_searchpaths /media/* # for each chunk in searchpath, show a tab (if not empty).
+# example:
+# /media -> show /media as a single tab
+# /media/* -> show a tab for each dir in /media
+# /media/mmcblk1p1:/media/mmcblk2p1 -> show 2 tabs, one for first partition on each SD
* overridespath may be NULL if you do not wish to search for pxml overrides
*/
pnd_box_handle pnd_disco_search ( char *searchpath, char *overridespath );
+pnd_box_handle pnd_disco_file ( char *path, char *filename ); // should you wish to 'discover' one .pnd-file
/* pnd_disco_t describes a given entry found by the discovery code; ie: the containers key is the path to
* the PXML file (since this is relatively unique), with the fields below detailing the executable path,
// NOTE: We really need to rework disco-t so it can include non-english titles/desc; perhaps more info as optional,
// or a name/value pairing system so it can have extra data in it, without a complex structure.
#define PND_DISCO_FLAG_OVR 1 // An ovr file was found for this app (not per subapp, just per .pnd)
+#define PND_DISCO_GENERATED 2 // This disco is 'faux', made up and not reflecting a real 'pnd file'
typedef struct {
// base
unsigned char object_type; // see enum above
return ( disco_box );
}
+
+pnd_box_handle pnd_disco_file ( char *path, char *filename ) {
+ struct stat statbuf;
+
+ // set up container
+ disco_overrides = NULL;
+ disco_box = pnd_box_new ( "discovery" );
+
+ // path
+ char fullpath [ PATH_MAX ];
+ sprintf ( fullpath, "%s/%s", path, filename );
+
+ // fake it
+ if ( stat ( fullpath, &statbuf ) < 0 ) {
+ return ( 0 );
+ }
+
+ struct FTW ftw;
+ ftw.base = strlen ( path );
+ ftw.level = 0;
+
+ pnd_disco_callback ( fullpath, &statbuf, FTW_F, &ftw );
+
+ // return whatever we found, or NULL if nada
+ if ( ! pnd_box_get_head ( disco_box ) ) {
+ pnd_box_delete ( disco_box );
+ disco_box = NULL;
+ }
+
+ return ( disco_box );
+}
} // stat
} // ovr?
- // pull icon into buffer from .pnd
- if ( ! iconbuf ) {
- iconbuf = pnd_emit_icon_to_buffer ( app, &buflen );
- }
+ // if this is a real pnd file (dir-app or pnd-file-app), then try to pull icon from there
+ if ( ! ( app -> object_flags & PND_DISCO_GENERATED ) ) {
+
+ // pull icon into buffer from .pnd if not already found an icon
+ if ( ! iconbuf ) {
+ iconbuf = pnd_emit_icon_to_buffer ( app, &buflen );
+ }
+
+ } // generated?
if ( ! iconbuf ) {
return ( 0 );
#include <string.h>
#include <strings.h>
#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include "pnd_conf.h"
#include "pnd_logger.h"
extern pnd_conf_handle g_conf;
-unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh ) {
+unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh, char *fspath ) {
mm_category_t *c;
// check category list; if found, append app to the end of it.
g_categories [ g_categorycount ].catname = strdup ( catname );
g_categories [ g_categorycount ].refs = NULL;
c = &(g_categories [ g_categorycount ]);
+
+ if ( fspath ) {
+ g_categories [ g_categorycount ].fspath = strdup ( fspath );;
+ }
+
g_categorycount++;
}
while ( iter ) {
if ( iter -> ref -> title_en ) {
- if ( strcmp ( ar -> ref -> title_en, iter -> ref -> title_en ) < 0 ) {
+ if ( cat_sort_score ( ar, iter ) < 0 ) {
// new guy is smaller than the current guy!
break;
}
return ( NULL );
}
+int cat_sort_score ( mm_appref_t *s1, mm_appref_t *s2 ) {
+
+ extern mm_category_t g_categories [ MAX_CATS ];
+ extern unsigned char g_categorycount;
+ extern unsigned char ui_category;
+
+ // are we in a directory browser, or looking at pnd-files?
+ if ( g_categories [ ui_category ].fspath ) {
+
+ if ( s1 == s2 ) {
+ return ( 0 ); // equal
+
+ } else if ( s1 -> ref -> object_type == pnd_object_type_directory &&
+ s2 -> ref -> object_type == pnd_object_type_directory )
+ {
+ // both are directories, be nice
+ return ( strcmp ( s1 -> ref -> title_en, s2 -> ref -> title_en ) );
+ } else if ( s1 -> ref -> object_type == pnd_object_type_directory &&
+ s2 -> ref -> object_type != pnd_object_type_directory )
+ {
+ return ( -1 ); // dir on the left is earlier than file on the right
+ } else if ( s1 -> ref -> object_type != pnd_object_type_directory &&
+ s2 -> ref -> object_type == pnd_object_type_directory )
+ {
+ return ( 1 ); // dir on the right is earlier than file on the left
+ } else {
+ // file on file
+ return ( strcmp ( s1 -> ref -> title_en, s2 -> ref -> title_en ) );
+ }
+
+ }
+
+ return ( strcmp ( s1 -> ref -> title_en, s2 -> ref -> title_en ) );
+}
+
void category_dump ( void ) {
unsigned int i;
{
//pnd_log ( pndn_debug, "target(%s) from(%s)\n", k, buffer );
- category_push ( k, NULL, 0 );
+ category_push ( k, NULL, 0, NULL /* fspath */ );
g_catmaps [ g_catmapcount ].target = category_query ( k );
g_catmaps [ g_catmapcount ].from = strdup ( buffer );
g_catmapcount++;
cat = category_map_query ( catname );
if ( cat ) {
- return ( category_push ( cat -> catname, app, ovrh ) );
+ return ( category_push ( cat -> catname, app, ovrh, NULL /* fspath */ ) );
}
// not mapped.. but default?
if ( pnd_conf_get_as_int_d ( g_conf, "categories.map_default_on", 0 ) ) {
char *def = pnd_conf_get_as_char ( g_conf, "categories.map_default_cat" );
if ( def ) {
- return ( category_push ( def, app, ovrh ) );
+ return ( category_push ( def, app, ovrh, NULL /* fspath */ ) );
}
}
} // cat map is desired?
// not default, just do it
- return ( category_push ( catname, app, ovrh ) );
+ return ( category_push ( catname, app, ovrh, NULL /* fspath */ ) );
+}
+
+unsigned char category_fs_restock ( mm_category_t *cat ) {
+
+ if ( ! cat -> fspath ) {
+ return ( 1 ); // not a filesystem browser tab
+ }
+
+ // clear any existing baggage
+ //
+
+ // apprefs
+ mm_appref_t *iter = cat -> refs, *next;
+ while ( iter ) {
+ next = iter -> next;
+ free ( iter );
+ iter = next;
+ }
+ cat -> refs = NULL;
+
+ // discos
+ if ( cat -> disco ) {
+ pnd_disco_t *p = pnd_box_get_head ( cat -> disco );
+ pnd_disco_t *n;
+ while ( p ) {
+ n = pnd_box_get_next ( p );
+ pnd_disco_destroy ( p );
+ p = n;
+ }
+ pnd_box_delete ( cat -> disco );
+ }
+
+ // rescan the filesystem
+ //
+
+ //pnd_log ( pndn_debug, "Restocking cat %s with path %s\n", cat -> catname, cat -> fspath );
+ DIR *d;
+
+ if ( ( d = opendir ( cat -> fspath ) ) ) {
+ struct dirent *de = readdir ( d );
+
+ pnd_disco_t *disco;
+ char uid [ 100 ];
+
+ cat -> disco = pnd_box_new ( cat -> catname );
+
+ while ( de ) {
+
+ struct stat buffy;
+ char fullpath [ PATH_MAX ];
+ sprintf ( fullpath, "%s/%s", cat -> fspath, de -> d_name );
+ int statret = stat ( fullpath, &buffy );
+
+ // if file is executable somehow or another
+ if ( statret == 0 &&
+ buffy.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)
+ )
+ {
+ // determine unique-id
+ sprintf ( uid, "%d", (int) de -> d_ino );
+ disco = NULL;
+
+ switch ( de -> d_type ) {
+
+ case DT_DIR:
+ if ( strcmp ( de -> d_name, "." ) == 0 ) {
+ // ignore ".", but ".." is fine
+ } else {
+ disco = pnd_box_allocinsert ( cat -> disco, uid, sizeof(pnd_disco_t) );
+ disco -> object_type = pnd_object_type_directory; // suggest to Grid that its a dir
+ }
+ break;
+ case DT_UNKNOWN:
+ case DT_REG:
+ disco = pnd_box_allocinsert ( cat -> disco, uid, sizeof(pnd_disco_t) );
+ disco -> object_type = pnd_object_type_unknown; // suggest to Grid that its a file
+ break;
+
+ } // switch
+
+ // found a directory or executable?
+ if ( disco ) {
+ // register with this category
+ disco -> unique_id = strdup ( uid );
+ disco -> title_en = strdup ( de -> d_name );
+ disco -> object_flags = PND_DISCO_GENERATED;
+ disco -> object_path = strdup ( cat -> fspath );
+ disco -> object_filename = strdup ( de -> d_name );
+ category_push ( cat -> catname, disco, 0, NULL /* fspath already set */ );
+ // if a override icon exists, cache it up
+ cache_icon ( disco, pnd_conf_get_as_int_d ( g_conf, "grid.icon_max_width", 50 ),
+ pnd_conf_get_as_int_d ( g_conf, "grid.icon_max_height", 50 ) );
+ }
+
+ } // stat
+
+ // next
+ de = readdir ( d );
+ }
+
+ closedir ( d );
+ }
+
+ return ( 1 );
}
typedef struct {
char *catname; // name of the category
+ // current applications
mm_appref_t *refs; // apps (from g_active_apps) that are in this category
unsigned int refcount; // how many apps in this category
+ // if a directory browser category, additional info is needed
+ char *fspath; // NULL if a pnd-category (not a filesystem category)
+ pnd_box_handle disco; // faux-applications generated from filesystem
} mm_category_t;
#define MAX_CATS 100
#define CATEGORY_ALL "All"
// try to populate as many cats as necessary
-unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh ); // catname is not pulled from app, so we can make them up on the fly (ie: "All")
+unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh, char *fspath ); // catname is not pulled from app, so we can make them up on the fly (ie: "All");
mm_category_t *category_query ( char *catname );
void category_dump ( void ); // sort the apprefs
void category_freeall ( void );
+int cat_sort_score ( mm_appref_t *s1, mm_appref_t *s2 ); // like strcmp, but used to sort apps by title
// category mapping hack
typedef struct {
mm_category_t *category_map_query ( char *cat );
unsigned char category_meta_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh );
+// filesystem browser
+unsigned char category_fs_restock ( mm_category_t *cat );
+
#endif
--- /dev/null
+
+#
+# mmcatmap.conf -- allows merging or renaming or mapping of categories from one name to another, for minimenu.
+#
+
+[categories]
+# Normally for mmenu, an encountered category is just used as is. 5 cats exist, you get 5 tabs.
+# If map_on is >0, then category transforms will occur
+# @NEWCAT oldcat1:oldcat2 <- means oldcat1, if found, will map to NEWCAT. "@" is discarded.
+# NOTE: FreeDesktop rules do not allow categories with spaces in the name; if needed, I can add it with quoting.
+# If map_default_on is set (>0), then any unmapped categories will be forced into the default category bucket (map_default_cat.)
+# If map_default_on is off (=0), then unmapped categories will become their own categories as normal.
+# Should probably still have an @ line to create the default category, since creating the cats comes before assigning defaults
+# NOTE: Individual app overrides occur at the time of app scanning, so before this category mapping occurs and thus is effected
+map_on 0 # if >0, will do category mapping at all; if 0, don't do any of this.
+map_default_on 0 # if >0, any unmapped category will get forced to map_default_cat; set to 0 to leave unmapped cats alone
+map_default_cat Spam # see map_default_on
+# NOTE: List the categories in reverse order to how you wish them in the tab list; last one shows up as first tab
+@Woogle Audio
+@Jimmy Game
+@Spam
#include <strings.h>
#include <ctype.h>
#include <sys/wait.h>
+#include <dirent.h>
#include "pnd_logger.h"
#include "pnd_pxml.h"
#include "pnd_locate.h"
#include "pnd_device.h"
#include "pnd_pndfiles.h"
+#include "../lib/pnd_pathiter.h"
#include "mmenu.h"
#include "mmwrapcmd.h"
emit_and_quit ( MM_QUIT );
}
+ /* category conf file
+ */
+ {
+ char *locater = pnd_locate_filename ( pnd_conf_get_as_char ( g_conf, "categories.catmap_searchpath" ),
+ pnd_conf_get_as_char ( g_conf, "categories.catmap_confname" ) );
+
+ if ( locater ) {
+ pnd_log ( pndn_rem, "Found category conf at '%s'\n", locater );
+ pnd_conf_handle h = pnd_conf_fetch_by_path ( locater );
+ if ( h ) {
+ // lets just merge the skin conf onto the regular conf, so it just magicly works
+ pnd_box_append ( g_conf, h );
+ }
+ } else {
+ pnd_log ( pndn_debug, "No additional category conf file found.\n" );
+ }
+
+ } // cat conf
+
// redo log filter
pnd_log_set_filter ( pnd_conf_get_as_int_d ( g_conf, "minimenu.loglevel", pndn_error ) );
// create all cat
if ( pnd_conf_get_as_int_d ( g_conf, "categories.do_all_cat", 1 ) ) {
- category_push ( g_x11_present ? CATEGORY_ALL " (X11)" : CATEGORY_ALL " (No X11)", NULL, 0 );
+ category_push ( g_x11_present ? CATEGORY_ALL " (X11)" : CATEGORY_ALL " (No X11)", NULL /*app*/, 0, NULL /* fspath */ );
}
// set up category mappings
exit ( 0 );
}
+static unsigned int is_dir_empty ( char *fullpath ) {
+ DIR *d = opendir ( fullpath );
+
+ if ( ! d ) {
+ return ( 0 ); // not empty, since we don't know
+ }
+
+ struct dirent *de = readdir ( d );
+
+ while ( de ) {
+
+ if ( strcmp ( de -> d_name, "." ) == 0 ) {
+ // irrelevent
+ } else if ( strcmp ( de -> d_name, ".." ) == 0 ) {
+ // irrelevent
+ } else {
+ // something else came in, so dir must not be empty
+ return ( 0 );
+ }
+
+ de = readdir ( d );
+ }
+
+ closedir ( d );
+
+ return ( 1 ); // dir is empty
+}
+
void applications_free ( void ) {
// free up all our category apprefs, but keep the preview and icon cache's..
// push to All category
// we do this first, so first category is always All
if ( pnd_conf_get_as_int_d ( g_conf, "categories.do_all_cat", 1 ) ) {
- if ( ! category_push ( g_x11_present ? CATEGORY_ALL " (X11)" : CATEGORY_ALL " (No X11)", iter, ovrh ) ) {
+ if ( ! category_push ( g_x11_present ? CATEGORY_ALL " (X11)" : CATEGORY_ALL " (No X11)", iter, ovrh, NULL /* fspath */ ) ) {
pnd_log ( pndn_warning, " Couldn't categorize to All: '%s'\n", IFNULL(iter -> title_en, "No Name") );
}
} // all?
itercount++;
} // while
+ // set up filesystem browser tabs
+ if ( pnd_conf_get_as_int_d ( g_conf, "filesystem.do_browser", 0 ) ) {
+ char *searchpath = pnd_conf_get_as_char ( g_conf, "filesystem.tab_searchpaths" );
+
+ SEARCHPATH_PRE
+ {
+ char *c, *tabname;
+ c = strrchr ( buffer, '/' );
+ if ( c && (*(c+1)!='\0') ) {
+ tabname = c;
+ } else {
+ tabname = buffer;
+ }
+
+ // check if dir is empty; if so, skip it.
+ if ( ! is_dir_empty ( buffer ) ) {
+ category_push ( tabname /* tab name */, NULL /* app */, 0 /* override */, buffer /* fspath */ );
+ }
+
+ }
+ SEARCHPATH_POST
+
+ } // set up fs browser tabs
+
// dump categories
//category_dump();
cache_findpath /media/mmcblk[12]p?/pandora/appdata/mmenu.pvwcache # where to look for cached preview pics
[categories]
-do_all_cat 1 # if >0, will show an All category; if 0, skip it, just your cats.
-# Normally for mmenu, an encountered category is just used as is. 5 cats exist, you get 5 tabs.
-# If map_on is >0, then category transforms will occur
-# @NEWCAT oldcat1:oldcat2 <- means oldcat1, if found, will map to NEWCAT. "@" is discarded.
-# NOTE: FreeDesktop rules do not allow categories with spaces in the name; if needed, I can add it with quoting.
-# If map_default_on is set (>0), then any unmapped categories will be forced into the default category bucket (map_default_cat.)
-# If map_default_on is off (=0), then unmapped categories will become their own categories as normal.
-# Should probably still have an @ line to create the default category, since creating the cats comes before assigning defaults
-# NOTE: Individual app overrides occur at the time of app scanning, so before this category mapping occurs and thus is effected
-map_on 0 # if >0, will do category mapping at all; if 0, don't do any of this.
-map_default_on 0 # if >0, any unmapped category will get forced to map_default_cat; set to 0 to leave unmapped cats alone
-map_default_cat Spam # see map_default_on
-# NOTE: List the categories in reverse order to how you wish them in the tab list; last one shows up as first tab
-@Woogle Audio
-@Jimmy Game
-@Spam
+catmap_searchpath /media/*/pandora/mmenu:/etc/pandora/mmenu:./minimenu
+catmap_confname mmcatmap.conf
+do_all_cat 1 # if >0, will show an All category; if 0, skip it, just your cats.
+
+[filesystem]
+do_browser 1 # if >0, will allow filesystem browsing somehow
+tab_searchpaths /media/* # for each chunk in searchpath, show a tab (if not empty).
+# example:
+# /media -> show /media as a single tab
+# /media/* -> show a tab for each dir in /media
+# /media/mmcblk1p1:/media/mmcblk2p1 -> show 2 tabs, one for first partition on each SD
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
+#include <stdio.h> /* for FILE etc */
+#include <stdlib.h> /* for malloc */
+#include <unistd.h> /* for unlink */
+#include <limits.h> /* for PATH_MAX */
+#include <sys/types.h>
+#include <sys/stat.h>
+#define __USE_GNU /* for strcasestr */
+#include <string.h> /* for making ftw.h happy */
#include <time.h>
-#include <unistd.h>
+#include <ftw.h>
#include "SDL.h"
#include "SDL_audio.h"
#include "SDL_image.h"
#include "SDL_gfxPrimitives.h"
#include "SDL_rotozoom.h"
#include "SDL_thread.h"
-#include <sys/types.h>
#include <dirent.h>
#include "pnd_conf.h"
#include "pnd_device.h"
#include "../lib/pnd_pathiter.h"
#include "pnd_utility.h"
+#include "pnd_pndfiles.h"
#include "mmenu.h"
#include "mmcat.h"
{ IMG_ARROW_DOWN, "graphics.IMG_ARROW_DOWN", },
{ IMG_ARROW_SCROLLBAR, "graphics.IMG_ARROW_SCROLLBAR", },
{ IMG_HOURGLASS, "graphics.IMG_HOURGLASS", },
+ { IMG_FOLDER, "graphics.IMG_FOLDER", },
+ { IMG_EXECBIN, "graphics.IMG_EXECBIN", },
{ IMG_MAX, NULL },
};
int topleft = col_max * ui_rows_scrolled_down;
int botright = ( col_max * ( ui_rows_scrolled_down + row_max ) - 1 );
- pnd_log ( PND_LOG_DEFAULT, "index %u tl %u br %u\n", index, topleft, botright );
-
if ( index < topleft ) {
ui_rows_scrolled_down -= pnd_conf_get_as_int_d ( g_conf, "grid.scroll_increment", 1 );
render_jobs_b |= R_ALL;
if ( g_imagecache [ IMG_TAB_SEL ].i && g_imagecache [ IMG_TAB_UNSEL ].i ) {
unsigned int tab_width = pnd_conf_get_as_int ( g_conf, "tabs.tab_width" );
unsigned int tab_height = pnd_conf_get_as_int ( g_conf, "tabs.tab_height" );
- unsigned int tab_selheight = pnd_conf_get_as_int ( g_conf, "tabs.tab_selheight" );
+ //unsigned int tab_selheight = pnd_conf_get_as_int ( g_conf, "tabs.tab_selheight" );
unsigned int tab_offset_x = pnd_conf_get_as_int ( g_conf, "tabs.tab_offset_x" );
unsigned int tab_offset_y = pnd_conf_get_as_int ( g_conf, "tabs.tab_offset_y" );
unsigned int text_offset_x = pnd_conf_get_as_int ( g_conf, "tabs.text_offset_x" );
iconsurface = ic -> i;
} else {
//pnd_log ( pndn_warning, "WARNING: TBD: Need Missin-icon icon for '%s'\n", IFNULL(appiter -> ref -> title_en,"No Name") );
- iconsurface = g_imagecache [ IMG_ICON_MISSING ].i;
+
+ // no icon override; was this a pnd-file (show the unknown icon then), or was this generated from
+ // filesystem (file or directory icon)
+ if ( appiter -> ref -> object_flags & PND_DISCO_GENERATED ) {
+ if ( appiter -> ref -> object_type == pnd_object_type_directory ) {
+ iconsurface = g_imagecache [ IMG_FOLDER ].i;
+ } else {
+ iconsurface = g_imagecache [ IMG_EXECBIN ].i;
+ }
+ } else {
+ iconsurface = g_imagecache [ IMG_ICON_MISSING ].i;
+ }
+
}
+
+ // got an icon I hope?
if ( iconsurface ) {
//pnd_log ( pndn_debug, "Got an icon for '%s'\n", IFNULL(appiter -> ref -> title_en,"No Name") );
void ui_push_exec ( void ) {
- if ( ui_selected ) {
+ if ( ! ui_selected ) {
+ return;
+ }
+
+ // was this icon generated from filesystem, or from pnd-file?
+ if ( ui_selected -> ref -> object_flags & PND_DISCO_GENERATED ) {
+
+ if ( ! ui_selected -> ref -> title_en ) {
+ return; // no filename
+ }
+
+ if ( ui_selected -> ref -> object_type == pnd_object_type_directory ) {
+ // delve up/down the dir tree
+
+ if ( strcmp ( ui_selected -> ref -> title_en, ".." ) == 0 ) {
+ // go up
+ char *c;
+
+ // lop off last word; if the thing ends with /, lop that one, then the next word.
+ while ( ( c = strrchr ( g_categories [ ui_category].fspath, '/' ) ) ) {
+ *c = '\0'; // lop off the last hunk
+ if ( *(c+1) != '\0' ) {
+ break;
+ }
+ } // while
+
+ // nothing left?
+ if ( g_categories [ ui_category].fspath [ 0 ] == '\0' ) {
+ strcpy ( g_categories [ ui_category].fspath, "/" );
+ }
+
+ } else {
+ // go down
+ strcat ( g_categories [ ui_category].fspath, "/" );
+ strcat ( g_categories [ ui_category].fspath, ui_selected -> ref -> title_en );
+ }
+
+ pnd_log ( pndn_debug, "Cat %s is now in path %s\n", g_categories [ ui_category ].catname, g_categories [ ui_category ].fspath );
+
+ // rescan the dir
+ category_fs_restock ( &(g_categories [ ui_category]) );
+ // forget the selection, nolonger applies
+ ui_selected = NULL;
+ ui_set_selected ( ui_selected );
+ // redraw the grid
+ render_mask |= CHANGED_SELECTION;
+
+ } else {
+ // just run it arbitrarily?
+
+ // if this a pnd-file, or just some executable?
+ if ( strcasestr ( ui_selected -> ref -> object_filename, PND_PACKAGE_FILEEXT ) ) {
+ // looks like a pnd, now what do we do..
+ pnd_box_handle h = pnd_disco_file ( ui_selected -> ref -> object_path, ui_selected -> ref -> object_filename );
+
+ if ( h ) {
+ pnd_disco_t *d = pnd_box_get_head ( h );
+ pnd_apps_exec_disco ( pnd_run_script, d, PND_EXEC_OPTION_NORUN, NULL );
+ char buffer [ PATH_MAX ];
+ sprintf ( buffer, "%s %s\n", MM_RUN, pnd_apps_exec_runline() );
+ emit_and_quit ( buffer );
+ }
+
+ } else {
+ // random bin file
+#if 1
+ char cwd [ PATH_MAX ];
+ getcwd ( cwd, PATH_MAX );
+
+ chdir ( g_categories [ ui_category ].fspath );
+ pnd_exec_no_wait_1 ( ui_selected -> ref -> title_en, NULL );
+ chdir ( cwd );
+#else
+ char buffer [ PATH_MAX ];
+ sprintf ( buffer, "%s %s/%s\n", MM_RUN, g_categories [ ui_category ].fspath, ui_selected -> ref -> title_en );
+ emit_and_quit ( buffer );
+#endif
+ } // pnd or bin?
+
+ } // dir or file?
+
+ } else {
pnd_apps_exec_disco ( pnd_run_script, ui_selected -> ref, PND_EXEC_OPTION_NORUN, NULL );
char buffer [ PATH_MAX ];
sprintf ( buffer, "%s %s\n", MM_RUN, pnd_apps_exec_runline() );
if ( ui_category > 0 ) {
ui_category--;
+ category_fs_restock ( &(g_categories [ ui_category ]) );
} else {
if ( pnd_conf_get_as_int_d ( g_conf, "tabs.wraparound", 0 ) > 0 ) {
ui_category = g_categorycount - 1;
+ category_fs_restock ( &(g_categories [ ui_category ]) );
}
}
if ( ui_category < ( g_categorycount - 1 ) ) {
ui_category++;
+ category_fs_restock ( &(g_categories [ ui_category ]) );
} else {
if ( pnd_conf_get_as_int_d ( g_conf, "tabs.wraparound", 0 ) > 0 ) {
ui_category = 0;
+ category_fs_restock ( &(g_categories [ ui_category ]) );
}
}
IMG_ARROW_DOWN,
IMG_ARROW_SCROLLBAR,
IMG_HOURGLASS,
+ IMG_FOLDER,
+ IMG_EXECBIN,
IMG_MAX, // before this point is loaded; after is generated
IMG_TRUEMAX
} mm_imgcache_e;
IMG_ARROW_DOWN arrowdown.png
IMG_ARROW_SCROLLBAR arrowscroller.png
IMG_HOURGLASS hourglass.png
+IMG_FOLDER /usr/share/icons/gnome/32x32/places/folder.png # in dirbrowser mode
+IMG_EXECBIN /usr/share/icons/gnome/32x32/categories/applications-other.png # in dirbrowser mode