static void FreeClipboard( void ) /*******************************/ { DLIST * objlist; DLIST_ELT elt; for( objlist = ClipBoard.objs; objlist != NULL; objlist = DListConsume( objlist ) ) { elt = DListElement( objlist ); Destroy( elt.copy, FALSE ); } InitClipboard(); }
/*----------------------* * Paste from Clipboard * *----------------------*/ BOOL PasteClip (LONG x, struct line_node *actline, struct InstData *data) { struct line_node *line = NULL; struct line_node *startline = NULL; struct line_node *previous = NULL; UWORD *styles = NULL; UWORD *colors = NULL; STRPTR textline; BOOL newline = TRUE; BOOL res = FALSE; ENTER(); if(InitClipboard(data, IFFF_READ)) { if(StopChunk(data->iff, ID_FTXT, ID_CHRS) == 0 && StopChunk(data->iff, ID_FTXT, ID_FLOW) == 0 && StopChunk(data->iff, ID_FTXT, ID_HIGH) == 0 && StopChunk(data->iff, ID_FTXT, ID_SBAR) == 0 && StopChunk(data->iff, ID_FTXT, ID_COLS) == 0 && StopChunk(data->iff, ID_FTXT, ID_STYL) == 0 && StopChunk(data->iff, ID_FTXT, ID_CSET) == 0) { LONG error, codeset = 0; UWORD flow = MUIV_TextEditor_Flow_Left; UWORD color = FALSE; UWORD separator = 0; BOOL ownclip = FALSE; LONG updatefrom; while(TRUE) { struct ContextNode *cn; error = ParseIFF(data->iff, IFFPARSE_SCAN); SHOWVALUE(DBF_CLIPBOARD, error); if(error == IFFERR_EOC) continue; else if(error) break; if((cn = CurrentChunk(data->iff)) != NULL) { switch (cn->cn_ID) { case ID_CSET: D(DBF_CLIPBOARD, "reading FLOW"); SHOWVALUE(DBF_CLIPBOARD, cn->cn_Size); if(cn->cn_Size >= 4) { /* Only the first four bytes are interesting */ if(ReadChunkBytes(data->iff, &codeset, 4) != 4) { codeset = 0; } SHOWVALUE(DBF_CLIPBOARD, codeset); } break; case ID_FLOW: D(DBF_CLIPBOARD, "reading FLOW"); SHOWVALUE(DBF_CLIPBOARD, cn->cn_Size); if(cn->cn_Size == 2) { if(ReadChunkBytes(data->iff, &flow, 2) == 2) if(flow > MUIV_TextEditor_Flow_Right) flow = MUIV_TextEditor_Flow_Left; SHOWVALUE(DBF_CLIPBOARD, flow); } break; case ID_HIGH: D(DBF_CLIPBOARD, "reading HIGH"); SHOWVALUE(DBF_CLIPBOARD, cn->cn_Size); if (cn->cn_Size == 2) { error = ReadChunkBytes(data->iff, &color, 2); SHOWVALUE(DBF_CLIPBOARD, color); SHOWVALUE(DBF_CLIPBOARD, error); } break; case ID_SBAR: D(DBF_CLIPBOARD, "reading SBAR"); SHOWVALUE(DBF_CLIPBOARD, cn->cn_Size); if (cn->cn_Size == 2) { error = ReadChunkBytes(data->iff, &separator, 2); SHOWVALUE(DBF_CLIPBOARD, separator); SHOWVALUE(DBF_CLIPBOARD, error); } break; case ID_COLS: D(DBF_CLIPBOARD, "reading COLS"); SHOWVALUE(DBF_CLIPBOARD, cn->cn_Size); if(colors) { MyFreePooled(data->mypool, colors); colors = NULL; } // allocate one word more than the chunk tell us, because we terminate the array with an additional value if(cn->cn_Size > 0 && (colors = (UWORD *)MyAllocPooled(data->mypool, cn->cn_Size + sizeof(UWORD))) != NULL) { error = ReadChunkBytes(data->iff, colors, cn->cn_Size); SHOWVALUE(DBF_CLIPBOARD, error); colors[cn->cn_Size / 2] = 0xffff; } break; case ID_STYL: D(DBF_CLIPBOARD, "reading STYL"); SHOWVALUE(DBF_CLIPBOARD, cn->cn_Size); ownclip = TRUE; if(styles) { MyFreePooled(data->mypool, styles); styles = NULL; } // allocate one word more than the chunk tell us, because we terminate the array with an additional value if(cn->cn_Size > 0 && (styles = (UWORD *)MyAllocPooled(data->mypool, cn->cn_Size + sizeof(UWORD))) != NULL) { error = ReadChunkBytes(data->iff, styles, cn->cn_Size); SHOWVALUE(DBF_CLIPBOARD, error); styles[cn->cn_Size / 2] = EOS; } break; case ID_CHRS: { D(DBF_CLIPBOARD, "reading CHRS"); SHOWVALUE(DBF_CLIPBOARD, cn->cn_Size); data->HasChanged = TRUE; if(cn->cn_Size > 0 && !ownclip) { char *contents; ULONG length = cn->cn_Size; if((contents = (char *)MyAllocPooled(data->mypool, length + 1)) != NULL) { error = ReadChunkBytes(data->iff, contents, length); SHOWVALUE(DBF_CLIPBOARD, error); if(contents[length - 1] != '\n') { newline = FALSE; } else { length--; } contents[length] = '\0'; #if defined(__MORPHOS__) if (codeset == CODESET_UTF8) { if (IS_MORPHOS2) contents = utf8_to_ansi(data, contents); } #endif if((line = ImportText(contents, data, &ImPlainHook, data->ImportWrap))) { if(!startline) startline = line; if(previous) previous->next = line; line->previous = previous; line->visual = VisualHeight(line, data); data->totallines += line->visual; while(line->next) { line = line->next; line->visual = VisualHeight(line, data); data->totallines += line->visual; } previous = line; } MyFreePooled(data->mypool, contents); } } else { ULONG length = cn->cn_Size; if(length > 0 && (textline = (char *)MyAllocPooled(data->mypool, length + 2)) != NULL) { error = ReadChunkBytes(data->iff, textline, length); SHOWVALUE(DBF_CLIPBOARD, error); if (textline[length - 1] != '\n') { newline = FALSE; textline[length] = '\n'; length++; } textline[length] = '\0'; if((line = AllocLine(data))) { line->next = NULL; line->previous = previous; line->line.Contents = textline; line->line.Length = length; line->visual = VisualHeight(line, data); line->line.Color = color; line->line.Flow = flow; line->line.Separator = separator; line->line.Styles = styles; line->line.Colors = colors; data->totallines += line->visual; if(!startline) startline = line; if(previous) previous->next = line; previous = line; } else { if(styles) MyFreePooled(data->mypool, (void *)styles); if(colors) MyFreePooled(data->mypool, (void *)colors); } } else { if(styles) MyFreePooled(data->mypool, styles); if(colors) MyFreePooled(data->mypool, (void *)colors); } styles = NULL; colors = NULL; flow = MUIV_TextEditor_Flow_Left; color = FALSE; separator = 0; ownclip = FALSE; } } break; } } } if(line) { BOOL oneline = FALSE; SplitLine(x, actline, FALSE, NULL, data); line->next = actline->next; actline->next->previous = line; actline->next = startline; startline->previous = actline; data->CPos_X = line->line.Length-1; if(actline->next == line) { data->CPos_X += actline->line.Length-1; oneline = TRUE; } if(!newline) MergeLines(line, data); MergeLines(actline, data); if(oneline) line = actline; if(newline) { line = line->next; data->CPos_X = 0; } data->actualline = line; } else { switch(error) { case IFFERR_MANGLED: case IFFERR_SYNTAX: case IFFERR_NOTIFF: D(DBF_CLIPBOARD, "no FTXT clip!"); DoMethod(data->object, MUIM_TextEditor_HandleError, Error_ClipboardIsNotFTXT); break; default: D(DBF_CLIPBOARD, "clipboard is empty!"); DoMethod(data->object, MUIM_TextEditor_HandleError, Error_ClipboardIsEmpty); break; } } data->update = TRUE; ScrollIntoDisplay(data); updatefrom = LineToVisual(actline, data)-1; if(updatefrom < 0) updatefrom = 0; DumpText(data->visual_y+updatefrom, updatefrom, data->maxlines, TRUE, data); if(data->update) res = TRUE; else data->update = TRUE; } EndClipSession(data); } RETURN(res); return res; }
LONG CutBlock2(struct InstData *data, BOOL Clipboard, BOOL NoCut, struct marking *newblock, BOOL update) { LONG tvisual_y, error; LONG startx, stopx; LONG res = 0; struct line_node *startline, *stopline; ENTER(); startx = newblock->startx; stopx = newblock->stopx; startline = newblock->startline; stopline = newblock->stopline; //D(DBF_STARTUP, "CutBlock2: %ld-%ld %lx-%lx %ld %ld", startx, stopx, startline, stopline, Clipboard, NoCut); if(startline != stopline) { struct line_node *c_startline = startline->next; data->update = FALSE; if(Clipboard == TRUE) { if(InitClipboard(data, IFFF_WRITE)) { D(DBF_CLIPBOARD, "writing FORM"); error = PushChunk(data->iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN); SHOWVALUE(DBF_CLIPBOARD, error); ClipChars(startx, startline, startline->line.Length-startx, data); } else { Clipboard = FALSE; } } while(c_startline != stopline) { if(Clipboard == TRUE) { ClipLine(c_startline, data); } if(NoCut == FALSE) { struct line_node *cc_startline = c_startline; MyFreePooled(data->mypool, c_startline->line.Contents); if(c_startline->line.Styles != NULL) MyFreePooled(data->mypool, c_startline->line.Styles); data->totallines -= c_startline->visual; c_startline = c_startline->next; //D(DBF_STARTUP, "FreeLine %08lx", cc_startline); FreeLine(cc_startline, data); } else c_startline = c_startline->next; } if(Clipboard == TRUE) { if(stopx != 0) ClipChars(0, stopline, stopx, data); EndClipSession(data); } if(NoCut == FALSE) { startline->next = stopline; stopline->previous = startline; //D(DBF_STARTUP, "RemoveChars: %ld %ld %08lx %ld", startx, stopx, startline, startline->line.Length); if(startline->line.Length-startx-1 > 0) RemoveChars(startx, startline, startline->line.Length-startx-1, data); if(stopx != 0) RemoveChars(0, stopline, stopx, data); data->CPos_X = startx; data->actualline = startline; MergeLines(startline, data); } } else { if(Clipboard == TRUE) { if(InitClipboard(data, IFFF_WRITE)) { D(DBF_CLIPBOARD, "writing FORM"); error = PushChunk(data->iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN); SHOWVALUE(DBF_CLIPBOARD, error); ClipChars(startx, startline, stopx-startx, data); EndClipSession(data); } if(update == TRUE && NoCut == TRUE) { MarkText(data->blockinfo.startx, data->blockinfo.startline, data->blockinfo.stopx, data->blockinfo.stopline, data); goto end; } } if(NoCut == FALSE) { data->CPos_X = startx; RemoveChars(startx, startline, stopx-startx, data); if(update == TRUE) goto end; } } tvisual_y = LineToVisual(startline, data)-1; if(tvisual_y < 0 || tvisual_y > data->maxlines) { //D(DBF_STARTUP, "ScrollIntoDisplay"); ScrollIntoDisplay(data); tvisual_y = 0; } if(update == TRUE) { //D(DBF_STARTUP, "DumpText! %ld %ld %ld", data->visual_y, tvisual_y, data->maxlines); data->update = TRUE; DumpText(data->visual_y+tvisual_y, tvisual_y, data->maxlines, TRUE, data); } res = tvisual_y; end: RETURN(res); return res; }