Changeset 2046

Show
Ignore:
Timestamp:
02/19/10 01:28:49 (5 months ago)
Author:
tpgww
Message:

additional action for partial matching

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/plugins/e2p_selmatch.c

    r1835 r2046  
    5555                GHashTable *selitems; 
    5656                FileInfo *info; 
     57                gboolean fullmatch, forward; 
     58                const gchar *seps; 
    5759 
    5860                e2_filelist_disable_refresh (); 
     
    6668                        return FALSE; 
    6769                } 
     70                // art->action->data is NULL for full name-scan, non-NULL for partial 
     71                fullmatch = (art->action->data == NULL); 
     72                if (fullmatch) 
     73                {       //warning prevention 
     74                        seps = NULL; 
     75                        forward = TRUE; 
     76                } 
     77                else 
     78                { 
     79                        seps = e2_option_str_get ("selmatch-separators"); 
     80                        if (seps != NULL && *seps == '\0') 
     81                        { 
     82                                fullmatch = TRUE; 
     83                                forward = TRUE; 
     84                        } 
     85                        else 
     86                                forward = e2_option_bool_get ("selmatch-start"); 
     87                } 
     88 
    6889                // Log the selected items, for quick lookup 
    69                 selitems = g_hash_table_new (g_str_hash, g_str_equal); 
     90                selitems = (fullmatch) ? 
     91                        g_hash_table_new (g_str_hash, g_str_equal): 
     92                        g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); 
     93 
    7094                for (rowpath = selpaths; rowpath != NULL; rowpath = rowpath->next) 
    7195                { 
     
    76100                        { 
    77101                                gtk_tree_model_get (modelo, &itero, FINFO, &info, -1); 
    78                                 g_hash_table_insert (selitems, info->filename, info); //no key dup, info must persist 
     102                                if (fullmatch) 
     103                                        g_hash_table_insert (selitems, info->filename, info); //no key dup, info must persist 
     104                                else 
     105                                { 
     106                                        gchar c; 
     107                                        gchar *target; 
     108                                        if (forward) 
     109                                        { 
     110                                                for (target = info->filename; (c = *target) != '\0'; target++) 
     111                                                { 
     112                                                        if (strchr (seps, c) != NULL) //assumes no UTF-8 chars 
     113                                                        { 
     114                                                                target = g_strndup (info->filename, target - info->filename); 
     115                                                                g_hash_table_insert (selitems, target, info); 
     116                                                                break; 
     117                                                        } 
     118                                                } 
     119                                                if (c == '\0') 
     120                                                        g_hash_table_insert (selitems, g_strdup (info->filename), info); 
     121                                        } 
     122                                        else 
     123                                        { 
     124                                                for (target = info->filename + strlen (info->filename) - 1 ; 
     125                                                        target >= info->filename; target--) 
     126                                                { 
     127                                                        if (strchr (seps, *target) != NULL) //assumes no UTF-8 chars 
     128                                                        { 
     129                                                                target = g_strndup (info->filename, target - info->filename); 
     130                                                                g_hash_table_insert (selitems, target, info); 
     131                                                                break; 
     132                                                        } 
     133                                                } 
     134                                                if (target < info->filename) 
     135                                                        g_hash_table_insert (selitems, g_strdup (info->filename), info); 
     136                                        } 
     137                                } 
    79138                        } 
    80139                        gtk_tree_path_free (path); 
     
    86145                do 
    87146                { 
     147                        gboolean partial; 
     148                        gchar *scan; 
     149 
    88150                        gtk_tree_model_get (models, &iters, FINFO, &info, -1); 
    89151                        //We only check for name, ignore other statbuf parameters 
    90                         if (g_hash_table_lookup(selitems, info->filename) != NULL) 
     152                        partial = FALSE; 
     153                        scan = NULL; 
     154                        if (!fullmatch) 
     155                        { 
     156                                gchar c; 
     157                                if (forward) 
     158                                { 
     159                                        for (scan = info->filename; (c = *scan) != '\0'; scan++) 
     160                                        { 
     161                                                if (strchr (seps, c) != NULL) //assumes no UTF-8 chars, too bad if different sep from other pane 
     162                                                { 
     163                                                        partial = TRUE; 
     164                                                        break; 
     165                                                } 
     166                                        } 
     167                                } 
     168                                else 
     169                                { 
     170                                        for (scan = info->filename + strlen (info->filename) - 1 ; 
     171                                                scan >= info->filename; scan--) 
     172                                        { 
     173                                                c = *scan; 
     174                                                if (strchr (seps, c) != NULL) //assumes no UTF-8 chars 
     175                                                { 
     176                                                        partial = TRUE; 
     177                                                        break; 
     178                                                } 
     179                                        } 
     180                                } 
     181                        } 
     182                        if (partial) 
     183                                scan = g_strndup (info->filename, scan - info->filename); 
     184                        else 
     185                                scan = info->filename; 
     186                        if (g_hash_table_lookup (selitems, scan) != NULL) 
    91187                                gtk_tree_selection_select_iter (sel, &iters); 
     188                        if (partial) 
     189                                g_free (scan); 
    92190                } while (gtk_tree_model_iter_next (models, &iters)); 
    93191 
     
    101199 
    102200//aname must be confined to this module 
    103 static gchar *aname; 
     201static gchar *aname, *aname2; 
    104202/** 
    105203@brief plugin initialization function, called by main program 
     
    112210{ 
    113211#define ANAME "selmatch" 
    114   aname = _("selmatch"); 
    115  
    116   p->signature = ANAME VERSION; 
    117   p->menu_name = _("_Select same"); 
    118   p->description = _("Select items whose name matches a selected item in the other pane"); 
    119   p->icon = "plugin_"ANAME E2ICONTB;  //prepend path if appropriate 
    120  
    121   if (p->action == NULL) 
    122  { 
    123         //don't free name string here 
    124         E2_Action plugact = 
    125         {g_strconcat (_A(7),".",aname,NULL),_e2p_select_same,FALSE,E2_ACTION_TYPE_ITEM,0,NULL,NULL}; // not _A(6) ! 
    126         p->action = e2_plugins_action_register (&plugact); 
    127         if G_LIKELY((p->action != NULL)) 
    128                 return TRUE; 
    129         g_free (plugact.name); 
    130   } 
    131   return FALSE; 
     212        aname = _("selmatch"); 
     213        aname2 = _("selmatchpart"); 
     214 
     215        p->signature = ANAME VERSION; 
     216        p->menu_name = _("_Select same"); 
     217        p->description = ""; 
     218        p->icon = "plugin_"ANAME E2ICONTB;  //prepend path if appropriate 
     219 
     220        //child UI data 
     221        gchar *sig1 = "0-"ANAME; 
     222        gchar *label1 = _("_Whole"); 
     223//      gchar *icon1 = "";      //no icon "plugin_"ANAME E2ICONTB;  //use icon file pathname if appropriate 
     224        gchar *tip1 = _("Select items whose whole name matches a selected item in the other pane"); 
     225        gchar *sig2 = "1-"ANAME; 
     226        gchar *label2 = _("_Partial"); 
     227//      gchar *icon2 = ""; 
     228        gchar *tip2 = _("Select items whose name partially matches a selected item in the other pane"); 
     229 
     230        if (p->action == NULL) 
     231        { 
     232                gboolean retval; 
     233                Plugin *pc = e2_plugins_create_child (p); 
     234                if (pc != NULL) 
     235                { 
     236                        //for reconciling with config treestore data, signatures must reflect 
     237                        //0-based index of each child's order in the list of children 
     238                        pc->signature = sig1; //begin with "n-", n=0,1, ... 
     239                        //these will generallly be discarded in favour of config treestore data 
     240                        //meaning that any non-constant string will leak 
     241                        pc->menu_name = label1; //or whatever 
     242//                      pc->description = _("Copy selected item(s), with displayed progress details"); 
     243                        pc->description = tip1; //or whatever 
     244//                      pc->icon = "plugin_copy"E2ICONTB;  //use icon file pathname if appropriate 
     245                        //normally don't free name string here 
     246                        E2_Action plugact = 
     247                        {g_strconcat (_A(7),".",aname,NULL),_e2p_select_same,FALSE,E2_ACTION_TYPE_ITEM,0,NULL,NULL}; // not _A(6) ! 
     248                        pc->action = e2_plugins_action_register (&plugact); 
     249                        retval = (pc->action != NULL); 
     250                        if (!retval) 
     251                                g_free (plugact.name); 
     252                } 
     253                else 
     254                        retval = FALSE; 
     255 
     256                //this will not be used, but MUST be set to allow checking whether to show 
     257                //the item in the context menu 
     258                if (retval) 
     259                        p->action = pc->action; 
     260 
     261                pc = e2_plugins_create_child (p); 
     262                if (pc != NULL) 
     263                { 
     264                        pc->signature = sig2;   //for reconciling with config treestore data 
     265                        pc->menu_name = label2; 
     266                        pc->description = tip2; 
     267//                      pc->icon = "plugin_copy"E2ICONTB;  //use icon file pathname if appropriate 
     268                        //don't free name string here 
     269                        E2_Action plugact = 
     270                        {g_strconcat (_A(7),".",aname2,NULL),_e2p_select_same,FALSE,E2_ACTION_TYPE_ITEM,0,GINT_TO_POINTER(1),NULL}; // not _A(6) ! 
     271                        pc->action = e2_plugins_action_register (&plugact); 
     272                        retval = (pc->action != NULL); 
     273                } 
     274                else 
     275                        retval = FALSE; 
     276 
     277                if (retval) 
     278                { 
     279                        E2_OptionSet *set; 
     280                        E2_OptionSetupExtra ex; 
     281                        gchar *group = g_strconcat(_C(34),".",_C(27),":",aname2,NULL); //_("plugins.options:selmatchpart" 
     282                        memset (&ex, 0, sizeof (E2_OptionSetupExtra)); 
     283                        ex.exbool = TRUE; 
     284                        set = e2_plugins_option_register (E2_OPTION_TYPE_BOOL, "selmatch-start", 
     285                                group, _("match to first separator"), 
     286                                _("If enabled, name matching stops at the first instance of any specified separator, otherwise, at the last instance"), 
     287                                NULL, &ex, E2_OPTION_FLAG_FREEGROUP | E2_OPTION_FLAG_ADVANCED); 
     288                        //because plugins are loaded after config data, config options need to 
     289                        //get any data from unknown-options data 
     290                        e2_option_transient_value_get (set); 
     291 
     292                        ex.exstr = "."; 
     293                        set = e2_plugins_option_register (E2_OPTION_TYPE_STR, "selmatch-separators", 
     294                                group, _("separator character(s)"), 
     295                                _("String comprising all chars considered to be a 'separator'"), 
     296                                NULL, &ex, E2_OPTION_FLAG_ADVANCED); 
     297                        e2_option_transient_value_get (set); 
     298                } 
     299 
     300                if (retval && (p->action == NULL)) 
     301                        p->action = pc->action; 
     302 
     303                return retval; 
     304        } 
     305        else    //setup children UI data for pushing into a config dialog 
     306        { 
     307                E2_Sextet *uidata; 
     308                uidata = e2_utils_sextet_new (); 
     309                p->child_list = g_list_append (p->child_list, uidata); 
     310                uidata->a = label1; 
     311                uidata->b = ""; //no icon 
     312                uidata->c = tip1; 
     313                uidata->d = sig1; 
     314                uidata = e2_utils_sextet_new (); 
     315                p->child_list = g_list_append (p->child_list, uidata); 
     316                uidata->a = label2; 
     317                uidata->b = ""; 
     318                uidata->c = tip2; 
     319                uidata->d = sig2; 
     320        } 
     321 
     322        return FALSE; 
    132323} 
    133324/** 
     
    140331gboolean clean_plugin (Plugin *p) 
    141332{ 
    142   gchar *action_name = g_strconcat (_A(7),".",aname,NULL); 
    143   gboolean ret = e2_plugins_action_unregister (action_name); 
    144   g_free (action_name); 
    145   return ret; 
     333        gchar *action_name = g_strconcat (_A(7),".",aname,NULL); 
     334        gboolean ret1 = e2_plugins_action_unregister (action_name); 
     335        g_free (action_name); 
     336        action_name = g_strconcat (_A(7),".",aname2,NULL); 
     337        gboolean ret2 = e2_plugins_action_unregister (action_name); 
     338        g_free (action_name); 
     339        if (ret1 && ret2) 
     340        { 
     341                ret1 = ret1 && e2_plugins_option_unregister ("selmatch-start"); 
     342                ret2 = ret2 && e2_plugins_option_unregister ("selmatch-separators"); 
     343        } 
     344        return (ret1 && ret2); 
    146345}