Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/space_userpref_keymap.py53
-rw-r--r--source/blender/blenkernel/intern/blender.c33
-rw-r--r--source/blender/blenloader/intern/readfile.c40
-rw-r--r--source/blender/blenloader/intern/writefile.c24
-rw-r--r--source/blender/editors/interface/interface_handlers.c25
-rw-r--r--source/blender/editors/interface/resources.c2
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h3
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h24
-rw-r--r--source/blender/makesrna/intern/rna_internal.h3
-rw-r--r--source/blender/makesrna/intern/rna_scene.c2
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c6
-rw-r--r--source/blender/makesrna/intern/rna_wm.c247
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c183
-rw-r--r--source/blender/windowmanager/WM_api.h44
-rw-r--r--source/blender/windowmanager/WM_keymap.h104
-rw-r--r--source/blender/windowmanager/intern/wm.c10
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c6
-rw-r--r--source/blender/windowmanager/intern/wm_files.c13
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c718
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c2
20 files changed, 1043 insertions, 499 deletions
diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py
index 585c3cffcb9..5658cc96281 100644
--- a/release/scripts/startup/bl_ui/space_userpref_keymap.py
+++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py
@@ -188,10 +188,10 @@ class InputKeyMapPanel:
if km.is_modal:
row.label(text="", icon='LINKED')
- if km.is_user_defined:
+ if km.is_user_modified:
row.operator("wm.keymap_restore", text="Restore")
else:
- row.operator("wm.keymap_edit", text="Edit")
+ row.label()
if km.show_expanded_children:
if children:
@@ -212,7 +212,6 @@ class InputKeyMapPanel:
# "Add New" at end of keymap item list
col = self.indented_layout(col, level + 1)
subcol = col.split(percentage=0.2).column()
- subcol.enabled = km.is_user_defined
subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
col.separator()
@@ -243,7 +242,7 @@ class InputKeyMapPanel:
col = self.indented_layout(layout, level)
- if km.is_user_defined:
+ if kmi.show_expanded:
col = col.column(align=True)
box = col.box()
else:
@@ -256,7 +255,6 @@ class InputKeyMapPanel:
row.prop(kmi, "show_expanded", text="", emboss=False)
row = split.row()
- row.enabled = km.is_user_defined
row.prop(kmi, "active", text="", emboss=False)
if km.is_modal:
@@ -265,7 +263,6 @@ class InputKeyMapPanel:
row.label(text=kmi.name)
row = split.row()
- row.enabled = km.is_user_defined
row.prop(kmi, "map_type", text="")
if map_type == 'KEYBOARD':
row.prop(kmi, "type", text="", full_event=True)
@@ -282,18 +279,17 @@ class InputKeyMapPanel:
else:
row.label()
- if not kmi.is_user_defined:
+ if (not kmi.is_user_defined) and kmi.is_user_modified:
op = row.operator("wm.keyitem_restore", text="", icon='BACK')
op.item_id = kmi.id
- op = row.operator("wm.keyitem_remove", text="", icon='X')
- op.item_id = kmi.id
+ else:
+ op = row.operator("wm.keyitem_remove", text="", icon='X')
+ op.item_id = kmi.id
# Expanded, additional event settings
if kmi.show_expanded:
box = col.box()
- box.enabled = km.is_user_defined
-
if map_type not in {'TEXTINPUT', 'TIMER'}:
split = box.split(percentage=0.4)
sub = split.row()
@@ -352,10 +348,10 @@ class InputKeyMapPanel:
row.label()
row.label()
- if km.is_user_defined:
+ if km.is_user_modified:
row.operator("wm.keymap_restore", text="Restore")
else:
- row.operator("wm.keymap_edit", text="Edit")
+ row.label()
for kmi in filtered_items:
self.draw_kmi(display_keymaps, kc, km, kmi, col, 1)
@@ -363,7 +359,6 @@ class InputKeyMapPanel:
# "Add New" at end of keymap item list
col = self.indented_layout(layout, 1)
subcol = col.split(percentage=0.2).column()
- subcol.enabled = km.is_user_defined
subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
def draw_hierarchy(self, display_keymaps, layout):
@@ -372,8 +367,7 @@ class InputKeyMapPanel:
def draw_keymaps(self, context, layout):
wm = context.window_manager
- kc = wm.keyconfigs.active
- defkc = wm.keyconfigs.default
+ kc = wm.keyconfigs.user
col = layout.column()
sub = col.column()
@@ -398,7 +392,7 @@ class InputKeyMapPanel:
col.separator()
- display_keymaps = _merge_keymaps(kc, defkc)
+ display_keymaps = _merge_keymaps(kc, kc)
if context.space_data.filter_text != "":
filter_text = context.space_data.filter_text.lower()
self.draw_filtered(display_keymaps, filter_text, col)
@@ -609,7 +603,7 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
# Generate a list of keymaps to export:
#
- # First add all user_defined keymaps (found in inputs.edited_keymaps list),
+ # First add all user_modified keymaps (found in keyconfigs.user.keymaps list),
# then add all remaining keymaps from the currently active custom keyconfig.
#
# This will create a final list of keymaps that can be used as a 'diff' against
@@ -619,7 +613,9 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
class FakeKeyConfig():
keymaps = []
edited_kc = FakeKeyConfig()
- edited_kc.keymaps.extend(context.user_preferences.inputs.edited_keymaps)
+ for km in wm.keyconfigs.user.keymaps:
+ if km.is_user_modified:
+ edited_kc.keymaps.append(km)
# merge edited keymaps with non-default keyconfig, if it exists
if kc != wm.keyconfigs.default:
export_keymaps = _merge_keymaps(edited_kc, kc)
@@ -669,17 +665,6 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
return {'RUNNING_MODAL'}
-class WM_OT_keymap_edit(bpy.types.Operator):
- "Edit stored key map"
- bl_idname = "wm.keymap_edit"
- bl_label = "Edit Key Map"
-
- def execute(self, context):
- km = context.keymap
- km.copy_to_user()
- return {'FINISHED'}
-
-
class WM_OT_keymap_restore(bpy.types.Operator):
"Restore key map(s)"
bl_idname = "wm.keymap_restore"
@@ -691,7 +676,7 @@ class WM_OT_keymap_restore(bpy.types.Operator):
wm = context.window_manager
if self.all:
- for km in wm.keyconfigs.default.keymaps:
+ for km in wm.keyconfigs.user.keymaps:
km.restore_to_default()
else:
km = context.keymap
@@ -710,13 +695,13 @@ class WM_OT_keyitem_restore(bpy.types.Operator):
@classmethod
def poll(cls, context):
keymap = getattr(context, "keymap", None)
- return keymap and keymap.is_user_defined
+ return keymap
def execute(self, context):
km = context.keymap
kmi = km.keymap_items.from_id(self.item_id)
- if not kmi.is_user_defined:
+ if (not kmi.is_user_defined) and kmi.is_user_modified:
km.restore_item_to_default(kmi)
return {'FINISHED'}
@@ -753,7 +738,7 @@ class WM_OT_keyitem_remove(bpy.types.Operator):
@classmethod
def poll(cls, context):
- return hasattr(context, "keymap") and context.keymap.is_user_defined
+ return hasattr(context, "keymap")
def execute(self, context):
km = context.keymap
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 8b4bbbd3c83..7e2097d1233 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -330,28 +330,45 @@ static int handle_subversion_warning(Main *main)
return 1;
}
+static void keymap_item_free(wmKeyMapItem *kmi)
+{
+ if(kmi->properties) {
+ IDP_FreeProperty(kmi->properties);
+ MEM_freeN(kmi->properties);
+ }
+ if(kmi->ptr)
+ MEM_freeN(kmi->ptr);
+}
+
void BKE_userdef_free(void)
{
wmKeyMap *km;
wmKeyMapItem *kmi;
+ wmKeyMapDiffItem *kmdi;
- for(km=U.keymaps.first; km; km=km->next) {
- for(kmi=km->items.first; kmi; kmi=kmi->next) {
- if(kmi->properties) {
- IDP_FreeProperty(kmi->properties);
- MEM_freeN(kmi->properties);
+ for(km=U.user_keymaps.first; km; km=km->next) {
+ for(kmdi=km->diff_items.first; kmdi; kmdi=kmdi->next) {
+ if(kmdi->add_item) {
+ keymap_item_free(kmdi->add_item);
+ MEM_freeN(kmdi->add_item);
+ }
+ if(kmdi->remove_item) {
+ keymap_item_free(kmdi->remove_item);
+ MEM_freeN(kmdi->remove_item);
}
- if(kmi->ptr)
- MEM_freeN(kmi->ptr);
}
+ for(kmi=km->items.first; kmi; kmi=kmi->next)
+ keymap_item_free(kmi);
+
+ BLI_freelistN(&km->diff_items);
BLI_freelistN(&km->items);
}
BLI_freelistN(&U.uistyles);
BLI_freelistN(&U.uifonts);
BLI_freelistN(&U.themes);
- BLI_freelistN(&U.keymaps);
+ BLI_freelistN(&U.user_keymaps);
BLI_freelistN(&U.addons);
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 44c8ca97be9..bd12677485c 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4726,6 +4726,8 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
wm->keyconfigs.first= wm->keyconfigs.last= NULL;
wm->defaultconf= NULL;
+ wm->addonconf= NULL;
+ wm->userconf= NULL;
wm->jobs.first= wm->jobs.last= NULL;
wm->drags.first= wm->drags.last= NULL;
@@ -11762,33 +11764,57 @@ static void lib_link_all(FileData *fd, Main *main)
lib_link_library(fd, main); /* only init users */
}
+static void direct_link_keymapitem(FileData *fd, wmKeyMapItem *kmi)
+{
+ kmi->properties= newdataadr(fd, kmi->properties);
+ if(kmi->properties)
+ IDP_DirectLinkProperty(kmi->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ kmi->ptr= NULL;
+ kmi->flag &= ~KMI_UPDATE;
+}
static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
{
UserDef *user;
wmKeyMap *keymap;
wmKeyMapItem *kmi;
+ wmKeyMapDiffItem *kmdi;
bfd->user= user= read_struct(fd, bhead, "user def");
/* read all data into fd->datamap */
bhead= read_data_into_oldnewmap(fd, bhead, "user def");
+ if(user->keymaps.first) {
+ /* backwards compatibility */
+ user->user_keymaps= user->keymaps;
+ user->keymaps.first= user->keymaps.last= NULL;
+ }
+
link_list(fd, &user->themes);
- link_list(fd, &user->keymaps);
+ link_list(fd, &user->user_keymaps);
link_list(fd, &user->addons);
- for(keymap=user->keymaps.first; keymap; keymap=keymap->next) {
+ for(keymap=user->user_keymaps.first; keymap; keymap=keymap->next) {
keymap->modal_items= NULL;
keymap->poll= NULL;
+ keymap->flag &= ~KEYMAP_UPDATE;
+ link_list(fd, &keymap->diff_items);
link_list(fd, &keymap->items);
- for(kmi=keymap->items.first; kmi; kmi=kmi->next) {
- kmi->properties= newdataadr(fd, kmi->properties);
- if(kmi->properties)
- IDP_DirectLinkProperty(kmi->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
- kmi->ptr= NULL;
+
+ for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) {
+ kmdi->remove_item= newdataadr(fd, kmdi->remove_item);
+ kmdi->add_item= newdataadr(fd, kmdi->add_item);
+
+ if(kmdi->remove_item)
+ direct_link_keymapitem(fd, kmdi->remove_item);
+ if(kmdi->add_item)
+ direct_link_keymapitem(fd, kmdi->add_item);
}
+
+ for(kmi=keymap->items.first; kmi; kmi=kmi->next)
+ direct_link_keymapitem(fd, kmi);
}
// XXX
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index bf86527b9d3..7d65248c0e9 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -717,11 +717,19 @@ static void write_renderinfo(WriteData *wd, Main *mainvar) /* for renderdeamon
}
}
+static void write_keymapitem(WriteData *wd, wmKeyMapItem *kmi)
+{
+ writestruct(wd, DATA, "wmKeyMapItem", 1, kmi);
+ if(kmi->properties)
+ IDP_WriteProperty(kmi->properties, wd);
+}
+
static void write_userdef(WriteData *wd)
{
bTheme *btheme;
wmKeyMap *keymap;
wmKeyMapItem *kmi;
+ wmKeyMapDiffItem *kmdi;
bAddon *bext;
uiStyle *style;
@@ -730,15 +738,19 @@ static void write_userdef(WriteData *wd)
for(btheme= U.themes.first; btheme; btheme=btheme->next)
writestruct(wd, DATA, "bTheme", 1, btheme);
- for(keymap= U.keymaps.first; keymap; keymap=keymap->next) {
+ for(keymap= U.user_keymaps.first; keymap; keymap=keymap->next) {
writestruct(wd, DATA, "wmKeyMap", 1, keymap);
- for(kmi=keymap->items.first; kmi; kmi=kmi->next) {
- writestruct(wd, DATA, "wmKeyMapItem", 1, kmi);
-
- if(kmi->properties)
- IDP_WriteProperty(kmi->properties, wd);
+ for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) {
+ writestruct(wd, DATA, "wmKeyMapDiffItem", 1, kmdi);
+ if(kmdi->remove_item)
+ write_keymapitem(wd, kmdi->remove_item);
+ if(kmdi->add_item)
+ write_keymapitem(wd, kmdi->add_item);
}
+
+ for(kmi=keymap->items.first; kmi; kmi=kmi->next)
+ write_keymapitem(wd, kmi);
}
for(bext= U.addons.first; bext; bext=bext->next)
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index b3272a2e3d4..d8d8354b0b9 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -4067,7 +4067,6 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
/* complex code to change name of button */
if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, buf, sizeof(buf))) {
- wmKeyMap *km= NULL;
char *butstr_orig;
// XXX but->str changed... should not, remove the hotkey from it
@@ -4080,10 +4079,6 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
but->str= but->strdata;
ui_check_but(but);
-
- /* set the keymap editable else the key wont save */
- WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, 1, &km);
- WM_keymap_copy_to_user(km);
}
else {
/* shortcut was removed */
@@ -4095,6 +4090,7 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
{
+ wmWindowManager *wm= CTX_wm_manager(C);
uiBlock *block;
uiBut *but = (uiBut *)arg;
wmKeyMap *km;
@@ -4107,7 +4103,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
kmi = WM_keymap_item_find_id(km, kmi_id);
- RNA_pointer_create(NULL, &RNA_KeyMapItem, kmi, &ptr);
+ RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
uiBlockSetHandleFunc(block, but_shortcut_name_func, but);
@@ -4126,6 +4122,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
{
+ wmWindowManager *wm= CTX_wm_manager(C);
uiBlock *block;
uiBut *but = (uiBut *)arg;
wmKeyMap *km;
@@ -4134,19 +4131,25 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
uiLayout *layout;
uiStyle *style= U.uistyles.first;
IDProperty *prop= (but->opptr)? but->opptr->data: NULL;
+ int kmi_id;
/* XXX this guess_opname can potentially return a different keymap than being found on adding later... */
km = WM_keymap_guess_opname(C, but->optype->idname);
kmi = WM_keymap_add_item(km, but->optype->idname, AKEY, KM_PRESS, 0, 0);
+ kmi_id = kmi->id;
- if (prop) {
+ /* copy properties, prop can be NULL for reset */
+ if(prop)
prop= IDP_CopyProperty(prop);
- }
-
- /* prop can be NULL */
WM_keymap_properties_reset(kmi, prop);
- RNA_pointer_create(NULL, &RNA_KeyMapItem, kmi, &ptr);
+ /* update and get pointers again */
+ WM_keyconfig_update(wm);
+
+ km = WM_keymap_guess_opname(C, but->optype->idname);
+ kmi = WM_keymap_item_find_id(km, kmi_id);
+
+ RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
uiBlockSetHandleFunc(block, but_shortcut_name_func, but);
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 32e87b3a793..f3db6ad11ae 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -1425,7 +1425,7 @@ void init_userdef_do_versions(void)
if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 8)) {
wmKeyMap *km;
- for(km=U.keymaps.first; km; km=km->next) {
+ for(km=U.user_keymaps.first; km; km=km->next) {
if (strcmp(km->idname, "Armature_Sketch")==0)
strcpy(km->idname, "Armature Sketch");
else if (strcmp(km->idname, "View3D")==0)
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index aa6da3aaeca..a555a196060 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -341,7 +341,8 @@ typedef struct UserDef {
struct ListBase themes;
struct ListBase uifonts;
struct ListBase uistyles;
- struct ListBase keymaps;
+ struct ListBase keymaps; /* deprecated in favor of user_keymaps */
+ struct ListBase user_keymaps;
struct ListBase addons;
char keyconfigstr[64];
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 31e59f18626..1f0ae28a00d 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -144,7 +144,9 @@ typedef struct wmWindowManager {
ListBase drags; /* active dragged items */
ListBase keyconfigs; /* known key configurations */
- struct wmKeyConfig *defaultconf; /* default configuration, not saved */
+ struct wmKeyConfig *defaultconf; /* default configuration */
+ struct wmKeyConfig *addonconf; /* addon configuration */
+ struct wmKeyConfig *userconf; /* user configuration */
ListBase timers; /* active timers */
struct wmTimer *autosavetimer; /* timer for auto save */
@@ -239,15 +241,26 @@ typedef struct wmKeyMapItem {
struct PointerRNA *ptr; /* rna pointer to access properties */
} wmKeyMapItem;
+/* used instead of wmKeyMapItem for diff keymaps */
+typedef struct wmKeyMapDiffItem {
+ struct wmKeyMapDiffItem *next, *prev;
+
+ wmKeyMapItem *remove_item;
+ wmKeyMapItem *add_item;
+} wmKeyMapDiffItem;
+
/* wmKeyMapItem.flag */
-#define KMI_INACTIVE 1
-#define KMI_EXPANDED 2
+#define KMI_INACTIVE 1
+#define KMI_EXPANDED 2
+#define KMI_USER_MODIFIED 4
+#define KMI_UPDATE 8
/* stored in WM, the actively used keymaps */
typedef struct wmKeyMap {
struct wmKeyMap *next, *prev;
ListBase items;
+ ListBase diff_items;
char idname[64]; /* global editor keymaps, or for more per space/region */
short spaceid; /* same IDs as in DNA_space_types.h */
@@ -263,9 +276,12 @@ typedef struct wmKeyMap {
/* wmKeyMap.flag */
#define KEYMAP_MODAL 1 /* modal map, not using operatornames */
-#define KEYMAP_USER 2 /* user created keymap */
+#define KEYMAP_USER 2 /* user keymap */
#define KEYMAP_EXPANDED 4
#define KEYMAP_CHILDREN_EXPANDED 8
+#define KEYMAP_DIFF 16 /* diff keymap for user preferences */
+#define KEYMAP_USER_MODIFIED 32 /* keymap has user modifications */
+#define KEYMAP_UPDATE 64
typedef struct wmKeyConfig {
struct wmKeyConfig *next, *prev;
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 9175806e2bb..c0ae7b02b1a 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -238,9 +238,12 @@ void RNA_api_image(struct StructRNA *srna);
void RNA_api_operator(struct StructRNA *srna);
void RNA_api_macro(struct StructRNA *srna);
void RNA_api_keyconfig(struct StructRNA *srna);
+void RNA_api_keyconfigs(struct StructRNA *srna);
void RNA_api_keyingset(struct StructRNA *srna);
void RNA_api_keymap(struct StructRNA *srna);
+void RNA_api_keymaps(struct StructRNA *srna);
void RNA_api_keymapitem(struct StructRNA *srna);
+void RNA_api_keymapitems(struct StructRNA *srna);
void RNA_api_area(struct StructRNA *srna);
void RNA_api_main(struct StructRNA *srna);
void RNA_api_material(StructRNA *srna);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index b3d8bc8ea18..29cfc695911 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1409,7 +1409,7 @@ void rna_def_render_layer_common(StructRNA *srna, int scene)
prop= RNA_def_property(srna, "layers_zmask", PROP_BOOLEAN, PROP_LAYER);
RNA_def_property_boolean_sdna(prop, NULL, "lay_zmask", 1);
RNA_def_property_array(prop, 20);
- RNA_def_property_ui_text(prop, "Zmask Layers", "Zmask scene layers");
+ RNA_def_property_ui_text(prop, "Zmask Layers", "Zmask scene layers for solid faces");
if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index a1a99c34e70..b3dbafeab7d 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -2795,12 +2795,6 @@ static void rna_def_userdef_input(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 32);
RNA_def_property_ui_text(prop, "Wheel Scroll Lines", "The number of lines scrolled at a time with the mouse wheel");
- /* U.keymaps - custom keymaps that have been edited from default configs */
- prop= RNA_def_property(srna, "edited_keymaps", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "keymaps", NULL);
- RNA_def_property_struct_type(prop, "KeyMap");
- RNA_def_property_ui_text(prop, "Edited Keymaps", "");
-
prop= RNA_def_property(srna, "active_keyconfig", PROP_STRING, PROP_DIRPATH);
RNA_def_property_string_sdna(prop, NULL, "keyconfigstr");
RNA_def_property_ui_text(prop, "Key Config", "The name of the active key configuration");
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index a046be59ab5..307cf0e175a 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -578,22 +578,6 @@ static EnumPropertyItem *rna_KeyMapItem_propvalue_itemf(bContext *C, PointerRNA
wmKeyConfig *kc;
wmKeyMap *km;
- /* check user keymaps */
- for(km=U.keymaps.first; km; km=km->next) {
- wmKeyMapItem *kmi;
- for (kmi=km->items.first; kmi; kmi=kmi->next) {
- if (kmi == ptr->data) {
- if (!km->modal_items) {
- if (!WM_keymap_user_init(wm, km)) {
- return keymap_propvalue_items; /* ERROR */
- }
- }
-
- return km->modal_items;
- }
- }
- }
-
for(kc=wm->keyconfigs.first; kc; kc=kc->next) {
for(km=kc->keymaps.first; km; km=km->next) {
/* only check if it's a modal keymap */
@@ -654,12 +638,13 @@ static PointerRNA rna_WindowManager_active_keyconfig_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_KeyConfig, kc);
}
-static void rna_WindowManager_active_keyconfig_set(PointerRNA *UNUSED(ptr), PointerRNA value)
+static void rna_WindowManager_active_keyconfig_set(PointerRNA *ptr, PointerRNA value)
{
+ wmWindowManager *wm= ptr->data;
wmKeyConfig *kc= value.data;
if(kc)
- BLI_strncpy(U.keyconfigstr, kc->idname, sizeof(U.keyconfigstr));
+ WM_keyconfig_set_active(wm, kc->idname);
}
static void rna_wmKeyMapItem_idname_get(PointerRNA *ptr, char *value)
@@ -1130,93 +1115,6 @@ static StructRNA* rna_MacroOperator_refine(PointerRNA *opr)
return (op->type && op->type->ext.srna)? op->type->ext.srna: &RNA_Macro;
}
-static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, const char *idname, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier)
-{
-// wmWindowManager *wm = CTX_wm_manager(C);
- char idname_bl[OP_MAX_TYPENAME];
- int modifier= 0;
-
- /* only on non-modal maps */
- if (km->flag & KEYMAP_MODAL) {
- BKE_report(reports, RPT_ERROR, "Not a non-modal keymap.");
- return NULL;
- }
-
- WM_operator_bl_idname(idname_bl, idname);
-
- if(shift) modifier |= KM_SHIFT;
- if(ctrl) modifier |= KM_CTRL;
- if(alt) modifier |= KM_ALT;
- if(oskey) modifier |= KM_OSKEY;
-
- if(any) modifier = KM_ANY;
-
- return WM_keymap_add_item(km, idname_bl, type, value, modifier, keymodifier);
-}
-
-static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km, bContext *C, ReportList *reports, const char *propvalue_str, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier)
-{
- wmWindowManager *wm = CTX_wm_manager(C);
- int modifier= 0;
- int propvalue = 0;
-
- /* only modal maps */
- if ((km->flag & KEYMAP_MODAL) == 0) {
- BKE_report(reports, RPT_ERROR, "Not a modal keymap.");
- return NULL;
- }
-
- if (!km->modal_items) {
- if(!WM_keymap_user_init(wm, km)) {
- BKE_report(reports, RPT_ERROR, "User defined keymap doesn't correspond to a system keymap.");
- return NULL;
- }
- }
-
- if (!km->modal_items) {
- BKE_report(reports, RPT_ERROR, "No property values defined.");
- return NULL;
- }
-
-
- if(RNA_enum_value_from_id(km->modal_items, propvalue_str, &propvalue)==0) {
- BKE_report(reports, RPT_WARNING, "Property value not in enumeration.");
- }
-
- if(shift) modifier |= KM_SHIFT;
- if(ctrl) modifier |= KM_CTRL;
- if(alt) modifier |= KM_ALT;
- if(oskey) modifier |= KM_OSKEY;
-
- if(any) modifier = KM_ANY;
-
- return WM_modalkeymap_add_item(km, type, value, modifier, keymodifier, propvalue);
-}
-
-static wmKeyMap *rna_keymap_new(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid, int modal)
-{
- if (modal == 0) {
- return WM_keymap_find(keyconf, idname, spaceid, regionid);
- } else {
- return WM_modalkeymap_add(keyconf, idname, NULL); /* items will be lazy init */
- }
-}
-
-static wmKeyMap *rna_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
-{
- return WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid);
-}
-
-static wmKeyMap *rna_keymap_find_modal(wmKeyConfig *UNUSED(keyconf), const char *idname)
-{
- wmOperatorType *ot = WM_operatortype_find(idname, 0);
-
- if (!ot)
- return NULL;
- else
- return ot->modalkeymap;
-}
-
/* just to work around 'const char *' warning and to ensure this is a python op */
static void rna_Operator_bl_idname_set(PointerRNA *ptr, const char *value)
{
@@ -1242,6 +1140,12 @@ static void rna_Operator_bl_description_set(PointerRNA *ptr, const char *value)
else assert(!"setting the bl_description on a non-builtin operator");
}
+static void rna_KeyMapItem_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ wmKeyMapItem *kmi= ptr->data;
+ WM_keyconfig_update_tag(NULL, kmi);
+}
+
#else /* RNA_RUNTIME */
static void rna_def_operator(BlenderRNA *brna)
@@ -1566,9 +1470,6 @@ static void rna_def_wm_keyconfigs(BlenderRNA *brna, PropertyRNA *cprop)
StructRNA *srna;
PropertyRNA *prop;
- FunctionRNA *func;
- PropertyRNA *parm;
-
RNA_def_property_srna(cprop, "KeyConfigurations");
srna= RNA_def_struct(brna, "KeyConfigurations", NULL);
RNA_def_struct_sdna(srna, "wmWindowManager");
@@ -1578,23 +1479,24 @@ static void rna_def_wm_keyconfigs(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_struct_type(prop, "KeyConfig");
RNA_def_property_pointer_funcs(prop, "rna_WindowManager_active_keyconfig_get", "rna_WindowManager_active_keyconfig_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Active KeyConfig", "Active wm KeyConfig");
+ RNA_def_property_ui_text(prop, "Active KeyConfig", "Active key configuration (preset)");
prop= RNA_def_property(srna, "default", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "defaultconf");
RNA_def_property_struct_type(prop, "KeyConfig");
- RNA_def_property_ui_text(prop, "Default Key Configuration", "");
+ RNA_def_property_ui_text(prop, "Default Key Configuration", "Default builtin key configuration");
+
+ prop= RNA_def_property(srna, "addon", PROP_POINTER, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "addonconf");
+ RNA_def_property_struct_type(prop, "KeyConfig");
+ RNA_def_property_ui_text(prop, "Addon Key Configuration", "Key configuration that can be extended by addons, and is added to the active configuration when handling events");
+
+ prop= RNA_def_property(srna, "user", PROP_POINTER, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "userconf");
+ RNA_def_property_struct_type(prop, "KeyConfig");
+ RNA_def_property_ui_text(prop, "User Key Configuration", "Final key configuration that combines keymaps from the active and addon configurations, and can be edited by the user");
- /* funcs */
- func= RNA_def_function(srna, "new", "WM_keyconfig_new_user"); // add_keyconfig
- parm= RNA_def_string(func, "name", "", 0, "Name", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Added key configuration.");
- RNA_def_function_return(func, parm);
-
- func= RNA_def_function(srna, "remove", "WM_keyconfig_remove"); // remove_keyconfig
- parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Removed key configuration.");
- RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_api_keyconfigs(srna);
}
static void rna_def_windowmanager(BlenderRNA *brna)
@@ -1631,107 +1533,30 @@ static void rna_def_windowmanager(BlenderRNA *brna)
static void rna_def_keymap_items(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
-// PropertyRNA *prop;
-
- FunctionRNA *func;
- PropertyRNA *parm;
RNA_def_property_srna(cprop, "KeyMapItems");
srna= RNA_def_struct(brna, "KeyMapItems", NULL);
RNA_def_struct_sdna(srna, "wmKeyMap");
RNA_def_struct_ui_text(srna, "KeyMap Items", "Collection of keymap items");
- func= RNA_def_function(srna, "new", "rna_KeyMap_item_new");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
- parm= RNA_def_string(func, "idname", "", 0, "Operator Identifier", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_boolean(func, "any", 0, "Any", "");
- RNA_def_boolean(func, "shift", 0, "Shift", "");
- RNA_def_boolean(func, "ctrl", 0, "Ctrl", "");
- RNA_def_boolean(func, "alt", 0, "Alt", "");
- RNA_def_boolean(func, "oskey", 0, "OS Key", "");
- RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", "");
- parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item.");
- RNA_def_function_return(func, parm);
-
- func= RNA_def_function(srna, "new_modal", "rna_KeyMap_item_new_modal");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
- parm= RNA_def_string(func, "propvalue", "", 0, "Property Value", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_boolean(func, "any", 0, "Any", "");
- RNA_def_boolean(func, "shift", 0, "Shift", "");
- RNA_def_boolean(func, "ctrl", 0, "Ctrl", "");
- RNA_def_boolean(func, "alt", 0, "Alt", "");
- RNA_def_boolean(func, "oskey", 0, "OS Key", "");
- RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", "");
- parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item.");
- RNA_def_function_return(func, parm);
-
- func= RNA_def_function(srna, "remove", "WM_keymap_remove_item");
- parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
-
- func= RNA_def_function(srna, "from_id", "WM_keymap_item_find_id");
- parm= RNA_def_property(func, "id", PROP_INT, PROP_NONE);
- RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_property_ui_text(parm, "id", "ID of the item");
- parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
- RNA_def_function_return(func, parm);
-
+ RNA_api_keymapitems(srna);
}
static void rna_def_wm_keymaps(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
- //PropertyRNA *prop;
-
- FunctionRNA *func;
- PropertyRNA *parm;
-
RNA_def_property_srna(cprop, "KeyMaps");
srna= RNA_def_struct(brna, "KeyMaps", NULL);
RNA_def_struct_sdna(srna, "wmKeyConfig");
RNA_def_struct_ui_text(srna, "Key Maps", "Collection of keymaps");
- func= RNA_def_function(srna, "new", "rna_keymap_new"); // add_keymap
- parm= RNA_def_string(func, "name", "", 0, "Name", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", "");
- RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", "");
- RNA_def_boolean(func, "modal", 0, "Modal", "");
- parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Added key map.");
- RNA_def_function_return(func, parm);
-
- func= RNA_def_function(srna, "find", "rna_keymap_find"); // find_keymap
- parm= RNA_def_string(func, "name", "", 0, "Name", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", "");
- RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", "");
- parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map.");
- RNA_def_function_return(func, parm);
-
- func= RNA_def_function(srna, "find_modal", "rna_keymap_find_modal"); // find_keymap_modal
- parm= RNA_def_string(func, "name", "", 0, "Operator Name", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map.");
- RNA_def_function_return(func, parm);
-
+ RNA_api_keymaps(srna);
}
static void rna_def_keyconfig(BlenderRNA *brna)
{
StructRNA *srna;
- // FunctionRNA *func;
- // PropertyRNA *parm;
PropertyRNA *prop;
static EnumPropertyItem map_type_items[] = {
@@ -1794,8 +1619,8 @@ static void rna_def_keyconfig(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Items", "Items in the keymap, linking an operator to an input event");
rna_def_keymap_items(brna, prop);
- prop= RNA_def_property(srna, "is_user_defined", PROP_BOOLEAN, PROP_NEVER_NULL);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYMAP_USER);
+ prop= RNA_def_property(srna, "is_user_modified", PROP_BOOLEAN, PROP_NEVER_NULL);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYMAP_USER_MODIFIED);
RNA_def_property_ui_text(prop, "User Defined", "Keymap is defined by the user");
prop= RNA_def_property(srna, "is_modal", PROP_BOOLEAN, PROP_NONE);
@@ -1826,6 +1651,7 @@ static void rna_def_keyconfig(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Identifier", "Identifier of operator to call on input event");
RNA_def_property_string_funcs(prop, "rna_wmKeyMapItem_idname_get", "rna_wmKeyMapItem_idname_length", "rna_wmKeyMapItem_idname_set");
RNA_def_struct_name_property(srna, prop);
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -1836,62 +1662,73 @@ static void rna_def_keyconfig(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "OperatorProperties");
RNA_def_property_pointer_funcs(prop, "rna_KeyMapItem_properties_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Properties", "Properties to set when the operator is called");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "map_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "maptype");
RNA_def_property_enum_items(prop, map_type_items);
RNA_def_property_enum_funcs(prop, "rna_wmKeyMapItem_map_type_get", "rna_wmKeyMapItem_map_type_set", NULL);
RNA_def_property_ui_text(prop, "Map Type", "Type of event mapping");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, event_type_items);
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_type_itemf");
RNA_def_property_ui_text(prop, "Type", "Type of event");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "value", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "val");
RNA_def_property_enum_items(prop, event_value_items);
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_value_itemf");
RNA_def_property_ui_text(prop, "Value", "");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "id", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "id");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "id", "ID of the item");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "any", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_any_getf", "rna_KeyMapItem_any_setf");
RNA_def_property_ui_text(prop, "Any", "Any modifier keys pressed");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "shift", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shift", 0);
// RNA_def_property_enum_sdna(prop, NULL, "shift");
// RNA_def_property_enum_items(prop, keymap_modifiers_items);
RNA_def_property_ui_text(prop, "Shift", "Shift key pressed");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "ctrl", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ctrl", 0);
// RNA_def_property_enum_sdna(prop, NULL, "ctrl");
// RNA_def_property_enum_items(prop, keymap_modifiers_items);
RNA_def_property_ui_text(prop, "Ctrl", "Control key pressed");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "alt", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "alt", 0);
// RNA_def_property_enum_sdna(prop, NULL, "alt");
// RNA_def_property_enum_items(prop, keymap_modifiers_items);
RNA_def_property_ui_text(prop, "Alt", "Alt key pressed");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "oskey", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "oskey", 0);
// RNA_def_property_enum_sdna(prop, NULL, "oskey");
// RNA_def_property_enum_items(prop, keymap_modifiers_items);
RNA_def_property_ui_text(prop, "OS Key", "Operating system key pressed");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "key_modifier", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "keymodifier");
RNA_def_property_enum_items(prop, event_type_items);
RNA_def_property_ui_text(prop, "Key Modifier", "Regular key pressed as a modifier");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", KMI_EXPANDED);
@@ -1903,15 +1740,21 @@ static void rna_def_keyconfig(BlenderRNA *brna)
RNA_def_property_enum_items(prop, keymap_propvalue_items);
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_propvalue_itemf");
RNA_def_property_ui_text(prop, "Property Value", "The value this event translates to in a modal keymap");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", KMI_INACTIVE);
RNA_def_property_ui_text(prop, "Active", "Activate or deactivate item");
RNA_def_property_ui_icon(prop, ICON_CHECKBOX_DEHLT, 1);
+ prop= RNA_def_property(srna, "is_user_modified", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", KMI_USER_MODIFIED);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "User Modified", "Is this keymap item modified by the user");
+
prop= RNA_def_property(srna, "is_user_defined", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "User Defined", "Is this keymap item user defined (doesn't just override a builtin item)");
+ RNA_def_property_ui_text(prop, "User Defined", "Is this keymap item user defined (doesn't just replace a builtin item)");
RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_userdefined_get", NULL);
RNA_api_keymapitem(srna);
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index d44b68950f7..89e946f498a 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -84,6 +84,85 @@ void rna_event_timer_remove(struct wmWindowManager *wm, wmTimer *timer)
WM_event_remove_timer(wm, timer->win, timer);
}
+static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, const char *idname, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier)
+{
+// wmWindowManager *wm = CTX_wm_manager(C);
+ char idname_bl[OP_MAX_TYPENAME];
+ int modifier= 0;
+
+ /* only on non-modal maps */
+ if (km->flag & KEYMAP_MODAL) {
+ BKE_report(reports, RPT_ERROR, "Not a non-modal keymap.");
+ return NULL;
+ }
+
+ WM_operator_bl_idname(idname_bl, idname);
+
+ if(shift) modifier |= KM_SHIFT;
+ if(ctrl) modifier |= KM_CTRL;
+ if(alt) modifier |= KM_ALT;
+ if(oskey) modifier |= KM_OSKEY;
+
+ if(any) modifier = KM_ANY;
+
+ return WM_keymap_add_item(km, idname_bl, type, value, modifier, keymodifier);
+}
+
+static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km, ReportList *reports, const char *propvalue_str, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier)
+{
+ int modifier= 0;
+ int propvalue = 0;
+
+ /* only modal maps */
+ if ((km->flag & KEYMAP_MODAL) == 0) {
+ BKE_report(reports, RPT_ERROR, "Not a modal keymap.");
+ return NULL;
+ }
+
+ if (!km->modal_items) {
+ BKE_report(reports, RPT_ERROR, "No property values defined.");
+ return NULL;
+ }
+
+
+ if(RNA_enum_value_from_id(km->modal_items, propvalue_str, &propvalue)==0) {
+ BKE_report(reports, RPT_WARNING, "Property value not in enumeration.");
+ }
+
+ if(shift) modifier |= KM_SHIFT;
+ if(ctrl) modifier |= KM_CTRL;
+ if(alt) modifier |= KM_ALT;
+ if(oskey) modifier |= KM_OSKEY;
+
+ if(any) modifier = KM_ANY;
+
+ return WM_modalkeymap_add_item(km, type, value, modifier, keymodifier, propvalue);
+}
+
+static wmKeyMap *rna_keymap_new(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid, int modal)
+{
+ if (modal == 0) {
+ return WM_keymap_find(keyconf, idname, spaceid, regionid);
+ } else {
+ return WM_modalkeymap_add(keyconf, idname, NULL); /* items will be lazy init */
+ }
+}
+
+static wmKeyMap *rna_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
+{
+ return WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid);
+}
+
+static wmKeyMap *rna_keymap_find_modal(wmKeyConfig *UNUSED(keyconf), const char *idname)
+{
+ wmOperatorType *ot = WM_operatortype_find(idname, 0);
+
+ if (!ot)
+ return NULL;
+ else
+ return ot->modalkeymap;
+}
+
#else
#define WM_GEN_INVOKE_EVENT (1<<0)
@@ -301,11 +380,8 @@ void RNA_api_keymap(StructRNA *srna)
parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Active key map.");
RNA_def_function_return(func, parm);
- func= RNA_def_function(srna, "copy_to_user", "WM_keymap_copy_to_user");
- parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "User editable key map.");
- RNA_def_function_return(func, parm);
-
- RNA_def_function(srna, "restore_to_default", "WM_keymap_restore_to_default");
+ func= RNA_def_function(srna, "restore_to_default", "WM_keymap_restore_to_default");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
func= RNA_def_function(srna, "restore_item_to_default", "rna_keymap_restore_item_to_default");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
@@ -324,5 +400,102 @@ void RNA_api_keymapitem(StructRNA *srna)
parm= RNA_def_boolean(func, "result", 0, "Comparison result", "");
RNA_def_function_return(func, parm);
}
+
+void RNA_api_keymapitems(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ func= RNA_def_function(srna, "new", "rna_KeyMap_item_new");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm= RNA_def_string(func, "idname", "", 0, "Operator Identifier", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_boolean(func, "any", 0, "Any", "");
+ RNA_def_boolean(func, "shift", 0, "Shift", "");
+ RNA_def_boolean(func, "ctrl", 0, "Ctrl", "");
+ RNA_def_boolean(func, "alt", 0, "Alt", "");
+ RNA_def_boolean(func, "oskey", 0, "OS Key", "");
+ RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", "");
+ parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "new_modal", "rna_KeyMap_item_new_modal");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm= RNA_def_string(func, "propvalue", "", 0, "Property Value", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_boolean(func, "any", 0, "Any", "");
+ RNA_def_boolean(func, "shift", 0, "Shift", "");
+ RNA_def_boolean(func, "ctrl", 0, "Ctrl", "");
+ RNA_def_boolean(func, "alt", 0, "Alt", "");
+ RNA_def_boolean(func, "oskey", 0, "OS Key", "");
+ RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", "");
+ parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "remove", "WM_keymap_remove_item");
+ parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ func= RNA_def_function(srna, "from_id", "WM_keymap_item_find_id");
+ parm= RNA_def_property(func, "id", PROP_INT, PROP_NONE);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_property_ui_text(parm, "id", "ID of the item");
+ parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
+ RNA_def_function_return(func, parm);
+}
+
+void RNA_api_keymaps(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ func= RNA_def_function(srna, "new", "rna_keymap_new"); // add_keymap
+ parm= RNA_def_string(func, "name", "", 0, "Name", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", "");
+ RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", "");
+ RNA_def_boolean(func, "modal", 0, "Modal", "");
+ parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Added key map.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "find", "rna_keymap_find"); // find_keymap
+ parm= RNA_def_string(func, "name", "", 0, "Name", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", "");
+ RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", "");
+ parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "find_modal", "rna_keymap_find_modal"); // find_keymap_modal
+ parm= RNA_def_string(func, "name", "", 0, "Operator Name", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map.");
+ RNA_def_function_return(func, parm);
+}
+
+void RNA_api_keyconfigs(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ func= RNA_def_function(srna, "new", "WM_keyconfig_new_user"); // add_keyconfig
+ parm= RNA_def_string(func, "name", "", 0, "Name", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Added key configuration.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "remove", "WM_keyconfig_remove"); // remove_keyconfig
+ parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Removed key configuration.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+}
+
#endif
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index e6325e2101a..42c3096dfc9 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -41,6 +41,7 @@
/* dna-savable wmStructs here */
#include "DNA_windowmanager_types.h"
+#include "WM_keymap.h"
#ifdef __cplusplus
extern "C" {
@@ -114,50 +115,9 @@ void WM_paint_cursor_end(struct wmWindowManager *wm, void *handle);
void WM_cursor_warp (struct wmWindow *win, int x, int y);
- /* keyconfig and keymap */
-wmKeyConfig *WM_keyconfig_new (struct wmWindowManager *wm, const char *idname);
-wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, const char *idname);
-void WM_keyconfig_remove (struct wmWindowManager *wm, struct wmKeyConfig *keyconf);
-void WM_keyconfig_free (struct wmKeyConfig *keyconf);
-void WM_keyconfig_userdef(void);
-
-void WM_keymap_init (struct bContext *C);
-void WM_keymap_free (struct wmKeyMap *keymap);
-
-wmKeyMapItem *WM_keymap_verify_item(struct wmKeyMap *keymap, const char *idname, int type,
- int val, int modifier, int keymodifier);
-wmKeyMapItem *WM_keymap_add_item(struct wmKeyMap *keymap, const char *idname, int type,
- int val, int modifier, int keymodifier);
-wmKeyMapItem *WM_keymap_add_menu(struct wmKeyMap *keymap, const char *idname, int type,
- int val, int modifier, int keymodifier);
-
-void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
-char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len);
-
-wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid);
-wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid);
-wmKeyMap *WM_keymap_find_all(const struct bContext *C, const char *idname, int spaceid, int regionid);
-wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *keymap);
-wmKeyMap *WM_keymap_guess_opname(const struct bContext *C, const char *opname);
-int WM_keymap_user_init(struct wmWindowManager *wm, struct wmKeyMap *keymap);
-wmKeyMap *WM_keymap_copy_to_user(struct wmKeyMap *keymap);
-void WM_keymap_restore_to_default(struct wmKeyMap *keymap);
-void WM_keymap_properties_reset(struct wmKeyMapItem *kmi, struct IDProperty *properties);
-void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
-
-wmKeyMapItem *WM_keymap_item_find_id(struct wmKeyMap *keymap, int id);
-int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2);
+ /* event map */
int WM_userdef_event_map(int kmitype);
-wmKeyMap *WM_modalkeymap_add(struct wmKeyConfig *keyconf, const char *idname, struct EnumPropertyItem *items);
-wmKeyMap *WM_modalkeymap_get(struct wmKeyConfig *keyconf, const char *idname);
-wmKeyMapItem *WM_modalkeymap_add_item(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value);
-void WM_modalkeymap_assign(struct wmKeyMap *km, const char *opname);
-
-const char *WM_key_event_string(short type);
-int WM_key_event_operator_id(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, int hotkey, struct wmKeyMap **keymap_r);
-char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, char *str, int len);
-
/* handlers */
struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap);
diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h
new file mode 100644
index 00000000000..e00cd288c9a
--- /dev/null
+++ b/source/blender/windowmanager/WM_keymap.h
@@ -0,0 +1,104 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2007 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef WM_KEYMAP_H
+#define WM_KEYMAP_H
+
+/** \file WM_keymap.h
+ * \ingroup wm
+ */
+
+/* dna-savable wmStructs here */
+#include "DNA_windowmanager_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct EnumPropertyItem;
+
+/* Key Configuration */
+
+wmKeyConfig *WM_keyconfig_new (struct wmWindowManager *wm, const char *idname);
+wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, const char *idname);
+void WM_keyconfig_remove (struct wmWindowManager *wm, struct wmKeyConfig *keyconf);
+void WM_keyconfig_free (struct wmKeyConfig *keyconf);
+
+void WM_keyconfig_set_active(struct wmWindowManager *wm, const char *idname);
+
+void WM_keyconfig_update(struct wmWindowManager *wm);
+void WM_keyconfig_update_tag(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
+
+/* Keymap */
+
+void WM_keymap_init (struct bContext *C);
+void WM_keymap_free (struct wmKeyMap *keymap);
+
+wmKeyMapItem *WM_keymap_verify_item(struct wmKeyMap *keymap, const char *idname, int type,
+ int val, int modifier, int keymodifier);
+wmKeyMapItem *WM_keymap_add_item(struct wmKeyMap *keymap, const char *idname, int type,
+ int val, int modifier, int keymodifier);
+wmKeyMapItem *WM_keymap_add_menu(struct wmKeyMap *keymap, const char *idname, int type,
+ int val, int modifier, int keymodifier);
+
+void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
+char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len);
+
+wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid);
+wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid);
+wmKeyMap *WM_keymap_find_all(const struct bContext *C, const char *idname, int spaceid, int regionid);
+wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *keymap);
+wmKeyMap *WM_keymap_guess_opname(const struct bContext *C, const char *opname);
+
+wmKeyMapItem *WM_keymap_item_find_id(struct wmKeyMap *keymap, int id);
+int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2);
+
+/* Modal Keymap */
+
+wmKeyMap *WM_modalkeymap_add(struct wmKeyConfig *keyconf, const char *idname, struct EnumPropertyItem *items);
+wmKeyMap *WM_modalkeymap_get(struct wmKeyConfig *keyconf, const char *idname);
+wmKeyMapItem *WM_modalkeymap_add_item(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value);
+void WM_modalkeymap_assign(struct wmKeyMap *km, const char *opname);
+
+/* Keymap Editor */
+
+void WM_keymap_restore_to_default(struct wmKeyMap *keymap, struct bContext *C);
+void WM_keymap_properties_reset(struct wmKeyMapItem *kmi, struct IDProperty *properties);
+void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
+
+/* Key Event */
+
+const char *WM_key_event_string(short type);
+int WM_key_event_operator_id(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, int hotkey, struct wmKeyMap **keymap_r);
+char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, char *str, int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WM_KEYMAP_H */
+
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index a535c0bc1f8..1d5cf1cdc53 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -210,12 +210,18 @@ void WM_keymap_init(bContext *C)
if(!wm->defaultconf)
wm->defaultconf= WM_keyconfig_new(wm, "Blender");
+ if(!wm->addonconf)
+ wm->addonconf= WM_keyconfig_new(wm, "Blender Addon");
+ if(!wm->userconf)
+ wm->userconf= WM_keyconfig_new(wm, "Blender User");
- if(wm && CTX_py_init_get(C) && (wm->initialized & WM_INIT_KEYMAP) == 0) {
+ if(CTX_py_init_get(C) && (wm->initialized & WM_INIT_KEYMAP) == 0) {
/* create default key config */
wm_window_keymap(wm->defaultconf);
ED_spacetypes_keymap(wm->defaultconf);
- WM_keyconfig_userdef();
+
+ WM_keyconfig_update_tag(NULL, NULL);
+ WM_keyconfig_update(wm);
wm->initialized |= WM_INIT_KEYMAP;
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 2f0c1a72be9..0dac0bd7401 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1735,6 +1735,9 @@ void wm_event_do_handlers(bContext *C)
wmWindowManager *wm= CTX_wm_manager(C);
wmWindow *win;
+ /* update key configuration before handling events */
+ WM_keyconfig_update(wm);
+
for(win= wm->windows.first; win; win= win->next) {
wmEvent *event;
@@ -1938,6 +1941,9 @@ void wm_event_do_handlers(bContext *C)
CTX_wm_window_set(C, NULL);
}
+
+ /* update key configuration after handling events */
+ WM_keyconfig_update(wm);
}
/* ********** filesector handling ************ */
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 27fc0caeccc..20f9d2237c2 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -224,6 +224,14 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist)
oldwm= oldwmlist->first;
wm= G.main->wm.first;
+ /* move addon key configuration to new wm, to preserve their keymaps */
+ if(oldwm->addonconf) {
+ wm->addonconf= oldwm->addonconf;
+ BLI_remlink(&oldwm->keyconfigs, oldwm->addonconf);
+ oldwm->addonconf= NULL;
+ BLI_addtail(&wm->keyconfigs, wm->addonconf);
+ }
+
/* ensure making new keymaps and set space types */
wm->initialized= 0;
wm->winactive= NULL;
@@ -794,11 +802,14 @@ int WM_write_homefile(bContext *C, wmOperator *op)
wmWindow *win= CTX_wm_window(C);
char filepath[FILE_MAXDIR+FILE_MAXFILE];
int fileflags;
-
+
/* check current window and close it if temp */
if(win->screen->temp)
wm_window_close(C, wm, win);
+ /* update keymaps in user preferences */
+ WM_keyconfig_update(wm);
+
BLI_make_file_string("/", filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE);
printf("trying to save homefile at %s ", filepath);
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 1720c738dd7..bf48f0e21e4 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -61,14 +61,67 @@
#include "wm_event_system.h"
#include "wm_event_types.h"
-/* ********************* key config ***********************/
+/******************************* Keymap Item **********************************
+ * Item in a keymap, that maps from an event to an operator or modal map item */
-static void keymap_properties_set(wmKeyMapItem *kmi)
+static wmKeyMapItem *wm_keymap_item_copy(wmKeyMapItem *kmi)
+{
+ wmKeyMapItem *kmin = MEM_dupallocN(kmi);
+
+ kmin->prev= kmin->next= NULL;
+ kmin->flag &= ~KMI_UPDATE;
+
+ if(kmin->properties) {
+ kmin->ptr= MEM_callocN(sizeof(PointerRNA), "UserKeyMapItemPtr");
+ WM_operator_properties_create(kmin->ptr, kmin->idname);
+
+ kmin->properties= IDP_CopyProperty(kmin->properties);
+ kmin->ptr->data= kmin->properties;
+ }
+
+ return kmin;
+}
+
+static void wm_keymap_item_free(wmKeyMapItem *kmi)
+{
+ /* not kmi itself */
+ if(kmi->ptr) {
+ WM_operator_properties_free(kmi->ptr);
+ MEM_freeN(kmi->ptr);
+ }
+}
+
+static void wm_keymap_item_properties_set(wmKeyMapItem *kmi)
{
WM_operator_properties_alloc(&(kmi->ptr), &(kmi->properties), kmi->idname);
WM_operator_properties_sanitize(kmi->ptr, 1);
}
+static int wm_keymap_item_equals_result(wmKeyMapItem *a, wmKeyMapItem *b)
+{
+ if(strcmp(a->idname, b->idname) != 0)
+ return 0;
+
+ if(!((a->ptr==NULL && b->ptr==NULL) ||
+ (a->ptr && b->ptr && IDP_EqualsProperties(a->ptr->data, b->ptr->data))))
+ return 0;
+
+ return (a->propvalue == b->propvalue);
+}
+
+static int wm_keymap_item_equals(wmKeyMapItem *a, wmKeyMapItem *b)
+{
+ return (wm_keymap_item_equals_result(a, b) &&
+ a->type == b->type &&
+ a->val == b->val &&
+ a->shift == b->shift &&
+ a->ctrl == b->ctrl &&
+ a->alt == b->alt &&
+ a->oskey == b->oskey &&
+ a->keymodifier == b->keymodifier &&
+ a->maptype == b->maptype);
+}
+
/* properties can be NULL, otherwise the arg passed is used and ownership is given to the kmi */
void WM_keymap_properties_reset(wmKeyMapItem *kmi, struct IDProperty *properties)
{
@@ -78,9 +131,41 @@ void WM_keymap_properties_reset(wmKeyMapItem *kmi, struct IDProperty *properties
kmi->ptr = NULL;
kmi->properties = properties;
- keymap_properties_set(kmi);
+ wm_keymap_item_properties_set(kmi);
+}
+
+/**************************** Keymap Diff Item *********************************
+ * Item in a diff keymap, used for saving diff of keymaps in user preferences */
+
+static wmKeyMapDiffItem *wm_keymap_diff_item_copy(wmKeyMapDiffItem *kmdi)
+{
+ wmKeyMapDiffItem *kmdin = MEM_dupallocN(kmdi);
+
+ kmdin->next = kmdin->prev = NULL;
+ if(kmdi->add_item)
+ kmdin->add_item = wm_keymap_item_copy(kmdi->add_item);
+ if(kmdi->remove_item)
+ kmdin->remove_item = wm_keymap_item_copy(kmdi->remove_item);
+
+ return kmdin;
+}
+
+static void wm_keymap_diff_item_free(wmKeyMapDiffItem *kmdi)
+{
+ if(kmdi->remove_item) {
+ wm_keymap_item_free(kmdi->remove_item);
+ MEM_freeN(kmdi->remove_item);
+ }
+ if(kmdi->add_item) {
+ wm_keymap_item_free(kmdi->add_item);
+ MEM_freeN(kmdi->add_item);
+ }
}
+/***************************** Key Configuration ******************************
+ * List of keymaps for all editors, modes, ... . There is a builtin default key
+ * configuration, a user key configuration, and other preset configurations. */
+
wmKeyConfig *WM_keyconfig_new(wmWindowManager *wm, const char *idname)
{
wmKeyConfig *keyconf;
@@ -106,6 +191,7 @@ void WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf)
if (keyconf) {
if (strncmp(U.keyconfigstr, keyconf->idname, sizeof(U.keyconfigstr)) == 0) {
BLI_strncpy(U.keyconfigstr, wm->defaultconf->idname, sizeof(U.keyconfigstr));
+ WM_keyconfig_update_tag(NULL, NULL);
}
BLI_remlink(&wm->keyconfigs, keyconf);
@@ -125,21 +211,6 @@ void WM_keyconfig_free(wmKeyConfig *keyconf)
MEM_freeN(keyconf);
}
-void WM_keyconfig_userdef(void)
-{
- wmKeyMap *km;
- wmKeyMapItem *kmi;
-
- for(km=U.keymaps.first; km; km=km->next) {
- /* modal keymaps don't have operator properties */
- if ((km->flag & KEYMAP_MODAL) == 0) {
- for(kmi=km->items.first; kmi; kmi=kmi->next) {
- keymap_properties_set(kmi);
- }
- }
- }
-}
-
static wmKeyConfig *wm_keyconfig_list_find(ListBase *lb, char *idname)
{
wmKeyConfig *kc;
@@ -151,23 +222,84 @@ static wmKeyConfig *wm_keyconfig_list_find(ListBase *lb, char *idname)
return NULL;
}
-/* ************************ free ************************* */
+wmKeyConfig *WM_keyconfig_active(wmWindowManager *wm)
+{
+ wmKeyConfig *keyconf;
-void WM_keymap_free(wmKeyMap *keymap)
+ /* first try from preset */
+ keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr);
+ if(keyconf)
+ return keyconf;
+
+ /* otherwise use default */
+ return wm->defaultconf;
+}
+
+void WM_keyconfig_set_active(wmWindowManager *wm, const char *idname)
{
- wmKeyMapItem *kmi;
+ /* setting a different key configuration as active: we ensure all is
+ updated properly before and after making the change */
+
+ WM_keyconfig_update(wm);
+
+ BLI_strncpy(U.keyconfigstr, idname, sizeof(U.keyconfigstr));
+
+ WM_keyconfig_update_tag(NULL, NULL);
+ WM_keyconfig_update(wm);
+}
+
+/********************************** Keymap *************************************
+ * List of keymap items for one editor, mode, modal operator, ... */
+
+static wmKeyMap *wm_keymap_new(const char *idname, int spaceid, int regionid)
+{
+ wmKeyMap *km= MEM_callocN(sizeof(struct wmKeyMap), "keymap list");
+
+ BLI_strncpy(km->idname, idname, KMAP_MAX_NAME);
+ km->spaceid= spaceid;
+ km->regionid= regionid;
+
+ return km;
+}
+
+static wmKeyMap *wm_keymap_copy(wmKeyMap *keymap)
+{
+ wmKeyMap *keymapn = MEM_dupallocN(keymap);
+ wmKeyMapItem *kmi, *kmin;
+ wmKeyMapDiffItem *kmdi, *kmdin;
+
+ keymapn->modal_items= keymap->modal_items;
+ keymapn->poll= keymap->poll;
+ keymapn->items.first= keymapn->items.last= NULL;
+ keymapn->flag &= ~(KEYMAP_UPDATE|KEYMAP_EXPANDED);
+
+ for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) {
+ kmdin= wm_keymap_diff_item_copy(kmdi);
+ BLI_addtail(&keymapn->items, kmdin);
+ }
for(kmi=keymap->items.first; kmi; kmi=kmi->next) {
- if(kmi->ptr) {
- WM_operator_properties_free(kmi->ptr);
- MEM_freeN(kmi->ptr);
- }
+ kmin= wm_keymap_item_copy(kmi);
+ BLI_addtail(&keymapn->items, kmin);
}
- BLI_freelistN(&keymap->items);
+ return keymapn;
}
-/* ***************** generic call, exported **************** */
+void WM_keymap_free(wmKeyMap *keymap)
+{
+ wmKeyMapItem *kmi;
+ wmKeyMapDiffItem *kmdi;
+
+ for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next)
+ wm_keymap_diff_item_free(kmdi);
+
+ for(kmi=keymap->items.first; kmi; kmi=kmi->next)
+ wm_keymap_item_free(kmi);
+
+ BLI_freelistN(&keymap->diff_items);
+ BLI_freelistN(&keymap->items);
+}
static void keymap_event_set(wmKeyMapItem *kmi, short type, short val, int modifier, short keymodifier)
{
@@ -229,7 +361,7 @@ wmKeyMapItem *WM_keymap_verify_item(wmKeyMap *keymap, const char *idname, int ty
keymap_item_set_id(keymap, kmi);
keymap_event_set(kmi, type, val, modifier, keymodifier);
- keymap_properties_set(kmi);
+ wm_keymap_item_properties_set(kmi);
}
return kmi;
}
@@ -243,10 +375,12 @@ wmKeyMapItem *WM_keymap_add_item(wmKeyMap *keymap, const char *idname, int type,
BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME);
keymap_event_set(kmi, type, val, modifier, keymodifier);
- keymap_properties_set(kmi);
+ wm_keymap_item_properties_set(kmi);
keymap_item_set_id(keymap, kmi);
+ WM_keyconfig_update_tag(keymap, kmi);
+
return kmi;
}
@@ -266,6 +400,232 @@ void WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi)
MEM_freeN(kmi->ptr);
}
BLI_freelinkN(&keymap->items, kmi);
+
+ WM_keyconfig_update_tag(keymap, kmi);
+ }
+}
+
+/************************** Keymap Diff and Patch ****************************
+ * Rather than saving the entire keymap for user preferences, we only save a
+ * diff so that changes in the defaults get synced. This system is not perfect
+ * but works better than overriding the keymap entirely when only few items
+ * are changed. */
+
+static void wm_keymap_addon_add(wmKeyMap *keymap, wmKeyMap *addonmap)
+{
+ wmKeyMapItem *kmi, *kmin;
+
+ for(kmi=addonmap->items.first; kmi; kmi=kmi->next) {
+ kmin = wm_keymap_item_copy(kmi);
+ keymap_item_set_id(keymap, kmin);
+ BLI_addhead(&keymap->items, kmin);
+ }
+}
+
+static wmKeyMapItem *wm_keymap_find_item_equals(wmKeyMap *km, wmKeyMapItem *needle)
+{
+ wmKeyMapItem *kmi;
+
+ for(kmi=km->items.first; kmi; kmi=kmi->next)
+ if(wm_keymap_item_equals(kmi, needle))
+ return kmi;
+
+ return NULL;
+}
+
+static wmKeyMapItem *wm_keymap_find_item_equals_result(wmKeyMap *km, wmKeyMapItem *needle)
+{
+ wmKeyMapItem *kmi;
+
+ for(kmi=km->items.first; kmi; kmi=kmi->next)
+ if(wm_keymap_item_equals_result(kmi, needle))
+ return kmi;
+
+ return NULL;
+}
+
+static void wm_keymap_diff(wmKeyMap *diff_km, wmKeyMap *from_km, wmKeyMap *to_km, wmKeyMap *orig_km, wmKeyMap *addon_km)
+{
+ wmKeyMapItem *kmi, *to_kmi, *orig_kmi;
+ wmKeyMapDiffItem *kmdi;
+
+ for(kmi=from_km->items.first; kmi; kmi=kmi->next) {
+ to_kmi = WM_keymap_item_find_id(to_km, kmi->id);
+
+ if(!to_kmi) {
+ /* remove item */
+ kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
+ kmdi->remove_item = wm_keymap_item_copy(kmi);
+ BLI_addtail(&diff_km->diff_items, kmdi);
+ }
+ else if(to_kmi && !wm_keymap_item_equals(kmi, to_kmi)) {
+ /* replace item */
+ kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
+ kmdi->remove_item = wm_keymap_item_copy(kmi);
+ kmdi->add_item = wm_keymap_item_copy(to_kmi);
+ BLI_addtail(&diff_km->diff_items, kmdi);
+ }
+
+ /* sync expanded flag back to original so we don't loose it on repatch */
+ if(to_kmi) {
+ orig_kmi = WM_keymap_item_find_id(orig_km, kmi->id);
+
+ if(!orig_kmi)
+ orig_kmi = wm_keymap_find_item_equals(addon_km, kmi);
+
+ if(orig_kmi) {
+ orig_kmi->flag &= ~KMI_EXPANDED;
+ orig_kmi->flag |= (to_kmi->flag & KMI_EXPANDED);
+ }
+ }
+ }
+
+ for(kmi=to_km->items.first; kmi; kmi=kmi->next) {
+ if(kmi->id < 0) {
+ /* add item */
+ kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
+ kmdi->add_item = wm_keymap_item_copy(kmi);
+ BLI_addtail(&diff_km->diff_items, kmdi);
+ }
+ }
+}
+
+static void wm_keymap_patch(wmKeyMap *km, wmKeyMap *diff_km)
+{
+ wmKeyMapDiffItem *kmdi;
+ wmKeyMapItem *kmi_remove, *kmi_add;
+
+ for(kmdi=diff_km->diff_items.first; kmdi; kmdi=kmdi->next) {
+ /* find item to remove */
+ kmi_remove = NULL;
+ if(kmdi->remove_item) {
+ kmi_remove = wm_keymap_find_item_equals(km, kmdi->remove_item);
+ if(!kmi_remove)
+ kmi_remove = wm_keymap_find_item_equals_result(km, kmdi->remove_item);
+ }
+
+ /* add item */
+ if(kmdi->add_item) {
+ /* only if nothing to remove or item to remove found */
+ if(!kmdi->remove_item || kmi_remove) {
+ kmi_add = wm_keymap_item_copy(kmdi->add_item);
+ kmi_add->flag |= KMI_USER_MODIFIED;
+
+ if(kmi_remove) {
+ kmi_add->flag &= ~KMI_EXPANDED;
+ kmi_add->flag |= (kmi_remove->flag & KMI_EXPANDED);
+ kmi_add->id = kmi_remove->id;
+ BLI_insertlinkbefore(&km->items, kmi_remove, kmi_add);
+ }
+ else {
+ keymap_item_set_id(km, kmi_add);
+ BLI_addtail(&km->items, kmi_add);
+ }
+ }
+ }
+
+ /* remove item */
+ if(kmi_remove) {
+ wm_keymap_item_free(kmi_remove);
+ BLI_freelinkN(&km->items, kmi_remove);
+ }
+ }
+}
+
+static void wm_keymap_patch_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *usermap)
+{
+ wmKeyMap *km;
+ int expanded = 0;
+
+ /* remove previous keymap in list, we will replace it */
+ km = WM_keymap_list_find(lb, defaultmap->idname, defaultmap->spaceid, defaultmap->regionid);
+ if(km) {
+ expanded = (km->flag & (KEYMAP_EXPANDED|KEYMAP_CHILDREN_EXPANDED));
+ WM_keymap_free(km);
+ BLI_freelinkN(lb, km);
+ }
+
+ /* copy new keymap from an existing one */
+ if(usermap && !(usermap->flag & KEYMAP_DIFF)) {
+ /* for compatibiltiy with old user preferences with non-diff
+ keymaps we override the original entirely */
+ wmKeyMapItem *kmi, *orig_kmi;
+
+ km = wm_keymap_copy(usermap);
+ km->modal_items = defaultmap->modal_items;
+ km->poll = defaultmap->poll;
+
+ /* try to find corresponding id's for items */
+ for(kmi=km->items.first; kmi; kmi=kmi->next) {
+ orig_kmi = wm_keymap_find_item_equals(defaultmap, kmi);
+ if(!orig_kmi)
+ orig_kmi = wm_keymap_find_item_equals_result(defaultmap, kmi);
+
+ if(orig_kmi)
+ kmi->id = orig_kmi->id;
+ else
+ kmi->id = -(km->kmi_id++);
+ }
+
+ km->flag |= KEYMAP_UPDATE; /* update again to create diff */
+ }
+ else
+ km = wm_keymap_copy(defaultmap);
+
+ /* add addon keymap items */
+ if(addonmap)
+ wm_keymap_addon_add(km, addonmap);
+
+ /* tag as being user edited */
+ if(usermap)
+ km->flag |= KEYMAP_USER_MODIFIED;
+ km->flag |= KEYMAP_USER|expanded;
+
+ /* apply user changes of diff keymap */
+ if(usermap && (usermap->flag & KEYMAP_DIFF))
+ wm_keymap_patch(km, usermap);
+
+ /* add to list */
+ BLI_addtail(lb, km);
+}
+
+static void wm_keymap_diff_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *km)
+{
+ wmKeyMap *diffmap, *prevmap, *origmap;
+
+ /* create temporary default + addon keymap for diff */
+ origmap = defaultmap;
+
+ if(addonmap) {
+ defaultmap = wm_keymap_copy(defaultmap);
+ wm_keymap_addon_add(defaultmap, addonmap);
+ }
+
+ /* remove previous diff keymap in list, we will replace it */
+ prevmap = WM_keymap_list_find(lb, km->idname, km->spaceid, km->regionid);
+ if(prevmap) {
+ WM_keymap_free(prevmap);
+ BLI_freelinkN(lb, prevmap);
+ }
+
+ /* create diff keymap */
+ diffmap= wm_keymap_new(km->idname, km->spaceid, km->regionid);
+ diffmap->flag |= KEYMAP_DIFF;
+ wm_keymap_diff(diffmap, defaultmap, km, origmap, addonmap);
+
+ /* add to list if not empty */
+ if(diffmap->diff_items.first) {
+ BLI_addtail(lb, diffmap);
+ }
+ else {
+ WM_keymap_free(diffmap);
+ MEM_freeN(diffmap);
+ }
+
+ /* free temporary default map */
+ if(addonmap) {
+ WM_keymap_free(defaultmap);
+ MEM_freeN(defaultmap);
}
}
@@ -292,11 +652,10 @@ wmKeyMap *WM_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid,
wmKeyMap *km= WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid);
if(km==NULL) {
- km= MEM_callocN(sizeof(struct wmKeyMap), "keymap list");
- BLI_strncpy(km->idname, idname, KMAP_MAX_NAME);
- km->spaceid= spaceid;
- km->regionid= regionid;
+ km= wm_keymap_new(idname, spaceid, regionid);
BLI_addtail(&keyconf->keymaps, km);
+
+ WM_keyconfig_update_tag(km, NULL);
}
return km;
@@ -304,29 +663,9 @@ wmKeyMap *WM_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid,
wmKeyMap *WM_keymap_find_all(const bContext *C, const char *idname, int spaceid, int regionid)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- wmKeyConfig *keyconf;
- wmKeyMap *km;
-
- /* first user defined keymaps */
- km= WM_keymap_list_find(&U.keymaps, idname, spaceid, regionid);
- if (km)
- return km;
-
- /* then user key config */
- keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr);
- if(keyconf) {
- km= WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid);
- if (km)
- return km;
- }
-
- /* then use default */
- km= WM_keymap_list_find(&wm->defaultconf->keymaps, idname, spaceid, regionid);
- if (km)
- return km;
- else
- return NULL;
+ wmWindowManager *wm= CTX_wm_manager(C);
+
+ return WM_keymap_list_find(&wm->userconf->keymaps, idname, spaceid, regionid);
}
/* ****************** modal keymaps ************ */
@@ -366,6 +705,8 @@ wmKeyMapItem *WM_modalkeymap_add_item(wmKeyMap *km, int type, int val, int modif
keymap_item_set_id(km, kmi);
+ WM_keyconfig_update_tag(km, kmi);
+
return kmi;
}
@@ -588,169 +929,209 @@ int WM_keymap_item_compare(wmKeyMapItem *k1, wmKeyMapItem *k2)
return 1;
}
-/* ***************** user preferences ******************* */
+/************************* Update Final Configuration *************************
+ * On load or other changes, the final user key configuration is rebuilt from
+ * the preset, addon and user preferences keymaps. We also test if the final
+ * configuration changed and write the changes to the user preferences. */
+
+static int WM_KEYMAP_UPDATE = 0;
-int WM_keymap_user_init(wmWindowManager *wm, wmKeyMap *keymap)
+void WM_keyconfig_update_tag(wmKeyMap *km, wmKeyMapItem *kmi)
{
- wmKeyConfig *keyconf;
- wmKeyMap *km;
+ /* quick tag to do delayed keymap updates */
+ WM_KEYMAP_UPDATE= 1;
- if(!keymap)
- return 0;
+ if(km)
+ km->flag |= KEYMAP_UPDATE;
+ if(kmi)
+ kmi->flag |= KMI_UPDATE;
+}
- /* init from user key config */
- keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr);
- if(keyconf) {
- km= WM_keymap_list_find(&keyconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
- if(km) {
- keymap->poll= km->poll; /* lazy init */
- keymap->modal_items= km->modal_items;
- return 1;
- }
- }
+static int wm_keymap_test_and_clear_update(wmKeyMap *km)
+{
+ wmKeyMapItem *kmi;
+ int update;
+
+ update= (km->flag & KEYMAP_UPDATE);
+ km->flag &= ~KEYMAP_UPDATE;
- /* or from default */
- km= WM_keymap_list_find(&wm->defaultconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
- if(km) {
- keymap->poll= km->poll; /* lazy init */
- keymap->modal_items= km->modal_items;
- return 1;
+ for(kmi=km->items.first; kmi; kmi=kmi->next) {
+ update= update || (kmi->flag & KMI_UPDATE);
+ kmi->flag &= ~KMI_UPDATE;
}
-
- return 0;
+
+ return update;
}
-wmKeyMap *WM_keymap_active(wmWindowManager *wm, wmKeyMap *keymap)
+static wmKeyMap *wm_keymap_preset(wmWindowManager *wm, wmKeyMap *km)
{
- wmKeyConfig *keyconf;
- wmKeyMap *km;
+ wmKeyConfig *keyconf= WM_keyconfig_active(wm);
+ wmKeyMap *keymap;
+ keymap= WM_keymap_list_find(&keyconf->keymaps, km->idname, km->spaceid, km->regionid);
if(!keymap)
- return NULL;
-
- /* first user defined keymaps */
- km= WM_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
- if(km) {
- km->poll= keymap->poll; /* lazy init */
- km->modal_items= keymap->modal_items;
- return km;
- }
-
- /* then user key config */
- keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr);
- if(keyconf) {
- km= WM_keymap_list_find(&keyconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
- if(km) {
- km->poll= keymap->poll; /* lazy init */
- km->modal_items= keymap->modal_items;
- return km;
- }
- }
+ keymap= WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, km->spaceid, km->regionid);
- /* then use default */
- km= WM_keymap_list_find(&wm->defaultconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
- return km;
+ return keymap;
}
-wmKeyMap *WM_keymap_copy_to_user(wmKeyMap *keymap)
+void WM_keyconfig_update(wmWindowManager *wm)
{
- wmKeyMap *usermap;
+ wmKeyMap *km, *defaultmap, *addonmap, *usermap;
wmKeyMapItem *kmi;
+ wmKeyMapDiffItem *kmdi;
+ int compat_update = 0;
- usermap= WM_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
-
- /* XXX this function is only used by RMB setting hotkeys, and it clears maps on 2nd try this way */
- if(keymap==usermap)
- return keymap;
+ if(!WM_KEYMAP_UPDATE)
+ return;
- if(!usermap) {
- /* not saved yet, duplicate existing */
- usermap= MEM_dupallocN(keymap);
- usermap->modal_items= NULL;
- usermap->poll= NULL;
- usermap->flag |= KEYMAP_USER;
+ /* update operator properties for non-modal user keymaps */
+ for(km=U.user_keymaps.first; km; km=km->next) {
+ if((km->flag & KEYMAP_MODAL) == 0) {
+ for(kmdi=km->diff_items.first; kmdi; kmdi=kmdi->next) {
+ if(kmdi->add_item)
+ wm_keymap_item_properties_set(kmdi->add_item);
+ if(kmdi->remove_item)
+ wm_keymap_item_properties_set(kmdi->remove_item);
+ }
- BLI_addtail(&U.keymaps, usermap);
+ for(kmi=km->items.first; kmi; kmi=kmi->next)
+ wm_keymap_item_properties_set(kmi);
+ }
}
- else {
- /* already saved, free items for re-copy */
- WM_keymap_free(usermap);
+
+ /* update U.user_keymaps with user key configuration changes */
+ for(km=wm->userconf->keymaps.first; km; km=km->next) {
+ /* only diff if the user keymap was modified */
+ if(wm_keymap_test_and_clear_update(km)) {
+ /* find keymaps */
+ defaultmap= wm_keymap_preset(wm, km);
+ addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid);
+
+ /* diff */
+ wm_keymap_diff_update(&U.user_keymaps, defaultmap, addonmap, km);
+ }
}
- BLI_duplicatelist(&usermap->items, &keymap->items);
+ /* create user key configuration from preset + addon + user preferences */
+ for(km=wm->defaultconf->keymaps.first; km; km=km->next) {
+ /* find keymaps */
+ defaultmap= wm_keymap_preset(wm, km);
+ addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid);
+ usermap= WM_keymap_list_find(&U.user_keymaps, km->idname, km->spaceid, km->regionid);
- for(kmi=usermap->items.first; kmi; kmi=kmi->next) {
- if(kmi->properties) {
- kmi->ptr= MEM_callocN(sizeof(PointerRNA), "UserKeyMapItemPtr");
- WM_operator_properties_create(kmi->ptr, kmi->idname);
+ /* add */
+ wm_keymap_patch_update(&wm->userconf->keymaps, defaultmap, addonmap, usermap);
- kmi->properties= IDP_CopyProperty(kmi->properties);
- kmi->ptr->data= kmi->properties;
- }
+ /* in case of old non-diff keymaps, force extra update to create diffs */
+ compat_update = compat_update || (usermap && !(usermap->flag & KEYMAP_DIFF));
}
- for(kmi=keymap->items.first; kmi; kmi=kmi->next)
- kmi->flag &= ~KMI_EXPANDED;
+ WM_KEYMAP_UPDATE= 0;
+
+ if(compat_update) {
+ WM_keyconfig_update_tag(NULL, NULL);
+ WM_keyconfig_update(wm);
+ }
+}
+
+/********************************* Event Handling *****************************
+ * Handlers have pointers to the keymap in the default configuration. During
+ * event handling this function is called to get the keymap from the final
+ * configuration. */
+
+wmKeyMap *WM_keymap_active(wmWindowManager *wm, wmKeyMap *keymap)
+{
+ wmKeyMap *km;
+
+ if(!keymap)
+ return NULL;
+
+ /* first user defined keymaps */
+ km= WM_keymap_list_find(&wm->userconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
+
+ if(km)
+ return km;
- return usermap;
+ return keymap;
}
+/******************************* Keymap Editor ********************************
+ * In the keymap editor the user key configuration is edited. */
+
void WM_keymap_restore_item_to_default(bContext *C, wmKeyMap *keymap, wmKeyMapItem *kmi)
{
wmWindowManager *wm = CTX_wm_manager(C);
- wmKeyConfig *keyconf;
- wmKeyMap *km = NULL;
+ wmKeyMap *defaultmap, *addonmap;
+ wmKeyMapItem *orig;
- /* look in user key config */
- keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr);
- if(keyconf) {
- km= WM_keymap_list_find(&keyconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
- }
+ if(!keymap)
+ return;
+
+ /* construct default keymap from preset + addons */
+ defaultmap= wm_keymap_preset(wm, keymap);
+ addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
- if (!km) {
- /* or from default */
- km= WM_keymap_list_find(&wm->defaultconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
+ if(addonmap) {
+ defaultmap = wm_keymap_copy(defaultmap);
+ wm_keymap_addon_add(defaultmap, addonmap);
}
- if (km) {
- wmKeyMapItem *orig = WM_keymap_item_find_id(km, kmi->id);
+ /* find original item */
+ orig = WM_keymap_item_find_id(defaultmap, kmi->id);
- if (orig) {
- if(strcmp(orig->idname, kmi->idname) != 0) {
- BLI_strncpy(kmi->idname, orig->idname, sizeof(kmi->idname));
+ if(orig) {
+ /* restore to original */
+ if(strcmp(orig->idname, kmi->idname) != 0) {
+ BLI_strncpy(kmi->idname, orig->idname, sizeof(kmi->idname));
+ WM_keymap_properties_reset(kmi, NULL);
+ }
- WM_keymap_properties_reset(kmi, NULL);
- }
-
- if (orig->properties) {
- kmi->properties= IDP_CopyProperty(orig->properties);
- kmi->ptr->data= kmi->properties;
+ if (orig->properties) {
+ if(kmi->properties) {
+ IDP_FreeProperty(kmi->properties);
+ MEM_freeN(kmi->properties);
+ kmi->properties= NULL;
}
- kmi->propvalue = orig->propvalue;
- kmi->type = orig->type;
- kmi->val = orig->val;
- kmi->shift = orig->shift;
- kmi->ctrl = orig->ctrl;
- kmi->alt = orig->alt;
- kmi->oskey = orig->oskey;
- kmi->keymodifier = orig->keymodifier;
- kmi->maptype = orig->maptype;
-
+ kmi->properties= IDP_CopyProperty(orig->properties);
+ kmi->ptr->data= kmi->properties;
}
+ kmi->propvalue = orig->propvalue;
+ kmi->type = orig->type;
+ kmi->val = orig->val;
+ kmi->shift = orig->shift;
+ kmi->ctrl = orig->ctrl;
+ kmi->alt = orig->alt;
+ kmi->oskey = orig->oskey;
+ kmi->keymodifier = orig->keymodifier;
+ kmi->maptype = orig->maptype;
+
+ WM_keyconfig_update_tag(keymap, kmi);
+ }
+
+ /* free temporary keymap */
+ if(addonmap) {
+ WM_keymap_free(defaultmap);
+ MEM_freeN(defaultmap);
}
}
-void WM_keymap_restore_to_default(wmKeyMap *keymap)
+void WM_keymap_restore_to_default(wmKeyMap *keymap, bContext *C)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
wmKeyMap *usermap;
- usermap= WM_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
+ /* remove keymap from U.user_keymaps and update */
+ usermap= WM_keymap_list_find(&U.user_keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
if(usermap) {
WM_keymap_free(usermap);
- BLI_freelinkN(&U.keymaps, usermap);
+ BLI_freelinkN(&U.user_keymaps, usermap);
+
+ WM_keyconfig_update_tag(NULL, NULL);
+ WM_keyconfig_update(wm);
}
}
@@ -951,3 +1332,4 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
return km;
}
+
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 548d272ffd2..983d4ecf5f8 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -208,10 +208,12 @@ struct wmKeyMap *WM_keymap_list_find(struct ListBase *lb, char *idname, int spac
struct wmKeyConfig *WM_keyconfig_new(struct wmWindowManager *wm, char *idname){return (struct wmKeyConfig *) NULL;}
struct wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, char *idname){return (struct wmKeyConfig *) NULL;}
void WM_keyconfig_remove(struct wmWindowManager *wm, char *idname){}
+void WM_keyconfig_set_active(struct wmWindowManager *wm, const char *idname) {}
void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi){}
void WM_keymap_restore_to_default(struct wmKeyMap *keymap){}
void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi){}
void WM_keymap_properties_reset(struct wmKeyMapItem *kmi){}
+void WM_keyconfig_update_tag(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi) {}
int WM_keymap_user_init(struct wmWindowManager *wm, struct wmKeyMap *keymap) {return 0;}
int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2){return 0;}