Blender V2.61 - r43446

wm_keymap.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version. 
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2007 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * 
00022  * Contributor(s): Blender Foundation
00023  *
00024  * ***** END GPL LICENSE BLOCK *****
00025  */
00026 
00032 #include <string.h>
00033 
00034 #include "DNA_object_types.h"
00035 #include "DNA_screen_types.h"
00036 #include "DNA_space_types.h"
00037 #include "DNA_userdef_types.h"
00038 #include "DNA_windowmanager_types.h"
00039 
00040 #include "MEM_guardedalloc.h"
00041 
00042 #include "BLI_blenlib.h"
00043 #include "BLI_utildefines.h"
00044 
00045 #include "BKE_blender.h"
00046 #include "BKE_context.h"
00047 #include "BKE_idprop.h"
00048 #include "BKE_global.h"
00049 #include "BKE_library.h"
00050 #include "BKE_main.h"
00051 #include "BKE_screen.h"
00052 
00053 
00054 #include "RNA_access.h"
00055 #include "RNA_enum_types.h"
00056 
00057 #include "WM_api.h"
00058 #include "WM_types.h"
00059 #include "wm_window.h"
00060 #include "wm_event_system.h"
00061 #include "wm_event_types.h"
00062 
00063 /******************************* Keymap Item **********************************
00064  * Item in a keymap, that maps from an event to an operator or modal map item */
00065 
00066 static wmKeyMapItem *wm_keymap_item_copy(wmKeyMapItem *kmi)
00067 {
00068     wmKeyMapItem *kmin = MEM_dupallocN(kmi);
00069 
00070     kmin->prev= kmin->next= NULL;
00071     kmin->flag &= ~KMI_UPDATE;
00072 
00073     if(kmin->properties) {
00074         kmin->ptr= MEM_callocN(sizeof(PointerRNA), "UserKeyMapItemPtr");
00075         WM_operator_properties_create(kmin->ptr, kmin->idname);
00076 
00077         kmin->properties= IDP_CopyProperty(kmin->properties);
00078         kmin->ptr->data= kmin->properties;
00079     }
00080 
00081     return kmin;
00082 }
00083 
00084 static void wm_keymap_item_free(wmKeyMapItem *kmi)
00085 {
00086     /* not kmi itself */
00087     if(kmi->ptr) {
00088         WM_operator_properties_free(kmi->ptr);
00089         MEM_freeN(kmi->ptr);
00090     }
00091 }
00092 
00093 static void wm_keymap_item_properties_set(wmKeyMapItem *kmi)
00094 {
00095     WM_operator_properties_alloc(&(kmi->ptr), &(kmi->properties), kmi->idname);
00096     WM_operator_properties_sanitize(kmi->ptr, 1);
00097 }
00098 
00099 static int wm_keymap_item_equals_result(wmKeyMapItem *a, wmKeyMapItem *b)
00100 {
00101     if(strcmp(a->idname, b->idname) != 0)
00102         return 0;
00103     
00104     if(!((a->ptr==NULL && b->ptr==NULL) ||
00105          (a->ptr && b->ptr && IDP_EqualsProperties(a->ptr->data, b->ptr->data))))
00106         return 0;
00107     
00108     if((a->flag & KMI_INACTIVE) != (b->flag & KMI_INACTIVE))
00109         return 0;
00110     
00111     return (a->propvalue == b->propvalue);
00112 }
00113 
00114 static int wm_keymap_item_equals(wmKeyMapItem *a, wmKeyMapItem *b)
00115 {
00116     return (wm_keymap_item_equals_result(a, b) &&
00117             a->type == b->type &&
00118             a->val == b->val &&
00119             a->shift == b->shift &&
00120             a->ctrl == b->ctrl &&
00121             a->alt == b->alt &&
00122             a->oskey == b->oskey &&
00123             a->keymodifier == b->keymodifier &&
00124             a->maptype == b->maptype);
00125 }
00126 
00127 /* properties can be NULL, otherwise the arg passed is used and ownership is given to the kmi */
00128 void WM_keymap_properties_reset(wmKeyMapItem *kmi, struct IDProperty *properties)
00129 {
00130     WM_operator_properties_free(kmi->ptr);
00131     MEM_freeN(kmi->ptr);
00132 
00133     kmi->ptr = NULL;
00134     kmi->properties = properties;
00135 
00136     wm_keymap_item_properties_set(kmi);
00137 }
00138 
00139 /**************************** Keymap Diff Item *********************************
00140  * Item in a diff keymap, used for saving diff of keymaps in user preferences */
00141 
00142 static wmKeyMapDiffItem *wm_keymap_diff_item_copy(wmKeyMapDiffItem *kmdi)
00143 {
00144     wmKeyMapDiffItem *kmdin = MEM_dupallocN(kmdi);
00145 
00146     kmdin->next = kmdin->prev = NULL;
00147     if(kmdi->add_item)
00148         kmdin->add_item = wm_keymap_item_copy(kmdi->add_item);
00149     if(kmdi->remove_item)
00150         kmdin->remove_item = wm_keymap_item_copy(kmdi->remove_item);
00151     
00152     return kmdin;
00153 }
00154 
00155 static void wm_keymap_diff_item_free(wmKeyMapDiffItem *kmdi)
00156 {
00157     if(kmdi->remove_item) {
00158         wm_keymap_item_free(kmdi->remove_item);
00159         MEM_freeN(kmdi->remove_item);
00160     }
00161     if(kmdi->add_item) {
00162         wm_keymap_item_free(kmdi->add_item);
00163         MEM_freeN(kmdi->add_item);
00164     }
00165 }
00166 
00167 /***************************** Key Configuration ******************************
00168  * List of keymaps for all editors, modes, ... . There is a builtin default key
00169  * configuration, a user key configuration, and other preset configurations. */
00170 
00171 wmKeyConfig *WM_keyconfig_new(wmWindowManager *wm, const char *idname)
00172 {
00173     wmKeyConfig *keyconf;
00174     
00175     keyconf= MEM_callocN(sizeof(wmKeyConfig), "wmKeyConfig");
00176     BLI_strncpy(keyconf->idname, idname, sizeof(keyconf->idname));
00177     BLI_addtail(&wm->keyconfigs, keyconf);
00178 
00179     return keyconf;
00180 }
00181 
00182 wmKeyConfig *WM_keyconfig_new_user(wmWindowManager *wm, const char *idname)
00183 {
00184     wmKeyConfig *keyconf = WM_keyconfig_new(wm, idname);
00185 
00186     keyconf->flag |= KEYCONF_USER;
00187 
00188     return keyconf;
00189 }
00190 
00191 void WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf)
00192 {
00193     if (keyconf) {
00194         if (strncmp(U.keyconfigstr, keyconf->idname, sizeof(U.keyconfigstr)) == 0) {
00195             BLI_strncpy(U.keyconfigstr, wm->defaultconf->idname, sizeof(U.keyconfigstr));
00196             WM_keyconfig_update_tag(NULL, NULL);
00197         }
00198 
00199         BLI_remlink(&wm->keyconfigs, keyconf);
00200         WM_keyconfig_free(keyconf);
00201     }
00202 }
00203 
00204 void WM_keyconfig_free(wmKeyConfig *keyconf)
00205 {
00206     wmKeyMap *km;
00207 
00208     while((km= keyconf->keymaps.first)) {
00209         WM_keymap_free(km);
00210         BLI_freelinkN(&keyconf->keymaps, km);
00211     }
00212 
00213     MEM_freeN(keyconf);
00214 }
00215 
00216 static wmKeyConfig *wm_keyconfig_list_find(ListBase *lb, char *idname)
00217 {
00218     wmKeyConfig *kc;
00219 
00220     for(kc= lb->first; kc; kc= kc->next)
00221         if(0==strncmp(idname, kc->idname, KMAP_MAX_NAME))
00222             return kc;
00223     
00224     return NULL;
00225 }
00226 
00227 static wmKeyConfig *WM_keyconfig_active(wmWindowManager *wm)
00228 {
00229     wmKeyConfig *keyconf;
00230 
00231     /* first try from preset */
00232     keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr);
00233     if(keyconf)
00234         return keyconf;
00235     
00236     /* otherwise use default */
00237     return wm->defaultconf;
00238 }
00239 
00240 void WM_keyconfig_set_active(wmWindowManager *wm, const char *idname)
00241 {
00242     /* setting a different key configuration as active: we ensure all is
00243        updated properly before and after making the change */
00244 
00245     WM_keyconfig_update(wm);
00246 
00247     BLI_strncpy(U.keyconfigstr, idname, sizeof(U.keyconfigstr));
00248 
00249     WM_keyconfig_update_tag(NULL, NULL);
00250     WM_keyconfig_update(wm);
00251 }
00252 
00253 /********************************** Keymap *************************************
00254  * List of keymap items for one editor, mode, modal operator, ... */
00255 
00256 static wmKeyMap *wm_keymap_new(const char *idname, int spaceid, int regionid)
00257 {
00258     wmKeyMap *km= MEM_callocN(sizeof(struct wmKeyMap), "keymap list");
00259 
00260     BLI_strncpy(km->idname, idname, KMAP_MAX_NAME);
00261     km->spaceid= spaceid;
00262     km->regionid= regionid;
00263 
00264     return km;
00265 }
00266 
00267 static wmKeyMap *wm_keymap_copy(wmKeyMap *keymap)
00268 {
00269     wmKeyMap *keymapn = MEM_dupallocN(keymap);
00270     wmKeyMapItem *kmi, *kmin;
00271     wmKeyMapDiffItem *kmdi, *kmdin;
00272 
00273     keymapn->modal_items= keymap->modal_items;
00274     keymapn->poll= keymap->poll;
00275     keymapn->items.first= keymapn->items.last= NULL;
00276     keymapn->flag &= ~(KEYMAP_UPDATE|KEYMAP_EXPANDED);
00277 
00278     for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) {
00279         kmdin= wm_keymap_diff_item_copy(kmdi);
00280         BLI_addtail(&keymapn->items, kmdin);
00281     }
00282 
00283     for(kmi=keymap->items.first; kmi; kmi=kmi->next) {
00284         kmin= wm_keymap_item_copy(kmi);
00285         BLI_addtail(&keymapn->items, kmin);
00286     }
00287 
00288     return keymapn;
00289 }
00290 
00291 void WM_keymap_free(wmKeyMap *keymap)
00292 {
00293     wmKeyMapItem *kmi;
00294     wmKeyMapDiffItem *kmdi;
00295 
00296     for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next)
00297         wm_keymap_diff_item_free(kmdi);
00298 
00299     for(kmi=keymap->items.first; kmi; kmi=kmi->next)
00300         wm_keymap_item_free(kmi);
00301 
00302     BLI_freelistN(&keymap->diff_items);
00303     BLI_freelistN(&keymap->items);
00304 }
00305 
00306 static void keymap_event_set(wmKeyMapItem *kmi, short type, short val, int modifier, short keymodifier)
00307 {
00308     kmi->type= type;
00309     kmi->val= val;
00310     kmi->keymodifier= keymodifier;
00311 
00312     if(modifier == KM_ANY) {
00313         kmi->shift= kmi->ctrl= kmi->alt= kmi->oskey= KM_ANY;
00314     }
00315     else {
00316         kmi->shift= (modifier & KM_SHIFT) ? KM_MOD_FIRST : ((modifier & KM_SHIFT2) ? KM_MOD_SECOND : FALSE);
00317         kmi->ctrl=  (modifier & KM_CTRL)  ? KM_MOD_FIRST : ((modifier & KM_CTRL2)  ? KM_MOD_SECOND : FALSE);
00318         kmi->alt=   (modifier & KM_ALT)   ? KM_MOD_FIRST : ((modifier & KM_ALT2)   ? KM_MOD_SECOND : FALSE);
00319         kmi->oskey= (modifier & KM_OSKEY) ? KM_MOD_FIRST : ((modifier & KM_OSKEY2) ? KM_MOD_SECOND : FALSE);
00320     }
00321 }
00322 
00323 static void keymap_item_set_id(wmKeyMap *keymap, wmKeyMapItem *kmi)
00324 {
00325     keymap->kmi_id++;
00326     if ((keymap->flag & KEYMAP_USER) == 0) {
00327         kmi->id = keymap->kmi_id;
00328     } else {
00329         kmi->id = -keymap->kmi_id; // User defined keymap entries have negative ids
00330     }
00331 }
00332 
00333 /* if item was added, then bail out */
00334 wmKeyMapItem *WM_keymap_verify_item(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
00335 {
00336     wmKeyMapItem *kmi;
00337     
00338     for(kmi= keymap->items.first; kmi; kmi= kmi->next)
00339         if(strncmp(kmi->idname, idname, OP_MAX_TYPENAME)==0)
00340             break;
00341     if(kmi==NULL) {
00342         kmi= MEM_callocN(sizeof(wmKeyMapItem), "keymap entry");
00343         
00344         BLI_addtail(&keymap->items, kmi);
00345         BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME);
00346         
00347         keymap_item_set_id(keymap, kmi);
00348 
00349         keymap_event_set(kmi, type, val, modifier, keymodifier);
00350         wm_keymap_item_properties_set(kmi);
00351     }
00352     return kmi;
00353 }
00354 
00355 /* always add item */
00356 wmKeyMapItem *WM_keymap_add_item(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
00357 {
00358     wmKeyMapItem *kmi= MEM_callocN(sizeof(wmKeyMapItem), "keymap entry");
00359     
00360     BLI_addtail(&keymap->items, kmi);
00361     BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME);
00362 
00363     keymap_event_set(kmi, type, val, modifier, keymodifier);
00364     wm_keymap_item_properties_set(kmi);
00365 
00366     keymap_item_set_id(keymap, kmi);
00367 
00368     WM_keyconfig_update_tag(keymap, kmi);
00369 
00370     return kmi;
00371 }
00372 
00373 /* menu wrapper for WM_keymap_add_item */
00374 wmKeyMapItem *WM_keymap_add_menu(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
00375 {
00376     wmKeyMapItem *kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", type, val, modifier, keymodifier);
00377     RNA_string_set(kmi->ptr, "name", idname);
00378     return kmi;
00379 }
00380 
00381 void WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi)
00382 {
00383     if(BLI_findindex(&keymap->items, kmi) != -1) {
00384         if(kmi->ptr) {
00385             WM_operator_properties_free(kmi->ptr);
00386             MEM_freeN(kmi->ptr);
00387         }
00388         BLI_freelinkN(&keymap->items, kmi);
00389 
00390         WM_keyconfig_update_tag(keymap, kmi);
00391     }
00392 }
00393 
00394 /************************** Keymap Diff and Patch ****************************
00395  * Rather than saving the entire keymap for user preferences, we only save a
00396  * diff so that changes in the defaults get synced. This system is not perfect
00397  * but works better than overriding the keymap entirely when only few items
00398  * are changed. */
00399 
00400 static void wm_keymap_addon_add(wmKeyMap *keymap, wmKeyMap *addonmap)
00401 {
00402     wmKeyMapItem *kmi, *kmin;
00403 
00404     for(kmi=addonmap->items.first; kmi; kmi=kmi->next) {
00405         kmin = wm_keymap_item_copy(kmi);
00406         keymap_item_set_id(keymap, kmin);
00407         BLI_addhead(&keymap->items, kmin);
00408     }
00409 }
00410 
00411 static wmKeyMapItem *wm_keymap_find_item_equals(wmKeyMap *km, wmKeyMapItem *needle)
00412 {
00413     wmKeyMapItem *kmi;
00414 
00415     for(kmi=km->items.first; kmi; kmi=kmi->next)
00416         if(wm_keymap_item_equals(kmi, needle))
00417             return kmi;
00418     
00419     return NULL;
00420 }
00421 
00422 static wmKeyMapItem *wm_keymap_find_item_equals_result(wmKeyMap *km, wmKeyMapItem *needle)
00423 {
00424     wmKeyMapItem *kmi;
00425 
00426     for(kmi=km->items.first; kmi; kmi=kmi->next)
00427         if(wm_keymap_item_equals_result(kmi, needle))
00428             return kmi;
00429     
00430     return NULL;
00431 }
00432 
00433 static void wm_keymap_diff(wmKeyMap *diff_km, wmKeyMap *from_km, wmKeyMap *to_km, wmKeyMap *orig_km, wmKeyMap *addon_km)
00434 {
00435     wmKeyMapItem *kmi, *to_kmi, *orig_kmi;
00436     wmKeyMapDiffItem *kmdi;
00437 
00438     for(kmi=from_km->items.first; kmi; kmi=kmi->next) {
00439         to_kmi = WM_keymap_item_find_id(to_km, kmi->id);
00440 
00441         if(!to_kmi) {
00442             /* remove item */
00443             kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
00444             kmdi->remove_item = wm_keymap_item_copy(kmi);
00445             BLI_addtail(&diff_km->diff_items, kmdi);
00446         }
00447         else if(to_kmi && !wm_keymap_item_equals(kmi, to_kmi)) {
00448             /* replace item */
00449             kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
00450             kmdi->remove_item = wm_keymap_item_copy(kmi);
00451             kmdi->add_item = wm_keymap_item_copy(to_kmi);
00452             BLI_addtail(&diff_km->diff_items, kmdi);
00453         }
00454 
00455         /* sync expanded flag back to original so we don't loose it on repatch */
00456         if(to_kmi) {
00457             orig_kmi = WM_keymap_item_find_id(orig_km, kmi->id);
00458 
00459             if(!orig_kmi)
00460                 orig_kmi = wm_keymap_find_item_equals(addon_km, kmi);
00461 
00462             if(orig_kmi) {
00463                 orig_kmi->flag &= ~KMI_EXPANDED;
00464                 orig_kmi->flag |= (to_kmi->flag & KMI_EXPANDED);
00465             }
00466         }
00467     }
00468 
00469     for(kmi=to_km->items.first; kmi; kmi=kmi->next) {
00470         if(kmi->id < 0) {
00471             /* add item */
00472             kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
00473             kmdi->add_item = wm_keymap_item_copy(kmi);
00474             BLI_addtail(&diff_km->diff_items, kmdi);
00475         }
00476     }
00477 }
00478 
00479 static void wm_keymap_patch(wmKeyMap *km, wmKeyMap *diff_km)
00480 {
00481     wmKeyMapDiffItem *kmdi;
00482     wmKeyMapItem *kmi_remove, *kmi_add;
00483 
00484     for(kmdi=diff_km->diff_items.first; kmdi; kmdi=kmdi->next) {
00485         /* find item to remove */
00486         kmi_remove = NULL;
00487         if(kmdi->remove_item) {
00488             kmi_remove = wm_keymap_find_item_equals(km, kmdi->remove_item);
00489             if(!kmi_remove)
00490                 kmi_remove = wm_keymap_find_item_equals_result(km, kmdi->remove_item);
00491         }
00492 
00493         /* add item */
00494         if(kmdi->add_item) {
00495             /* only if nothing to remove or item to remove found */
00496             if(!kmdi->remove_item || kmi_remove) {
00497                 kmi_add = wm_keymap_item_copy(kmdi->add_item);
00498                 kmi_add->flag |= KMI_USER_MODIFIED;
00499 
00500                 if(kmi_remove) {
00501                     kmi_add->flag &= ~KMI_EXPANDED;
00502                     kmi_add->flag |= (kmi_remove->flag & KMI_EXPANDED);
00503                     kmi_add->id = kmi_remove->id;
00504                     BLI_insertlinkbefore(&km->items, kmi_remove, kmi_add);
00505                 }
00506                 else {
00507                     keymap_item_set_id(km, kmi_add);
00508                     BLI_addtail(&km->items, kmi_add);
00509                 }
00510             }
00511         }
00512 
00513         /* remove item */
00514         if(kmi_remove) {
00515             wm_keymap_item_free(kmi_remove);
00516             BLI_freelinkN(&km->items, kmi_remove);
00517         }
00518     }
00519 }
00520 
00521 static wmKeyMap *wm_keymap_patch_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *usermap)
00522 {
00523     wmKeyMap *km;
00524     int expanded = 0;
00525 
00526     /* remove previous keymap in list, we will replace it */
00527     km = WM_keymap_list_find(lb, defaultmap->idname, defaultmap->spaceid, defaultmap->regionid);
00528     if(km) {
00529         expanded = (km->flag & (KEYMAP_EXPANDED|KEYMAP_CHILDREN_EXPANDED));
00530         WM_keymap_free(km);
00531         BLI_freelinkN(lb, km);
00532     }
00533 
00534     /* copy new keymap from an existing one */
00535     if(usermap && !(usermap->flag & KEYMAP_DIFF)) {
00536         /* for compatibiltiy with old user preferences with non-diff
00537            keymaps we override the original entirely */
00538         wmKeyMapItem *kmi, *orig_kmi;
00539 
00540         km = wm_keymap_copy(usermap);
00541 
00542         /* try to find corresponding id's for items */
00543         for(kmi=km->items.first; kmi; kmi=kmi->next) {
00544             orig_kmi = wm_keymap_find_item_equals(defaultmap, kmi);
00545             if(!orig_kmi)
00546                 orig_kmi = wm_keymap_find_item_equals_result(defaultmap, kmi);
00547 
00548             if(orig_kmi)
00549                 kmi->id = orig_kmi->id;
00550             else
00551                 kmi->id = -(km->kmi_id++);
00552         }
00553 
00554         km->flag |= KEYMAP_UPDATE; /* update again to create diff */
00555     }
00556     else
00557         km = wm_keymap_copy(defaultmap);
00558 
00559     /* add addon keymap items */
00560     if(addonmap)
00561         wm_keymap_addon_add(km, addonmap);
00562 
00563     /* tag as being user edited */
00564     if(usermap)
00565         km->flag |= KEYMAP_USER_MODIFIED;
00566     km->flag |= KEYMAP_USER|expanded;
00567 
00568     /* apply user changes of diff keymap */
00569     if(usermap && (usermap->flag & KEYMAP_DIFF))
00570         wm_keymap_patch(km, usermap);
00571 
00572     /* add to list */
00573     BLI_addtail(lb, km);
00574     
00575     return km;
00576 }
00577 
00578 static void wm_keymap_diff_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *km)
00579 {
00580     wmKeyMap *diffmap, *prevmap, *origmap;
00581 
00582     /* create temporary default + addon keymap for diff */
00583     origmap = defaultmap;
00584 
00585     if(addonmap) {
00586         defaultmap = wm_keymap_copy(defaultmap);
00587         wm_keymap_addon_add(defaultmap, addonmap);
00588     }
00589 
00590     /* remove previous diff keymap in list, we will replace it */
00591     prevmap = WM_keymap_list_find(lb, km->idname, km->spaceid, km->regionid);
00592     if(prevmap) {
00593         WM_keymap_free(prevmap);
00594         BLI_freelinkN(lb, prevmap);
00595     }
00596 
00597     /* create diff keymap */
00598     diffmap= wm_keymap_new(km->idname, km->spaceid, km->regionid);
00599     diffmap->flag |= KEYMAP_DIFF;
00600     if(defaultmap->flag & KEYMAP_MODAL)
00601         diffmap->flag |= KEYMAP_MODAL;
00602     wm_keymap_diff(diffmap, defaultmap, km, origmap, addonmap);
00603 
00604     /* add to list if not empty */
00605     if(diffmap->diff_items.first) {
00606         BLI_addtail(lb, diffmap);
00607     }
00608     else {
00609         WM_keymap_free(diffmap);
00610         MEM_freeN(diffmap);
00611     }
00612 
00613     /* free temporary default map */
00614     if(addonmap) {
00615         WM_keymap_free(defaultmap);
00616         MEM_freeN(defaultmap);
00617     }
00618 }
00619 
00620 /* ****************** storage in WM ************ */
00621 
00622 /* name id's are for storing general or multiple keymaps, 
00623    space/region ids are same as DNA_space_types.h */
00624 /* gets free'd in wm.c */
00625 
00626 wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid)
00627 {
00628     wmKeyMap *km;
00629 
00630     for(km= lb->first; km; km= km->next)
00631         if(km->spaceid==spaceid && km->regionid==regionid)
00632             if(0==strncmp(idname, km->idname, KMAP_MAX_NAME))
00633                 return km;
00634     
00635     return NULL;
00636 }
00637 
00638 wmKeyMap *WM_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
00639 {
00640     wmKeyMap *km= WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid);
00641     
00642     if(km==NULL) {
00643         km= wm_keymap_new(idname, spaceid, regionid);
00644         BLI_addtail(&keyconf->keymaps, km);
00645 
00646         WM_keyconfig_update_tag(km, NULL);
00647     }
00648     
00649     return km;
00650 }
00651 
00652 wmKeyMap *WM_keymap_find_all(const bContext *C, const char *idname, int spaceid, int regionid)
00653 {
00654     wmWindowManager *wm= CTX_wm_manager(C);
00655 
00656     return WM_keymap_list_find(&wm->userconf->keymaps, idname, spaceid, regionid);
00657 }
00658 
00659 /* ****************** modal keymaps ************ */
00660 
00661 /* modal maps get linked to a running operator, and filter the keys before sending to modal() callback */
00662 
00663 wmKeyMap *WM_modalkeymap_add(wmKeyConfig *keyconf, const char *idname, EnumPropertyItem *items)
00664 {
00665     wmKeyMap *km= WM_keymap_find(keyconf, idname, 0, 0);
00666     km->flag |= KEYMAP_MODAL;
00667     km->modal_items= items;
00668 
00669     if(!items) {
00670         /* init modal items from default config */
00671         wmWindowManager *wm = G.main->wm.first;
00672         wmKeyMap *defaultkm= WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, 0, 0);
00673 
00674         if(defaultkm) {
00675             km->modal_items = defaultkm->modal_items;
00676             km->poll = defaultkm->poll;
00677         }
00678     }
00679     
00680     return km;
00681 }
00682 
00683 wmKeyMap *WM_modalkeymap_get(wmKeyConfig *keyconf, const char *idname)
00684 {
00685     wmKeyMap *km;
00686     
00687     for(km= keyconf->keymaps.first; km; km= km->next)
00688         if(km->flag & KEYMAP_MODAL)
00689             if(0==strncmp(idname, km->idname, KMAP_MAX_NAME))
00690                 break;
00691     
00692     return km;
00693 }
00694 
00695 
00696 wmKeyMapItem *WM_modalkeymap_add_item(wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value)
00697 {
00698     wmKeyMapItem *kmi= MEM_callocN(sizeof(wmKeyMapItem), "keymap entry");
00699     
00700     BLI_addtail(&km->items, kmi);
00701     kmi->propvalue= value;
00702     
00703     keymap_event_set(kmi, type, val, modifier, keymodifier);
00704 
00705     keymap_item_set_id(km, kmi);
00706 
00707     WM_keyconfig_update_tag(km, kmi);
00708 
00709     return kmi;
00710 }
00711 
00712 void WM_modalkeymap_assign(wmKeyMap *km, const char *opname)
00713 {
00714     wmOperatorType *ot= WM_operatortype_find(opname, 0);
00715     
00716     if(ot)
00717         ot->modalkeymap= km;
00718     else
00719         printf("error: modalkeymap_assign, unknown operator %s\n", opname);
00720 }
00721 
00722 /* ***************** get string from key events **************** */
00723 
00724 const char *WM_key_event_string(short type)
00725 {
00726     const char *name= NULL;
00727     if(RNA_enum_name(event_type_items, (int)type, &name))
00728         return name;
00729     
00730     return "";
00731 }
00732 
00733 char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len)
00734 {
00735     char buf[128];
00736 
00737     buf[0]= 0;
00738 
00739     if (kmi->shift == KM_ANY &&
00740         kmi->ctrl == KM_ANY &&
00741         kmi->alt == KM_ANY &&
00742         kmi->oskey == KM_ANY) {
00743 
00744         strcat(buf, "Any ");
00745     } else {
00746         if(kmi->shift)
00747             strcat(buf, "Shift ");
00748 
00749         if(kmi->ctrl)
00750             strcat(buf, "Ctrl ");
00751 
00752         if(kmi->alt)
00753             strcat(buf, "Alt ");
00754 
00755         if(kmi->oskey)
00756             strcat(buf, "Cmd ");
00757     }
00758         
00759     if(kmi->keymodifier) {
00760         strcat(buf, WM_key_event_string(kmi->keymodifier));
00761         strcat(buf, " ");
00762     }
00763 
00764     strcat(buf, WM_key_event_string(kmi->type));
00765     BLI_strncpy(str, buf, len);
00766 
00767     return str;
00768 }
00769 
00770 static wmKeyMapItem *wm_keymap_item_find_handlers(const bContext *C, ListBase *handlers, const char *opname, int UNUSED(opcontext), IDProperty *properties, int compare_props, int hotkey, wmKeyMap **keymap_r)
00771 {
00772     wmWindowManager *wm= CTX_wm_manager(C);
00773     wmEventHandler *handler;
00774     wmKeyMap *keymap;
00775     wmKeyMapItem *kmi;
00776 
00777     /* find keymap item in handlers */
00778     for(handler=handlers->first; handler; handler=handler->next) {
00779         keymap= WM_keymap_active(wm, handler->keymap);
00780 
00781         if(keymap && (!keymap->poll || keymap->poll((bContext*)C))) {
00782             for(kmi=keymap->items.first; kmi; kmi=kmi->next) {
00783                 
00784                 if(strcmp(kmi->idname, opname) == 0 && WM_key_event_string(kmi->type)[0]) {
00785                     if (hotkey)
00786                         if (!ISHOTKEY(kmi->type))
00787                             continue;
00788                     
00789                     if(compare_props) {
00790                         if(kmi->ptr && IDP_EqualsProperties(properties, kmi->ptr->data)) {
00791                             if(keymap_r) *keymap_r= keymap;
00792                             return kmi;
00793                         }
00794                     }
00795                     else {
00796                         if(keymap_r) *keymap_r= keymap;
00797                         return kmi;
00798                     }
00799                 }
00800             }
00801         }
00802     }
00803     
00804     /* ensure un-initialized keymap is never used */
00805     if(keymap_r) *keymap_r= NULL;
00806     return NULL;
00807 }
00808 
00809 static wmKeyMapItem *wm_keymap_item_find_props(const bContext *C, const char *opname, int opcontext, IDProperty *properties, int compare_props, int hotkey, wmKeyMap **keymap_r)
00810 {
00811     wmWindow *win= CTX_wm_window(C);
00812     ScrArea *sa= CTX_wm_area(C);
00813     ARegion *ar= CTX_wm_region(C);
00814     wmKeyMapItem *found= NULL;
00815 
00816     /* look into multiple handler lists to find the item */
00817     if(win)
00818         found= wm_keymap_item_find_handlers(C, &win->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r);
00819     
00820 
00821     if(sa && found==NULL)
00822         found= wm_keymap_item_find_handlers(C, &sa->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r);
00823 
00824     if(found==NULL) {
00825         if(ELEM(opcontext, WM_OP_EXEC_REGION_WIN, WM_OP_INVOKE_REGION_WIN)) {
00826             if(sa) {
00827                 if (!(ar && ar->regiontype == RGN_TYPE_WINDOW))
00828                     ar= BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
00829                 
00830                 if(ar)
00831                     found= wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r);
00832             }
00833         }
00834         else if(ELEM(opcontext, WM_OP_EXEC_REGION_CHANNELS, WM_OP_INVOKE_REGION_CHANNELS)) {
00835             if (!(ar && ar->regiontype == RGN_TYPE_CHANNELS))
00836                 ar= BKE_area_find_region_type(sa, RGN_TYPE_CHANNELS);
00837 
00838             if(ar)
00839                 found= wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r);
00840         }
00841         else if(ELEM(opcontext, WM_OP_EXEC_REGION_PREVIEW, WM_OP_INVOKE_REGION_PREVIEW)) {
00842             if (!(ar && ar->regiontype == RGN_TYPE_PREVIEW))
00843                 ar= BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW);
00844 
00845             if(ar)
00846                 found= wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r);
00847         }
00848         else {
00849             if(ar)
00850                 found= wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r);
00851         }
00852     }
00853     
00854     return found;
00855 }
00856 
00857 static wmKeyMapItem *wm_keymap_item_find(const bContext *C, const char *opname, int opcontext, IDProperty *properties, const short hotkey, const short sloppy, wmKeyMap **keymap_r)
00858 {
00859     wmKeyMapItem *found= wm_keymap_item_find_props(C, opname, opcontext, properties, 1, hotkey, keymap_r);
00860 
00861     if(!found && sloppy)
00862         found= wm_keymap_item_find_props(C, opname, opcontext, NULL, 0, hotkey, keymap_r);
00863 
00864     return found;
00865 }
00866 
00867 char *WM_key_event_operator_string(const bContext *C, const char *opname, int opcontext, IDProperty *properties, const short sloppy, char *str, int len)
00868 {
00869     wmKeyMapItem *kmi= wm_keymap_item_find(C, opname, opcontext, properties, 0, sloppy, NULL);
00870     
00871     if(kmi) {
00872         WM_keymap_item_to_string(kmi, str, len);
00873         return str;
00874     }
00875 
00876     return NULL;
00877 }
00878 
00879 int WM_key_event_operator_id(const bContext *C, const char *opname, int opcontext, IDProperty *properties, int hotkey, wmKeyMap **keymap_r)
00880 {
00881     wmKeyMapItem *kmi= wm_keymap_item_find(C, opname, opcontext, properties, hotkey, TRUE, keymap_r);
00882     
00883     if(kmi)
00884         return kmi->id;
00885     else
00886         return 0;
00887 }
00888 
00889 int WM_keymap_item_compare(wmKeyMapItem *k1, wmKeyMapItem *k2)
00890 {
00891     int k1type, k2type;
00892 
00893     if (k1->flag & KMI_INACTIVE || k2->flag & KMI_INACTIVE)
00894         return 0;
00895 
00896     /* take event mapping into account */
00897     k1type = WM_userdef_event_map(k1->type);
00898     k2type = WM_userdef_event_map(k2->type);
00899 
00900     if(k1type != KM_ANY && k2type != KM_ANY && k1type != k2type)
00901         return 0;
00902 
00903     if(k1->val != KM_ANY && k2->val != KM_ANY) {
00904         /* take click, press, release conflict into account */
00905         if (k1->val == KM_CLICK && ELEM3(k2->val, KM_PRESS, KM_RELEASE, KM_CLICK) == 0)
00906             return 0;
00907         if (k2->val == KM_CLICK && ELEM3(k1->val, KM_PRESS, KM_RELEASE, KM_CLICK) == 0)
00908             return 0;
00909         if (k1->val != k2->val)
00910             return 0;
00911     }
00912 
00913     if(k1->shift != KM_ANY && k2->shift != KM_ANY && k1->shift != k2->shift)
00914         return 0;
00915 
00916     if(k1->ctrl != KM_ANY && k2->ctrl != KM_ANY && k1->ctrl != k2->ctrl)
00917         return 0;
00918 
00919     if(k1->alt != KM_ANY && k2->alt != KM_ANY && k1->alt != k2->alt)
00920         return 0;
00921 
00922     if(k1->oskey != KM_ANY && k2->oskey != KM_ANY && k1->oskey != k2->oskey)
00923         return 0;
00924 
00925     if(k1->keymodifier != k2->keymodifier)
00926         return 0;
00927 
00928     return 1;
00929 }
00930 
00931 /************************* Update Final Configuration *************************
00932  * On load or other changes, the final user key configuration is rebuilt from
00933  * the preset, addon and user preferences keymaps. We also test if the final
00934  * configuration changed and write the changes to the user preferences. */
00935 
00936 static int WM_KEYMAP_UPDATE = 0;
00937 
00938 void WM_keyconfig_update_tag(wmKeyMap *km, wmKeyMapItem *kmi)
00939 {
00940     /* quick tag to do delayed keymap updates */
00941     WM_KEYMAP_UPDATE= 1;
00942 
00943     if(km)
00944         km->flag |= KEYMAP_UPDATE;
00945     if(kmi)
00946         kmi->flag |= KMI_UPDATE;
00947 }
00948 
00949 static int wm_keymap_test_and_clear_update(wmKeyMap *km)
00950 {
00951     wmKeyMapItem *kmi;
00952     int update;
00953     
00954     update= (km->flag & KEYMAP_UPDATE);
00955     km->flag &= ~KEYMAP_UPDATE;
00956 
00957     for(kmi=km->items.first; kmi; kmi=kmi->next) {
00958         update= update || (kmi->flag & KMI_UPDATE);
00959         kmi->flag &= ~KMI_UPDATE;
00960     }
00961     
00962     return update;
00963 }
00964 
00965 static wmKeyMap *wm_keymap_preset(wmWindowManager *wm, wmKeyMap *km)
00966 {
00967     wmKeyConfig *keyconf= WM_keyconfig_active(wm);
00968     wmKeyMap *keymap;
00969 
00970     keymap= WM_keymap_list_find(&keyconf->keymaps, km->idname, km->spaceid, km->regionid);
00971     if(!keymap)
00972         keymap= WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, km->spaceid, km->regionid);
00973 
00974     return keymap;
00975 }
00976 
00977 void WM_keyconfig_update(wmWindowManager *wm)
00978 {
00979     wmKeyMap *km, *defaultmap, *addonmap, *usermap, *kmn;
00980     wmKeyMapItem *kmi;
00981     wmKeyMapDiffItem *kmdi;
00982     int compat_update = 0;
00983 
00984     if(G.background)
00985         return;
00986     if(!WM_KEYMAP_UPDATE)
00987         return;
00988     
00989     /* update operator properties for non-modal user keymaps */
00990     for(km=U.user_keymaps.first; km; km=km->next) {
00991         if((km->flag & KEYMAP_MODAL) == 0) {
00992             for(kmdi=km->diff_items.first; kmdi; kmdi=kmdi->next) {
00993                 if(kmdi->add_item)
00994                     wm_keymap_item_properties_set(kmdi->add_item);
00995                 if(kmdi->remove_item)
00996                     wm_keymap_item_properties_set(kmdi->remove_item);
00997             }
00998 
00999             for(kmi=km->items.first; kmi; kmi=kmi->next)
01000                 wm_keymap_item_properties_set(kmi);
01001         }
01002     }
01003 
01004     /* update U.user_keymaps with user key configuration changes */
01005     for(km=wm->userconf->keymaps.first; km; km=km->next) {
01006         /* only diff if the user keymap was modified */
01007         if(wm_keymap_test_and_clear_update(km)) {
01008             /* find keymaps */
01009             defaultmap= wm_keymap_preset(wm, km);
01010             addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid);
01011 
01012             /* diff */
01013             if(defaultmap)
01014                 wm_keymap_diff_update(&U.user_keymaps, defaultmap, addonmap, km);
01015         }
01016     }
01017 
01018     /* create user key configuration from preset + addon + user preferences */
01019     for(km=wm->defaultconf->keymaps.first; km; km=km->next) {
01020         /* find keymaps */
01021         defaultmap= wm_keymap_preset(wm, km);
01022         addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid);
01023         usermap= WM_keymap_list_find(&U.user_keymaps, km->idname, km->spaceid, km->regionid);
01024 
01025         /* add */
01026         kmn= wm_keymap_patch_update(&wm->userconf->keymaps, defaultmap, addonmap, usermap);
01027 
01028         if(kmn) {
01029             kmn->modal_items= km->modal_items;
01030             kmn->poll= km->poll;
01031         }
01032 
01033         /* in case of old non-diff keymaps, force extra update to create diffs */
01034         compat_update = compat_update || (usermap && !(usermap->flag & KEYMAP_DIFF));
01035     }
01036 
01037     WM_KEYMAP_UPDATE= 0;
01038 
01039     if(compat_update) {
01040         WM_keyconfig_update_tag(NULL, NULL);
01041         WM_keyconfig_update(wm);
01042     }
01043 }
01044 
01045 /********************************* Event Handling *****************************
01046  * Handlers have pointers to the keymap in the default configuration. During
01047  * event handling this function is called to get the keymap from the final
01048  * configuration. */
01049 
01050 wmKeyMap *WM_keymap_active(wmWindowManager *wm, wmKeyMap *keymap)
01051 {
01052     wmKeyMap *km;
01053 
01054     if(!keymap)
01055         return NULL;
01056     
01057     /* first user defined keymaps */
01058     km= WM_keymap_list_find(&wm->userconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
01059 
01060     if(km)
01061         return km;
01062 
01063     return keymap;
01064 }
01065 
01066 /******************************* Keymap Editor ********************************
01067  * In the keymap editor the user key configuration is edited. */
01068 
01069 void WM_keymap_restore_item_to_default(bContext *C, wmKeyMap *keymap, wmKeyMapItem *kmi)
01070 {
01071     wmWindowManager *wm = CTX_wm_manager(C);
01072     wmKeyMap *defaultmap, *addonmap;
01073     wmKeyMapItem *orig;
01074 
01075     if(!keymap)
01076         return;
01077 
01078     /* construct default keymap from preset + addons */
01079     defaultmap= wm_keymap_preset(wm, keymap);
01080     addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
01081 
01082     if(addonmap) {
01083         defaultmap = wm_keymap_copy(defaultmap);
01084         wm_keymap_addon_add(defaultmap, addonmap);
01085     }
01086 
01087     /* find original item */
01088     orig = WM_keymap_item_find_id(defaultmap, kmi->id);
01089 
01090     if(orig) {
01091         /* restore to original */
01092         if(strcmp(orig->idname, kmi->idname) != 0) {
01093             BLI_strncpy(kmi->idname, orig->idname, sizeof(kmi->idname));
01094             WM_keymap_properties_reset(kmi, NULL);
01095         }
01096 
01097         if (orig->properties) {
01098             if(kmi->properties) {
01099                 IDP_FreeProperty(kmi->properties);
01100                 MEM_freeN(kmi->properties);
01101                 kmi->properties= NULL;
01102             }
01103 
01104             kmi->properties= IDP_CopyProperty(orig->properties);
01105             kmi->ptr->data= kmi->properties;
01106         }
01107 
01108         kmi->propvalue = orig->propvalue;
01109         kmi->type = orig->type;
01110         kmi->val = orig->val;
01111         kmi->shift = orig->shift;
01112         kmi->ctrl = orig->ctrl;
01113         kmi->alt = orig->alt;
01114         kmi->oskey = orig->oskey;
01115         kmi->keymodifier = orig->keymodifier;
01116         kmi->maptype = orig->maptype;
01117 
01118         WM_keyconfig_update_tag(keymap, kmi);
01119     }
01120 
01121     /* free temporary keymap */
01122     if(addonmap) {
01123         WM_keymap_free(defaultmap);
01124         MEM_freeN(defaultmap);
01125     }
01126 }
01127 
01128 void WM_keymap_restore_to_default(wmKeyMap *keymap, bContext *C)
01129 {
01130     wmWindowManager *wm = CTX_wm_manager(C);
01131     wmKeyMap *usermap;
01132 
01133     /* remove keymap from U.user_keymaps and update */
01134     usermap= WM_keymap_list_find(&U.user_keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
01135 
01136     if(usermap) {
01137         WM_keymap_free(usermap);
01138         BLI_freelinkN(&U.user_keymaps, usermap);
01139 
01140         WM_keyconfig_update_tag(NULL, NULL);
01141         WM_keyconfig_update(wm);
01142     }
01143 }
01144 
01145 wmKeyMapItem *WM_keymap_item_find_id(wmKeyMap *keymap, int id)
01146 {
01147     wmKeyMapItem *kmi;
01148     
01149     for (kmi=keymap->items.first; kmi; kmi=kmi->next) {
01150         if (kmi->id == id) {
01151             return kmi;
01152         }
01153     }
01154     
01155     return NULL;
01156 }
01157 
01158 /* Guess an appropriate keymap from the operator name */
01159 /* Needs to be kept up to date with Keymap and Operator naming */
01160 wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
01161 {
01162     wmKeyMap *km=NULL;
01163     SpaceLink *sl = CTX_wm_space_data(C);
01164     
01165     /* Window */
01166     if (strstr(opname, "WM_OT")) {
01167         km = WM_keymap_find_all(C, "Window", 0, 0);
01168     }
01169     /* Screen */
01170     else if (strstr(opname, "SCREEN_OT")) {
01171         km = WM_keymap_find_all(C, "Screen", 0, 0);
01172     }
01173     /* Grease Pencil */
01174     else if (strstr(opname, "GPENCIL_OT")) {
01175         km = WM_keymap_find_all(C, "Grease Pencil", 0, 0);
01176     }
01177     /* Markers */
01178     else if (strstr(opname, "MARKER_OT")) {
01179         km = WM_keymap_find_all(C, "Markers", 0, 0);
01180     }
01181     
01182     
01183     /* 3D View */
01184     else if (strstr(opname, "VIEW3D_OT")) {
01185         km = WM_keymap_find_all(C, "3D View", sl->spacetype, 0);
01186     }
01187     else if (strstr(opname, "OBJECT_OT")) {
01188         km = WM_keymap_find_all(C, "Object Mode", 0, 0);
01189     }
01190 
01191     
01192     /* Editing Modes */
01193     else if (strstr(opname, "MESH_OT")) {
01194         km = WM_keymap_find_all(C, "Mesh", 0, 0);
01195         
01196         /* some mesh operators are active in object mode too, like add-prim */
01197         if(km && km->poll && km->poll((bContext *)C)==0) {
01198             km = WM_keymap_find_all(C, "Object Mode", 0, 0);
01199         }
01200     }
01201     else if (strstr(opname, "CURVE_OT")) {
01202         km = WM_keymap_find_all(C, "Curve", 0, 0);
01203         
01204         /* some curve operators are active in object mode too, like add-prim */
01205         if(km && km->poll && km->poll((bContext *)C)==0) {
01206             km = WM_keymap_find_all(C, "Object Mode", 0, 0);
01207         }
01208     }
01209     else if (strstr(opname, "ARMATURE_OT")) {
01210         km = WM_keymap_find_all(C, "Armature", 0, 0);
01211     }
01212     else if (strstr(opname, "POSE_OT")) {
01213         km = WM_keymap_find_all(C, "Pose", 0, 0);
01214     }
01215     else if (strstr(opname, "SCULPT_OT")) {
01216         km = WM_keymap_find_all(C, "Sculpt", 0, 0);
01217     }
01218     else if (strstr(opname, "MBALL_OT")) {
01219         km = WM_keymap_find_all(C, "Metaball", 0, 0);
01220         
01221         /* some mball operators are active in object mode too, like add-prim */
01222         if(km && km->poll && km->poll((bContext *)C)==0) {
01223             km = WM_keymap_find_all(C, "Object Mode", 0, 0);
01224         }
01225     }
01226     else if (strstr(opname, "LATTICE_OT")) {
01227         km = WM_keymap_find_all(C, "Lattice", 0, 0);
01228     }
01229     else if (strstr(opname, "PARTICLE_OT")) {
01230         km = WM_keymap_find_all(C, "Particle", 0, 0);
01231     }
01232     else if (strstr(opname, "FONT_OT")) {
01233         km = WM_keymap_find_all(C, "Font", 0, 0);
01234     }
01235     else if (strstr(opname, "PAINT_OT")) {
01236         
01237         /* check for relevant mode */
01238         switch(CTX_data_mode_enum(C)) {
01239             case OB_MODE_WEIGHT_PAINT:
01240                 km = WM_keymap_find_all(C, "Weight Paint", 0, 0);
01241                 break;
01242             case OB_MODE_VERTEX_PAINT:
01243                 km = WM_keymap_find_all(C, "Vertex Paint", 0, 0);
01244                 break;
01245             case OB_MODE_TEXTURE_PAINT:
01246                 km = WM_keymap_find_all(C, "Image Paint", 0, 0);
01247                 break;
01248         }
01249     }
01250     /* Paint Face Mask */
01251     else if (strstr(opname, "PAINT_OT_face_select")) {
01252         km = WM_keymap_find_all(C, "Face Mask", sl->spacetype, 0);
01253     }
01254     /* Timeline */
01255     else if (strstr(opname, "TIME_OT")) {
01256         km = WM_keymap_find_all(C, "Timeline", sl->spacetype, 0);
01257     }
01258     /* Image Editor */
01259     else if (strstr(opname, "IMAGE_OT")) {
01260         km = WM_keymap_find_all(C, "Image", sl->spacetype, 0);
01261     }
01262     /* UV Editor */
01263     else if (strstr(opname, "UV_OT")) {
01264         km = WM_keymap_find_all(C, "UV Editor", sl->spacetype, 0);
01265     }
01266     /* Node Editor */
01267     else if (strstr(opname, "NODE_OT")) {
01268         km = WM_keymap_find_all(C, "Node Editor", sl->spacetype, 0);
01269     }
01270     /* Animation Editor Channels */
01271     else if (strstr(opname, "ANIM_OT_channels")) {
01272         km = WM_keymap_find_all(C, "Animation Channels", sl->spacetype, 0);
01273     }
01274     /* Animation Generic - after channels */
01275     else if (strstr(opname, "ANIM_OT")) {
01276         km = WM_keymap_find_all(C, "Animation", 0, 0);
01277     }
01278     /* Graph Editor */
01279     else if (strstr(opname, "GRAPH_OT")) {
01280         km = WM_keymap_find_all(C, "Graph Editor", sl->spacetype, 0);
01281     }
01282     /* Dopesheet Editor */
01283     else if (strstr(opname, "ACTION_OT")) {
01284         km = WM_keymap_find_all(C, "Dopesheet", sl->spacetype, 0);
01285     }
01286     /* NLA Editor */
01287     else if (strstr(opname, "NLA_OT")) {
01288         km = WM_keymap_find_all(C, "NLA Editor", sl->spacetype, 0);
01289     }
01290     /* Script */
01291     else if (strstr(opname, "SCRIPT_OT")) {
01292         km = WM_keymap_find_all(C, "Script", sl->spacetype, 0);
01293     }
01294     /* Text */
01295     else if (strstr(opname, "TEXT_OT")) {
01296         km = WM_keymap_find_all(C, "Text", sl->spacetype, 0);
01297     }
01298     /* Sequencer */
01299     else if (strstr(opname, "SEQUENCER_OT")) {
01300         km = WM_keymap_find_all(C, "Sequencer", sl->spacetype, 0);
01301     }
01302     /* Console */
01303     else if (strstr(opname, "CONSOLE_OT")) {
01304         km = WM_keymap_find_all(C, "Console", sl->spacetype, 0);
01305     }
01306     /* Console */
01307     else if (strstr(opname, "INFO_OT")) {
01308         km = WM_keymap_find_all(C, "Info", sl->spacetype, 0);
01309     }
01310     
01311     /* Transform */
01312     else if (strstr(opname, "TRANSFORM_OT")) {
01313         
01314         /* check for relevant editor */
01315         switch(sl->spacetype) {
01316             case SPACE_VIEW3D:
01317                 km = WM_keymap_find_all(C, "3D View", sl->spacetype, 0);
01318                 break;
01319             case SPACE_IPO:
01320                 km = WM_keymap_find_all(C, "Graph Editor", sl->spacetype, 0);
01321                 break;
01322             case SPACE_ACTION:
01323                 km = WM_keymap_find_all(C, "Dopesheet", sl->spacetype, 0);
01324                 break;
01325             case SPACE_NLA:
01326                 km = WM_keymap_find_all(C, "NLA Editor", sl->spacetype, 0);
01327                 break;
01328             case SPACE_IMAGE:
01329                 km = WM_keymap_find_all(C, "UV Editor", sl->spacetype, 0);
01330                 break;
01331             case SPACE_NODE:
01332                 km = WM_keymap_find_all(C, "Node Editor", sl->spacetype, 0);
01333                 break;
01334             case SPACE_SEQ:
01335                 km = WM_keymap_find_all(C, "Sequencer", sl->spacetype, 0);
01336                 break;
01337         }
01338     }
01339     
01340     return km;
01341 }
01342