Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2008 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * 00022 * Contributor(s): Blender Foundation 00023 * 00024 * ***** END GPL LICENSE BLOCK ***** 00025 */ 00026 00032 #include <ctype.h> 00033 #include <stdio.h> 00034 #include <stdlib.h> 00035 00036 #include "DNA_screen_types.h" 00037 #include "DNA_space_types.h" 00038 #include "DNA_text_types.h" 00039 00040 #include "BKE_suggestions.h" 00041 #include "BKE_text.h" 00042 00043 #include "BLI_blenlib.h" 00044 #include "BLI_utildefines.h" 00045 00046 #include "WM_types.h" 00047 00048 #include "text_intern.h" 00049 00050 int text_do_suggest_select(SpaceText *st, ARegion *ar) 00051 { 00052 SuggItem *item, *first, *last /* , *sel */ /* UNUSED */; 00053 TextLine *tmp; 00054 int l, x, y, w, h, i; 00055 int tgti, *top; 00056 int mval[2] = {0, 0}; 00057 00058 if(!st || !st->text) return 0; 00059 if(!texttool_text_is_active(st->text)) return 0; 00060 00061 first = texttool_suggest_first(); 00062 last = texttool_suggest_last(); 00063 /* sel = texttool_suggest_selected(); */ /* UNUSED */ 00064 top = texttool_suggest_top(); 00065 00066 if(!last || !first) 00067 return 0; 00068 00069 /* Count the visible lines to the cursor */ 00070 for(tmp=st->text->curl, l=-st->top; tmp; tmp=tmp->prev, l++); 00071 if(l<0) return 0; 00072 00073 text_update_character_width(st); 00074 00075 if(st->showlinenrs) { 00076 x = st->cwidth*(st->text->curc-st->left) + TXT_OFFSET + TEXTXLOC - 4; 00077 } 00078 else { 00079 x = st->cwidth*(st->text->curc-st->left) + TXT_OFFSET - 4; 00080 } 00081 y = ar->winy - st->lheight*l - 2; 00082 00083 w = SUGG_LIST_WIDTH*st->cwidth + 20; 00084 h = SUGG_LIST_SIZE*st->lheight + 8; 00085 00086 // XXX getmouseco_areawin(mval); 00087 00088 if(mval[0]<x || x+w<mval[0] || mval[1]<y-h || y<mval[1]) 00089 return 0; 00090 00091 /* Work out which of the items is at the top of the visible list */ 00092 for(i=0, item=first; i<*top && item->next; i++, item=item->next); 00093 00094 /* Work out the target item index in the visible list */ 00095 tgti = (y-mval[1]-4) / st->lheight; 00096 if(tgti<0 || tgti>SUGG_LIST_SIZE) 00097 return 1; 00098 00099 for(i=tgti; i>0 && item->next; i--, item=item->next); 00100 if(item) 00101 texttool_suggest_select(item); 00102 return 1; 00103 } 00104 00105 void text_pop_suggest_list(void) 00106 { 00107 SuggItem *item, *sel; 00108 int *top, i; 00109 00110 item= texttool_suggest_first(); 00111 sel= texttool_suggest_selected(); 00112 top= texttool_suggest_top(); 00113 00114 i= 0; 00115 while(item && item != sel) { 00116 item= item->next; 00117 i++; 00118 } 00119 if(i > *top+SUGG_LIST_SIZE-1) 00120 *top= i-SUGG_LIST_SIZE+1; 00121 else if(i < *top) 00122 *top= i; 00123 } 00124 00125 static void get_suggest_prefix(Text *text, int offset) 00126 { 00127 int i, len; 00128 char *line, tmp[256]; 00129 00130 if(!text) return; 00131 if(!texttool_text_is_active(text)) return; 00132 00133 line= text->curl->line; 00134 for(i=text->curc-1+offset; i>=0; i--) 00135 if(!text_check_identifier(line[i])) 00136 break; 00137 i++; 00138 len= text->curc-i+offset; 00139 if(len > 255) { 00140 printf("Suggestion prefix too long\n"); 00141 len = 255; 00142 } 00143 BLI_strncpy(tmp, line+i, len); 00144 tmp[len]= '\0'; 00145 texttool_suggest_prefix(tmp); 00146 } 00147 00148 static void confirm_suggestion(Text *text, int skipleft) 00149 { 00150 SuggItem *sel; 00151 int i, over=0; 00152 char *line; 00153 00154 if(!text) return; 00155 if(!texttool_text_is_active(text)) return; 00156 00157 sel = texttool_suggest_selected(); 00158 if(!sel) return; 00159 00160 line= text->curl->line; 00161 i=text->curc-skipleft-1; 00162 while(i>=0) { 00163 if(!text_check_identifier(line[i])) 00164 break; 00165 over++; 00166 i--; 00167 } 00168 00169 for(i=0; i<skipleft; i++) 00170 txt_move_left(text, 0); 00171 for(i=0; i<over; i++) 00172 txt_move_left(text, 1); 00173 00174 txt_insert_buf(text, sel->name); 00175 00176 for(i=0; i<skipleft; i++) 00177 txt_move_right(text, 0); 00178 00179 texttool_text_clear(); 00180 } 00181 00182 // XXX 00183 #define L_MOUSE 0 00184 #define M_MOUSE 0 00185 #define R_MOUSE 0 00186 #define LR_SHIFTKEY 0 00187 #define LR_ALTKEY 0 00188 #define LR_CTRLKEY 0 00189 #define LR_OSKEY 0 00190 00191 // XXX 00192 static int doc_scroll= 0; 00193 00194 static short UNUSED_FUNCTION(do_texttools)(SpaceText *st, char ascii, unsigned short evnt, short val) 00195 { 00196 ARegion *ar= NULL; // XXX 00197 int qual= 0; // XXX 00198 int draw=0, tools=0, swallow=0, scroll=1; 00199 if(!texttool_text_is_active(st->text)) return 0; 00200 if(!st->text || st->text->id.lib) return 0; 00201 00202 if(st->doplugins && texttool_text_is_active(st->text)) { 00203 if(texttool_suggest_first()) tools |= TOOL_SUGG_LIST; 00204 if(texttool_docs_get()) tools |= TOOL_DOCUMENT; 00205 } 00206 00207 if(ascii) { 00208 if(tools & TOOL_SUGG_LIST) { 00209 if((ascii != '_' && ascii != '*' && ispunct(ascii)) || text_check_whitespace(ascii)) { 00210 confirm_suggestion(st->text, 0); 00211 text_update_line_edited(st->text->curl); 00212 } 00213 else if((st->overwrite && txt_replace_char(st->text, ascii)) || txt_add_char(st->text, ascii)) { 00214 get_suggest_prefix(st->text, 0); 00215 text_pop_suggest_list(); 00216 swallow= 1; 00217 draw= 1; 00218 } 00219 } 00220 if(tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll= 0, draw= 1; 00221 00222 } 00223 else if(val==1 && evnt) { 00224 switch (evnt) { 00225 case LEFTMOUSE: 00226 if(text_do_suggest_select(st, ar)) 00227 swallow= 1; 00228 else { 00229 if(tools & TOOL_SUGG_LIST) texttool_suggest_clear(); 00230 if(tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll= 0; 00231 } 00232 draw= 1; 00233 break; 00234 case MIDDLEMOUSE: 00235 if(text_do_suggest_select(st, ar)) { 00236 confirm_suggestion(st->text, 0); 00237 text_update_line_edited(st->text->curl); 00238 swallow= 1; 00239 } 00240 else { 00241 if(tools & TOOL_SUGG_LIST) texttool_suggest_clear(); 00242 if(tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll= 0; 00243 } 00244 draw= 1; 00245 break; 00246 case ESCKEY: 00247 draw= swallow= 1; 00248 if(tools & TOOL_SUGG_LIST) texttool_suggest_clear(); 00249 else if(tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll= 0; 00250 else draw= swallow= 0; 00251 break; 00252 case RETKEY: 00253 if(tools & TOOL_SUGG_LIST) { 00254 confirm_suggestion(st->text, 0); 00255 text_update_line_edited(st->text->curl); 00256 swallow= 1; 00257 draw= 1; 00258 } 00259 if(tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll= 0, draw= 1; 00260 break; 00261 case LEFTARROWKEY: 00262 case BACKSPACEKEY: 00263 if(tools & TOOL_SUGG_LIST) { 00264 if(qual) 00265 texttool_suggest_clear(); 00266 else { 00267 /* Work out which char we are about to delete/pass */ 00268 if(st->text->curl && st->text->curc > 0) { 00269 char ch= st->text->curl->line[st->text->curc-1]; 00270 if((ch=='_' || !ispunct(ch)) && !text_check_whitespace(ch)) { 00271 get_suggest_prefix(st->text, -1); 00272 text_pop_suggest_list(); 00273 } 00274 else 00275 texttool_suggest_clear(); 00276 } 00277 else 00278 texttool_suggest_clear(); 00279 } 00280 } 00281 if(tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll= 0; 00282 break; 00283 case RIGHTARROWKEY: 00284 if(tools & TOOL_SUGG_LIST) { 00285 if(qual) 00286 texttool_suggest_clear(); 00287 else { 00288 /* Work out which char we are about to pass */ 00289 if(st->text->curl && st->text->curc < st->text->curl->len) { 00290 char ch= st->text->curl->line[st->text->curc+1]; 00291 if((ch=='_' || !ispunct(ch)) && !text_check_whitespace(ch)) { 00292 get_suggest_prefix(st->text, 1); 00293 text_pop_suggest_list(); 00294 } 00295 else 00296 texttool_suggest_clear(); 00297 } 00298 else 00299 texttool_suggest_clear(); 00300 } 00301 } 00302 if(tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll= 0; 00303 break; 00304 case PAGEDOWNKEY: 00305 scroll= SUGG_LIST_SIZE-1; 00306 case WHEELDOWNMOUSE: 00307 case DOWNARROWKEY: 00308 if(tools & TOOL_DOCUMENT) { 00309 doc_scroll++; 00310 swallow= 1; 00311 draw= 1; 00312 break; 00313 } 00314 else if(tools & TOOL_SUGG_LIST) { 00315 SuggItem *sel = texttool_suggest_selected(); 00316 if(!sel) { 00317 texttool_suggest_select(texttool_suggest_first()); 00318 } 00319 else while(sel && sel!=texttool_suggest_last() && sel->next && scroll--) { 00320 texttool_suggest_select(sel->next); 00321 sel= sel->next; 00322 } 00323 text_pop_suggest_list(); 00324 swallow= 1; 00325 draw= 1; 00326 break; 00327 } 00328 case PAGEUPKEY: 00329 scroll= SUGG_LIST_SIZE-1; 00330 case WHEELUPMOUSE: 00331 case UPARROWKEY: 00332 if(tools & TOOL_DOCUMENT) { 00333 if(doc_scroll>0) doc_scroll--; 00334 swallow= 1; 00335 draw= 1; 00336 break; 00337 } 00338 else if(tools & TOOL_SUGG_LIST) { 00339 SuggItem *sel = texttool_suggest_selected(); 00340 while(sel && sel!=texttool_suggest_first() && sel->prev && scroll--) { 00341 texttool_suggest_select(sel->prev); 00342 sel= sel->prev; 00343 } 00344 text_pop_suggest_list(); 00345 swallow= 1; 00346 draw= 1; 00347 break; 00348 } 00349 case RIGHTSHIFTKEY: 00350 case LEFTSHIFTKEY: 00351 break; 00352 default: 00353 if(tools & TOOL_SUGG_LIST) texttool_suggest_clear(), draw= 1; 00354 if(tools & TOOL_DOCUMENT) texttool_docs_clear(), doc_scroll= 0, draw= 1; 00355 } 00356 } 00357 00358 if(draw) 00359 {}; // XXX redraw_alltext(); 00360 00361 return swallow; 00362 } 00363 00364 #if 0 00365 #ifdef WITH_PYTHON 00366 /* Run text plugin scripts if enabled */ 00367 if(st->doplugins && event && val) { 00368 if(BPY_menu_do_shortcut(PYMENU_TEXTPLUGIN, event, qual)) { 00369 do_draw= 1; 00370 } 00371 } 00372 #endif 00373 if(do_draw) 00374 ; // XXX redraw_alltext(); 00375 #endif 00376 00377 static short UNUSED_FUNCTION(do_textmarkers)(SpaceText *st, char ascii, unsigned short evnt, short val) 00378 { 00379 Text *text; 00380 TextMarker *marker, *mrk, *nxt; 00381 int c, s, draw=0, swallow=0; 00382 int qual= 0; // XXX 00383 00384 text= st->text; 00385 if(!text || text->id.lib || text->curl != text->sell) return 0; 00386 00387 marker= txt_find_marker(text, text->sell, text->selc, 0, 0); 00388 if(marker && (marker->start > text->curc || marker->end < text->curc)) 00389 marker= NULL; 00390 00391 if(!marker) { 00392 /* Find the next temporary marker */ 00393 if(evnt==TABKEY) { 00394 int lineno= txt_get_span(text->lines.first, text->curl); 00395 mrk= text->markers.first; 00396 while(mrk) { 00397 if(!marker && (mrk->flags & TMARK_TEMP)) marker= mrk; 00398 if((mrk->flags & TMARK_TEMP) && (mrk->lineno > lineno || (mrk->lineno==lineno && mrk->end > text->curc))) { 00399 marker= mrk; 00400 break; 00401 } 00402 mrk= mrk->next; 00403 } 00404 if(marker) { 00405 txt_move_to(text, marker->lineno, marker->start, 0); 00406 txt_move_to(text, marker->lineno, marker->end, 1); 00407 // XXX text_update_cursor_moved(C); 00408 // XXX WM_event_add_notifier(C, NC_TEXT|ND_CURSOR, text); 00409 evnt= ascii= val= 0; 00410 draw= 1; 00411 swallow= 1; 00412 } 00413 } 00414 else if(evnt==ESCKEY) { 00415 if(txt_clear_markers(text, 0, TMARK_TEMP)) swallow= 1; 00416 else if(txt_clear_markers(text, 0, 0)) swallow= 1; 00417 else return 0; 00418 evnt= ascii= val= 0; 00419 draw= 1; 00420 } 00421 if(!swallow) return 0; 00422 } 00423 00424 if(ascii) { 00425 if(marker->flags & TMARK_EDITALL) { 00426 c= text->curc-marker->start; 00427 s= text->selc-marker->start; 00428 if(s<0 || s>marker->end-marker->start) return 0; 00429 00430 mrk= txt_next_marker(text, marker); 00431 while(mrk) { 00432 nxt=txt_next_marker(text, mrk); /* mrk may become invalid */ 00433 txt_move_to(text, mrk->lineno, mrk->start+c, 0); 00434 if(s!=c) txt_move_to(text, mrk->lineno, mrk->start+s, 1); 00435 if(st->overwrite) { 00436 if(txt_replace_char(text, ascii)) 00437 text_update_line_edited(st->text->curl); 00438 } 00439 else { 00440 if(txt_add_char(text, ascii)) { 00441 text_update_line_edited(st->text->curl); 00442 } 00443 } 00444 00445 if(mrk==marker || mrk==nxt) break; 00446 mrk=nxt; 00447 } 00448 swallow= 1; 00449 draw= 1; 00450 } 00451 } 00452 else if(val) { 00453 switch(evnt) { 00454 case BACKSPACEKEY: 00455 if(marker->flags & TMARK_EDITALL) { 00456 c= text->curc-marker->start; 00457 s= text->selc-marker->start; 00458 if(s<0 || s>marker->end-marker->start) return 0; 00459 00460 mrk= txt_next_marker(text, marker); 00461 while(mrk) { 00462 nxt= txt_next_marker(text, mrk); /* mrk may become invalid */ 00463 txt_move_to(text, mrk->lineno, mrk->start+c, 0); 00464 if(s!=c) txt_move_to(text, mrk->lineno, mrk->start+s, 1); 00465 txt_backspace_char(text); 00466 text_update_line_edited(st->text->curl); 00467 if(mrk==marker || mrk==nxt) break; 00468 mrk= nxt; 00469 } 00470 swallow= 1; 00471 draw= 1; 00472 } 00473 break; 00474 case DELKEY: 00475 if(marker->flags & TMARK_EDITALL) { 00476 c= text->curc-marker->start; 00477 s= text->selc-marker->start; 00478 if(s<0 || s>marker->end-marker->start) return 0; 00479 00480 mrk= txt_next_marker(text, marker); 00481 while(mrk) { 00482 nxt= txt_next_marker(text, mrk); /* mrk may become invalid */ 00483 txt_move_to(text, mrk->lineno, mrk->start+c, 0); 00484 if(s!=c) txt_move_to(text, mrk->lineno, mrk->start+s, 1); 00485 txt_delete_char(text); 00486 text_update_line_edited(st->text->curl); 00487 if(mrk==marker || mrk==nxt) break; 00488 mrk= nxt; 00489 } 00490 swallow= 1; 00491 draw= 1; 00492 } 00493 break; 00494 case TABKEY: 00495 if(qual & LR_SHIFTKEY) { 00496 nxt= marker->prev; 00497 if(!nxt) nxt= text->markers.last; 00498 } 00499 else { 00500 nxt= marker->next; 00501 if(!nxt) nxt= text->markers.first; 00502 } 00503 if(marker->flags & TMARK_TEMP) { 00504 if(nxt==marker) nxt= NULL; 00505 BLI_freelinkN(&text->markers, marker); 00506 } 00507 mrk= nxt; 00508 if(mrk) { 00509 txt_move_to(text, mrk->lineno, mrk->start, 0); 00510 txt_move_to(text, mrk->lineno, mrk->end, 1); 00511 // XXX text_update_cursor_moved(C); 00512 // XXX WM_event_add_notifier(C, NC_TEXT|ND_CURSOR, text); 00513 } 00514 swallow= 1; 00515 draw= 1; 00516 break; 00517 00518 /* Events that should clear markers */ 00519 case UKEY: if(!(qual & LR_ALTKEY)) break; 00520 case ZKEY: if(evnt==ZKEY && !(qual & LR_CTRLKEY)) break; 00521 case RETKEY: 00522 case ESCKEY: 00523 if(marker->flags & (TMARK_EDITALL | TMARK_TEMP)) 00524 txt_clear_markers(text, marker->group, 0); 00525 else 00526 BLI_freelinkN(&text->markers, marker); 00527 swallow= 1; 00528 draw= 1; 00529 break; 00530 case RIGHTMOUSE: /* Marker context menu? */ 00531 case LEFTMOUSE: 00532 break; 00533 case FKEY: /* Allow find */ 00534 if(qual & LR_SHIFTKEY) swallow= 1; 00535 break; 00536 00537 default: 00538 if(qual!=0 && qual!=LR_SHIFTKEY) 00539 swallow= 1; /* Swallow all other shortcut events */ 00540 } 00541 } 00542 00543 if(draw) 00544 {}; // XXX redraw_alltext(); 00545 00546 return swallow; 00547 } 00548