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 bContext *UNUSED(C))
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_BOTTOM;
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, const Scene *UNUSED(scene))
129 {
130         SpaceText *st = sa->spacedata.first;
131
132         /* context changes */
133         switch (wmn->category) {
134                 case NC_TEXT:
135                         /* check if active text was changed, no need to redraw if text isn't active
136                          * (reference == NULL) means text was unlinked, should update anyway for this
137                          * case -- no way to know was text active before unlinking or not */
138                         if (wmn->reference && wmn->reference != st->text)
139                                 break;
140
141                         switch (wmn->data) {
142                                 case ND_DISPLAY:
143                                         ED_area_tag_redraw(sa);
144                                         break;
145                                 case ND_CURSOR:
146                                         if (st->text && st->text == wmn->reference)
147                                                 text_scroll_to_cursor__area(st, sa, true);
148
149                                         ED_area_tag_redraw(sa);
150                                         break;
151                         }
152
153                         switch (wmn->action) {
154                                 case NA_EDITED:
155                                         if (st->text) {
156                                                 text_drawcache_tag_update(st, 1);
157                                                 text_update_edited(st->text);
158                                         }
159
160                                         ED_area_tag_redraw(sa);
161                                         ATTR_FALLTHROUGH;  /* fall down to tag redraw */
162                                 case NA_ADDED:
163                                 case NA_REMOVED:
164                                         ED_area_tag_redraw(sa);
165                                         break;
166                                 case NA_SELECTED:
167                                         if (st->text && st->text == wmn->reference)
168                                                 text_scroll_to_cursor__area(st, sa, true);
169
170                                         break;
171                         }
172
173                         break;
174                 case NC_SPACE:
175                         if (wmn->data == ND_SPACE_TEXT)
176                                 ED_area_tag_redraw(sa);
177                         break;
178         }
179 }
180
181 static void text_operatortypes(void)
182 {
183         WM_operatortype_append(TEXT_OT_new);
184         WM_operatortype_append(TEXT_OT_open);
185         WM_operatortype_append(TEXT_OT_reload);
186         WM_operatortype_append(TEXT_OT_unlink);
187         WM_operatortype_append(TEXT_OT_save);
188         WM_operatortype_append(TEXT_OT_save_as);
189         WM_operatortype_append(TEXT_OT_make_internal);
190         WM_operatortype_append(TEXT_OT_run_script);
191         WM_operatortype_append(TEXT_OT_refresh_pyconstraints);
192
193         WM_operatortype_append(TEXT_OT_paste);
194         WM_operatortype_append(TEXT_OT_copy);
195         WM_operatortype_append(TEXT_OT_cut);
196         WM_operatortype_append(TEXT_OT_duplicate_line);
197
198         WM_operatortype_append(TEXT_OT_convert_whitespace);
199         WM_operatortype_append(TEXT_OT_uncomment);
200         WM_operatortype_append(TEXT_OT_comment);
201         WM_operatortype_append(TEXT_OT_unindent);
202         WM_operatortype_append(TEXT_OT_indent);
203
204         WM_operatortype_append(TEXT_OT_select_line);
205         WM_operatortype_append(TEXT_OT_select_all);
206         WM_operatortype_append(TEXT_OT_select_word);
207         
208         WM_operatortype_append(TEXT_OT_move_lines);
209
210         WM_operatortype_append(TEXT_OT_jump);
211         WM_operatortype_append(TEXT_OT_move);
212         WM_operatortype_append(TEXT_OT_move_select);
213         WM_operatortype_append(TEXT_OT_delete);
214         WM_operatortype_append(TEXT_OT_overwrite_toggle);
215
216         WM_operatortype_append(TEXT_OT_selection_set);
217         WM_operatortype_append(TEXT_OT_cursor_set);
218         WM_operatortype_append(TEXT_OT_scroll);
219         WM_operatortype_append(TEXT_OT_scroll_bar);
220         WM_operatortype_append(TEXT_OT_line_number);
221
222         WM_operatortype_append(TEXT_OT_line_break);
223         WM_operatortype_append(TEXT_OT_insert);
224
225         WM_operatortype_append(TEXT_OT_properties);
226
227         WM_operatortype_append(TEXT_OT_find);
228         WM_operatortype_append(TEXT_OT_find_set_selected);
229         WM_operatortype_append(TEXT_OT_replace);
230         WM_operatortype_append(TEXT_OT_replace_set_selected);
231
232         WM_operatortype_append(TEXT_OT_start_find);
233         
234         WM_operatortype_append(TEXT_OT_to_3d_object);
235
236         WM_operatortype_append(TEXT_OT_resolve_conflict);
237
238         WM_operatortype_append(TEXT_OT_autocomplete);
239 }
240
241 static void text_keymap(struct wmKeyConfig *keyconf)
242 {
243         wmKeyMap *keymap;
244         wmKeyMapItem *kmi;
245         
246         keymap = WM_keymap_find(keyconf, "Text Generic", SPACE_TEXT, 0);
247         WM_keymap_add_item(keymap, "TEXT_OT_start_find", FKEY, KM_PRESS, KM_CTRL, 0);
248 #ifdef __APPLE__
249         WM_keymap_add_item(keymap, "TEXT_OT_start_find", FKEY, KM_PRESS, KM_OSKEY, 0);
250 #endif
251         WM_keymap_add_item(keymap, "TEXT_OT_jump", JKEY, KM_PRESS, KM_CTRL, 0);
252         WM_keymap_add_item(keymap, "TEXT_OT_find", GKEY, KM_PRESS, KM_CTRL, 0);
253         WM_keymap_add_item(keymap, "TEXT_OT_replace", HKEY, KM_PRESS, KM_CTRL, 0);
254         WM_keymap_add_item(keymap, "TEXT_OT_properties", TKEY, KM_PRESS, KM_CTRL, 0);
255
256         keymap = WM_keymap_find(keyconf, "Text", SPACE_TEXT, 0);
257         
258 #ifdef __APPLE__
259         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);
260         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", LINE_END);
261         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_ALT, 0)->ptr, "type", PREV_WORD);
262         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_ALT, 0)->ptr, "type", NEXT_WORD);
263         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", UPARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", FILE_TOP);
264         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", DOWNARROWKEY, KM_PRESS, KM_OSKEY, 0)->ptr, "type", FILE_BOTTOM);
265         
266         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0)->ptr, "type", LINE_BEGIN);
267         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0)->ptr, "type", LINE_END);
268         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "type", PREV_WORD);
269         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "type", NEXT_WORD);
270         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", UPARROWKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0)->ptr, "type", FILE_TOP);
271         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", DOWNARROWKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0)->ptr, "type", FILE_BOTTOM);
272         
273         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", BACKSPACEKEY, KM_PRESS, KM_ALT, 0)->ptr, "type", DEL_PREV_WORD);
274         
275         WM_keymap_add_item(keymap, "TEXT_OT_save", SKEY, KM_PRESS, KM_ALT | KM_OSKEY, 0);
276         WM_keymap_add_item(keymap, "TEXT_OT_save_as", SKEY, KM_PRESS, KM_ALT | KM_SHIFT | KM_OSKEY, 0);
277         WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_OSKEY, 0);
278         WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0); 
279         WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);
280         WM_keymap_add_item(keymap, "TEXT_OT_find_set_selected", EKEY, KM_PRESS, KM_OSKEY, 0);
281         WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_OSKEY, 0);
282         WM_keymap_add_item(keymap, "TEXT_OT_select_line", AKEY, KM_PRESS, KM_SHIFT | KM_OSKEY, 0);
283 #endif
284         
285         kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0);
286         RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
287         RNA_boolean_set(kmi->ptr, "reverse", false);
288         
289         kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0);
290         RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
291         RNA_boolean_set(kmi->ptr, "reverse", true);
292
293         kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
294         RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
295         RNA_boolean_set(kmi->ptr, "reverse", false);
296         
297         kmi = WM_keymap_add_item(keymap, "WM_OT_context_cycle_int", PADMINUS, KM_PRESS, KM_CTRL, 0);
298         RNA_string_set(kmi->ptr, "data_path", "space_data.font_size");
299         RNA_boolean_set(kmi->ptr, "reverse", true);
300
301         WM_keymap_add_item(keymap, "TEXT_OT_new", NKEY, KM_PRESS, KM_CTRL, 0);
302         WM_keymap_add_item(keymap, "TEXT_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
303         WM_keymap_add_item(keymap, "TEXT_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
304         WM_keymap_add_item(keymap, "TEXT_OT_save", SKEY, KM_PRESS, KM_ALT, 0);
305         WM_keymap_add_item(keymap, "TEXT_OT_save_as", SKEY, KM_PRESS, KM_ALT | KM_SHIFT | KM_CTRL, 0);
306
307         WM_keymap_add_item(keymap, "TEXT_OT_run_script", PKEY, KM_PRESS, KM_ALT, 0);
308         
309         WM_keymap_add_item(keymap, "TEXT_OT_cut", XKEY, KM_PRESS, KM_CTRL, 0);
310         WM_keymap_add_item(keymap, "TEXT_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
311         WM_keymap_add_item(keymap, "TEXT_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
312
313         WM_keymap_add_item(keymap, "TEXT_OT_cut", DELKEY, KM_PRESS, KM_SHIFT, 0);
314         WM_keymap_add_item(keymap, "TEXT_OT_copy", INSERTKEY, KM_PRESS, KM_CTRL, 0);
315         WM_keymap_add_item(keymap, "TEXT_OT_paste", INSERTKEY, KM_PRESS, KM_SHIFT, 0);
316         
317         WM_keymap_add_item(keymap, "TEXT_OT_duplicate_line", DKEY, KM_PRESS, KM_CTRL, 0);
318
319         if (U.uiflag & USER_MMB_PASTE) { // XXX not dynamic
320                 kmi = WM_keymap_add_item(keymap, "TEXT_OT_paste", MIDDLEMOUSE, KM_PRESS, 0, 0);
321                 RNA_boolean_set(kmi->ptr, "selection", true);
322         }
323
324         WM_keymap_add_item(keymap, "TEXT_OT_select_all", AKEY, KM_PRESS, KM_CTRL, 0);
325         WM_keymap_add_item(keymap, "TEXT_OT_select_line", AKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
326         WM_keymap_add_item(keymap, "TEXT_OT_select_word", LEFTMOUSE, KM_DBL_CLICK, 0, 0);
327
328         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);
329         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);
330         
331         WM_keymap_add_item(keymap, "TEXT_OT_indent", TABKEY, KM_PRESS, 0, 0);
332         WM_keymap_add_item(keymap, "TEXT_OT_unindent", TABKEY, KM_PRESS, KM_SHIFT, 0);
333         WM_keymap_add_item(keymap, "TEXT_OT_uncomment", DKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
334
335         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN);
336         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END);
337         
338         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", EKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", LINE_END);
339         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", EKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "type", LINE_END);
340         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_CHAR);
341         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_CHAR);
342         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", PREV_WORD);
343         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", NEXT_WORD);
344         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_LINE);
345         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", DOWNARROWKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_LINE);
346         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", PAGEUPKEY, KM_PRESS, 0, 0)->ptr, "type", PREV_PAGE);
347         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", PAGEDOWNKEY, KM_PRESS, 0, 0)->ptr, "type", NEXT_PAGE);
348         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", HOMEKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", FILE_TOP);
349         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move", ENDKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", FILE_BOTTOM);
350
351         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", HOMEKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", LINE_BEGIN);
352         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", ENDKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", LINE_END);
353         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", PREV_CHAR);
354         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", NEXT_CHAR);
355         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "type", PREV_WORD);
356         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "type", NEXT_WORD);
357         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", UPARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", PREV_LINE);
358         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", DOWNARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", NEXT_LINE);
359         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", PAGEUPKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", PREV_PAGE);
360         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", PAGEDOWNKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", NEXT_PAGE);
361         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", HOMEKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "type", FILE_TOP);
362         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_move_select", ENDKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "type", FILE_BOTTOM);
363
364         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", DELKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_NEXT_CHAR);
365         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_PREV_CHAR);
366         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] */
367         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", DELKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_NEXT_WORD);
368         RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", BACKSPACEKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_PREV_WORD);
369         
370         WM_keymap_add_item(keymap, "TEXT_OT_overwrite_toggle", INSERTKEY, KM_PRESS, 0, 0);
371
372         WM_keymap_add_item(keymap, "TEXT_OT_scroll_bar", LEFTMOUSE, KM_PRESS, 0, 0);
373         WM_keymap_add_item(keymap, "TEXT_OT_scroll_bar", MIDDLEMOUSE, KM_PRESS, 0, 0);
374
375         WM_keymap_add_item(keymap, "TEXT_OT_scroll", MIDDLEMOUSE, KM_PRESS, 0, 0);
376         WM_keymap_add_item(keymap, "TEXT_OT_scroll", MOUSEPAN, 0, 0, 0);
377         WM_keymap_add_item(keymap, "TEXT_OT_selection_set", EVT_TWEAK_L, KM_ANY, 0, 0);
378         WM_keymap_add_item(keymap, "TEXT_OT_cursor_set", LEFTMOUSE, KM_PRESS, 0, 0);
379         kmi = WM_keymap_add_item(keymap, "TEXT_OT_selection_set", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
380         RNA_boolean_set(kmi->ptr, "select", true);
381         RNA_int_set(WM_keymap_add_item(keymap, "TEXT_OT_scroll", WHEELUPMOUSE, KM_PRESS, 0, 0)->ptr, "lines", -1);
382         RNA_int_set(WM_keymap_add_item(keymap, "TEXT_OT_scroll", WHEELDOWNMOUSE, KM_PRESS, 0, 0)->ptr, "lines", 1);
383
384         WM_keymap_add_item(keymap, "TEXT_OT_line_break", RETKEY, KM_PRESS, 0, 0);
385         WM_keymap_add_item(keymap, "TEXT_OT_line_break", PADENTER, KM_PRESS, 0, 0);
386
387         WM_keymap_add_menu(keymap, "TEXT_MT_toolbox", RIGHTMOUSE, KM_PRESS, KM_ANY, 0);
388
389         WM_keymap_add_item(keymap, "TEXT_OT_autocomplete", SPACEKEY, KM_PRESS, KM_CTRL, 0);
390         
391         WM_keymap_add_item(keymap, "TEXT_OT_line_number", KM_TEXTINPUT, KM_ANY, KM_ANY, 0);
392         WM_keymap_add_item(keymap, "TEXT_OT_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last!
393 }
394
395 const char *text_context_dir[] = {"edit_text", NULL};
396
397 static int text_context(const bContext *C, const char *member, bContextDataResult *result)
398 {
399         SpaceText *st = CTX_wm_space_text(C);
400
401         if (CTX_data_dir(member)) {
402                 CTX_data_dir_set(result, text_context_dir);
403                 return 1;
404         }
405         else if (CTX_data_equals(member, "edit_text")) {
406                 CTX_data_id_pointer_set(result, &st->text->id);
407                 return 1;
408         }
409
410         return 0;
411 }
412
413 /********************* main region ********************/
414
415 /* add handlers, stuff you only do once or on area/region changes */
416 static void text_main_region_init(wmWindowManager *wm, ARegion *ar)
417 {
418         wmKeyMap *keymap;
419         ListBase *lb;
420         
421         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
422         
423         /* own keymap */
424         keymap = WM_keymap_find(wm->defaultconf, "Text Generic", SPACE_TEXT, 0);
425         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
426         keymap = WM_keymap_find(wm->defaultconf, "Text", SPACE_TEXT, 0);
427         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
428         
429         /* add drop boxes */
430         lb = WM_dropboxmap_find("Text", SPACE_TEXT, RGN_TYPE_WINDOW);
431         
432         WM_event_add_dropbox_handler(&ar->handlers, lb);
433 }
434
435 static void text_main_region_draw(const bContext *C, ARegion *ar)
436 {
437         /* draw entirely, view changes should be handled here */
438         SpaceText *st = CTX_wm_space_text(C);
439         //View2D *v2d = &ar->v2d;
440         
441         /* clear and setup matrix */
442         UI_ThemeClearColor(TH_BACK);
443         glClear(GL_COLOR_BUFFER_BIT);
444         
445         // UI_view2d_view_ortho(v2d);
446                 
447         /* data... */
448         draw_text_main(st, ar);
449         
450         /* reset view matrix */
451         // UI_view2d_view_restore(C);
452         
453         /* scrollers? */
454 }
455
456 static void text_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
457 {
458         SpaceText *st = sa->spacedata.first;
459         int wmcursor = BC_TEXTEDITCURSOR;
460
461         if (st->text && BLI_rcti_isect_pt(&st->txtbar, win->eventstate->x - ar->winrct.xmin, st->txtbar.ymin)) {
462                 wmcursor = CURSOR_STD;
463         }
464
465         WM_cursor_set(win, wmcursor);
466 }
467
468
469
470 /* ************* dropboxes ************* */
471
472 static int text_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
473 {
474         if (drag->type == WM_DRAG_PATH) {
475                 /* rule might not work? */
476                 if (ELEM(drag->icon, ICON_FILE_SCRIPT, ICON_FILE_TEXT, ICON_FILE_BLANK)) {
477                         return true;
478                 }
479         }
480         return false;
481 }
482
483 static void text_drop_copy(wmDrag *drag, wmDropBox *drop)
484 {
485         /* copy drag path to properties */
486         RNA_string_set(drop->ptr, "filepath", drag->path);
487 }
488
489 static int text_drop_paste_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
490 {
491         if (drag->type == WM_DRAG_ID)
492                 return true;
493
494         return false;
495 }
496
497 static void text_drop_paste(wmDrag *drag, wmDropBox *drop)
498 {
499         char *text;
500         ID *id = drag->poin;
501
502         /* copy drag path to properties */
503         text = RNA_path_full_ID_py(id);
504         RNA_string_set(drop->ptr, "text", text);
505         MEM_freeN(text);
506 }
507
508 /* this region dropbox definition */
509 static void text_dropboxes(void)
510 {
511         ListBase *lb = WM_dropboxmap_find("Text", SPACE_TEXT, RGN_TYPE_WINDOW);
512         
513         WM_dropbox_add(lb, "TEXT_OT_open", text_drop_poll, text_drop_copy);
514         WM_dropbox_add(lb, "TEXT_OT_insert", text_drop_paste_poll, text_drop_paste);
515 }
516
517 /* ************* end drop *********** */
518
519
520 /****************** header region ******************/
521
522 /* add handlers, stuff you only do once or on area/region changes */
523 static void text_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar)
524 {
525         ED_region_header_init(ar);
526 }
527
528 static void text_header_region_draw(const bContext *C, ARegion *ar)
529 {
530         ED_region_header(C, ar);
531 }
532
533 /****************** properties region ******************/
534
535 /* add handlers, stuff you only do once or on area/region changes */
536 static void text_properties_region_init(wmWindowManager *wm, ARegion *ar)
537 {
538         wmKeyMap *keymap;
539
540         ar->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
541         ED_region_panels_init(wm, ar);
542
543         /* own keymaps */
544         keymap = WM_keymap_find(wm->defaultconf, "Text Generic", SPACE_TEXT, 0);
545         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
546
547 }
548
549 static void text_properties_region_draw(const bContext *C, ARegion *ar)
550 {
551         SpaceText *st = CTX_wm_space_text(C);
552         
553         ED_region_panels(C, ar, NULL, -1, true);
554         
555         /* this flag trick is make sure buttons have been added already */
556         if (st->flags & ST_FIND_ACTIVATE) {
557                 if (UI_textbutton_activate_rna(C, ar, st, "find_text")) {
558                         /* if the panel was already open we need to do another redraw */
559                         ScrArea *sa = CTX_wm_area(C);
560                         WM_event_add_notifier(C, NC_SPACE | ND_SPACE_TEXT, sa);
561                 }
562                 st->flags &= ~ST_FIND_ACTIVATE;
563         }
564 }
565
566 static void text_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
567 {
568         SpaceText *stext = (SpaceText *)slink;
569
570         if (!ELEM(GS(old_id->name), ID_TXT)) {
571                 return;
572         }
573
574         if ((ID *)stext->text == old_id) {
575                 stext->text = (Text *)new_id;
576                 id_us_ensure_real(new_id);
577         }
578 }
579
580 /********************* registration ********************/
581
582 /* only called once, from space/spacetypes.c */
583 void ED_spacetype_text(void)
584 {
585         SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype text");
586         ARegionType *art;
587         
588         st->spaceid = SPACE_TEXT;
589         strncpy(st->name, "Text", BKE_ST_MAXNAME);
590         
591         st->new = text_new;
592         st->free = text_free;
593         st->init = text_init;
594         st->duplicate = text_duplicate;
595         st->operatortypes = text_operatortypes;
596         st->keymap = text_keymap;
597         st->listener = text_listener;
598         st->context = text_context;
599         st->dropboxes = text_dropboxes;
600         st->id_remap = text_id_remap;
601
602         /* regions: main window */
603         art = MEM_callocN(sizeof(ARegionType), "spacetype text region");
604         art->regionid = RGN_TYPE_WINDOW;
605         art->init = text_main_region_init;
606         art->draw = text_main_region_draw;
607         art->cursor = text_cursor;
608         art->event_cursor = true;
609
610         BLI_addhead(&st->regiontypes, art);
611         
612         /* regions: properties */
613         art = MEM_callocN(sizeof(ARegionType), "spacetype text region");
614         art->regionid = RGN_TYPE_UI;
615         art->prefsizex = UI_COMPACT_PANEL_WIDTH;
616         art->keymapflag = ED_KEYMAP_UI;
617         
618         art->init = text_properties_region_init;
619         art->draw = text_properties_region_draw;
620         BLI_addhead(&st->regiontypes, art);
621
622         /* regions: header */
623         art = MEM_callocN(sizeof(ARegionType), "spacetype text region");
624         art->regionid = RGN_TYPE_HEADER;
625         art->prefsizey = HEADERY;
626         art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;
627         
628         art->init = text_header_region_init;
629         art->draw = text_header_region_draw;
630
631         BLI_addhead(&st->regiontypes, art);
632
633         BKE_spacetype_register(st);
634
635         /* register formatters */
636         ED_text_format_register_py();
637         ED_text_format_register_osl();
638         ED_text_format_register_lua();
639         ED_text_format_register_pov();
640         ED_text_format_register_pov_ini();
641 }
642