Added Copy and Paste functions to GHOST.
[blender-staging.git] / source / blender / src / header_text.c
1 /**
2  * header_text.c oct-2003
3  *
4  * Functions to draw the "Text Editor" window header
5  * and handle user events sent to it.
6  * 
7  * $Id$
8  *
9  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version. The Blender
15  * Foundation also sells licenses for use in proprietary software under
16  * the Blender License.  See http://www.blender.org/BL/ for information
17  * about this.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
27  *
28  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
29  * All rights reserved.
30  *
31  * The Original Code is: all of this file.
32  *
33  * Contributor(s): none yet.
34  *
35  * ***** END GPL/BL DUAL LICENSE BLOCK *****
36  */
37
38 #include <stdlib.h>
39 #include <string.h>
40 #include <stdio.h>
41
42 #ifdef HAVE_CONFIG_H
43 #include <config.h>
44 #endif
45
46 #include "BMF_Api.h"
47 #include "BIF_language.h"
48
49 #include "BSE_headerbuttons.h"
50
51 #include "DNA_ID.h"
52 #include "DNA_screen_types.h"
53 #include "DNA_space_types.h"
54 #include "DNA_text_types.h"
55 #include "DNA_constraint_types.h"
56 #include "DNA_action_types.h"
57
58 #include "BIF_drawtext.h"
59 #include "BIF_interface.h"
60 #include "BIF_resources.h"
61 #include "BIF_screen.h"
62 #include "BIF_space.h"
63 #include "BIF_toolbox.h"
64
65 #include "BKE_global.h"
66 #include "BKE_library.h"
67 #include "BKE_main.h"
68 #include "BKE_sca.h"
69 #include "BKE_text.h"
70 #include "BKE_depsgraph.h"
71
72 #include "BSE_filesel.h"
73
74 #include "BPY_extern.h"
75 #include "BPY_menus.h"
76
77 #include "blendef.h"
78 #include "mydevice.h"
79
80 void do_text_buttons(unsigned short event)
81 {
82         SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
83         ID *id, *idtest;
84         int nr= 1;
85         Text *text;
86         
87         if (st==NULL || st->spacetype != SPACE_TEXT) return;
88         
89         switch (event) {
90         case B_TEXTBROWSE:
91                 if (st->menunr==-2) {
92                         activate_databrowse((ID *)st->text, ID_TXT, 0, B_TEXTBROWSE,
93                                                                                         &st->menunr, do_text_buttons);
94                         break;
95                 }
96                 if(st->menunr < 0) break;
97                         
98                 text= st->text;
99
100                 nr= 1;
101                 id= (ID *)text;
102                 
103                 if (st->menunr==32767) {
104                         st->text= (Text *)add_empty_text( "Text" );
105
106                         st->top= 0;
107                         
108                         allqueue(REDRAWTEXT, 0);
109                         allqueue(REDRAWHEADERS, 0); 
110                 }
111                 else if (st->menunr==32766) {
112                         activate_fileselect(FILE_SPECIAL, "Open Text File", G.sce, add_text_fs); 
113                         return;
114                 }
115                 else {          
116                         idtest= G.main->text.first;
117                         while(idtest) {
118                                 if(nr==st->menunr) {
119                                         break;
120                                 }
121                                 nr++;
122                                 idtest= idtest->next;
123                         }
124                         if(idtest==0) { /* new text */
125                                 activate_fileselect(FILE_SPECIAL, "Open Text File",
126                                                                                                 G.sce, add_text_fs); 
127                                 return;
128                         }
129                         if(idtest!=id) {
130                                 st->text= (Text *)idtest;
131                                 st->top= 0;
132                                 
133                                 pop_space_text(st);
134                                 if (st->showsyntax) get_format_string(st);
135                                 allqueue(REDRAWTEXT, 0);
136                                 allqueue(REDRAWHEADERS, 0);
137                         }
138                 }
139                 break;
140                 
141         case B_TEXTDELETE:
142                 {
143                         text= st->text;
144                         if (!text) return;
145                         
146                         /* make the previous text active, if its not there make the next text active */
147                         if (st->text->id.prev) {
148                                 st->text = st->text->id.prev;
149                                 pop_space_text(st);
150                         } else if (st->text->id.next) {
151                                 st->text = st->text->id.next;
152                                 pop_space_text(st);
153                         }
154                         
155                         BPY_clear_bad_scriptlinks(text);
156                         BPY_free_pyconstraint_links(text);
157                         free_text_controllers(text);
158                         
159                         unlink_text(text);
160                         free_libblock(&G.main->text, text);
161                         
162                         allqueue(REDRAWTEXT, 0);
163                         allqueue(REDRAWHEADERS, 0);
164                         
165                         /*for if any object constraints were changed.*/
166                         allqueue(REDRAWVIEW3D, 0);
167                         allqueue(REDRAWBUTSOBJECT, 0);
168                         allqueue(REDRAWBUTSEDIT, 0);
169                         
170                         BIF_undo_push("Delete Text");
171                 }
172                 break;
173                 
174 /*
175         case B_TEXTSTORE:
176                 st->text->flags ^= TXT_ISEXT;
177                 
178                 allqueue(REDRAWHEADERS, 0);
179                 break;
180 */               
181         case B_TEXTLINENUM:
182                 allqueue(REDRAWTEXT, 0);
183                 allqueue(REDRAWHEADERS, 0);
184                 break;
185
186         case B_TEXTFONT:
187                 switch(st->font_id) {
188                 case 0:
189                         st->lheight= 12; break;
190                 case 1:
191                         st->lheight= 15; 
192                         break;
193                 }
194                         
195                 allqueue(REDRAWTEXT, 0);
196                 allqueue(REDRAWHEADERS, 0);
197
198                 break;
199         case B_TAB_NUMBERS:
200                 if (st->showsyntax) get_format_string(st);
201                 allqueue(REDRAWTEXT, 0);
202                 allqueue(REDRAWHEADERS, 0);
203                 break;
204         case B_SYNTAX:
205                 if (st->showsyntax) {
206                         get_format_string(st);
207                 }
208                 allqueue(REDRAWTEXT, 0);
209                 allqueue(REDRAWHEADERS, 0);
210                 break;
211         }
212 }
213
214 static void do_text_template_scriptsmenu(void *arg, int event)
215 {
216         BPY_menu_do_python(PYMENU_SCRIPTTEMPLATE, event);
217         
218         allqueue(REDRAWIMAGE, 0);
219 }
220
221 static uiBlock *text_template_scriptsmenu (void *args_unused)
222 {
223         uiBlock *block;
224         BPyMenu *pym;
225         int i= 0;
226         short yco = 20, menuwidth = 120;
227         
228         block= uiNewBlock(&curarea->uiblocks, "text_template_scriptsmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
229         uiBlockSetButmFunc(block, do_text_template_scriptsmenu, NULL);
230         
231         /* note that we acount for the N previous entries with i+20: */
232         for (pym = BPyMenuTable[PYMENU_SCRIPTTEMPLATE]; pym; pym = pym->next, i++) {
233                 
234                 uiDefIconTextBut(block, BUTM, 1, ICON_PYTHON, pym->name, 0, yco-=20, menuwidth, 19, 
235                                                  NULL, 0.0, 0.0, 1, i, 
236                                                  pym->tooltip?pym->tooltip:pym->filename);
237         }
238         
239         uiBlockSetDirection(block, UI_RIGHT);
240         uiTextBoundsBlock(block, 60);
241         
242         return block;
243 }
244
245 /* action executed after clicking in File menu */
246 static void do_text_filemenu(void *arg, int event)
247 {
248         SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
249         Text *text;
250         ScrArea *sa;
251         
252         if (st==NULL || st->spacetype != SPACE_TEXT) return;
253         
254         text= st->text;
255         
256         switch(event) {
257         case 1:
258                 st->text= add_empty_text( "Text" );
259                 st->top=0;
260                 
261                 allqueue(REDRAWTEXT, 0);
262                 allqueue(REDRAWHEADERS, 0);
263                 break;
264         case 2:
265                 activate_fileselect(FILE_SPECIAL, "Open Text File", G.sce, add_text_fs);
266                 break;
267         case 3:
268                 if (text->compiled) BPY_free_compiled_text(text);
269                         text->compiled = NULL;
270                         if (okee("Reopen Text")) {
271                                 if (!reopen_text(text)) {
272                                         error("Could not reopen file");
273                                 }
274                         if (st->showsyntax) get_format_string(st);
275                         }
276                 break;
277         case 5:
278                 text->flags |= TXT_ISMEM;
279         case 4:
280                 txt_write_file(text);
281                 break;
282         case 6:
283                 run_python_script(st);
284                 break;
285         case 7:
286         {
287                 Object *ob;
288                 bConstraint *con;
289                 short update;
290                 
291                 /* check all pyconstraints */
292                 for (ob= G.main->object.first; ob; ob= ob->id.next) {
293                         update = 0;
294                         if (ob->type==OB_ARMATURE && ob->pose) {
295                                 bPoseChannel *pchan;
296                                 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
297                                         for (con = pchan->constraints.first; con; con= con->next) {
298                                                 if (con->type==CONSTRAINT_TYPE_PYTHON) {
299                                                         bPythonConstraint *data = con->data;
300                                                         if (data->text==text) BPY_pyconstraint_update(ob, con);
301                                                         update = 1;
302                                                         
303                                                 }
304                                         }
305                                 }
306                         }
307                         for (con = ob->constraints.first; con; con= con->next) {
308                                 if (con->type==CONSTRAINT_TYPE_PYTHON) {
309                                         bPythonConstraint *data = con->data;
310                                         if (data->text==text) BPY_pyconstraint_update(ob, con);
311                                         update = 1;
312                                 }
313                         }
314                         
315                         if (update) {
316                                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
317                         }
318                 }
319         }
320                 break;
321         default:
322                 break;
323         }
324         for (sa= G.curscreen->areabase.first; sa; sa= sa->next) {
325                 SpaceText *st= sa->spacedata.first;
326                 if (st && st->spacetype==SPACE_TEXT) {
327                         scrarea_queue_redraw(sa);
328                 }
329         }
330 }
331
332 /* action executed after clicking in Edit menu */
333 static void do_text_editmenu(void *arg, int event)
334 {
335         SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
336         Text *text;
337         ScrArea *sa;
338         
339         if (st==NULL || st->spacetype != SPACE_TEXT) return;
340         
341         text= st->text;
342         
343         switch(event) {
344         case 1:
345                 txt_do_undo(text);
346                 break;
347         case 2:
348                 txt_do_redo(text);
349                 break;
350         case 3:
351                 txt_copy_clipboard(text);
352                 txt_cut_sel(text);
353                 pop_space_text(st);
354                 break;
355         case 4:
356                 //txt_copy_sel(text);
357                 txt_copy_clipboard(text);
358                 break;
359         case 5:
360                 txt_paste_clipboard(text);
361                 if (st->showsyntax) get_format_string(st);
362                 break;
363         case 6:
364                 txt_print_cutbuffer();
365                 break;
366         case 7:
367                 jumptoline_interactive(st);
368                 break;
369         case 8:
370                 txt_find_panel(st,1);
371                 break;
372         case 9:
373                 txt_find_panel(st,0);
374                 break;
375         default:
376                 break;
377         }
378
379         for (sa= G.curscreen->areabase.first; sa; sa= sa->next) {
380                 SpaceText *st= sa->spacedata.first;
381                 if (st && st->spacetype==SPACE_TEXT) {
382                         scrarea_queue_redraw(sa);
383                 }
384         }
385 }
386
387 /* action executed after clicking in View menu */
388 static void do_text_editmenu_viewmenu(void *arg, int event)
389 {
390         SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
391         Text *text;
392         ScrArea *sa;
393         
394         if (st==NULL || st->spacetype != SPACE_TEXT) return;
395         
396         text = st->text;
397         
398         switch(event) {
399                 case 1:
400                         txt_move_bof(text, 0);
401                         pop_space_text(st);
402                         break;
403                 case 2:
404                         txt_move_eof(text, 0);
405                         pop_space_text(st);
406                         break;
407                 default:
408                         break;
409         }
410
411         for (sa= G.curscreen->areabase.first; sa; sa= sa->next) {
412                 SpaceText *st= sa->spacedata.first;
413                 if (st && st->spacetype==SPACE_TEXT) {
414                         scrarea_queue_redraw(sa);
415                 }
416         }
417 }
418
419 /* action executed after clicking in Select menu */
420 static void do_text_editmenu_selectmenu(void *arg, int event)
421 {
422         SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
423         Text *text;
424         ScrArea *sa;
425         
426         if (st==NULL || st->spacetype != SPACE_TEXT) return;
427         
428         text = st->text;
429         
430         switch(event) {
431         case 1:
432                 txt_sel_all(text);
433                 break;          
434         case 2:
435                 txt_sel_line(text);
436                 break;
437         default:
438                 break;
439         }
440
441         for (sa= G.curscreen->areabase.first; sa; sa= sa->next) {
442                 SpaceText *st= sa->spacedata.first;
443                 if (st && st->spacetype==SPACE_TEXT) {
444                         scrarea_queue_redraw(sa);
445                 }
446         }
447 }
448
449 /* action executed after clicking in Format menu */
450 static void do_text_formatmenu(void *arg, int event)
451 {
452         SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
453         Text *text;
454         ScrArea *sa;
455         
456         if (st==NULL || st->spacetype != SPACE_TEXT) return;
457         
458         text = st->text;
459         
460         switch(event) {
461         case 3:
462                 if (txt_has_sel(text)) {
463                         txt_order_cursors(text);
464                         indent(text);
465                         break;
466                 }
467                 else {
468                         txt_add_char(text, '\t');
469                         break;
470                 }
471         case 4:
472                 if ( txt_has_sel(text)) {
473                         txt_order_cursors(text);
474                         unindent(text);
475                         break;
476                 }
477                 break;
478         case 5:
479                 if ( txt_has_sel(text)) {
480                         txt_order_cursors(text);
481                         comment(text);
482                         if (st->showsyntax) get_format_string(st);
483                         break;
484                 }
485                 break;
486         case 6:
487                 if ( txt_has_sel(text)) {
488                         txt_order_cursors(text);
489                         uncomment(text);
490                         if (st->showsyntax) get_format_string(st);
491                         break;
492                 }
493                 break;
494         default:
495                 break;
496         }
497
498         for (sa= G.curscreen->areabase.first; sa; sa= sa->next) {
499                 SpaceText *st= sa->spacedata.first;
500                 if (st && st->spacetype==SPACE_TEXT) {
501                         scrarea_queue_redraw(sa);
502                 }
503         }
504 }
505
506 /* View menu */
507 static uiBlock *text_editmenu_viewmenu(void *arg_unused)
508 {
509         uiBlock *block;
510         short yco = 20, menuwidth = 120;
511
512         block= uiNewBlock(&curarea->uiblocks, "text_editmenu_viewmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
513         uiBlockSetButmFunc(block, do_text_editmenu_viewmenu, NULL);
514
515         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Top of File", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
516         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Bottom of File", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
517
518         uiBlockSetDirection(block, UI_RIGHT);
519         uiTextBoundsBlock(block, 60);
520         
521         return block;
522 }
523
524 /* Select menu */
525 static uiBlock *text_editmenu_selectmenu(void *arg_unused)
526 {
527         uiBlock *block;
528         short yco = 20, menuwidth = 120;
529
530         block= uiNewBlock(&curarea->uiblocks, "text_editmenu_selectmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
531         uiBlockSetButmFunc(block, do_text_editmenu_selectmenu, NULL);
532
533         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select All|Ctrl A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
534         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Line", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
535         
536         uiBlockSetDirection(block, UI_RIGHT);
537         uiTextBoundsBlock(block, 60);
538         
539         return block;
540 }
541
542 void do_text_formatmenu_convert(void *arg, int event)
543 {
544         SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
545         
546         if (st==NULL || st->spacetype != SPACE_TEXT) return;
547         
548         switch(event) {
549         case 1: convert_tabs(st, 0); break;
550         case 2: convert_tabs(st, 1); break;
551         }
552         allqueue(REDRAWVIEW3D, 0);
553 }
554
555 static uiBlock *text_formatmenu_convert(void *arg_unused)
556 {
557         uiBlock *block;
558         short yco = 20, menuwidth = 120;
559
560         block= uiNewBlock(&curarea->uiblocks, "do_text_formatmenu_convert", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
561         uiBlockSetButmFunc(block, do_text_formatmenu_convert, NULL);
562
563         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "To Spaces",              0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "Converts script whitespace to spaces based on Tab:");
564         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "To Tabs",                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "Converts script whitespace to tabs based on Tab:");
565         
566         uiBlockSetDirection(block, UI_RIGHT);
567         uiTextBoundsBlock(block, 60);
568         return block;
569 }
570
571 /* Format menu */
572 static uiBlock *text_formatmenu(void *arg_unused)
573 {
574         uiBlock *block;
575         short yco= 0, menuwidth=120;
576
577         block= uiNewBlock(&curarea->uiblocks, "text_formatmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
578         uiBlockSetButmFunc(block, do_text_formatmenu, NULL);
579
580         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
581         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Indent|Tab", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
582         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unindent|Shift Tab", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
583         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
584         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Comment", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
585         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Uncomment|Ctrl Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
586         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
587         uiDefIconTextBlockBut(block, text_formatmenu_convert, NULL, ICON_RIGHTARROW_THIN, "Convert whitespace", 0, yco-=20, menuwidth, 19, "");
588         
589         if(curarea->headertype==HEADERTOP) {
590                 uiBlockSetDirection(block, UI_DOWN);
591         }
592         else {
593                 uiBlockSetDirection(block, UI_TOP);
594                 uiBlockFlipOrder(block);
595         }
596
597         uiTextBoundsBlock(block, 50);
598         return block;
599 }
600
601
602 /* action executed after clicking in Object to 3d Sub Menu */
603 void do_text_editmenu_to3dmenu(void *arg, int event)
604 {
605         SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
606         Text *text;
607         if (st==NULL || st->spacetype != SPACE_TEXT) return;
608         
609         text = st->text;
610         
611         switch(event) {
612         case 1: txt_export_to_object(text); break;
613         case 2: txt_export_to_objects(text); break;
614         }
615         allqueue(REDRAWVIEW3D, 0);
616 }
617
618 /* Object to 3d Sub Menu */
619 static uiBlock *text_editmenu_to3dmenu(void *arg_unused)
620 {
621         uiBlock *block;
622         short yco = 20, menuwidth = 120;
623
624         block= uiNewBlock(&curarea->uiblocks, "do_text_editmenu_to3dmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
625         uiBlockSetButmFunc(block, do_text_editmenu_to3dmenu, NULL);
626
627         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "One Object | Alt-M",             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
628         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "One Object Per Line",            0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
629         
630         uiBlockSetDirection(block, UI_RIGHT);
631         uiTextBoundsBlock(block, 60);
632         return block;
633 }
634
635
636 /* Edit menu */
637 static uiBlock *text_editmenu(void *arg_unused)
638 {
639         uiBlock *block;
640         short yco= 0, menuwidth=120;
641
642         block= uiNewBlock(&curarea->uiblocks, "text_editmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
643         uiBlockSetButmFunc(block, do_text_editmenu, NULL);
644
645         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Undo|Ctrl Z", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
646         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Redo|Ctrl Shift Z", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
647         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
648         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cut|Alt X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
649         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Copy|Alt C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
650         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Paste|Alt V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
651         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Print Cut Buffer", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
652         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
653         uiDefIconTextBlockBut(block, text_editmenu_viewmenu, NULL, ICON_RIGHTARROW_THIN, "View|Alt Shift V   ", 0, yco-=20, 120, 19, "");
654         uiDefIconTextBlockBut(block, text_editmenu_selectmenu, NULL, ICON_RIGHTARROW_THIN, "Select|Alt Shift S   ", 0, yco-=20, 120, 19, "");
655         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
656         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump...|Alt J", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
657         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find...|Alt Ctrl F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
658         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Again|Alt F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
659         uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
660         uiDefIconTextBlockBut(block, text_editmenu_to3dmenu, NULL, ICON_RIGHTARROW_THIN, "Text to 3d Object", 0, yco-=20, 120, 19, "");
661         
662         if(curarea->headertype==HEADERTOP) {
663                 uiBlockSetDirection(block, UI_DOWN);
664         }
665         else {
666                 uiBlockSetDirection(block, UI_TOP);
667                 uiBlockFlipOrder(block);
668         }
669
670         uiTextBoundsBlock(block, 50);
671         return block;
672 }
673
674 /* File menu */
675 static uiBlock *text_filemenu(void *arg_unused)
676 {
677         SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
678         Text *text= st->text;
679         uiBlock *block;
680         short yco= 0, menuwidth=120;
681
682         block= uiNewBlock(&curarea->uiblocks, "text_filemenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
683         uiBlockSetButmFunc(block, do_text_filemenu, NULL);
684
685         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "New|Alt N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
686         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Open...|Alt O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
687         
688         if(text) {
689                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reopen|Alt R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
690                 
691                 uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
692                 
693                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save|Alt S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
694                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save As...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
695                 
696                 uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
697                 
698                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Run Python Script|Alt P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
699                 
700                 if (BPY_is_pyconstraint(text))
701                         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Refresh All PyConstraints", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
702                         
703                 uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
704         }
705         
706         uiDefIconTextBlockBut(block, text_template_scriptsmenu, NULL, ICON_RIGHTARROW_THIN, "Script Templates", 0, yco-=20, 120, 19, "");
707
708         if(curarea->headertype==HEADERTOP) {
709                 uiBlockSetDirection(block, UI_DOWN);
710         }
711         else {
712                 uiBlockSetDirection(block, UI_TOP);
713                 uiBlockFlipOrder(block);
714         }
715
716         uiTextBoundsBlock(block, 50);
717         return block;
718 }
719
720 /* header */
721 void text_buttons(void)
722 {
723         uiBlock *block;
724         SpaceText *st= curarea->spacedata.first;
725         Text *text;
726         short xco, xmax;
727         char naam[256];
728         
729         if (st==NULL || st->spacetype != SPACE_TEXT) return;
730         
731         text = st->text;
732
733         sprintf(naam, "header %d", curarea->headwin);
734         block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSS, UI_HELV, curarea->headwin);
735
736         if(area_is_active_area(curarea)) uiBlockSetCol(block, TH_HEADER);
737         else uiBlockSetCol(block, TH_HEADERDESEL);
738
739         curarea->butspacetype= SPACE_TEXT;
740
741         xco = 8;
742         uiDefIconTextButC(block, ICONTEXTROW,B_NEWSPACE, ICON_VIEW3D, windowtype_pup(), xco,0,XIC+10,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Displays Current Window Type. Click for menu of available types.");
743         xco+= XIC+14;
744
745         uiBlockSetEmboss(block, UI_EMBOSSN);
746         if(curarea->flag & HEADER_NO_PULLDOWN) {
747                 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, ICON_DISCLOSURE_TRI_RIGHT,
748                                 xco,2,XIC,YIC-2,
749                                 &(curarea->flag), 0, 0, 0, 0, "Enables display of pulldown menus");
750         } else {
751                 uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, ICON_DISCLOSURE_TRI_DOWN,
752                                 xco,2,XIC,YIC-2,
753                                 &(curarea->flag), 0, 0, 0, 0, "Hides pulldown menus");
754         }
755         uiBlockSetEmboss(block, UI_EMBOSS);
756         xco+=XIC;
757
758         /* pull down menus */
759         if((curarea->flag & HEADER_NO_PULLDOWN)==0) {
760                 uiBlockSetEmboss(block, UI_EMBOSSP);
761         
762                 xmax= GetButStringLength("File");
763                 uiDefPulldownBut(block,text_filemenu, NULL, "File", xco, 0, xmax, 20, "");
764                 xco+=xmax;
765         
766                 if(text) {
767                         xmax= GetButStringLength("Edit");
768                         uiDefPulldownBut(block,text_editmenu, NULL, "Edit", xco, 0, xmax, 20, "");
769                         xco+=xmax;
770                         
771                         xmax= GetButStringLength("Format");
772                         uiDefPulldownBut(block,text_formatmenu, NULL, "Format", xco, 0, xmax, 20, "");
773                         xco+=xmax;
774                 }
775         }
776         uiBlockSetEmboss(block, UI_EMBOSS);
777         xco += 10;
778         
779         /* FULL WINDOW */
780         uiBlockBeginAlign(block);
781         if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN,     xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Returns to multiple views window (CTRL+Up arrow)");
782         else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN,   xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Makes current window full screen (CTRL+Down arrow)");
783                 
784         uiDefIconButI(block, ICONTOG, B_TEXTLINENUM, ICON_LONGDISPLAY, xco+=XIC,0,XIC,YIC, &st->showlinenrs, 0, 0, 0, 0, "Displays line numbers");
785
786         uiDefIconButI(block, ICONTOG, B_SYNTAX, ICON_SYNTAX, xco+=XIC,0,XIC,YIC, &st->showsyntax, 0, 0, 0, 0, "Enables Syntax Highlighting");
787         uiBlockEndAlign(block);
788         
789         /* STD TEXT BUTTONS */
790         xco+= 2*XIC;
791         xco= std_libbuttons(block, xco, 0, 0, NULL, B_TEXTBROWSE, ID_TXT, 0, (ID*)st->text, 0, &(st->menunr), 0, 0, B_TEXTDELETE, 0, 0);
792
793         /*
794         if (st->text) {
795                 if (st->text->flags & TXT_ISDIRTY && (st->text->flags & TXT_ISEXT || !(st->text->flags & TXT_ISMEM)))
796                         uiDefIconBut(block, BUT,0, ICON_ERROR, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "The text has been changed");
797                 if (st->text->flags & TXT_ISEXT) 
798                         uiDefBut(block, BUT,B_TEXTSTORE, ICON(),        xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Stores text in project file");
799                 else 
800                         uiDefBut(block, BUT,B_TEXTSTORE, ICON(),        xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Disables storing of text in project file");
801                 xco+=10;
802         }
803         */              
804
805         xco+=XIC;
806         if(st->font_id>1) st->font_id= 0;
807         uiDefButI(block, MENU, B_TEXTFONT, "Screen 12 %x0|Screen 15%x1", xco,0,100,YIC, &st->font_id, 0, 0, 0, 0, "Displays available fonts");
808         xco+=110;
809         
810         uiDefButI(block, NUM, B_TAB_NUMBERS, "Tab:",            xco, 0, XIC+50, YIC, &st->tabnumber, 2, 8, 0, 0, "Set spacing of Tab");
811         xco+= XIC+50;
812         
813         /* always as last  */
814         curarea->headbutlen= xco+2*XIC;
815
816         uiDrawBlock(block);
817 }