예제 #1
0
static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
{
	wmOperatorType *ot;
	PointerRNA ptr;
	const char *opname = _PyUnicode_AsString(value);
	BPy_StructRNA *pyrna = NULL;
	
	if (opname == NULL) {
		PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_rna() expects a string argument");
		return NULL;
	}
	ot = WM_operatortype_find(opname, true);
	if (ot == NULL) {
		PyErr_Format(PyExc_KeyError, "_bpy.ops.get_rna(\"%s\") not found", opname);
		return NULL;
	}
	
	/* type */
	//RNA_pointer_create(NULL, &RNA_Struct, ot->srna, &ptr);

	/* XXX - should call WM_operator_properties_free */
	WM_operator_properties_create_ptr(&ptr, ot);
	WM_operator_properties_sanitize(&ptr, 0);

	
	pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
#ifdef PYRNA_FREE_SUPPORT
	pyrna->freeptr = true;
#endif
	return (PyObject *)pyrna;
}
예제 #2
0
static wmKeyMapItem *wm_keymap_item_find(
        const bContext *C, const char *opname, int opcontext,
        IDProperty *properties, const short hotkey, const bool strict, wmKeyMap **keymap_r)
{
	wmKeyMapItem *found = wm_keymap_item_find_props(C, opname, opcontext, properties, strict, hotkey, keymap_r);

	if (!found && properties) {
		wmOperatorType *ot = WM_operatortype_find(opname, TRUE);
		if (ot) {
			/* make a copy of the properties and set any unset props
			 * to their default values, so the ID property compare function succeeds */
			PointerRNA opptr;
			IDProperty *properties_default = IDP_CopyProperty(properties);

			RNA_pointer_create(NULL, ot->srna, properties_default, &opptr);

			if (WM_operator_properties_default(&opptr, true) ||
			    (!strict && ot->prop && RNA_property_is_set(&opptr, ot->prop)))
			{
				/* for operator that has enum menu, unset it so it always matches */
				if (!strict && ot->prop) {
					RNA_property_unset(&opptr, ot->prop);
				}

				found = wm_keymap_item_find_props(C, opname, opcontext, properties_default, false, hotkey, keymap_r);
			}

			IDP_FreeProperty(properties_default);
			MEM_freeN(properties_default);
		}
	}

	return found;
}
예제 #3
0
static PointerRNA rna_uiItemO(
        uiLayout *layout, const char *opname, const char *name, const char *text_ctxt,
        bool translate, int icon, bool emboss, bool depress, int icon_value)
{
	wmOperatorType *ot;

	ot = WM_operatortype_find(opname, 0); /* print error next */
	if (!ot || !ot->srna) {
		RNA_warning("%s '%s'", ot ? "unknown operator" : "operator missing srna", opname);
		return PointerRNA_NULL;
	}

	/* Get translated name (label). */
	name = rna_translate_ui_text(name, text_ctxt, ot->srna, NULL, translate);

	if (icon_value && !icon) {
		icon = icon_value;
	}
	int flag = (emboss) ? 0 : UI_ITEM_R_NO_BG;
	flag |= (depress) ? UI_ITEM_O_DEPRESS : 0;

	PointerRNA opptr;
	uiItemFullO_ptr(layout, ot, name, icon, NULL, uiLayoutGetOperatorContext(layout), flag, &opptr);
	return opptr;
}
예제 #4
0
static void poselib_add_menu_invoke__replacemenu (bContext *C, uiLayout *layout, void *UNUSED(arg))
{
	Object *ob= get_poselib_object(C);
	bAction *act= ob->poselib; /* never NULL */
	TimeMarker *marker;
	
	wmOperatorType *ot = WM_operatortype_find("POSELIB_OT_pose_add", 1);

	BLI_assert(ot != NULL);

	/* set the operator execution context correctly */
	uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
	
	/* add each marker to this menu */
	for (marker= act->markers.first; marker; marker= marker->next) {
		PointerRNA props_ptr;
		
		props_ptr = uiItemFullO_ptr(layout, ot,
		                            marker->name, ICON_ARMATURE_DATA, NULL,
		                            WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
		
		RNA_int_set(&props_ptr, "frame", marker->frame);
		RNA_string_set(&props_ptr, "name", marker->name);
	}
}
예제 #5
0
static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args)
{
	wmOperatorType *ot;
	PointerRNA ptr;

	char     *opname;
	PyObject *kw = NULL; /* optional args */
	int all_args = 1;
	int macro_args = 1;
	int error_val = 0;

	char *buf = NULL;
	PyObject *pybuf;

	bContext *C = (bContext *)BPy_GetContext();

	if (C == NULL) {
		PyErr_SetString(PyExc_RuntimeError, "Context is None, cant get the string representation of this object.");
		return NULL;
	}
	
	if (!PyArg_ParseTuple(args, "s|O!ii:_bpy.ops.as_string", &opname, &PyDict_Type, &kw, &all_args, &macro_args))
		return NULL;

	ot = WM_operatortype_find(opname, true);

	if (ot == NULL) {
		PyErr_Format(PyExc_AttributeError,
		             "_bpy.ops.as_string: operator \"%.200s\" "
		             "could not be found", opname);
		return NULL;
	}

	/* WM_operator_properties_create(&ptr, opname); */
	/* Save another lookup */
	RNA_pointer_create(NULL, ot->srna, NULL, &ptr);

	if (kw && PyDict_Size(kw))
		error_val = pyrna_pydict_to_props(&ptr, kw, 0, "Converting py args to operator properties: ");

	if (error_val == 0)
		buf = WM_operator_pystring_ex(C, NULL, all_args, macro_args, ot, &ptr);

	WM_operator_properties_free(&ptr);

	if (error_val == -1) {
		return NULL;
	}

	if (buf) {
		pybuf = PyUnicode_FromString(buf);
		MEM_freeN(buf);
	}
	else {
		pybuf = PyUnicode_FromString("");
	}

	return pybuf;
}
예제 #6
0
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;
}
예제 #7
0
void WM_modalkeymap_assign(wmKeyMap *km, const char *opname)
{
	wmOperatorType *ot= WM_operatortype_find(opname, 0);
	
	if(ot)
		ot->modalkeymap= km;
	else
		printf("error: modalkeymap_assign, unknown operator %s\n", opname);
}
예제 #8
0
static void workspace_add_menu(bContext *C, uiLayout *layout, void *template_v)
{
  Main *bmain = CTX_data_main(C);
  const char *app_template = template_v;
  bool has_startup_items = false;

  wmOperatorType *ot_append = WM_operatortype_find("WORKSPACE_OT_append_activate", true);
  WorkspaceConfigFileData *startup_config = workspace_config_file_read(app_template);
  WorkspaceConfigFileData *builtin_config = workspace_system_file_read(app_template);

  if (startup_config) {
    for (WorkSpace *workspace = startup_config->workspaces.first; workspace;
         workspace = workspace->id.next) {
      uiLayout *row = uiLayoutRow(layout, false);
      if (BLI_findstring(&bmain->workspaces, workspace->id.name, offsetof(ID, name))) {
        uiLayoutSetActive(row, false);
      }

      workspace_append_button(row, ot_append, workspace, startup_config->main);
      has_startup_items = true;
    }
  }

  if (builtin_config) {
    bool has_title = false;

    for (WorkSpace *workspace = builtin_config->workspaces.first; workspace;
         workspace = workspace->id.next) {
      if (startup_config &&
          BLI_findstring(&startup_config->workspaces, workspace->id.name, offsetof(ID, name))) {
        continue;
      }

      if (!has_title) {
        if (has_startup_items) {
          uiItemS(layout);
        }
        has_title = true;
      }

      uiLayout *row = uiLayoutRow(layout, false);
      if (BLI_findstring(&bmain->workspaces, workspace->id.name, offsetof(ID, name))) {
        uiLayoutSetActive(row, false);
      }

      workspace_append_button(row, ot_append, workspace, builtin_config->main);
    }
  }

  if (startup_config) {
    BKE_blendfile_workspace_config_data_free(startup_config);
  }
  if (builtin_config) {
    BKE_blendfile_workspace_config_data_free(builtin_config);
  }
}
예제 #9
0
static PointerRNA rna_WindoManager_operator_properties_last(const char *idname)
{
  wmOperatorType *ot = WM_operatortype_find(idname, true);

  if (ot != NULL) {
    PointerRNA ptr;
    WM_operator_last_properties_ensure(ot, &ptr);
    return ptr;
  }
  return PointerRNA_NULL;
}
예제 #10
0
static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
	int exit_code;

	TransInfo *t = op->customdata;
	const enum TfmMode mode_prev = t->mode;

#if 0
	// stable 2D mouse coords map to different 3D coords while the 3D mouse is active
	// in other words, 2D deltas are no longer good enough!
	// disable until individual 'transformers' behave better

	if (event->type == NDOF_MOTION)
		return OPERATOR_PASS_THROUGH;
#endif

	/* XXX insert keys are called here, and require context */
	t->context = C;
	exit_code = transformEvent(t, event);
	t->context = NULL;

	transformApply(C, t);

	exit_code |= transformEnd(C, t);

	if ((exit_code & OPERATOR_RUNNING_MODAL) == 0) {
		transformops_exit(C, op);
		exit_code &= ~OPERATOR_PASS_THROUGH; /* preventively remove passthrough */
	}
	else {
		if (mode_prev != t->mode) {
			/* WARNING: this is not normal to switch operator types
			 * normally it would not be supported but transform happens
			 * to share callbacks between differernt operators. */
			wmOperatorType *ot_new = NULL;
			TransformModeItem *item = transform_modes;
			while (item->idname) {
				if (item->mode == t->mode) {
					ot_new = WM_operatortype_find(item->idname, false);
					break;
				}
				item++;
			}

			BLI_assert(ot_new != NULL);
			if (ot_new) {
				WM_operator_type_set(op, ot_new);
			}
			/* end suspicious code */
		}
	}

	return exit_code;
}
예제 #11
0
PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args)
{
	wmOperatorType *ot;
	wmOperatorTypeMacro *otmacro;
	PyObject *macro;
	PointerRNA ptr_otmacro;
	StructRNA *srna;

	char *opname;
	const char *macroname;

	if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", &macro, &opname))
		return NULL;

	if (WM_operatortype_find(opname, TRUE) == NULL) {
		PyErr_Format(PyExc_ValueError,
		             "Macro Define: '%s' is not a valid operator id",
		             opname);
		return NULL;
	}

	/* identifiers */
	srna = srna_from_self(macro, "Macro Define:");
	macroname = RNA_struct_identifier(srna);

	ot = WM_operatortype_find(macroname, TRUE);

	if (!ot) {
		PyErr_Format(PyExc_ValueError,
		             "Macro Define: '%s' is not a valid macro or hasn't been registered yet",
		             macroname);
		return NULL;
	}

	otmacro = WM_operatortype_macro_define(ot, opname);

	RNA_pointer_create(NULL, &RNA_OperatorMacro, otmacro, &ptr_otmacro);

	return pyrna_struct_CreatePyObject(&ptr_otmacro);
}
예제 #12
0
static void rna_uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opname, const char *propname, const char *name,
                                const char *text_ctxt, int translate, int icon)
{
	wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */

	if (!ot || !ot->srna) {
		RNA_warning("%s '%s'", ot ? "unknown operator" : "operator missing srna", opname);
		return;
	}

	/* Get translated name (label). */
	name = rna_translate_ui_text(name, text_ctxt, ot->srna, NULL, translate);

	/* XXX This will search operator again :( */
	uiItemMenuEnumO(layout, C, opname, propname, name, icon);
}
예제 #13
0
static int workspace_append(bContext *C, const char *directory, const char *idname)
{
  wmOperatorType *ot = WM_operatortype_find("WM_OT_append", false);
  PointerRNA opptr;
  int retval;

  WM_operator_properties_create_ptr(&opptr, ot);
  RNA_string_set(&opptr, "directory", directory);
  RNA_string_set(&opptr, "filename", idname);
  RNA_boolean_set(&opptr, "autoselect", false);

  retval = WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &opptr);

  WM_operator_properties_free(&opptr);

  return retval;
}
예제 #14
0
static int add_driver_button_exec(bContext *C, wmOperator *op)
{
	short mapping_type = RNA_enum_get(op->ptr, "mapping_type");
	if (ELEM(mapping_type, CREATEDRIVER_MAPPING_NONE, CREATEDRIVER_MAPPING_NONE_ALL)) {
		/* Just create driver with no targets */
		return add_driver_button_none(C, op, mapping_type);
	}
	else {
		/* Create Driver using Eyedropper */
		wmOperatorType *ot = WM_operatortype_find("UI_OT_eyedropper_driver", true);
		
		/* XXX: We assume that it's fine to use the same set of properties, since they're actually the same... */
		WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, op->ptr);
		
		return OPERATOR_FINISHED;
	}
}
예제 #15
0
/**
 * Sets the mode to a compatible state (use before entering the mode).
 *
 * This is so each mode's exec function can call
 */
bool ED_object_mode_compat_set(bContext *C, Object *ob, eObjectMode mode, ReportList *reports)
{
	bool ok;
	if (!ELEM(ob->mode, mode, OB_MODE_OBJECT)) {
		const char *opstring = object_mode_op_string(ob->mode);
		WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL);
		ok = ELEM(ob->mode, mode, OB_MODE_OBJECT);
		if (!ok) {
			wmOperatorType *ot = WM_operatortype_find(opstring, false);
			BKE_reportf(reports, RPT_ERROR, "Unable to execute '%s', error changing modes", ot->name);
		}
	}
	else {
		ok = true;
	}

	return ok;
}
예제 #16
0
static PointerRNA rna_uiItemO(uiLayout *layout, const char *opname, const char *name, const char *text_ctxt,
                              int translate, int icon, int emboss)
{
	wmOperatorType *ot;
	int flag;

	ot = WM_operatortype_find(opname, 0); /* print error next */
	if (!ot || !ot->srna) {
		RNA_warning("%s '%s'", ot ? "unknown operator" : "operator missing srna", opname);
		return PointerRNA_NULL;
	}

	/* Get translated name (label). */
	name = rna_translate_ui_text(name, text_ctxt, ot->srna, NULL, translate);

	flag = UI_ITEM_O_RETURN_PROPS;
	flag |= (emboss) ? 0 : UI_ITEM_R_NO_BG;

	return uiItemFullO_ptr(layout, ot, name, icon, NULL, uiLayoutGetOperatorContext(layout), flag);
}
예제 #17
0
wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(bContext *, wmDrag *, wmEvent *),
						  void (*copy)(wmDrag *, wmDropBox *))
{
	wmDropBox *drop= MEM_callocN(sizeof(wmDropBox), "wmDropBox");
	
	drop->poll= poll;
	drop->copy= copy;
	drop->ot= WM_operatortype_find(idname, 0);
	drop->opcontext= WM_OP_INVOKE_DEFAULT;
	
	if(drop->ot==NULL) {
		MEM_freeN(drop);
		printf("Error: dropbox with unknown operator: %s\n", idname);
		return NULL;
	}
	WM_operator_properties_alloc(&(drop->ptr), &(drop->properties), idname);
	
	BLI_addtail(lb, drop);
	
	return drop;
}
예제 #18
0
static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value)
{
	wmOperatorType *ot;
	wmOperator *op;
	PointerRNA ptr;
	const char *opname = _PyUnicode_AsString(value);
	BPy_StructRNA *pyrna = NULL;

	if (opname == NULL) {
		PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_instance() expects a string argument");
		return NULL;
	}
	ot = WM_operatortype_find(opname, true);
	if (ot == NULL) {
		PyErr_Format(PyExc_KeyError, "_bpy.ops.get_instance(\"%s\") not found", opname);
		return NULL;
	}

#ifdef PYRNA_FREE_SUPPORT
	op = MEM_callocN(sizeof(wmOperator), __func__);
#else
	op = PyMem_MALLOC(sizeof(wmOperator));
	memset(op, 0, sizeof(wmOperator));
#endif
	BLI_strncpy(op->idname, op->idname, sizeof(op->idname)); /* in case its needed */
	op->type = ot;

	RNA_pointer_create(NULL, &RNA_Operator, op, &ptr);

	pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
#ifdef PYRNA_FREE_SUPPORT
	pyrna->freeptr = true;
#endif
	op->ptr = &pyrna->ptr;

	return (PyObject *)pyrna;
}
예제 #19
0
static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
	int exit_code;

	TransInfo *t = op->customdata;
	const enum TfmMode mode_prev = t->mode;

#if 0
	// stable 2D mouse coords map to different 3D coords while the 3D mouse is active
	// in other words, 2D deltas are no longer good enough!
	// disable until individual 'transformers' behave better

	if (event->type == NDOF_MOTION)
		return OPERATOR_PASS_THROUGH;
#endif

	/* XXX insert keys are called here, and require context */
	t->context = C;
	exit_code = transformEvent(t, event);
	t->context = NULL;

	/* XXX, workaround: active needs to be calculated before transforming,
	 * since we're not reading from 'td->center' in this case. see: T40241 */
	if (t->tsnap.target == SCE_SNAP_TARGET_ACTIVE) {
		/* In camera view, tsnap callback is not set (see initSnappingMode() in transfrom_snap.c, and T40348). */
		if (t->tsnap.targetSnap && ((t->tsnap.status & TARGET_INIT) == 0)) {
			t->tsnap.targetSnap(t);
		}
	}

	transformApply(C, t);

	exit_code |= transformEnd(C, t);

	if ((exit_code & OPERATOR_RUNNING_MODAL) == 0) {
		transformops_exit(C, op);
		exit_code &= ~OPERATOR_PASS_THROUGH; /* preventively remove passthrough */
	}
	else {
		if (mode_prev != t->mode) {
			/* WARNING: this is not normal to switch operator types
			 * normally it would not be supported but transform happens
			 * to share callbacks between different operators. */
			wmOperatorType *ot_new = NULL;
			TransformModeItem *item = transform_modes;
			while (item->idname) {
				if (item->mode == t->mode) {
					ot_new = WM_operatortype_find(item->idname, false);
					break;
				}
				item++;
			}

			BLI_assert(ot_new != NULL);
			if (ot_new) {
				WM_operator_type_set(op, ot_new);
			}
			/* end suspicious code */
		}
	}

	return exit_code;
}
예제 #20
0
static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
{
	wmOperatorType *ot;
	char     *opname;
	PyObject *context_dict = NULL; /* optional args */
	PyObject *context_dict_back;
	char     *context_str = NULL;
	PyObject *ret;

	int context = WM_OP_EXEC_DEFAULT;

	/* XXX Todo, work out a better solution for passing on context,
	 * could make a tuple from self and pack the name and Context into it... */
	bContext *C = (bContext *)BPy_GetContext();
	
	if (C == NULL) {
		PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators");
		return NULL;
	}

	if (!PyArg_ParseTuple(args, "s|Os:_bpy.ops.poll", &opname, &context_dict, &context_str))
		return NULL;
	
	ot = WM_operatortype_find(opname, true);

	if (ot == NULL) {
		PyErr_Format(PyExc_AttributeError,
		             "Polling operator \"bpy.ops.%s\" error, "
		             "could not be found", opname);
		return NULL;
	}

	if (context_str) {
		if (RNA_enum_value_from_id(operator_context_items, context_str, &context) == 0) {
			char *enum_str = BPy_enum_as_string(operator_context_items);
			PyErr_Format(PyExc_TypeError,
			             "Calling operator \"bpy.ops.%s.poll\" error, "
			             "expected a string enum in (%.200s)",
			             opname, enum_str);
			MEM_freeN(enum_str);
			return NULL;
		}
	}
	
	if (context_dict == NULL || context_dict == Py_None) {
		context_dict = NULL;
	}
	else if (!PyDict_Check(context_dict)) {
		PyErr_Format(PyExc_TypeError,
		             "Calling operator \"bpy.ops.%s.poll\" error, "
		             "custom context expected a dict or None, got a %.200s",
		             opname, Py_TYPE(context_dict)->tp_name);
		return NULL;
	}

	context_dict_back = CTX_py_dict_get(C);
	CTX_py_dict_set(C, (void *)context_dict);
	Py_XINCREF(context_dict); /* so we done loose it */
	
	/* main purpose of thsi function */
	ret = WM_operator_poll_context((bContext *)C, ot, context) ? Py_True : Py_False;
	
	/* restore with original context dict, probably NULL but need this for nested operator calls */
	Py_XDECREF(context_dict);
	CTX_py_dict_set(C, (void *)context_dict_back);
	
	Py_INCREF(ret);
	return ret;
}
예제 #21
0
static bool workspace_append_activate_poll(bContext *C)
{
  wmOperatorType *ot = WM_operatortype_find("WM_OT_append", false);
  return WM_operator_poll(C, ot);
}
예제 #22
0
/* mouse coordinate converversion happens here */
static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr)
{
    bContext *C = C_void_ptr;
    wmWindowManager *wm = CTX_wm_manager(C);
    GHOST_TEventType type = GHOST_GetEventType(evt);
    int time = GHOST_GetEventTime(evt);

    if (type == GHOST_kEventQuit) {
        WM_exit(C);
    }
    else {
        GHOST_WindowHandle ghostwin = GHOST_GetEventWindow(evt);
        GHOST_TEventDataPtr data = GHOST_GetEventData(evt);
        wmWindow *win;

        /* Ghost now can call this function for life resizes, but it should return if WM didn't initialize yet.
         * Can happen on file read (especially full size window)  */
        if ((wm->initialized & WM_INIT_WINDOW) == 0) {
            return 1;
        }
        if (!ghostwin) {
            /* XXX - should be checked, why are we getting an event here, and */
            /* what is it? */
            puts("<!> event has no window");
            return 1;
        }
        else if (!GHOST_ValidWindow(g_system, ghostwin)) {
            /* XXX - should be checked, why are we getting an event here, and */
            /* what is it? */
            puts("<!> event has invalid window");
            return 1;
        }
        else {
            win = GHOST_GetWindowUserData(ghostwin);
        }

        switch (type) {
        case GHOST_kEventWindowDeactivate:
            wm_event_add_ghostevent(wm, win, type, time, data);
            win->active = 0; /* XXX */

            /* clear modifiers for inactive windows */
            win->eventstate->alt = 0;
            win->eventstate->ctrl = 0;
            win->eventstate->shift = 0;
            win->eventstate->oskey = 0;
            win->eventstate->keymodifier = 0;

            break;
        case GHOST_kEventWindowActivate:
        {
            GHOST_TEventKeyData kdata;
            wmEvent event;
            int wx, wy;
            const int keymodifier = ((query_qual(SHIFT)     ? KM_SHIFT : 0) |
                                     (query_qual(CONTROL)   ? KM_CTRL  : 0) |
                                     (query_qual(ALT)       ? KM_ALT   : 0) |
                                     (query_qual(OS)        ? KM_OSKEY : 0));

            /* Win23/GHOST modifier bug, see T40317 */
#ifndef WIN32
//#  define USE_WIN_ACTIVATE
#endif

            wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */

            win->active = 1;
//				window_handle(win, INPUTCHANGE, win->active);

            /* bad ghost support for modifier keys... so on activate we set the modifiers again */

            /* TODO: This is not correct since a modifier may be held when a window is activated...
             * better solve this at ghost level. attempted fix r54450 but it caused bug [#34255]
             *
             * For now don't send GHOST_kEventKeyDown events, just set the 'eventstate'.
             */
            kdata.ascii = '\0';
            kdata.utf8_buf[0] = '\0';

            if (win->eventstate->shift) {
                if ((keymodifier & KM_SHIFT) == 0) {
                    kdata.key = GHOST_kKeyLeftShift;
                    wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
                }
            }
#ifdef USE_WIN_ACTIVATE
            else {
                if (keymodifier & KM_SHIFT) {
                    win->eventstate->shift = KM_MOD_FIRST;
                }
            }
#endif
            if (win->eventstate->ctrl) {
                if ((keymodifier & KM_CTRL) == 0) {
                    kdata.key = GHOST_kKeyLeftControl;
                    wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
                }
            }
#ifdef USE_WIN_ACTIVATE
            else {
                if (keymodifier & KM_CTRL) {
                    win->eventstate->ctrl = KM_MOD_FIRST;
                }
            }
#endif
            if (win->eventstate->alt) {
                if ((keymodifier & KM_ALT) == 0) {
                    kdata.key = GHOST_kKeyLeftAlt;
                    wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
                }
            }
#ifdef USE_WIN_ACTIVATE
            else {
                if (keymodifier & KM_ALT) {
                    win->eventstate->alt = KM_MOD_FIRST;
                }
            }
#endif
            if (win->eventstate->oskey) {
                if ((keymodifier & KM_OSKEY) == 0) {
                    kdata.key = GHOST_kKeyOS;
                    wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata);
                }
            }
#ifdef USE_WIN_ACTIVATE
            else {
                if (keymodifier & KM_OSKEY) {
                    win->eventstate->oskey = KM_MOD_FIRST;
                }
            }
#endif

#undef USE_WIN_ACTIVATE


            /* keymodifier zero, it hangs on hotkeys that open windows otherwise */
            win->eventstate->keymodifier = 0;

            /* entering window, update mouse pos. but no event */
            wm_get_cursor_position(win,  &wx, &wy);

            win->eventstate->x = wx;
            win->eventstate->y = wy;

            win->addmousemove = 1;   /* enables highlighted buttons */

            wm_window_make_drawable(wm, win);

            /* window might be focused by mouse click in configuration of window manager
             * when focus is not following mouse
             * click could have been done on a button and depending on window manager settings
             * click would be passed to blender or not, but in any case button under cursor
             * should be activated, so at max next click on button without moving mouse
             * would trigger it's handle function
             * currently it seems to be common practice to generate new event for, but probably
             * we'll need utility function for this? (sergey)
             */
            wm_event_init_from_window(win, &event);
            event.type = MOUSEMOVE;
            event.prevx = event.x;
            event.prevy = event.y;

            wm_event_add(win, &event);

            break;
        }
        case GHOST_kEventWindowClose:
        {
            wm_window_close(C, wm, win);
            break;
        }
        case GHOST_kEventWindowUpdate:
        {
            if (G.debug & G_DEBUG_EVENTS) {
                printf("%s: ghost redraw %d\n", __func__, win->winid);
            }

            wm_window_make_drawable(wm, win);
            WM_event_add_notifier(C, NC_WINDOW, NULL);

            break;
        }
        case GHOST_kEventWindowSize:
        case GHOST_kEventWindowMove:
        {
            GHOST_TWindowState state;
            state = GHOST_GetWindowState(win->ghostwin);
            win->windowstate = state;

            /* stop screencast if resize */
            if (type == GHOST_kEventWindowSize) {
                WM_jobs_stop(wm, win->screen, NULL);
            }

            /* win32: gives undefined window size when minimized */
            if (state != GHOST_kWindowStateMinimized) {
                GHOST_RectangleHandle client_rect;
                int l, t, r, b, scr_w, scr_h;
                int sizex, sizey, posx, posy;

                client_rect = GHOST_GetClientBounds(win->ghostwin);
                GHOST_GetRectangle(client_rect, &l, &t, &r, &b);

                GHOST_DisposeRectangle(client_rect);

                wm_get_desktopsize(&scr_w, &scr_h);
                sizex = r - l;
                sizey = b - t;
                posx = l;
                posy = scr_h - t - win->sizey;

                /*
                 * Ghost sometimes send size or move events when the window hasn't changed.
                 * One case of this is using compiz on linux. To alleviate the problem
                 * we ignore all such event here.
                 *
                 * It might be good to eventually do that at Ghost level, but that is for
                 * another time.
                 */
                if (win->sizex != sizex ||
                        win->sizey != sizey ||
                        win->posx != posx ||
                        win->posy != posy)
                {
                    win->sizex = sizex;
                    win->sizey = sizey;
                    win->posx = posx;
                    win->posy = posy;

                    /* debug prints */
                    if (G.debug & G_DEBUG_EVENTS) {
                        const char *state_str;
                        state = GHOST_GetWindowState(win->ghostwin);

                        if (state == GHOST_kWindowStateNormal) {
                            state_str = "normal";
                        }
                        else if (state == GHOST_kWindowStateMinimized) {
                            state_str = "minimized";
                        }
                        else if (state == GHOST_kWindowStateMaximized) {
                            state_str = "maximized";
                        }
                        else if (state == GHOST_kWindowStateFullScreen) {
                            state_str = "fullscreen";
                        }
                        else {
                            state_str = "<unknown>";
                        }

                        printf("%s: window %d state = %s\n", __func__, win->winid, state_str);

                        if (type != GHOST_kEventWindowSize) {
                            printf("win move event pos %d %d size %d %d\n",
                                   win->posx, win->posy, win->sizex, win->sizey);
                        }
                    }

                    wm_window_make_drawable(wm, win);
                    wm_draw_window_clear(win);
                    WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
                    WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);

#if defined(__APPLE__) || defined(WIN32)
                    /* OSX and Win32 don't return to the mainloop while resize */
                    wm_event_do_handlers(C);
                    wm_event_do_notifiers(C);
                    wm_draw_update(C);
#endif
                }
            }
            break;
        }

        case GHOST_kEventOpenMainFile:
        {
            PointerRNA props_ptr;
            wmWindow *oldWindow;
            const char *path = GHOST_GetEventData(evt);

            if (path) {
                wmOperatorType *ot = WM_operatortype_find("WM_OT_open_mainfile", false);
                /* operator needs a valid window in context, ensures
                 * it is correctly set */
                oldWindow = CTX_wm_window(C);
                CTX_wm_window_set(C, win);

                WM_operator_properties_create_ptr(&props_ptr, ot);
                RNA_string_set(&props_ptr, "filepath", path);
                WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &props_ptr);
                WM_operator_properties_free(&props_ptr);

                CTX_wm_window_set(C, oldWindow);
            }
            break;
        }
        case GHOST_kEventDraggingDropDone:
        {
            wmEvent event;
            GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt);
            int wx, wy;

            /* entering window, update mouse pos */
            wm_get_cursor_position(win, &wx, &wy);
            win->eventstate->x = wx;
            win->eventstate->y = wy;

            wm_event_init_from_window(win, &event);  /* copy last state, like mouse coords */

            /* activate region */
            event.type = MOUSEMOVE;
            event.prevx = event.x;
            event.prevy = event.y;

            wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */
            win->active = 1;

            wm_event_add(win, &event);


            /* make blender drop event with custom data pointing to wm drags */
            event.type = EVT_DROP;
            event.val = KM_RELEASE;
            event.custom = EVT_DATA_DRAGDROP;
            event.customdata = &wm->drags;
            event.customdatafree = 1;

            wm_event_add(win, &event);

            /* printf("Drop detected\n"); */

            /* add drag data to wm for paths: */

            if (ddd->dataType == GHOST_kDragnDropTypeFilenames) {
                GHOST_TStringArray *stra = ddd->data;
                int a, icon;

                for (a = 0; a < stra->count; a++) {
                    printf("drop file %s\n", stra->strings[a]);
                    /* try to get icon type from extension */
                    icon = ED_file_extension_icon((char *)stra->strings[a]);

                    WM_event_start_drag(C, icon, WM_DRAG_PATH, stra->strings[a], 0.0, WM_DRAG_NOP);
                    /* void poin should point to string, it makes a copy */
                    break; /* only one drop element supported now */
                }
            }

            break;
        }
        case GHOST_kEventNativeResolutionChange:
            // printf("change, pixel size %f\n", GHOST_GetNativePixelSize(win->ghostwin));

            U.pixelsize = wm_window_pixelsize(win);
            BKE_userdef_state();
            WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
            WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);

            break;
        case GHOST_kEventTrackpad:
        {
            GHOST_TEventTrackpadData *pd = data;

            wm_convert_cursor_position(win, &pd->x, &pd->y);
            wm_event_add_ghostevent(wm, win, type, time, data);
            break;
        }
        case GHOST_kEventCursorMove:
        {
            GHOST_TEventCursorData *cd = data;

            wm_convert_cursor_position(win, &cd->x, &cd->y);
            wm_event_add_ghostevent(wm, win, type, time, data);
            break;
        }
        default:
            wm_event_add_ghostevent(wm, win, type, time, data);
            break;
        }

    }
    return 1;
}
예제 #23
0
static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
{
	wmOperatorType *ot;
	int error_val = 0;
	PointerRNA ptr;
	int operator_ret = OPERATOR_CANCELLED;

	char     *opname;
	char     *context_str = NULL;
	PyObject *kw = NULL; /* optional args */
	PyObject *context_dict = NULL; /* optional args */
	PyObject *context_dict_back;

	/* note that context is an int, python does the conversion in this case */
	int context = WM_OP_EXEC_DEFAULT;
	int is_undo = false;

	/* XXX Todo, work out a better solution for passing on context,
	 * could make a tuple from self and pack the name and Context into it... */
	bContext *C = (bContext *)BPy_GetContext();
	
	if (C == NULL) {
		PyErr_SetString(PyExc_RuntimeError, "Context is None, cant poll any operators");
		return NULL;
	}
	
	if (!PyArg_ParseTuple(args, "sO|O!si:_bpy.ops.call",
	                      &opname, &context_dict, &PyDict_Type, &kw, &context_str, &is_undo))
	{
		return NULL;
	}

	ot = WM_operatortype_find(opname, true);

	if (ot == NULL) {
		PyErr_Format(PyExc_AttributeError,
		             "Calling operator \"bpy.ops.%s\" error, "
		             "could not be found", opname);
		return NULL;
	}
	
	if (!pyrna_write_check()) {
		PyErr_Format(PyExc_RuntimeError,
		             "Calling operator \"bpy.ops.%s\" error, "
		             "can't modify blend data in this state (drawing/rendering)",
		             opname);
		return NULL;
	}

	if (context_str) {
		if (RNA_enum_value_from_id(operator_context_items, context_str, &context) == 0) {
			char *enum_str = BPy_enum_as_string(operator_context_items);
			PyErr_Format(PyExc_TypeError,
			             "Calling operator \"bpy.ops.%s\" error, "
			             "expected a string enum in (%.200s)",
			             opname, enum_str);
			MEM_freeN(enum_str);
			return NULL;
		}
	}

	if (context_dict == NULL || context_dict == Py_None) {
		context_dict = NULL;
	}
	else if (!PyDict_Check(context_dict)) {
		PyErr_Format(PyExc_TypeError,
		             "Calling operator \"bpy.ops.%s\" error, "
		             "custom context expected a dict or None, got a %.200s",
		             opname, Py_TYPE(context_dict)->tp_name);
		return NULL;
	}

	context_dict_back = CTX_py_dict_get(C);

	CTX_py_dict_set(C, (void *)context_dict);
	Py_XINCREF(context_dict); /* so we done loose it */

	if (WM_operator_poll_context((bContext *)C, ot, context) == false) {
		const char *msg = CTX_wm_operator_poll_msg_get(C);
		PyErr_Format(PyExc_RuntimeError,
		             "Operator bpy.ops.%.200s.poll() %.200s",
		             opname, msg ? msg : "failed, context is incorrect");
		CTX_wm_operator_poll_msg_set(C, NULL); /* better set to NULL else it could be used again */
		error_val = -1;
	}
	else {
		WM_operator_properties_create_ptr(&ptr, ot);
		WM_operator_properties_sanitize(&ptr, 0);

		if (kw && PyDict_Size(kw))
			error_val = pyrna_pydict_to_props(&ptr, kw, 0, "Converting py args to operator properties: ");


		if (error_val == 0) {
			ReportList *reports;

			reports = MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
			BKE_reports_init(reports, RPT_STORE | RPT_OP_HOLD); /* own so these don't move into global reports */

#ifdef BPY_RELEASE_GIL
			/* release GIL, since a thread could be started from an operator
			 * that updates a driver */
			/* note: I have not seen any examples of code that does this
			 * so it may not be officially supported but seems to work ok. */
			{
				PyThreadState *ts = PyEval_SaveThread();
#endif

				operator_ret = WM_operator_call_py(C, ot, context, &ptr, reports, is_undo);

#ifdef BPY_RELEASE_GIL
				/* regain GIL */
				PyEval_RestoreThread(ts);
			}
#endif

			error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, false);

			/* operator output is nice to have in the terminal/console too */
			if (reports->list.first) {
				char *report_str = BKE_reports_string(reports, 0); /* all reports */
	
				if (report_str) {
					PySys_WriteStdout("%s\n", report_str);
					MEM_freeN(report_str);
				}
			}
	
			BKE_reports_clear(reports);
			if ((reports->flag & RPT_FREE) == 0) {
				MEM_freeN(reports);
			}
		}

		WM_operator_properties_free(&ptr);

#if 0
		/* if there is some way to know an operator takes args we should use this */
		{
			/* no props */
			if (kw != NULL) {
				PyErr_Format(PyExc_AttributeError,
				             "Operator \"%s\" does not take any args",
				             opname);
				return NULL;
			}

			WM_operator_name_call(C, opname, WM_OP_EXEC_DEFAULT, NULL);
		}
#endif
	}

	/* restore with original context dict, probably NULL but need this for nested operator calls */
	Py_XDECREF(context_dict);
	CTX_py_dict_set(C, (void *)context_dict_back);

	if (error_val == -1) {
		return NULL;
	}

	/* when calling  bpy.ops.wm.read_factory_settings() bpy.data's main pointer is freed by clear_globals(),
	 * further access will crash blender. setting context is not needed in this case, only calling because this
	 * function corrects bpy.data (internal Main pointer) */
	BPY_modules_update(C);

	/* needed for when WM_OT_read_factory_settings us called from within a script */
	bpy_import_main_set(CTX_data_main(C));

	/* return operator_ret as a bpy enum */
	return pyrna_enum_bitfield_to_py(operator_return_items, operator_ret);

}
예제 #24
0
void unpack_menu(bContext *C, const char *opname, const char *id_name, const char *abs_name, const char *folder, struct PackedFile *pf)
{
	PointerRNA props_ptr;
	uiPopupMenu *pup;
	uiLayout *layout;
	char line[FILE_MAX + 100];
	wmOperatorType *ot = WM_operatortype_find(opname, 1);

	pup = uiPupMenuBegin(C, IFACE_("Unpack File"), ICON_NONE);
	layout = uiPupMenuLayout(pup);

	props_ptr = uiItemFullO_ptr(layout, ot, IFACE_("Remove Pack"), ICON_NONE,
	                            NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
	RNA_enum_set(&props_ptr, "method", PF_REMOVE);
	RNA_string_set(&props_ptr, "id", id_name);

	if (G.relbase_valid) {
		char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];

		BLI_split_file_part(abs_name, fi, sizeof(fi));
		BLI_snprintf(local_name, sizeof(local_name), "//%s/%s", folder, fi);
		if (strcmp(abs_name, local_name) != 0) {
			switch (checkPackedFile(local_name, pf)) {
				case PF_NOFILE:
					BLI_snprintf(line, sizeof(line), IFACE_("Create %s"), local_name);
					props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
					RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
					RNA_string_set(&props_ptr, "id", id_name);

					break;
				case PF_EQUAL:
					BLI_snprintf(line, sizeof(line), IFACE_("Use %s (identical)"), local_name);
					//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_LOCAL);
					props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
					RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
					RNA_string_set(&props_ptr, "id", id_name);

					break;
				case PF_DIFFERS:
					BLI_snprintf(line, sizeof(line), IFACE_("Use %s (differs)"), local_name);
					//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_LOCAL);
					props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
					RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL);
					RNA_string_set(&props_ptr, "id", id_name);

					BLI_snprintf(line, sizeof(line), IFACE_("Overwrite %s"), local_name);
					//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_LOCAL);
					props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
					RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL);
					RNA_string_set(&props_ptr, "id", id_name);
					break;
			}
		}
	}

	switch (checkPackedFile(abs_name, pf)) {
		case PF_NOFILE:
			BLI_snprintf(line, sizeof(line), IFACE_("Create %s"), abs_name);
			//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL);
			props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
			RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
			RNA_string_set(&props_ptr, "id", id_name);
			break;
		case PF_EQUAL:
			BLI_snprintf(line, sizeof(line), IFACE_("Use %s (identical)"), abs_name);
			//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_ORIGINAL);
			props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
			RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
			RNA_string_set(&props_ptr, "id", id_name);
			break;
		case PF_DIFFERS:
			BLI_snprintf(line, sizeof(line), IFACE_("Use %s (differs)"), abs_name);
			//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_ORIGINAL);
			props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
			RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL);
			RNA_string_set(&props_ptr, "id", id_name);

			BLI_snprintf(line, sizeof(line), IFACE_("Overwrite %s"), abs_name);
			//uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL);
			props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
			RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL);
			RNA_string_set(&props_ptr, "id", id_name);
			break;
	}

	uiPupMenuEnd(C, pup);
}
예제 #25
0
static int edittranslation_exec(bContext *C, wmOperator *op)
{
	uiBut *but = uiContextActiveButton(C);
	int ret = OPERATOR_CANCELLED;

	if (but) {
		PointerRNA ptr;
		char popath[FILE_MAX];
		const char *root = U.i18ndir;
		const char *uilng = BLF_lang_get();

		uiStringInfo but_label = {BUT_GET_LABEL, NULL};
		uiStringInfo rna_label = {BUT_GET_RNA_LABEL, NULL};
		uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL};
		uiStringInfo but_tip = {BUT_GET_TIP, NULL};
		uiStringInfo rna_tip = {BUT_GET_RNA_TIP, NULL};
		uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, NULL};
		uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, NULL};
		uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, NULL};
		uiStringInfo rna_enum = {BUT_GET_RNAENUM_IDENTIFIER, NULL};
		uiStringInfo rna_ctxt = {BUT_GET_RNA_LABEL_CONTEXT, NULL};

		if (!BLI_is_dir(root)) {
			BKE_report(op->reports, RPT_ERROR, "Please set your User Preferences' 'Translation Branches "
			                                   "Directory' path to a valid directory");
			return OPERATOR_CANCELLED;
		}
		if (!WM_operatortype_find(EDTSRC_I18N_OP_NAME, 0)) {
			BKE_reportf(op->reports, RPT_ERROR, "Could not find operator '%s'! Please enable ui_translate addon "
			                                    "in the User Preferences", EDTSRC_I18N_OP_NAME);
			return OPERATOR_CANCELLED;
		}
		/* Try to find a valid po file for current language... */
		edittranslation_find_po_file(root, uilng, popath, FILE_MAX);
/*		printf("po path: %s\n", popath);*/
		if (popath[0] == '\0') {
			BKE_reportf(op->reports, RPT_ERROR, "No valid po found for language '%s' under %s", uilng, root);
			return OPERATOR_CANCELLED;
		}

		uiButGetStrInfo(C, but, &but_label, &rna_label, &enum_label, &but_tip, &rna_tip, &enum_tip,
		                &rna_struct, &rna_prop, &rna_enum, &rna_ctxt, NULL);

		WM_operator_properties_create(&ptr, EDTSRC_I18N_OP_NAME);
		RNA_string_set(&ptr, "lang", uilng);
		RNA_string_set(&ptr, "po_file", popath);
		RNA_string_set(&ptr, "but_label", but_label.strinfo);
		RNA_string_set(&ptr, "rna_label", rna_label.strinfo);
		RNA_string_set(&ptr, "enum_label", enum_label.strinfo);
		RNA_string_set(&ptr, "but_tip", but_tip.strinfo);
		RNA_string_set(&ptr, "rna_tip", rna_tip.strinfo);
		RNA_string_set(&ptr, "enum_tip", enum_tip.strinfo);
		RNA_string_set(&ptr, "rna_struct", rna_struct.strinfo);
		RNA_string_set(&ptr, "rna_prop", rna_prop.strinfo);
		RNA_string_set(&ptr, "rna_enum", rna_enum.strinfo);
		RNA_string_set(&ptr, "rna_ctxt", rna_ctxt.strinfo);
		ret = WM_operator_name_call(C, EDTSRC_I18N_OP_NAME, WM_OP_INVOKE_DEFAULT, &ptr);

		/* Clean up */
		if (but_label.strinfo)
			MEM_freeN(but_label.strinfo);
		if (rna_label.strinfo)
			MEM_freeN(rna_label.strinfo);
		if (enum_label.strinfo)
			MEM_freeN(enum_label.strinfo);
		if (but_tip.strinfo)
			MEM_freeN(but_tip.strinfo);
		if (rna_tip.strinfo)
			MEM_freeN(rna_tip.strinfo);
		if (enum_tip.strinfo)
			MEM_freeN(enum_tip.strinfo);
		if (rna_struct.strinfo)
			MEM_freeN(rna_struct.strinfo);
		if (rna_prop.strinfo)
			MEM_freeN(rna_prop.strinfo);
		if (rna_enum.strinfo)
			MEM_freeN(rna_enum.strinfo);
		if (rna_ctxt.strinfo)
			MEM_freeN(rna_ctxt.strinfo);

		return ret;
	}
	else {
		BKE_report(op->reports, RPT_ERROR, "Active button not found");
		return OPERATOR_CANCELLED;
	}
}
예제 #26
0
static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
	PointerRNA ptr;
	PropertyRNA *prop;
	bool is_undo;
	FileBrowseOp *fbo;
	char *str;

	if (CTX_wm_space_file(C)) {
		BKE_report(op->reports, RPT_ERROR, "Cannot activate a file selector, one already open");
		return OPERATOR_CANCELLED;
	}

	UI_context_active_but_prop_get_filebrowser(C, &ptr, &prop, &is_undo);

	if (!prop)
		return OPERATOR_CANCELLED;

	str = RNA_property_string_get_alloc(&ptr, prop, NULL, 0, NULL);

	/* useful yet irritating feature, Shift+Click to open the file
	 * Alt+Click to browse a folder in the OS's browser */
	if (event->shift || event->alt) {
		wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true);
		PointerRNA props_ptr;

		if (event->alt) {
			char *lslash = (char *)BLI_last_slash(str);
			if (lslash)
				*lslash = '\0';
		}


		WM_operator_properties_create_ptr(&props_ptr, ot);
		RNA_string_set(&props_ptr, "filepath", str);
		WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &props_ptr);
		WM_operator_properties_free(&props_ptr);

		MEM_freeN(str);
		return OPERATOR_CANCELLED;
	}
	else {
		PropertyRNA *prop_relpath;
		const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath";
		fbo = MEM_callocN(sizeof(FileBrowseOp), "FileBrowseOp");
		fbo->ptr = ptr;
		fbo->prop = prop;
		fbo->is_undo = is_undo;
		op->customdata = fbo;

		RNA_string_set(op->ptr, path_prop, str);
		MEM_freeN(str);

		/* normally ED_fileselect_get_params would handle this but we need to because of stupid
		 * user-prefs exception - campbell */
		if ((prop_relpath = RNA_struct_find_property(op->ptr, "relative_path"))) {
			if (!RNA_property_is_set(op->ptr, prop_relpath)) {
				/* annoying exception!, if were dealing with the user prefs, default relative to be off */
				RNA_property_boolean_set(op->ptr, prop_relpath, U.flag & USER_RELPATHS && (ptr.data != &U));
			}
		}
		WM_event_add_fileselect(C, op);

		return OPERATOR_RUNNING_MODAL;
	}
}