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:
Diffstat (limited to 'source/blender/blenkernel/intern/text.c')
-rw-r--r--source/blender/blenkernel/intern/text.c172
1 files changed, 146 insertions, 26 deletions
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 9f441b45db9..89456763b95 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -330,7 +330,7 @@ static void text_from_buf(Text *text, const unsigned char *buffer, const int len
text->curc = text->selc = 0;
}
-int BKE_text_reload(Text *text)
+bool BKE_text_reload(Text *text)
{
FILE *fp;
int len;
@@ -339,13 +339,24 @@ int BKE_text_reload(Text *text)
char str[FILE_MAX];
BLI_stat_t st;
- if (!text->name) return 0;
-
+ if (!text->name) {
+ return false;
+ }
+
BLI_strncpy(str, text->name, FILE_MAX);
BLI_path_abs(str, G.main->name);
fp = BLI_fopen(str, "r");
- if (fp == NULL) return 0;
+ if (fp == NULL) {
+ return false;
+ }
+ fseek(fp, 0L, SEEK_END);
+ len = ftell(fp);
+ fseek(fp, 0L, SEEK_SET);
+ if (UNLIKELY(len == -1)) {
+ fclose(fp);
+ return false;
+ }
/* free memory: */
@@ -363,11 +374,6 @@ int BKE_text_reload(Text *text)
MEM_freeN(text->undo_buf);
init_undo_text(text);
- fseek(fp, 0L, SEEK_END);
- len = ftell(fp);
- fseek(fp, 0L, SEEK_SET);
-
-
buffer = MEM_mallocN(len, "text_buffer");
/* under windows fread can return less than len bytes because
* of CR stripping */
@@ -385,7 +391,7 @@ int BKE_text_reload(Text *text)
text_from_buf(text, buffer, len);
MEM_freeN(buffer);
- return 1;
+ return true;
}
Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const bool is_internal)
@@ -402,8 +408,18 @@ Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const
BLI_path_abs(str, relpath);
fp = BLI_fopen(str, "r");
- if (fp == NULL) return NULL;
-
+ if (fp == NULL) {
+ return NULL;
+ }
+
+ fseek(fp, 0L, SEEK_END);
+ len = ftell(fp);
+ fseek(fp, 0L, SEEK_SET);
+ if (UNLIKELY(len == -1)) {
+ fclose(fp);
+ return NULL;
+ }
+
ta = BKE_libblock_alloc(bmain, ID_TXT, BLI_path_basename(str));
ta->id.us = 1;
@@ -423,10 +439,6 @@ Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const
/* clear undo buffer */
init_undo_text(ta);
-
- fseek(fp, 0L, SEEK_END);
- len = ftell(fp);
- fseek(fp, 0L, SEEK_SET);
buffer = MEM_mallocN(len, "text_buffer");
/* under windows fread can return less than len bytes because
@@ -473,6 +485,7 @@ Text *BKE_text_copy(Main *bmain, Text *ta)
BLI_listbase_clear(&tan->lines);
tan->curl = tan->sell = NULL;
+ tan->compiled = NULL;
tan->nlines = ta->nlines;
@@ -651,7 +664,7 @@ void BKE_text_unlink(Main *bmain, Text *text)
}
}
- /* Freestyle (while looping oer the scene) */
+ /* Freestyle (while looping over the scene) */
for (srl = sce->r.layers.first; srl; srl = srl->next) {
for (module = srl->freestyleConfig.modules.first; module; module = module->next) {
if (module->script == text)
@@ -1895,6 +1908,47 @@ static void txt_undo_add_charop(Text *text, int op_start, unsigned int c)
text->undo_buf[text->undo_pos + 1] = 0;
}
+/* extends Link */
+struct LinkInt {
+ struct LinkInt *next, *prev;
+ int value;
+};
+
+/* unindentLines points to a ListBase composed of LinkInt elements, listing the numbers
+ * of the lines that should not be indented back. */
+static void txt_undo_add_unindent_op(Text *text, const ListBase *line_index_mask, const int line_index_mask_len)
+{
+ struct LinkInt *idata;
+
+ BLI_assert(BLI_listbase_count(line_index_mask) == line_index_mask_len);
+
+ /* OP byte + UInt32 count + counted UInt32 line numbers + UInt32 count + 12-bytes selection + OP byte */
+ if (!max_undo_test(text, 1 + 4 + (line_index_mask_len * 4) + 4 + 12 + 1)) {
+ return;
+ }
+
+ /* Opening buffer sequence with OP */
+ text->undo_pos++;
+ text->undo_buf[text->undo_pos] = UNDO_UNINDENT;
+ text->undo_pos++;
+ /* Adding number of line numbers to read */
+ txt_undo_store_uint32(text->undo_buf, &text->undo_pos, line_index_mask_len);
+
+ /* Adding linenumbers of lines that shall not be indented if undoing */
+ for (idata = line_index_mask->first; idata; idata = idata->next) {
+ txt_undo_store_uint32(text->undo_buf, &text->undo_pos, idata->value);
+ }
+
+ /* Adding number of line numbers to read again */
+ txt_undo_store_uint32(text->undo_buf, &text->undo_pos, line_index_mask_len);
+ /* Adding current selection */
+ txt_undo_store_cursors(text);
+ /* Closing with OP (same as above) */
+ text->undo_buf[text->undo_pos] = UNDO_UNINDENT;
+ /* Marking as last undo operation */
+ text->undo_buf[text->undo_pos + 1] = 0;
+}
+
static unsigned short txt_undo_read_uint16(const char *undo_buf, int *undo_pos)
{
unsigned short val;
@@ -2189,7 +2243,6 @@ void txt_do_undo(Text *text)
text->undo_pos--;
break;
case UNDO_INDENT:
- case UNDO_UNINDENT:
case UNDO_COMMENT:
case UNDO_UNCOMMENT:
case UNDO_DUPLICATE:
@@ -2203,9 +2256,6 @@ void txt_do_undo(Text *text)
if (op == UNDO_INDENT) {
txt_unindent(text);
}
- else if (op == UNDO_UNINDENT) {
- txt_indent(text);
- }
else if (op == UNDO_COMMENT) {
txt_uncomment(text);
}
@@ -2224,6 +2274,37 @@ void txt_do_undo(Text *text)
text->undo_pos--;
break;
+ case UNDO_UNINDENT:
+ {
+ int count;
+ int i;
+ /* Get and restore the cursors */
+ txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, selln, selc, 1);
+
+ /* Un-unindent */
+ txt_indent(text);
+
+ /* Get the count */
+ count = txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
+ /* Iterate! */
+ txt_pop_sel(text);
+
+ for (i = 0; i < count; i++) {
+ txt_move_to(text, txt_undo_read_uint32(text->undo_buf, &text->undo_pos), 0, 0);
+ /* Un-un-unindent */
+ txt_unindent(text);
+ }
+ /* Restore selection */
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, selln, selc, 1);
+ /* Jumo over count */
+ txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
+ /* Jump over closing OP byte */
+ text->undo_pos--;
+ break;
+ }
default:
//XXX error("Undo buffer error - resetting");
text->undo_pos = -1;
@@ -2353,7 +2434,6 @@ void txt_do_redo(Text *text)
break;
case UNDO_INDENT:
- case UNDO_UNINDENT:
case UNDO_COMMENT:
case UNDO_UNCOMMENT:
case UNDO_DUPLICATE:
@@ -2369,9 +2449,6 @@ void txt_do_redo(Text *text)
if (op == UNDO_INDENT) {
txt_indent(text);
}
- else if (op == UNDO_UNINDENT) {
- txt_unindent(text);
- }
else if (op == UNDO_COMMENT) {
txt_comment(text);
}
@@ -2401,6 +2478,26 @@ void txt_do_redo(Text *text)
txt_move_to(text, selln, selc, 1);
break;
+ case UNDO_UNINDENT:
+ {
+ int count;
+ int i;
+
+ text->undo_pos++;
+ /* Scan all the stuff described in txt_undo_add_unindent_op */
+ count = txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
+ for (i = 0; i < count; i++) {
+ txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
+ }
+ /* Count again */
+ txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
+ /* Get the selection and re-unindent */
+ txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, selln, selc, 1);
+ txt_unindent(text);
+ break;
+ }
default:
//XXX error("Undo buffer error - resetting");
text->undo_pos = -1;
@@ -2801,6 +2898,12 @@ void txt_unindent(Text *text)
int indentlen = 1;
bool unindented_first = false;
+ /* List of lines that are already at indent level 0, to store them later into the undo buffer */
+ ListBase line_index_mask = {NULL, NULL};
+ int line_index_mask_len = 0;
+ int curl_span_init = 0;
+
+
/* hardcoded: TXT_TABSIZE = 4 spaces: */
int spaceslen = TXT_TABSIZE;
@@ -2814,6 +2917,10 @@ void txt_unindent(Text *text)
indentlen = spaceslen;
}
+ if (!undoing) {
+ curl_span_init = txt_get_span(text->lines.first, text->curl);
+ }
+
while (true) {
bool changed = false;
if (STREQLEN(text->curl->line, remove, indentlen)) {
@@ -2823,6 +2930,16 @@ void txt_unindent(Text *text)
memmove(text->curl->line, text->curl->line + indentlen, text->curl->len + 1);
changed = true;
}
+ else {
+ if (!undoing) {
+ /* Create list element for 0 indent line */
+ struct LinkInt *idata = MEM_mallocN(sizeof(struct LinkInt), __func__);
+ idata->value = curl_span_init + num;
+ BLI_assert(idata->value == txt_get_span(text->lines.first, text->curl));
+ BLI_addtail(&line_index_mask, idata);
+ line_index_mask_len += 1;
+ }
+ }
txt_make_dirty(text);
txt_clean_text(text);
@@ -2835,6 +2952,7 @@ void txt_unindent(Text *text)
else {
text->curl = text->curl->next;
num++;
+
}
}
@@ -2848,8 +2966,10 @@ void txt_unindent(Text *text)
}
if (!undoing) {
- txt_undo_add_op(text, UNDO_UNINDENT);
+ txt_undo_add_unindent_op(text, &line_index_mask, line_index_mask_len);
}
+
+ BLI_freelistN(&line_index_mask);
}
void txt_comment(Text *text)