summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Williams <andy@andywilliams.me>2017-05-16 22:10:56 +0100
committerAndy Williams <andy@andywilliams.me>2017-05-16 22:15:48 +0100
commit73f05a36d054496f6a9634c6fa7d724dbd8e25e9 (patch)
treed63be1fc1711e8abd469fcd4145fb7e1876ed38f
parent377441d82f7d63fba694ddee3264b9ce3e28aae7 (diff)
elm_code: Fix insertion of multiline content in widget
A small refactoring to reduce code duplication as well :)
-rw-r--r--src/lib/elementary/elm_code_widget.c74
-rw-r--r--src/lib/elementary/elm_code_widget_selection.c84
-rw-r--r--src/lib/elementary/elm_code_widget_text.c114
3 files changed, 118 insertions, 154 deletions
diff --git a/src/lib/elementary/elm_code_widget.c b/src/lib/elementary/elm_code_widget.c
index a0150ce1c8..245be0ae8a 100644
--- a/src/lib/elementary/elm_code_widget.c
+++ b/src/lib/elementary/elm_code_widget.c
@@ -1313,74 +1313,6 @@ _elm_code_widget_change_selection_add(Evas_Object *widget)
1313 free(selection); 1313 free(selection);
1314} 1314}
1315 1315
1316void
1317_elm_code_widget_text_at_cursor_insert_do(Elm_Code_Widget *widget, const char *text, int length, Eina_Bool undo)
1318{
1319 Elm_Code *code;
1320 Elm_Code_Line *line;
1321 Elm_Code_Widget_Change_Info *change;
1322 unsigned int row, col, position, col_width, curlen, indent;
1323 const char *curtext, *indent_text;
1324
1325 if (undo)
1326 elm_code_widget_selection_delete(widget);
1327
1328 code = elm_obj_code_widget_code_get(widget);
1329 elm_obj_code_widget_cursor_position_get(widget, &row, &col);
1330 line = elm_code_file_line_get(code->file, row);
1331 if (line == NULL)
1332 {
1333 elm_code_file_line_append(code->file, "", 0, NULL);
1334 row = elm_code_file_lines_get(code->file);
1335 line = elm_code_file_line_get(code->file, row);
1336 }
1337 if (text[0] == '}')
1338 {
1339 curtext = elm_code_line_text_get(line, &curlen);
1340
1341 if (elm_code_text_is_whitespace(curtext, line->length))
1342 {
1343 indent_text = elm_code_line_indent_matching_braces_get(line, &indent);
1344 elm_code_line_text_leading_whitespace_strip(line);
1345
1346 if (indent > 0)
1347 elm_code_line_text_insert(line, 0, indent_text, indent);
1348
1349 elm_obj_code_widget_cursor_position_set(widget, row, indent + 1);
1350 elm_obj_code_widget_cursor_position_get(widget, &row, &col);
1351 }
1352 }
1353
1354 position = elm_code_widget_line_text_position_for_column_get(widget, line, col);
1355 elm_code_line_text_insert(line, position, text, length);
1356 col_width = elm_code_widget_line_text_column_width_to_position(widget, line, position + length) -
1357 elm_code_widget_line_text_column_width_to_position(widget, line, position);
1358
1359 // a workaround for when the cursor position would be off the line width
1360 _elm_code_widget_resize(widget, line);
1361 elm_obj_code_widget_cursor_position_set(widget, row, col + col_width);
1362 efl_event_callback_legacy_call(widget, ELM_OBJ_CODE_WIDGET_EVENT_CHANGED_USER, NULL);
1363
1364 if (undo)
1365 {
1366 change = _elm_code_widget_change_create(col, row, col + col_width - 1, row, text, length, EINA_TRUE);
1367 _elm_code_widget_undo_change_add(widget, change);
1368 _elm_code_widget_change_free(change);
1369 }
1370}
1371
1372EOLIAN void
1373_elm_code_widget_text_at_cursor_insert(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd EINA_UNUSED, const char *text)
1374{
1375 _elm_code_widget_text_at_cursor_insert_do(widget, text, strlen(text), EINA_TRUE);
1376}
1377
1378void
1379_elm_code_widget_text_at_cursor_insert_no_undo(Elm_Code_Widget *widget, const char *text, unsigned int length)
1380{
1381 _elm_code_widget_text_at_cursor_insert_do(widget, text, length, EINA_FALSE);
1382}
1383
1384static void 1316static void
1385_elm_code_widget_tab_at_cursor_insert(Elm_Code_Widget *widget) 1317_elm_code_widget_tab_at_cursor_insert(Elm_Code_Widget *widget)
1386{ 1318{
@@ -1390,7 +1322,7 @@ _elm_code_widget_tab_at_cursor_insert(Elm_Code_Widget *widget)
1390 pd = efl_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); 1322 pd = efl_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
1391 if (!pd->tab_inserts_spaces) 1323 if (!pd->tab_inserts_spaces)
1392 { 1324 {
1393 _elm_code_widget_text_at_cursor_insert(widget, pd, "\t"); 1325 elm_code_widget_text_at_cursor_insert(widget, "\t");
1394 return; 1326 return;
1395 } 1327 }
1396 1328
@@ -1399,7 +1331,7 @@ _elm_code_widget_tab_at_cursor_insert(Elm_Code_Widget *widget)
1399 1331
1400 while (rem < pd->tabstop) 1332 while (rem < pd->tabstop)
1401 { 1333 {
1402 _elm_code_widget_text_at_cursor_insert(widget, pd, " "); 1334 elm_code_widget_text_at_cursor_insert(widget, " ");
1403 rem++; 1335 rem++;
1404 } 1336 }
1405} 1337}
@@ -1716,7 +1648,7 @@ _elm_code_widget_key_down_cb(void *data, Evas *evas EINA_UNUSED,
1716 elm_code_widget_selection_clear(widget); 1648 elm_code_widget_selection_clear(widget);
1717 1649
1718 else if (ev->string && strlen(ev->string) == 1) 1650 else if (ev->string && strlen(ev->string) == 1)
1719 _elm_code_widget_text_at_cursor_insert(widget, pd, ev->string); 1651 elm_code_widget_text_at_cursor_insert(widget, ev->string);
1720 else 1652 else
1721 INF("Unhandled key %s (%s) (%s)", ev->key, ev->keyname, ev->string); 1653 INF("Unhandled key %s (%s) (%s)", ev->key, ev->keyname, ev->string);
1722} 1654}
diff --git a/src/lib/elementary/elm_code_widget_selection.c b/src/lib/elementary/elm_code_widget_selection.c
index cba2bd1c4b..c8c1dacde8 100644
--- a/src/lib/elementary/elm_code_widget_selection.c
+++ b/src/lib/elementary/elm_code_widget_selection.c
@@ -397,96 +397,14 @@ elm_code_widget_selection_copy(Evas_Object *widget)
397 free(text); 397 free(text);
398} 398}
399 399
400static void
401_selection_paste_single(Elm_Code_Widget *widget, Elm_Code *code,
402 unsigned int col, unsigned int row, const char *text, unsigned int len)
403{
404 Elm_Code_Line *line;
405 unsigned int position, newcol;
406
407 line = elm_code_file_line_get(code->file, row);
408 position = elm_code_widget_line_text_position_for_column_get(widget, line, col);
409 elm_code_line_text_insert(line, position, text, len);
410
411 newcol = elm_code_widget_line_text_column_width_to_position(widget, line, position + len);
412 elm_obj_code_widget_cursor_position_set(widget, row, newcol);
413}
414
415static void
416_selection_paste_multi(Elm_Code_Widget *widget, Elm_Code *code,
417 unsigned int col, unsigned int row, const char *text, unsigned int len)
418{
419 Elm_Code_Line *line;
420 unsigned int position, newrow, remain;
421 int nlpos;
422 short nllen;
423 char *ptr;
424
425 line = elm_code_file_line_get(code->file, row);
426 position = elm_code_widget_line_text_position_for_column_get(widget, line, col);
427 elm_code_line_split_at(line, position);
428
429 newrow = row;
430 ptr = (char *)text;
431 remain = len;
432 while ((nlpos = elm_code_text_newlinenpos(ptr, remain, &nllen)) != ELM_CODE_TEXT_NOT_FOUND)
433 {
434 if (newrow == row)
435 _selection_paste_single(widget, code, col, row, text, nlpos);
436 else
437 elm_code_file_line_insert(code->file, newrow, ptr, nlpos, NULL);
438
439 remain -= nlpos + nllen;
440 ptr += nlpos + nllen;
441 newrow++;
442 }
443
444 _selection_paste_single(widget, code, 1, newrow, ptr, len - (ptr - text));
445}
446
447static Eina_Bool 400static Eina_Bool
448_selection_paste_cb(void *data, Evas_Object *obj EINA_UNUSED, Elm_Selection_Data *ev) 401_selection_paste_cb(void *data, Evas_Object *obj EINA_UNUSED, Elm_Selection_Data *ev)
449{ 402{
450 Elm_Code *code;
451 Elm_Code_Line *line;
452 Elm_Code_Widget *widget; 403 Elm_Code_Widget *widget;
453 Elm_Code_Widget_Change_Info *change;
454 unsigned int row, col, end_row, end_col, position;
455 404
456 widget = (Elm_Code_Widget *)data; 405 widget = (Elm_Code_Widget *)data;
457 406
458 if (ev->format != ELM_SEL_FORMAT_TEXT) 407 elm_code_widget_text_at_cursor_insert(widget, ev->data);
459 return EINA_TRUE;
460 if (ev->len <= 0)
461 return EINA_TRUE;
462
463 code = elm_obj_code_widget_code_get(widget);
464 elm_obj_code_widget_cursor_position_get(widget, &row, &col);
465
466 if (elm_code_text_newlinenpos(ev->data, ev->len, NULL) == ELM_CODE_TEXT_NOT_FOUND)
467 _selection_paste_single(widget, code, col, row, ev->data, ev->len - 1);
468 else
469 _selection_paste_multi(widget, code, col, row, ev->data, ev->len - 1);
470
471 elm_obj_code_widget_cursor_position_get(widget, &end_row, &end_col);
472
473 line = elm_code_file_line_get(code->file, end_row);
474 position = elm_code_widget_line_text_position_for_column_get(widget, line, end_col);
475
476 change = calloc(1, sizeof(Elm_Code_Widget_Change_Info));
477 change->insert = EINA_TRUE;
478 change->start_col = col;
479 change->start_line = row;
480 change->end_col = position;
481 change->end_line = end_row;
482 change->content = strndup(ev->data, ev->len);
483 change->length = ev->len;
484
485 _elm_code_widget_undo_change_add(widget, change);
486 free((char *)change->content);
487 free(change);
488
489 efl_event_callback_legacy_call(widget, ELM_OBJ_CODE_WIDGET_EVENT_CHANGED_USER, NULL);
490 return EINA_TRUE; 408 return EINA_TRUE;
491} 409}
492 410
diff --git a/src/lib/elementary/elm_code_widget_text.c b/src/lib/elementary/elm_code_widget_text.c
index 1b1b9cbcdd..a06fb8aa0b 100644
--- a/src/lib/elementary/elm_code_widget_text.c
+++ b/src/lib/elementary/elm_code_widget_text.c
@@ -193,3 +193,117 @@ _elm_code_widget_text_tabwidth_at_column_get(Eo *obj EINA_UNUSED, Elm_Code_Widge
193 return pd->tabstop - ((column - 1) % pd->tabstop); 193 return pd->tabstop - ((column - 1) % pd->tabstop);
194} 194}
195 195
196static void
197_elm_code_widget_text_insert_single(Elm_Code_Widget *widget, Elm_Code *code,
198 unsigned int col, unsigned int row, const char *text, unsigned int len)
199{
200 Elm_Code_Line *line;
201 unsigned int position, newcol;
202
203 line = elm_code_file_line_get(code->file, row);
204 position = elm_code_widget_line_text_position_for_column_get(widget, line, col);
205 elm_code_line_text_insert(line, position, text, len);
206
207 newcol = elm_code_widget_line_text_column_width_to_position(widget, line, position + len);
208 elm_obj_code_widget_cursor_position_set(widget, row, newcol);
209}
210
211static void
212_elm_code_widget_text_insert_multi(Elm_Code_Widget *widget, Elm_Code *code,
213 unsigned int col, unsigned int row, const char *text, unsigned int len)
214{
215 Elm_Code_Line *line;
216 unsigned int position, newrow, remain;
217 int nlpos;
218 short nllen;
219 char *ptr;
220
221 line = elm_code_file_line_get(code->file, row);
222 position = elm_code_widget_line_text_position_for_column_get(widget, line, col);
223 elm_code_line_split_at(line, position);
224
225 newrow = row;
226 ptr = (char *)text;
227 remain = len;
228 while ((nlpos = elm_code_text_newlinenpos(ptr, remain, &nllen)) != ELM_CODE_TEXT_NOT_FOUND)
229 {
230 if (newrow == row)
231 _elm_code_widget_text_insert_single(widget, code, col, row, text, nlpos);
232 else
233 elm_code_file_line_insert(code->file, newrow, ptr, nlpos, NULL);
234
235 remain -= nlpos + nllen;
236 ptr += nlpos + nllen;
237 newrow++;
238 }
239
240 _elm_code_widget_text_insert_single(widget, code, 1, newrow, ptr, len - (ptr - text));
241}
242
243void
244_elm_code_widget_text_at_cursor_insert_do(Elm_Code_Widget *widget, const char *text, int length, Eina_Bool undo)
245{
246 Elm_Code *code;
247 Elm_Code_Line *line;
248 Elm_Code_Widget_Change_Info *change;
249 unsigned int row, col, end_row, end_col, curlen, indent;
250 const char *curtext, *indent_text;
251
252 if (undo)
253 elm_code_widget_selection_delete(widget);
254
255 code = elm_obj_code_widget_code_get(widget);
256 elm_obj_code_widget_cursor_position_get(widget, &row, &col);
257 line = elm_code_file_line_get(code->file, row);
258 if (line == NULL)
259 {
260 elm_code_file_line_append(code->file, "", 0, NULL);
261 row = elm_code_file_lines_get(code->file);
262 line = elm_code_file_line_get(code->file, row);
263 }
264 if (text[0] == '}')
265 {
266 curtext = elm_code_line_text_get(line, &curlen);
267
268 if (elm_code_text_is_whitespace(curtext, line->length))
269 {
270 indent_text = elm_code_line_indent_matching_braces_get(line, &indent);
271 elm_code_line_text_leading_whitespace_strip(line);
272
273 if (indent > 0)
274 elm_code_line_text_insert(line, 0, indent_text, indent);
275
276 elm_obj_code_widget_cursor_position_set(widget, row, indent + 1);
277 elm_obj_code_widget_cursor_position_get(widget, &row, &col);
278 }
279 }
280
281 if (elm_code_text_newlinenpos(text, length, NULL) == ELM_CODE_TEXT_NOT_FOUND)
282 _elm_code_widget_text_insert_single(widget, code, col, row, text, length);
283 else
284 _elm_code_widget_text_insert_multi(widget, code, col, row, text, length);
285 elm_obj_code_widget_cursor_position_get(widget, &end_row, &end_col);
286
287 // a workaround for when the cursor position would be off the line width
288 _elm_code_widget_resize(widget, line);
289 efl_event_callback_legacy_call(widget, ELM_OBJ_CODE_WIDGET_EVENT_CHANGED_USER, NULL);
290
291 if (undo)
292 {
293 change = _elm_code_widget_change_create(col, row, end_col, end_row, text, length, EINA_TRUE);
294 _elm_code_widget_undo_change_add(widget, change);
295 _elm_code_widget_change_free(change);
296 }
297}
298
299EOLIAN void
300_elm_code_widget_text_at_cursor_insert(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd EINA_UNUSED, const char *text)
301{
302 _elm_code_widget_text_at_cursor_insert_do(widget, text, strlen(text), EINA_TRUE);
303}
304
305void
306_elm_code_widget_text_at_cursor_insert_no_undo(Elm_Code_Widget *widget, const char *text, unsigned int length)
307{
308 _elm_code_widget_text_at_cursor_insert_do(widget, text, length, EINA_FALSE);
309}