Пример #1
0
static void uilist_filter_items(uiList *ui_list, bContext *C, PointerRNA *dataptr, const char *propname)
{
	extern FunctionRNA rna_UIList_filter_items_func;

	PointerRNA ul_ptr;
	ParameterList list;
	FunctionRNA *func;
	PropertyRNA *parm;

	uiListDyn *flt_data = ui_list->dyn_data;
	int *filter_flags, *filter_neworder;
	void *ret1, *ret2;
	int ret_len;
	int len = flt_data->items_len = RNA_collection_length(dataptr, propname);

	RNA_pointer_create(&CTX_wm_screen(C)->id, ui_list->type->ext.srna, ui_list, &ul_ptr);
	func = &rna_UIList_filter_items_func; /* RNA_struct_find_function(&ul_ptr, "filter_items"); */

	RNA_parameter_list_create(&list, &ul_ptr, func);
	RNA_parameter_set_lookup(&list, "context", &C);
	RNA_parameter_set_lookup(&list, "data", dataptr);
	RNA_parameter_set_lookup(&list, "property", &propname);

	ui_list->type->ext.call((bContext *)C, &ul_ptr, func, &list);

	parm = RNA_function_find_parameter(NULL, func, "filter_flags");
	ret_len = RNA_parameter_dynamic_length_get(&list, parm);
	if (ret_len != len && ret_len != 0) {
		printf("%s: Error, py func returned %d items in %s, %d or none were expected.\n", __func__,
		       RNA_parameter_dynamic_length_get(&list, parm), "filter_flags", len);
		/* Note: we cannot return here, we would let flt_data in inconsistent state... see T38356. */
		filter_flags = NULL;
	}
	else {
		RNA_parameter_get(&list, parm, &ret1);
		filter_flags = (int *)ret1;
	}

	parm = RNA_function_find_parameter(NULL, func, "filter_neworder");
	ret_len = RNA_parameter_dynamic_length_get(&list, parm);
	if (ret_len != len && ret_len != 0) {
		printf("%s: Error, py func returned %d items in %s, %d or none were expected.\n", __func__,
		       RNA_parameter_dynamic_length_get(&list, parm), "filter_neworder", len);
		/* Note: we cannot return here, we would let flt_data in inconsistent state... see T38356. */
		filter_neworder = NULL;
	}
	else {
		RNA_parameter_get(&list, parm, &ret2);
		filter_neworder = (int *)ret2;
	}

	/* We have to do some final checks and transforms... */
	{
		int i, filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
		if (filter_flags) {
			flt_data->items_filter_flags = MEM_mallocN(sizeof(int) * len, __func__);
			memcpy(flt_data->items_filter_flags, filter_flags, sizeof(int) * len);

			if (filter_neworder) {
				/* For sake of simplicity, py filtering is expected to filter all items, but we actually only want
				 * reordering data for shown items!
				 */
				int items_shown, shown_idx;
				int t_idx, t_ni, prev_ni;
				flt_data->items_shown = 0;
				for (i = 0, shown_idx = 0; i < len; i++) {
					if ((filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude) {
						filter_neworder[shown_idx++] = filter_neworder[i];
					}
				}
				items_shown = flt_data->items_shown = shown_idx;
				flt_data->items_filter_neworder = MEM_mallocN(sizeof(int) * items_shown, __func__);
				/* And now, bring back new indices into the [0, items_shown[ range!
				 * XXX This is O(N²)... :/
				 */
				for (shown_idx = 0, prev_ni = -1; shown_idx < items_shown; shown_idx++) {
					for (i = 0, t_ni = len, t_idx = -1; i < items_shown; i++) {
						int ni = filter_neworder[i];
						if (ni > prev_ni && ni < t_ni) {
							t_idx = i;
							t_ni = ni;
						}
					}
					if (t_idx >= 0) {
						prev_ni = t_ni;
						flt_data->items_filter_neworder[t_idx] = shown_idx;
					}
				}
			}
			else {
				/* we still have to set flt_data->items_shown... */
				flt_data->items_shown = 0;
				for (i = 0; i < len; i++) {
					if ((filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude) {
						flt_data->items_shown++;
					}
				}
			}
		}
		else {
			flt_data->items_shown = len;

			if (filter_neworder) {
				flt_data->items_filter_neworder = MEM_mallocN(sizeof(int) * len, __func__);
				memcpy(flt_data->items_filter_neworder, filter_neworder, sizeof(int) * len);
			}
		}
	}

	RNA_parameter_list_free(&list);
}
Пример #2
0
static int open_exec(bContext *C, wmOperator *op)
{
	SpaceClip *sc = CTX_wm_space_clip(C);
	bScreen *screen = CTX_wm_screen(C);
	Main *bmain = CTX_data_main(C);
	PropertyPointerRNA *pprop;
	PointerRNA idptr;
	MovieClip *clip = NULL;
	char str[FILE_MAX];

	if (RNA_collection_length(op->ptr, "files")) {
		PointerRNA fileptr;
		PropertyRNA *prop;
		char dir_only[FILE_MAX], file_only[FILE_MAX];
		int relative = RNA_boolean_get(op->ptr, "relative_path");

		RNA_string_get(op->ptr, "directory", dir_only);
		if (relative)
			BLI_path_rel(dir_only, G.main->name);

		prop = RNA_struct_find_property(op->ptr, "files");
		RNA_property_collection_lookup_int(op->ptr, prop, 0, &fileptr);
		RNA_string_get(&fileptr, "name", file_only);

		BLI_join_dirfile(str, sizeof(str), dir_only, file_only);
	}
	else {
		BKE_report(op->reports, RPT_ERROR, "No files selected to be opened");

		return OPERATOR_CANCELLED;
	}

	/* default to frame 1 if there's no scene in context */

	errno = 0;

	clip = BKE_movieclip_file_add(bmain, str);

	if (!clip) {
		if (op->customdata)
			MEM_freeN(op->customdata);

		BKE_reportf(op->reports, RPT_ERROR, "Cannot read '%s': %s", str,
		            errno ? strerror(errno) : TIP_("unsupported movie clip format"));

		return OPERATOR_CANCELLED;
	}

	if (!op->customdata)
		open_init(C, op);

	/* hook into UI */
	pprop = op->customdata;

	if (pprop->prop) {
		/* when creating new ID blocks, use is already 1, but RNA
		 * pointer se also increases user, so this compensates it */
		clip->id.us--;

		RNA_id_pointer_create(&clip->id, &idptr);
		RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
		RNA_property_update(C, &pprop->ptr, pprop->prop);
	}
	else if (sc) {
		ED_space_clip_set_clip(C, screen, sc, clip);
	}

	WM_event_add_notifier(C, NC_MOVIECLIP | NA_ADDED, clip);

	MEM_freeN(op->customdata);

	return OPERATOR_FINISHED;
}