bugfix [#20694] Copy Paste to buffer missing in Console editor
authorCampbell Barton <ideasman42@gmail.com>
Fri, 26 Feb 2010 23:56:16 +0000 (23:56 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 26 Feb 2010 23:56:16 +0000 (23:56 +0000)
- console selection working
- copy selection to clipboard
- paste selection from clipboard works with multiline paste

word-wrap is still not working with selection drawing.

source/blender/blenlib/BLI_dynstr.h
source/blender/blenlib/intern/BLI_dynstr.c
source/blender/editors/space_console/console_draw.c
source/blender/editors/space_console/console_ops.c

index 8544b451b65ad9a4d10aa3d8873da55683db9b06..c5158264e72d0093538b751e9c242cbd805a774c 100644 (file)
@@ -60,6 +60,15 @@ DynStr*      BLI_dynstr_new                                  (void);
         */
 void   BLI_dynstr_append                               (DynStr *ds, const char *cstr);
 
+/**
+ * Append a length clamped c-string to a DynStr.
+ *
+ * @param ds The DynStr to append to.
+ * @param cstr The c-string to append.
+ * @param len The maximum length of the c-string to copy.
+ */
+void   BLI_dynstr_nappend                              (DynStr *ds, const char *cstr, int len);
+
        /**
         * Append a c-string to a DynStr, but with formatting like printf.
         * 
index 02c7ff2e9e5be5b297a9c66595060626e7989714..09d28ddbc3af4a875f9fdf41f9e016b56dab471a 100644 (file)
@@ -83,6 +83,23 @@ void BLI_dynstr_append(DynStr *ds, const char *cstr) {
        ds->curlen+= cstrlen;
 }
 
+void BLI_dynstr_nappend(DynStr *ds, const char *cstr, int len) {
+       DynStrElem *dse= malloc(sizeof(*dse));
+       int cstrlen= strnlen(cstr, len);
+
+       dse->str= malloc(cstrlen+1);
+       memcpy(dse->str, cstr, cstrlen);
+       dse->str[cstrlen] = '\0';
+       dse->next= NULL;
+
+       if (!ds->last)
+               ds->last= ds->elems= dse;
+       else
+               ds->last= ds->last->next= dse;
+
+       ds->curlen+= cstrlen;
+}
+
 void BLI_dynstr_vappendf(DynStr *ds, const char *format, va_list args)
 {
        char *message, fixedmessage[256];
index 16f5f47075e93020063338c2aed7e19701d6d840..708089f8f4cf23d5a18a293281903c8a2f24a785 100644 (file)
@@ -140,9 +140,23 @@ typedef struct ConsoleDrawContext {
 
 static void console_draw_sel(int sel[2], int xy[2], int str_len, int cwidth, int console_width, int lheight)
 {
-       if(sel[0] < str_len && sel[1] > 0) {
+       if(sel[0] <= str_len && sel[1] >= 0) {
                int sta = MAX2(sel[0], 0);
                int end = MIN2(sel[1], str_len);
+
+               /* highly confusing but draws correctly */
+               if(sel[0] < 0 || sel[1] > str_len) {
+                       if(sel[0] > 0) {
+                               end= sta;
+                               sta= 0;
+                       }
+                       if (sel[1] <= str_len) {
+                               sta= end;
+                               end= str_len;
+                       }
+               }
+               /* end confusement */
+
                {
                        glEnable(GL_POLYGON_STIPPLE);
                        glPolygonStipple(stipple_halftone);
@@ -157,8 +171,8 @@ static void console_draw_sel(int sel[2], int xy[2], int str_len, int cwidth, int
                }
        }
 
-       sel[0] -= str_len;
-       sel[1] -= str_len;
+       sel[0] -= str_len + 1;
+       sel[1] -= str_len + 1;
 }
 
 
@@ -179,7 +193,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, char *str, int str_len,
                                        int ofs = (int)floor(((float)cdc->mval[0] / (float)cdc->cwidth));
                                        *cdc->pos_pick += MIN2(ofs, str_len);
                                } else
-                                       *cdc->pos_pick += str_len;
+                                       *cdc->pos_pick += str_len + 1;
                        }
 
                }
@@ -190,6 +204,13 @@ static int console_draw_string(ConsoleDrawContext *cdc, char *str, int str_len,
        else if (y_next-cdc->lheight < cdc->ymin) {
                /* have not reached the drawable area so don't break */
                cdc->xy[1]= y_next;
+
+               /* adjust selection even if not drawing */
+               if(cdc->sel[0] != cdc->sel[1]) {
+                       cdc->sel[0] -= str_len + 1;
+                       cdc->sel[1] -= str_len + 1;
+               }
+
                return 1;
        }
 
@@ -314,6 +335,7 @@ static int console_text_main__internal(struct SpaceConsole *sc, struct ARegion *
                if(sc->sel_start != sc->sel_end) {
                        sel[0]= sc->sel_start;
                        sel[1]= sc->sel_end;
+                       // printf("%d %d\n", sel[0], sel[1]);
                }
                
                /* text */
index 44c0b2159d73f36ac4426af3b282b0d3e0861ce4..763436dd05f7d4618fa02ccc18c8872b3c6d5c10 100644 (file)
@@ -681,23 +681,71 @@ static int copy_exec(bContext *C, wmOperator *op)
        char *buf_str;
        
        ConsoleLine *cl;
-       
+       int sel[2];
+       int offset= 0;
+
+#if 0
+       /* copy whole file */
        for(cl= sc->scrollback.first; cl; cl= cl->next) {
                BLI_dynstr_append(buf_dyn, cl->line);
                BLI_dynstr_append(buf_dyn, "\n");
        }
+#endif
+
+       if(sc->sel_start == sc->sel_end)
+               return OPERATOR_CANCELLED;
+
+
+       for(cl= sc->scrollback.first; cl; cl= cl->next) {
+               offset += cl->len + 1;
+       }
+
+       if(offset==0)
+               return OPERATOR_CANCELLED;
+
+
+       offset -= 1;
+       sel[0]= offset - sc->sel_end;
+       sel[1]= offset - sc->sel_start;
+
+       for(cl= sc->scrollback.first; cl; cl= cl->next) {
+
+               int sta= MAX2(0, sel[0]);
+               int end= MIN2(cl->len, sel[1]);
+
+               if(sel[0] <= cl->len && sel[1] >= 0) {
+                       int str_len= cl->len;
+
+                       /* highly confusing but draws correctly */
+                       if(sel[0] < 0 || sel[1] > str_len) {
+                               if(sel[0] > 0) {
+                                       end= sta;
+                                       sta= 0;
+                               }
+                               if (sel[1] <= str_len) {
+                                       sta= end;
+                                       end= str_len;
+                               }
+                       }
+                       /* end confusement */
+
+                       SWAP(int, sta, end);
+                       end= cl->len - end;
+                       sta= cl->len - sta;
+
+                       if(BLI_dynstr_get_len(buf_dyn))
+                               BLI_dynstr_append(buf_dyn, "\n");
+
+                       BLI_dynstr_nappend(buf_dyn, cl->line + sta, end - sta);
+               }
+
+               sel[0] -= cl->len + 1;
+               sel[1] -= cl->len + 1;
+       }
 
        buf_str= BLI_dynstr_get_cstring(buf_dyn);
        buf_len= BLI_dynstr_get_len(buf_dyn);
        BLI_dynstr_free(buf_dyn);
-
-       /* hack for selection */
-#if 0
-       if(sc->sel_start != sc->sel_end) {
-               buf_str[buf_len - sc->sel_start]= '\0';
-               WM_clipboard_text_set(buf_str+(buf_len - sc->sel_end), 0);
-       }
-#endif
        WM_clipboard_text_set(buf_str, 0);
 
        MEM_freeN(buf_str);
@@ -723,11 +771,28 @@ static int paste_exec(bContext *C, wmOperator *op)
        ConsoleLine *ci= console_history_verify(C);
 
        char *buf_str= WM_clipboard_text_get(0);
+       char *buf_step, *buf_next;
 
        if(buf_str==NULL)
                return OPERATOR_CANCELLED;
 
-       console_line_insert(ci, buf_str); /* TODO - Multiline copy?? */
+       buf_next= buf_str;
+       buf_step= buf_str;
+
+       while((buf_next=buf_step) && buf_next[0] != '\0') {
+               buf_step= strchr(buf_next, '\n');
+               if(buf_step) {
+                       *buf_step= '\0';
+                       buf_step++;
+               }
+
+               if(buf_next != buf_str) {
+                       WM_operator_name_call(C, "CONSOLE_OT_execute", WM_OP_EXEC_DEFAULT, NULL);
+                       ci= console_history_verify(C);
+               }
+
+               console_line_insert(ci, buf_next);
+       }
 
        MEM_freeN(buf_str);