163 lines
4.9 KiB
C
163 lines
4.9 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup pythonintern
|
|
*
|
|
* This file extends the text editor with C/Python API methods and attributes.
|
|
*/
|
|
|
|
#define PY_SSIZE_T_CLEAN
|
|
|
|
#include <Python.h>
|
|
|
|
#include "DNA_text_types.h"
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "WM_api.h"
|
|
|
|
#include "BKE_text.h"
|
|
|
|
#include "bpy_capi_utils.h"
|
|
#include "bpy_rna.h"
|
|
#include "bpy_rna_text.h"
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Data structures.
|
|
* \{ */
|
|
|
|
/**
|
|
* Struct representing a selection which is extracted from Python arguments.
|
|
*/
|
|
typedef struct TextRegion {
|
|
int curl;
|
|
int curc;
|
|
int sell;
|
|
int selc;
|
|
} TextRegion;
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Text Editor Get / Set region text API
|
|
* \{ */
|
|
|
|
PyDoc_STRVAR(bpy_rna_region_as_string_doc,
|
|
".. method:: region_as_string(range=None)\n"
|
|
"\n"
|
|
" :arg range: The region of text to be returned, "
|
|
"defaulting to the selection when no range is passed.\n"
|
|
" Each int pair represents a line and column: "
|
|
"((start_line, start_column), (end_line, end_column))\n"
|
|
" The values match Python's slicing logic "
|
|
"(negative values count backwards from the end, the end value is not inclusive).\n"
|
|
" :type range: Two pairs of ints\n"
|
|
" :return: The specified region as a string.\n"
|
|
" :rtype: str.\n");
|
|
/* Receive a Python Tuple as parameter to represent the region range. */
|
|
static PyObject *bpy_rna_region_as_string(PyObject *self, PyObject *args, PyObject *kwds)
|
|
{
|
|
BPy_StructRNA *pyrna = (BPy_StructRNA *)self;
|
|
Text *text = pyrna->ptr.data;
|
|
/* Parse the region range. */
|
|
TextRegion region;
|
|
|
|
static const char *_keywords[] = {"range", NULL};
|
|
static _PyArg_Parser _parser = {
|
|
"|$" /* Optional keyword only arguments. */
|
|
"((ii)(ii))" /* `range` */
|
|
":region_as_string",
|
|
_keywords,
|
|
0,
|
|
};
|
|
if (!_PyArg_ParseTupleAndKeywordsFast(
|
|
args, kwds, &_parser, ®ion.curl, ®ion.curc, ®ion.sell, ®ion.selc)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (PyDict_GET_SIZE(kwds) > 0) {
|
|
txt_sel_set(text, region.curl, region.curc, region.sell, region.selc);
|
|
}
|
|
|
|
/* Return an empty string if there is no selection. */
|
|
if (!txt_has_sel(text)) {
|
|
return PyUnicode_FromString("");
|
|
}
|
|
char *buf = txt_sel_to_buf(text, NULL);
|
|
PyObject *sel_text = PyUnicode_FromString(buf);
|
|
MEM_freeN(buf);
|
|
/* Return the selected text. */
|
|
return sel_text;
|
|
}
|
|
|
|
PyMethodDef BPY_rna_region_as_string_method_def = {
|
|
"region_as_string",
|
|
(PyCFunction)bpy_rna_region_as_string,
|
|
METH_VARARGS | METH_KEYWORDS,
|
|
bpy_rna_region_as_string_doc,
|
|
};
|
|
|
|
PyDoc_STRVAR(bpy_rna_region_from_string_doc,
|
|
".. method:: region_from_string(body, range=None)\n"
|
|
"\n"
|
|
" :arg body: The text to be inserted.\n"
|
|
" :type body: str\n"
|
|
" :arg range: The region of text to be returned, "
|
|
"defaulting to the selection when no range is passed.\n"
|
|
" Each int pair represents a line and column: "
|
|
"((start_line, start_column), (end_line, end_column))\n"
|
|
" The values match Python's slicing logic "
|
|
"(negative values count backwards from the end, the end value is not inclusive).\n"
|
|
" :type range: Two pairs of ints\n");
|
|
static PyObject *bpy_rna_region_from_string(PyObject *self, PyObject *args, PyObject *kwds)
|
|
{
|
|
BPy_StructRNA *pyrna = (BPy_StructRNA *)self;
|
|
Text *text = pyrna->ptr.data;
|
|
|
|
/* Parse the region range. */
|
|
const char *buf;
|
|
Py_ssize_t buf_len;
|
|
TextRegion region;
|
|
|
|
static const char *_keywords[] = {"", "range", NULL};
|
|
static _PyArg_Parser _parser = {
|
|
"s#" /* `buf` (positional). */
|
|
"|$" /* Optional keyword only arguments. */
|
|
"((ii)(ii))" /* `range` */
|
|
":region_from_string",
|
|
_keywords,
|
|
0,
|
|
};
|
|
if (!_PyArg_ParseTupleAndKeywordsFast(args,
|
|
kwds,
|
|
&_parser,
|
|
&buf,
|
|
&buf_len,
|
|
®ion.curl,
|
|
®ion.curc,
|
|
®ion.sell,
|
|
®ion.selc)) {
|
|
return NULL;
|
|
}
|
|
|
|
if (PyDict_GET_SIZE(kwds) > 0) {
|
|
txt_sel_set(text, region.curl, region.curc, region.sell, region.selc);
|
|
}
|
|
|
|
/* Set the selected text. */
|
|
txt_insert_buf(text, buf, buf_len);
|
|
/* Update the text editor. */
|
|
WM_main_add_notifier(NC_TEXT | NA_EDITED, text);
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
PyMethodDef BPY_rna_region_from_string_method_def = {
|
|
"region_from_string",
|
|
(PyCFunction)bpy_rna_region_from_string,
|
|
METH_VARARGS | METH_KEYWORDS,
|
|
bpy_rna_region_from_string_doc,
|
|
};
|
|
|
|
/** \} */
|