| 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 | } |
| 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; |