Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / space_text / space_text.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2008 Blender Foundation.
19  * All rights reserved.
20  *
21  *
22  * Contributor(s): Blender Foundation
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/space_text/space_text.c
28  *  \ingroup sptext
29  */
30
31
32 #include <string.h>
33
34 #include "DNA_text_types.h"
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BLI_blenlib.h"
39
40 #include "BKE_context.h"
41 #include "BKE_library.h"
42 #include "BKE_screen.h"
43 #include "BKE_text.h"
44
45 #include "ED_space_api.h"
46 #include "ED_screen.h"
47
48 #include "BIF_gl.h"
49
50 #include "WM_api.h"
51 #include "WM_types.h"
52
53 #include "UI_interface.h"
54 #include "UI_resources.h"
55 #include "UI_view2d.h"
56
57 #include "RNA_access.h"
58
59
60 #include "text_format.h"
61 #include "text_intern.h"  /* own include */
62
63 /* ******************** default callbacks for text space ***************** */
64
65 static SpaceLink *text_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
66 {
67         ARegion *ar;
68         SpaceText *stext;
69
70         stext = MEM_callocN(sizeof(SpaceText), "inittext");
71         stext->spacetype = SPACE_TEXT;
72
73         stext->lheight = 12;
74         stext->tabnumber = 4;
75         stext->margin_column = 80;
76
77         /* header */
78         ar = MEM_callocN(sizeof(ARegion), "header for text");
79
80         BLI_addtail(&stext->regionbase, ar);
81         ar->regiontype = RGN_TYPE_HEADER;
82         ar->alignment = RGN_ALIGN_TOP;
83
84         /* properties region */
85         ar = MEM_callocN(sizeof(ARegion), "properties region for text");
86
87         BLI_addtail(&stext->regionbase, ar);
88         ar->regiontype = RGN_TYPE_UI;
89         ar->alignment = RGN_ALIGN_LEFT;
90         ar->flag = RGN_FLAG_HIDDEN;
91
92         /* main region */
93         ar = MEM_callocN(sizeof(ARegion), "main region for text");
94
95         BLI_addtail(&stext->regionbase, ar);
96         ar->regiontype = RGN_TYPE_WINDOW;
97
98         return (SpaceLink *)stext;
99 }
100
101 /* not spacelink itself */
102 static void text_free(SpaceLink *sl)
103 {
104         SpaceText *stext = (SpaceText *) sl;
105
106         stext->text = NULL;
107         text_free_caches(stext);
108 }
109
110
111 /* spacetype; init callback */
112 static void text_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
113 {
114
115 }
116
117 static SpaceLink *text_duplicate(SpaceLink *sl)
118 {
119         SpaceText *stextn = MEM_dupallocN(sl);
120
121         /* clear or remove stuff from old */
122
123         stextn->drawcache = NULL; /* space need it's own cache */
124
125         return (SpaceLink *)stextn;
126 }
127
128 static void text_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene),
129                           WorkSpace *UNUSED(workspace))
130 {
131         SpaceText *st = sa->spacedata.first;
132
133         /* context changes */
134         switch (wmn->category) {
135                 case NC_TEXT:
136                         /* check if active text was changed, no need to redraw if text isn't active
137                          * (reference == NULL) means text was unlinked, should update anyway for this
138                          * case -- no way to know was text active before unlinking or not */
139                         if (wmn->reference && wmn->reference != st->text)
140                                 break;
141
142                         switch (wmn->data) {
143                                 case ND_DISPLAY:
144                                         ED_area_tag_redraw(sa);
145                                         break;
146                                 case ND_CURSOR:
147                                         if (st->text && st->text == wmn->reference)
148                                                 text_scroll_to_cursor__area(st, sa, true);
149
150                                         ED_area_tag_redraw(sa);
151                                         break;
152                         }
153
154                         switch (wmn->action) {
155                                 case NA_EDITED:
156                                         if (st->text) {
157                                                 text_drawcache_tag_update(st, 1);
158                                                 text_update_edited(st->text);
159                                         }
160
161                                         ED_area_tag_redraw(sa);
162                                         ATTR_FALLTHROUGH;  /* fall down to tag redraw */
163                                 case NA_ADDED:
164                                 case NA_REMOVED:
165                                         ED_area_tag_redraw(sa);
166                                         break;
167                                 case NA_SELECTED:
168                                         if (st->text && st->text == wmn->reference)
169                                                 text_scroll_to_cursor__area(st, sa, true);
170
171                                         break;
172                         }
173
174                         break;
175                 case NC_SPACE:
176                         if (wmn->data == ND_SPACE_TEXT)
177                                 ED_area_tag_redraw(sa);
178                         break;
179         }
180 }
181
182 static void text_operatortypes(void)
183 {
184         WM_operatortype_append(TEXT_OT_new);
185         WM_operatortype_append(TEXT_OT_open);
186         WM_operatortype_append(TEXT_OT_reload);
187         WM_operatortype_append(TEXT_OT_unlink);
188         WM_operatortype_append(TEXT_OT_save);
189         WM_operatortype_append(TEXT_OT_save_as);
190         WM_operatortype_append(TEXT_OT_make_internal);
191         WM_operatortype_append(TEXT_OT_run_script);
192         WM_operatortype_append(TEXT_OT_refresh_pyconstraints);
193
194         WM_operatortype_append(TEXT_OT_paste);
195         WM_operatortype_append(TEXT_OT_copy);
196         WM_operatortype_append(TEXT_OT_cut);
197         WM_operatortype_append(TEXT_OT_duplicate_line);
198
199         WM_operatortype_append(TEXT_OT_convert_whitespace);
200         WM_operatortype_append(TEXT_OT_uncomment);
201         WM_operatortype_append(TEXT_OT_comment);
202         WM_operatortype_append(TEXT_OT_unindent);
203         WM_operatortype_append(TEXT_OT_indent);
204
205         WM_operatortype_append(TEXT_OT_select_line);
206         WM_operatortype_append(TEXT_OT_select_all);
207         WM_operatortype_append(TEXT_OT_select_word);
208
209         WM_operatortype_append(TEXT_OT_move_lines);
210
211         WM_operatortype_append(TEXT_OT_jump);
212         WM_operatortype_append(TEXT_OT_move);
213         WM_operatortype_append(TEXT_OT_move_select);
214         WM_operatortype_append(TEXT_OT_delete);
215         WM_operatortype_append(TEXT_OT_overwrite_toggle);
216
217         WM_operatortype_append(TEXT_OT_selection_set);
218         WM_operatortype_append(TEXT_OT_cursor_set);
219         WM_operatortype_append(TEXT_OT_scroll);
220         WM_operatortype_append(TEXT_OT_scroll_bar);
221         WM_operatortype_append(TEXT_OT_line_number);
222
223         WM_operatortype_append(TEXT_OT_line_break);
224         WM_operatortype_append(TEXT_OT_insert);
225
226         WM_operatortype_append(TEXT_OT_properties);
227
228         WM_operatortype_append(TEXT_OT_find);
229         WM_operatortype_append(TEXT_OT_find_set_selected);
230         WM_operatortype_append(TEXT_OT_replace);
231         WM_operatortype_append(TEXT_OT_replace_set_selected);
232
233         WM_operatortype_append(TEXT_OT_start_find);
234
235         WM_operatortype_append(TEXT_OT_to_3d_object);
236
237         WM_operatortype_append(TEXT_OT_resolve_conflict);
238
239         WM_operatortype_append(TEXT_OT_autocomplete);
240 }
241
242 static void text_keymap(struct wmKeyConfig *keyconf)
243 {
244         wmKeyMap *keymap;
245         wmKeyMapItem *kmi;
246
247         keymap = WM_keymap_find(keyconf, "Text Generic", SPACE_TEXT, 0);
248         WM_keymap_add_item(keymap, "TEXT_OT_start_find", FKEY, KM_PRESS, KM_CTRL, 0);
249 #ifdef __APPLE__
250         WM_keymap_add_item(keymap, "TEXT_OT_start_find", FKEY, KM_PRESS, KM_OSKEY, 0);
251 #endif
252         WM_keymap_add_item(keymap, "TEXT_OT_jump", JKEY, KM_PRESS, KM_CTRL, 0);
253         WM_keymap_add_item(keymap, "TEXT_OT_find", GKEY, KM_PRESS, KM_CTRL, 0);
254         WM_keymap_add_item(keymap, "TEXT_OT_replace", HKEY, KM_PRESS, KM_CTRL, 0);
255         WM_keymap_add_item(keymap, "TEXT_OT_properties", TKEY, KM_PRESS, KM_CTRL, 0);
256
257         keymap = WM_keymap_find(keyconf, "Text", SPACE_TEXT, 0);
258
259 #ifdef __APPLE__
260         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);
261         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_END);
262         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_ALT, 0)->ptr, "type", PREV_WORD);
263         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_ALT, 0)->ptr, "type", NEXT_WORD);
264         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", UPARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", FILE_TOP);
265         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", DOWNARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", FILE_BOTTOM);
266
267         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);
268         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0)->ptr, "type", LINE_END);
269         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "type", PREV_WORD);
270         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "type", NEXT_WORD);
271         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", UPARROWKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0)->ptr, "type", FILE_TOP);
272         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", DOWNARROWKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0)->ptr, "type", FILE_BOTTOM);
273
274         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", BACKSPACEKEY, KM_PRESS, KM_ALT, 0)->ptr, "type", DEL_PREV_WORD);
275
276         WM_keymap_add_item(keymap, "TEXT_OT_save", SKEY, KM_PRESS, KM_ALT | KM_OSKEY, 0);
277         WM_keymap_add_item(keymap, "TEXT_OT_save_as", SKEY, KM_PRESS, KM_ALT | KM_SHIFT | KM_OSKEY, 0);
278         WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_OSKEY, 0);
279         WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);
280         WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);
281         WM_keymap_add_item(keymap, "TEXT_OT_find_set_selected", EKEY, KM_PRESS, KM_OSKEY, 0);
282         WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_OSKEY, 0);
283         WM_keymap_add_item(keymap, "TEXT_OT_select_line", AKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0);
284 #endif
285
286         kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0);
287         RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
288         RNA_boolean_set(kmi->ptr, "reverse", false);
289
290         kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0);
291         RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
292         RNA_boolean_set(kmi->ptr, "reverse", true);
293
294         kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
295         RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
296         RNA_boolean_set(kmi->ptr, "reverse", false);
297
298         kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADMINUS, KM_PRESS, KM_CTRL, 0);
299         RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
300         RNA_boolean_set(kmi->ptr, "reverse", true);
301
302         WM_keymap_add_item(keymap, "TEXT_OT_new", NKEY, KM_PRESS, KM_CTRL, 0);
303         WM_keymap_add_item(keymap, "TEXT_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
304         WM_keymap_add_item(keymap, "TEXT_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
305         WM_keymap_add_item(keymap, "TEXT_OT_save", SKEY, KM_PRESS, KM_ALT, 0);
306         WM_keymap_add_item(keymap, "TEXT_OT_save_as", SKEY, KM_PRESS, KM_ALT | KM_SHIFT | KM_CTRL, 0);
307
308         WM_keymap_add_item(keymap, "TEXT_OT_run_script", PKEY, KM_PRESS, KM_ALT, 0);
309
310         WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_CTRL, 0);
311         WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
312         WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
313
314         WM_keymap_add_item(keymap, "TEXT_OT_cut", DELKEY, KM_PRESS, KM_SHIFT, 0);
315         WM_keymap_add_item(keymap, "TEXT_OT_copy", INSERTKEY, KM_PRESS, KM_CTRL, 0);
316         WM_keymap_add_item(keymap, "TEXT_OT_paste", INSERTKEY, KM_PRESS, KM_SHIFT, 0);
317
318         WM_keymap_add_item(keymap, "TEXT_OT_duplicate_line", DKEY, KM_PRESS, KM_CTRL, 0);
319
320         if (U.uiflag & USER_MMB_PASTE) { // XXX not dynamic
321                 kmi = WM_keymap_add_item(keymap, "TEXT_OT_paste", MIDDLEMOUSE, KM_PRESS, 0, 0);
322                 RNA_boolean_set(kmi->ptr, "selection", true);
323         }
324
325         WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_CTRL, 0);
326         WM_keymap_add_item(keymap, "TEXT_OT_select_line", AKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
327         WM_keymap_add_item(keymap, "TEXT_OT_select_word", LEFTMOUSE, KM_DBL_CLICK, 0, 0);
328
329         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_lines", UPARROWKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "direction", TXT_MOVE_LINE_UP);
330         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_lines", DOWNARROWKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "direction", TXT_MOVE_LINE_DOWN);
331
332         WM_keymap_add_item(keymap, "TEXT_OT_indent", TABKEY, KM_PRESS, 0, 0);
333         WM_keymap_add_item(keymap, "TEXT_OT_unindent", TABKEY, KM_PRESS, KM_SHIFT, 0);
334         WM_keymap_add_item(keymap, "TEXT_OT_uncomment", DKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
335
336         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN);
337         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END);
338
339         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", EKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_END);
340         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", EKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "type", LINE_END);
341         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_CHAR);
342         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_CHAR);
343         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", PREV_WORD);
344         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", NEXT_WORD);
345         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_LINE);
346         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_LINE);
347         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", PAGEUPKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_PAGE);
348         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", PAGEDOWNKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_PAGE);
349         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", HOMEKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", FILE_TOP);
350         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", ENDKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", FILE_BOTTOM);
351
352         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", HOMEKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", LINE_BEGIN);
353         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", ENDKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", LINE_END);
354         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", PREV_CHAR);
355         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", NEXT_CHAR);
356         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "type", PREV_WORD);
357         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "type", NEXT_WORD);
358         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", UPARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", PREV_LINE);
359         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", DOWNARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", NEXT_LINE);
360         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", PAGEUPKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", PREV_PAGE);
361         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", PAGEDOWNKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", NEXT_PAGE);
362         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", HOMEKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "type", FILE_TOP);
363         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", ENDKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "type", FILE_BOTTOM);
364
365         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", DELKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_NEXT_CHAR);
366         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_PREV_CHAR);
367         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", BACKSPACEKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", DEL_PREV_CHAR); /* same as above [#26623] */
368         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", DELKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_NEXT_WORD);
369         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", BACKSPACEKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_PREV_WORD);
370
371         WM_keymap_add_item(keymap, "TEXT_OT_overwrite_toggle", INSERTKEY, KM_PRESS, 0, 0);
372
373         WM_keymap_add_item(keymap, "TEXT_OT_scroll_bar", LEFTMOUSE, KM_PRESS, 0, 0);
374         WM_keymap_add_item(keymap, "TEXT_OT_scroll_bar", MIDDLEMOUSE, KM_PRESS, 0, 0);
375
376         WM_keymap_add_item(keymap, "TEXT_OT_scroll", MIDDLEMOUSE, KM_PRESS, 0, 0);
377         WM_keymap_add_item(keymap, "TEXT_OT_scroll", MOUSEPAN, 0, 0, 0);
378         WM_keymap_add_item(keymap, "TEXT_OT_selection_set", EVT_TWEAK_L, KM_ANY, 0, 0);
379         WM_keymap_add_item(keymap, "TEXT_OT_cursor_set", LEFTMOUSE, KM_PRESS, 0, 0);
380         kmi = WM_keymap_add_item(keymap, "TEXT_OT_selection_set", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
381         RNA_boolean_set(kmi->ptr, "select", true);
382         RNA_int_set(WM_keymap_add_item(keymap, "TEXT_OT_scroll", WHEELUPMOUSE, KM_PRESS, 0, 0)->ptr, "lines", -1);
383         RNA_int_set(WM_keymap_add_item(keymap, "TEXT_OT_scroll", WHEELDOWNMOUSE, KM_PRESS, 0, 0)->ptr, "lines", 1);
384
385         WM_keymap_add_item(keymap, "TEXT_OT_line_break", RETKEY, KM_PRESS, 0, 0);
386         WM_keymap_add_item(keymap, "TEXT_OT_line_break", PADENTER, KM_PRESS, 0, 0);
387
388         WM_keymap_add_menu(keymap, "TEXT_MT_toolbox", RIGHTMOUSE, KM_PRESS, KM_ANY, 0);
389
390         WM_keymap_add_item(keymap, "TEXT_OT_autocomplete", SPACEKEY, KM_PRESS, KM_CTRL, 0);
391
392         WM_keymap_add_item(keymap, "TEXT_OT_line_number", KM_TEXTINPUT, KM_ANY, KM_ANY, 0);
393         WM_keymap_add_item(keymap, "TEXT_OT_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last!
394 }
395
396 const char *text_context_dir[] = {"edit_text", NULL};
397
398 static int text_context(const bContext *C, const char *member, bContextDataResult *result)
399 {
400         SpaceText *st = CTX_wm_space_text(C);
401
402         if (CTX_data_dir(member)) {
403                 CTX_data_dir_set(result, text_context_dir);
404                 return 1;
405         }
406         else if (CTX_data_equals(member, "edit_text")) {
407                 CTX_data_id_pointer_set(result, &st->text->id);
408                 return 1;
409         }
410
411         return 0;
412 }
413
414 /********************* main region ********************/
415
416 /* add handlers, stuff you only do once or on area/region changes */
417 static void text_main_region_init(wmWindowManager *wm, ARegion *ar)
418 {
419         wmKeyMap *keymap;
420         ListBase *lb;
421
422         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
423
424         /* own keymap */
425         keymap = WM_keymap_find(wm->defaultconf, "Text Generic", SPACE_TEXT, 0);
426         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
427         keymap = WM_keymap_find(wm->defaultconf, "Text", SPACE_TEXT, 0);
428         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
429
430         /* add drop boxes */
431         lb = WM_dropboxmap_find("Text", SPACE_TEXT, RGN_TYPE_WINDOW);
432
433         WM_event_add_dropbox_handler(&ar->handlers, lb);
434 }
435
436 static void text_main_region_draw(const bContext *C, ARegion *ar)
437 {
438         /* draw entirely, view changes should be handled here */
439         SpaceText *st = CTX_wm_space_text(C);
440         //View2D *v2d = &ar->v2d;
441
442         /* clear and setup matrix */
443         UI_ThemeClearColor(TH_BACK);
444         glClear(GL_COLOR_BUFFER_BIT);
445
446         // UI_view2d_view_ortho(v2d);
447
448         /* data... */
449         draw_text_main(st, ar);
450
451         /* reset view matrix */
452         // UI_view2d_view_restore(C);
453
454         /* scrollers? */
455 }
456
457 static void text_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
458 {
459         SpaceText *st = sa->spacedata.first;
460         int wmcursor = BC_TEXTEDITCURSOR;
461
462         if (st->text && BLI_rcti_isect_pt(&st->txtbar, win->eventstate->x - ar->winrct.xmin, st->txtbar.ymin)) {
463                 wmcursor = CURSOR_STD;
464         }
465
466         WM_cursor_set(win, wmcursor);
467 }
468
469
470
471 /* ************* dropboxes ************* */
472
473 static int text_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
474 {
475         if (drag->type == WM_DRAG_PATH) {
476                 /* rule might not work? */
477                 if (ELEM(drag->icon, ICON_FILE_SCRIPT, ICON_FILE_TEXT, ICON_FILE_BLANK)) {
478                         return true;
479                 }
480         }
481         return false;
482 }
483
484 static void text_drop_copy(wmDrag *drag, wmDropBox *drop)
485 {
486         /* copy drag path to properties */
487         RNA_string_set(drop->ptr, "filepath", drag->path);
488 }
489
490 static int text_drop_paste_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
491 {
492         if (drag->type == WM_DRAG_ID)
493                 return true;
494
495         return false;
496 }
497
498 static void text_drop_paste(wmDrag *drag, wmDropBox *drop)
499 {
500         char *text;
501         ID *id = drag->poin;
502
503         /* copy drag path to properties */
504         text = RNA_path_full_ID_py(id);
505         RNA_string_set(drop->ptr, "text", text);
506         MEM_freeN(text);
507 }
508
509 /* this region dropbox definition */
510 static void text_dropboxes(void)
511 {
512         ListBase *lb = WM_dropboxmap_find("Text", SPACE_TEXT, RGN_TYPE_WINDOW);
513
514         WM_dropbox_add(lb, "TEXT_OT_open", text_drop_poll, text_drop_copy);
515         WM_dropbox_add(lb, "TEXT_OT_insert", text_drop_paste_poll, text_drop_paste);
516 }
517
518 /* ************* end drop *********** */
519
520
521 /****************** header region ******************/
522
523 /* add handlers, stuff you only do once or on area/region changes */
524 static void text_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar)
525 {
526         ED_region_header_init(ar);
527 }
528
529 static void text_header_region_draw(const bContext *C, ARegion *ar)
530 {
531         ED_region_header(C, ar);
532 }
533
534 /****************** properties region ******************/
535
536 /* add handlers, stuff you only do once or on area/region changes */
537 static void text_properties_region_init(wmWindowManager *wm, ARegion *ar)
538 {
539         wmKeyMap *keymap;
540
541         ar->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
542         ED_region_panels_init(wm, ar);
543
544         /* own keymaps */
545         keymap = WM_keymap_find(wm->defaultconf, "Text Generic", SPACE_TEXT, 0);
546         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
547
548 }
549
550 static void text_properties_region_draw(const bContext *C, ARegion *ar)
551 {
552         SpaceText *st = CTX_wm_space_text(C);
553
554         ED_region_panels(C, ar, NULL, -1, true);
555
556         /* this flag trick is make sure buttons have been added already */
557         if (st->flags & ST_FIND_ACTIVATE) {
558                 if (UI_textbutton_activate_rna(C, ar, st, "find_text")) {
559                         /* if the panel was already open we need to do another redraw */
560                         ScrArea *sa = CTX_wm_area(C);
561                         WM_event_add_notifier(C, NC_SPACE | ND_SPACE_TEXT, sa);
562                 }
563                 st->flags &= ~ST_FIND_ACTIVATE;
564         }
565 }
566
567 static void text_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
568 {
569         SpaceText *stext = (SpaceText *)slink;
570
571         if (!ELEM(GS(old_id->name), ID_TXT)) {
572                 return;
573         }
574
575         if ((ID *)stext->text == old_id) {
576                 stext->text = (Text *)new_id;
577                 id_us_ensure_real(new_id);
578         }
579 }
580
581 /********************* registration ********************/
582
583 /* only called once, from space/spacetypes.c */
584 void ED_spacetype_text(void)
585 {
586         SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype text");
587         ARegionType *art;
588
589         st->spaceid = SPACE_TEXT;
590         strncpy(st->name, "Text", BKE_ST_MAXNAME);
591
592         st->new = text_new;
593         st->free = text_free;
594         st->init = text_init;
595         st->duplicate = text_duplicate;
596         st->operatortypes = text_operatortypes;
597         st->keymap = text_keymap;
598         st->listener = text_listener;
599         st->context = text_context;
600         st->dropboxes = text_dropboxes;
601         st->id_remap = text_id_remap;
602
603         /* regions: main window */
604         art = MEM_callocN(sizeof(ARegionType), "spacetype text region");
605         art->regionid = RGN_TYPE_WINDOW;
606         art->init = text_main_region_init;
607         art->draw = text_main_region_draw;
608         art->cursor = text_cursor;
609         art->event_cursor = true;
610
611         BLI_addhead(&st->regiontypes, art);
612
613         /* regions: properties */
614         art = MEM_callocN(sizeof(ARegionType), "spacetype text region");
615         art->regionid = RGN_TYPE_UI;
616         art->prefsizex = UI_COMPACT_PANEL_WIDTH;
617         art->keymapflag = ED_KEYMAP_UI;
618
619         art->init = text_properties_region_init;
620         art->draw = text_properties_region_draw;
621         BLI_addhead(&st->regiontypes, art);
622
623         /* regions: header */
624         art = MEM_callocN(sizeof(ARegionType), "spacetype text region");
625         art->regionid = RGN_TYPE_HEADER;
626         art->prefsizey = HEADERY;
627         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;
628
629         art->init = text_header_region_init;
630         art->draw = text_header_region_draw;
631
632         BLI_addhead(&st->regiontypes, art);
633
634         BKE_spacetype_register(st);
635
636         /* register formatters */
637         ED_text_format_register_py();
638         ED_text_format_register_osl();
639         ED_text_format_register_lua();
640         ED_text_format_register_pov();
641         ED_text_format_register_pov_ini();
642 }
643