added 'subcats as folders' option and support, set default ON.
authorskeezix <skeezix@flotsam-vm.(none)>
Wed, 26 Jan 2011 19:54:12 +0000 (14:54 -0500)
committerskeezix <skeezix@flotsam-vm.(none)>
Wed, 26 Jan 2011 19:54:12 +0000 (14:54 -0500)
Makefile
minimenu/mmcat.c
minimenu/mmcat.h
minimenu/mmconf.c
minimenu/mmenu.c
minimenu/mmui.c
minimenu/skin/default/mmskin.conf

index 46032f4..4220ac6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,7 @@ ALLOBJ = pnd_conf.o pnd_container.o pnd_discovery.o pnd_pxml.o pnd_notify.o pnd_
 all: ${SOLIB} ${LIB} conftest discotest evdevtest notifytest pndnotifyd rawpxmltest pndvalidator loggertest dbusnotifytest pnd_run pndevmapperd pnd_info evtest mmenu mmwrapper
 
 clean:
-       ${RM} -f ${ALLOBJ} ${XMLOBJ} ${LIB} ${SOLIB1} locatetest.o bin/locatetest conftest.o bin/conftest discotest.o evdevtest.o bin/evdevtest bin/discotest dbusnotifytest.o bin/dbusnotifytest loggertest.o bin/loggertest bin/notifytest notifytest.o bin/rawpxmltest rawpxmltest.o bin/pnd_run pnd_run.o pnd_info.o bin/pnd_info bin/pndevmapperd pndevmapperd.o bin/pndnotifyd pndnotifyd.o ${SOLIB} testdata/dotdesktop/*.desktop testdata/menu/*.desktop testdata/apps/*.pnd testdata/dotdesktop/*.png deployment/usr/lib/libpnd* deployment/usr/bin/pndnotifyd deployment/usr/bin/pnd_run deployment/usr/bin/pnd_info deployment/usr/pandora/scripts/* deployment/etc/sudoers deployment/etc/init.d/pndnotifyd bin/pndvalidator pndvalidator.o deployment/usr/bin/pndevmapperd testdata/menuicons/* evtest.o bin/evtest bin/mmenu bin/mmwrapper mmenu.o mmwrapper.o deployment/usr/bin/mmenu deployment/usr/bin/mmwrapper mmcache.o mmui.o mmcat.o mmconf.o freedsktop_cats.o
+       ${RM} -f ${ALLOBJ} ${XMLOBJ} ${LIB} ${SOLIB1} locatetest.o bin/locatetest conftest.o bin/conftest discotest.o evdevtest.o bin/evdevtest bin/discotest dbusnotifytest.o bin/dbusnotifytest loggertest.o bin/loggertest bin/notifytest notifytest.o bin/rawpxmltest rawpxmltest.o bin/pnd_run pnd_run.o pnd_info.o bin/pnd_info bin/pndevmapperd pndevmapperd.o bin/pndnotifyd pndnotifyd.o ${SOLIB} testdata/dotdesktop/*.desktop testdata/menu/*.desktop testdata/apps/*.pnd testdata/dotdesktop/*.png deployment/usr/lib/libpnd* deployment/usr/bin/pndnotifyd deployment/usr/bin/pnd_run deployment/usr/bin/pnd_info deployment/usr/pandora/scripts/* deployment/etc/sudoers deployment/etc/init.d/pndnotifyd bin/pndvalidator pndvalidator.o deployment/usr/bin/pndevmapperd testdata/menuicons/* evtest.o bin/evtest bin/mmenu bin/mmwrapper mmenu.o mmwrapper.o deployment/usr/bin/mmenu deployment/usr/bin/mmwrapper mmcache.o mmui.o mmcat.o mmconf.o freedsktop_cats.o freedesktop_cats.o
        ${RM} -rf deployment/media deployment/etc/pandora/mmenu
        find . -name "*~*" -exec rm {} \; -print
 
index 267507e..e96aa23 100644 (file)
@@ -39,7 +39,7 @@ void category_init ( void ) {
   return;
 }
 
-unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh, char *fspath, unsigned char visiblep ) {
+unsigned char category_push ( char *catname, char *parentcatname, pnd_disco_t *app, pnd_conf_handle ovrh, char *fspath, unsigned char visiblep ) {
   mm_category_t *c;
 
   // check category list; if found, append app to the end of it.
@@ -58,11 +58,22 @@ unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle o
     //pnd_log ( PND_LOG_DEFAULT, "New category '%s'\n", catname );
     c = pnd_box_allocinsert ( m_categories, catname, sizeof(mm_category_t) );
     c -> catname = strdup ( catname );
+    if ( parentcatname ) {
+      c -> parent_catname = strdup ( parentcatname );
+    }
+
     if ( visiblep ) {
       c -> catflags = CFNORMAL;
     } else {
       c -> catflags = CFHIDDEN;
     }
+
+    // if user prefers subcats-as-folders, lets reflag this sucker
+    if ( parentcatname && pnd_conf_get_as_int_d ( g_conf, "tabs.subcat_as_folders", 1 ) ) {
+      //printf ( "subcat: %s parent: %s\n", catname, parentcatname ? parentcatname : "none" );
+      c -> catflags = CFSUBCAT;
+    }
+
     c -> refs = NULL;
 
     if ( fspath ) {
@@ -255,7 +266,7 @@ unsigned char category_map_setup ( void ) {
       {
        //pnd_log ( pndn_debug, "target(%s) from(%s)\n", k, buffer );
 
-       category_push ( k, NULL, 0, NULL /* fspath */, 1 );
+       category_push ( k, NULL /* parent cat */, NULL, 0, NULL /* fspath */, 1 );
        g_catmaps [ g_catmapcount ].target = pnd_box_find_by_key ( m_categories, k );
        g_catmaps [ g_catmapcount ].from = strdup ( buffer );
        g_catmapcount++;
@@ -343,7 +354,7 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco
     cat = category_map_query ( catname );
 
     if ( cat ) {
-      category_push ( cat -> catname, app, ovrh, NULL /* fspath */, visiblep );
+      category_push ( cat -> catname, parentcatname /* parent cat */, app, ovrh, NULL /* fspath */, visiblep );
       goto meta_done;
     }
 
@@ -351,7 +362,7 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco
     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 ) {
-       category_push ( def, app, ovrh, NULL /* fspath */, visiblep );
+       category_push ( def, parentcatname /* parent cat */, app, ovrh, NULL /* fspath */, visiblep );
        goto meta_done;
       }
     }
@@ -359,7 +370,69 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco
   } // cat map is desired?
 
   // not default, just do it
-  category_push ( catname, app, ovrh, NULL /* fspath */, visiblep );
+  category_push ( catname, parentcatname /* parent cat */, app, ovrh, NULL /* fspath */, visiblep );
+
+  // if subcats as folders, then lets just make up a dummy app that pretends to be a folder,
+  // and stuff it into the parent cat
+  if ( parentcatname && pnd_conf_get_as_int_d ( g_conf, "tabs.subcat_as_folders", 1 ) ) {
+
+    // it is implicit that since we're talking parentcat, its already been created in a previous call
+    // therefore, we need to..
+    // i) find the parent cat
+    // ii) ensure it already has a faux-disco container
+    // iii) ensure that disco container doesn't already contain a disco-entry for this subcat
+    // iv) create the dummy app folder by pushing the disco into the apprefs as normal
+    // v) create a dummy '..' for going back up, in the child
+
+    mm_category_t *pcat = pnd_box_find_by_key ( m_categories, parentcatname );
+
+    if ( ! pcat -> disco ) {
+      pcat -> disco = pnd_box_new ( pcat -> catname );
+    }
+
+    // if this subcat is already in the faux-disco list, then its probably already
+    // handled so we needn't concern ourselves anymore. If not, then we can
+    // create it and push it into the parent as a new 'app'
+    pnd_disco_t *disco = pnd_box_find_by_key ( pcat -> disco, catname );
+
+    if ( ! disco ) {
+
+      disco = pnd_box_allocinsert ( pcat -> disco, catname, sizeof(pnd_disco_t) );
+      if ( disco ) {
+
+       // create the subcat faux-disco entry, and register into parent cat
+       char uid [ 30 ];
+       sprintf ( uid, "%p", catname );
+
+       disco -> unique_id = strdup ( uid );
+       if ( strchr ( catname, '.' ) ) {
+         disco -> title_en = strdup ( strchr ( catname, '.' ) + 1 );
+       } else {
+         disco -> title_en = strdup ( catname );
+       }
+       disco -> object_flags = PND_DISCO_GENERATED;
+       disco -> object_type = pnd_object_type_directory; // suggest to Grid that its a dir
+       disco -> object_path = strdup ( catname );
+
+       category_push ( parentcatname, NULL /* parent cat */, disco, 0 /*ovrh*/, NULL /* fspath */, 1 /* visible */ );
+
+       // create .. faux-disco entry into child cat
+       disco = pnd_box_allocinsert ( pcat -> disco, catname, sizeof(pnd_disco_t) );
+
+       sprintf ( uid, "%p", uid );
+
+       disco -> unique_id = strdup ( uid );
+       disco -> title_en = strdup ( ".." );
+       disco -> object_flags = PND_DISCO_GENERATED;
+       disco -> object_type = pnd_object_type_directory; // suggest to Grid that its a dir
+
+       category_push ( catname, parentcatname /* parent cat */, disco, 0 /*ovrh*/, NULL /* fspath */, 1 /* visible */ );
+
+      } // making faux disco entries
+
+    } // disco already exist?
+
+  } // subcat as folder?
 
   // hack :(
  meta_done:
@@ -455,7 +528,7 @@ unsigned char category_fs_restock ( mm_category_t *cat ) {
          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 /* no ovr */, NULL /* fspath already set */, 1 /* visible */ );
+         category_push ( cat -> catname, NULL /* parent cat */, disco, 0 /* no ovr */, NULL /* fspath already set */, 1 /* visible */ );
          // 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 ) );
@@ -526,6 +599,10 @@ void category_publish ( unsigned int filter_mask, char *param ) {
     // is this category desired?
     if ( filter_mask == CFALL ) {
       interested = 1;
+    } else if ( filter_mask == CFBYNAME ) {
+      if ( strcasecmp ( iter -> catname, param ) == 0 ) {
+       interested = 1;
+      }
     } else if ( iter -> catflags == filter_mask ) {
       interested = 1;
     } // if
index c886f2d..d367a2f 100644 (file)
@@ -17,6 +17,7 @@ typedef struct _mm_appref_t {
 // an actual category reference; points to a list of appref's and supplies a tabname, a filesystem mountpoint, etc.
 typedef struct _mm_category_t {
   char *catname;          // name of the category
+  char *parent_catname;   // if known, parent cat name
   unsigned int catflags;  // flags
 
   // current applications
@@ -42,7 +43,7 @@ typedef struct _mm_category_t {
 
 // try to populate as many cats as necessary
 void category_init ( void ); // set up; call first!
-unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh, char *fspath, unsigned char visiblep ); // catname is not pulled from app, so we can make them up on the fly (ie: "All");
+unsigned char category_push ( char *catname, char *parentcatname, pnd_disco_t *app, pnd_conf_handle ovrh, char *fspath, unsigned char visiblep ); // catname is not pulled from app, so we can make them up on the fly (ie: "All");
 void category_dump ( void ); // sort the apprefs
 void category_freeall ( void );
 int cat_sort_score ( mm_category_t *cat, mm_appref_t *s1, mm_appref_t *s2 ); // like strcmp, but used to sort apps by title
index d0db0ba..8a69ef1 100644 (file)
@@ -569,6 +569,7 @@ unsigned char conf_prepare_page ( confitem_t *page ) {
       unsigned int i;
       char catname [ 512 ];
       char *actual_catname;
+      char finalbuf [ 101 ];
 
       for ( i = 0;  i < g_categorycount; i++ ) {
 
@@ -587,7 +588,13 @@ unsigned char conf_prepare_page ( confitem_t *page ) {
          continue;
        }
 
-       p -> text = strndup ( actual_catname, 40 );
+       if ( g_categories [ i ] -> parent_catname ) {
+         snprintf ( finalbuf, 100, "%s [%s]", actual_catname, g_categories [ i ] -> parent_catname );
+       } else {
+         strncpy ( finalbuf, actual_catname, 100 );
+       }
+
+       p -> text = strndup ( finalbuf, 40 );
        p -> desc = NULL;
        p -> def = NULL;
 
index 83743bc..02fe2a1 100644 (file)
@@ -359,7 +359,7 @@ int main ( int argc, char *argv[] ) {
 
   // 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 /*app*/, 0, NULL /* fspath */, 1 /* visible */ );
+    category_push ( g_x11_present ? CATEGORY_ALL "    (X11)" : CATEGORY_ALL "   (No X11)", NULL /* parent cat */, NULL /*app*/, 0, NULL /* fspath */, 1 /* visible */ );
   }
 
   // set up category mappings
@@ -677,7 +677,7 @@ void applications_scan ( void ) {
        // 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 ) ) {
-         category_push ( g_x11_present ? CATEGORY_ALL "    (X11)" : CATEGORY_ALL "   (No X11)", iter, ovrh, NULL /* fspath */, 1 /* visible */ );
+         category_push ( g_x11_present ? CATEGORY_ALL "    (X11)" : CATEGORY_ALL "   (No X11)", NULL /* parent cat */, iter, ovrh, NULL /* fspath */, 1 /* visible */ );
        } // all?
 
        // is this app suppressed? if not, show it in whatever categories the user is allowing
@@ -721,7 +721,7 @@ void applications_scan ( void ) {
 
       // 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 */, 1 /* visible */ );
+       category_push ( tabname /* tab name */, NULL /* parent cat */, NULL /* app */, 0 /* override */, buffer /* fspath */, 1 /* visible */ );
       }
 
     }
index 32b73ff..2b34fa5 100644 (file)
@@ -1620,43 +1620,83 @@ void ui_push_exec ( void ) {
     }
 
     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;
+      // check if this guy is a dir-browser tab, or is a directory on a pnd tab
+      if ( ! g_categories [ ui_category] -> fspath ) {
+       // pnd subcat as dir
 
-       // 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;
+       static char *ui_category_stack = NULL;
+
+       // are we already in a subcat? if so, go back to parent; there is no grandparenting or deeper
+       if ( g_categories [ ui_category ] -> parent_catname ) {
+         // go back up
+
+         // set to first cat!
+         ui_category = 0;
+         // republish cats .. shoudl just be the one
+         category_publish ( CFNORMAL, NULL );
+
+         if ( ui_category_stack ) {
+           ui_category = category_index ( ui_category_stack );
          }
-       } // while
 
-       // nothing left?
-       if ( g_categories [ ui_category] -> fspath [ 0 ] == '\0' ) {
-         free ( g_categories [ ui_category] -> fspath );
-         g_categories [ ui_category] -> fspath = strdup ( "/" );
+       } else {
+         // delve into subcat
+
+         // set to first cat!
+         ui_category_stack = g_categories [ ui_category ] -> catname;
+         ui_category = 0;
+         // republish cats .. shoudl just be the one
+         category_publish ( CFBYNAME, ui_selected -> ref -> object_path );
+
        }
 
+       // forget the selection, nolonger applies
+       ui_selected = NULL;
+       ui_set_selected ( ui_selected );
+       // redraw the grid
+       render_mask |= CHANGED_EVERYTHING;
+
       } else {
-       // go down
-       char *temp = malloc ( strlen ( g_categories [ ui_category] -> fspath ) + strlen ( ui_selected -> ref -> title_en ) + 1 + 1 );
-       sprintf ( temp, "%s/%s", g_categories [ ui_category] -> fspath, ui_selected -> ref -> title_en );
-       free ( g_categories [ ui_category] -> fspath );
-       g_categories [ ui_category] -> fspath = temp;
-      }
 
-      pnd_log ( pndn_debug, "Cat %s is now in path %s\n", g_categories [ ui_category ] -> catname, g_categories [ ui_category ]-> fspath );
+       // delve up/down the dir tree
+       if ( strcmp ( ui_selected -> ref -> title_en, ".." ) == 0 ) {
+         // go up
+         char *c;
 
-      // forget the selection, nolonger applies
-      ui_selected = NULL;
-      ui_set_selected ( ui_selected );
-      // rescan the dir
-      category_fs_restock ( g_categories [ ui_category ] );
-      // redraw the grid
-      render_mask |= CHANGED_SELECTION;
+         // 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' ) {
+           free ( g_categories [ ui_category] -> fspath );
+           g_categories [ ui_category] -> fspath = strdup ( "/" );
+         }
+
+       } else {
+         // go down
+         char *temp = malloc ( strlen ( g_categories [ ui_category] -> fspath ) + strlen ( ui_selected -> ref -> title_en ) + 1 + 1 );
+         sprintf ( temp, "%s/%s", g_categories [ ui_category] -> fspath, ui_selected -> ref -> title_en );
+         free ( g_categories [ ui_category] -> fspath );
+         g_categories [ ui_category] -> fspath = temp;
+       }
+
+       pnd_log ( pndn_debug, "Cat %s is now in path %s\n", g_categories [ ui_category ] -> catname, g_categories [ ui_category ]-> fspath );
+
+       // forget the selection, nolonger applies
+       ui_selected = NULL;
+       ui_set_selected ( ui_selected );
+       // rescan the dir
+       category_fs_restock ( g_categories [ ui_category ] );
+       // redraw the grid
+       render_mask |= CHANGED_SELECTION;
+
+      } // directory browser or pnd subcat?
 
     } else {
       // just run it arbitrarily?
index 7be0e35..cd71c14 100644 (file)
@@ -64,9 +64,9 @@ arrow_up_x            450     # left edge of up-arrow showing more icons scrolled away
 arrow_up_y             80      # top edge of up-arrow showing more icons scrolled away
 arrow_up_x_w           780     # left edge of up-arrow showing more icons scrolled away [detail pane hidden]
 arrow_up_y_w           80      # top edge of up-arrow showing more icons scrolled away [detail pane hidden]
-arrow_down_x           780     # left edge of down-arrow showing more icons scrolled away
+arrow_down_x           450     # left edge of down-arrow showing more icons scrolled away
 arrow_down_y           380     # top edge of down-arrow showing more icons scrolled away
-arrow_down_x_w         450     # left edge of down-arrow showing more icons scrolled away [detail pane hidden]
+arrow_down_x_w         780     # left edge of down-arrow showing more icons scrolled away [detail pane hidden]
 arrow_down_y_w         380     # top edge of down-arrow showing more icons scrolled away [detail pane hidden]
 arrow_bar_x            450     # left edge of scrollbar
 arrow_bar_y            98      # top edge of scrollbar