Commit 3869741b authored by ROOL's avatar ROOL 🤖
Browse files

Update to use clipboard cut & paste

Detail:
  Initial implementation of the cut-and-paste aspects of 1309,419/FS revision G.
  The former model (limited to only being able copy locally within a document) now uses RAM (or file based fallback) transfer of draw objects (DrawFile/Sprite/JPEG/Text).
Admin:
  Submission for Clipboard Support bounty.

Version 1.31. Tagged as 'Draw-1_31'
parent 15e2c31d
......@@ -91,26 +91,26 @@ OBJS =\
o.Draw o.DrawAction o.DrawCheck o.DrawDispl o.DrawDXF\
o.DrawEdit o.DrawEnter o.DrawFileIO o.DrawGrid o.DrawHelp\
o.DrawMenu o.DrawObject o.DrawPrint o.DrawScan o.DrawSelect\
o.DrawTextC o.DrawTrans o.DrawUndo o.bezierarc
o.DrawTextC o.DrawTrans o.DrawUndo o.bezierarc o.DrawClipb
OBJSZ =\
oz.Draw oz.DrawAction oz.DrawCheck oz.DrawDispl oz.DrawDXF\
oz.DrawEdit oz.DrawEnter oz.DrawFileIO oz.DrawGrid oz.DrawHelp\
oz.DrawMenu oz.DrawObject oz.DrawPrint oz.DrawScan oz.DrawSelect\
oz.DrawTextC oz.DrawTrans oz.DrawUndo oz.bezierarc
oz.DrawTextC oz.DrawTrans oz.DrawUndo oz.bezierarc oz.DrawClipb
OBJSD =\
od.Draw od.DrawAction od.DrawCheck od.DrawDispl\
od.DrawDXF od.DrawEdit od.DrawEnter od.DrawFileIO od.DrawGrid\
od.DrawHelp od.DrawMenu od.DrawObject od.DrawPrint od.DrawScan\
od.DrawSelect od.DrawTextC od.DrawTrans od.DrawUndo\
od.bezierarc od.ftrace od.guard od.flex
od.bezierarc od.ftrace od.guard od.flex od.DrawClipb
ASMS =\
s.Draw s.DrawAction s.DrawCheck s.DrawDispl s.DrawDXF\
s.DrawEdit s.DrawEnter s.DrawFileIO s.DrawGrid s.DrawHelp\
s.DrawMenu s.DrawObject s.DrawPrint s.DrawScan s.DrawSelect\
s.DrawTextC s.DrawTrans s.DrawUndo s.bezierarc
s.DrawTextC s.DrawTrans s.DrawUndo s.bezierarc s.DrawClipb
#
# Rule patterns
......
No preview for this file type
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "1.30"
Module_Version SETA 130
Module_MajorVersion SETS "1.31"
Module_Version SETA 131
Module_MinorVersion SETS ""
Module_Date SETS "27 Oct 2016"
Module_ApplicationDate SETS "27-Oct-16"
Module_Date SETS "09 Feb 2019"
Module_ApplicationDate SETS "09-Feb-19"
Module_ComponentName SETS "Draw"
Module_ComponentPath SETS "castle/RiscOS/Sources/Apps/Draw"
Module_FullVersion SETS "1.30"
Module_HelpVersion SETS "1.30 (27 Oct 2016)"
Module_ComponentPath SETS "apache/RiscOS/Sources/Apps/Draw"
Module_FullVersion SETS "1.31"
Module_HelpVersion SETS "1.31 (09 Feb 2019)"
END
/* (1.30)
/* (1.31)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 1.30
#define Module_MajorVersion_CMHG 1.31
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 27 Oct 2016
#define Module_Date_CMHG 09 Feb 2019
#define Module_MajorVersion "1.30"
#define Module_Version 130
#define Module_MajorVersion "1.31"
#define Module_Version 131
#define Module_MinorVersion ""
#define Module_Date "27 Oct 2016"
#define Module_Date "09 Feb 2019"
#define Module_ApplicationDate "27-Oct-16"
#define Module_ApplicationDate "09-Feb-19"
#define Module_ComponentName "Draw"
#define Module_ComponentPath "castle/RiscOS/Sources/Apps/Draw"
#define Module_ComponentPath "apache/RiscOS/Sources/Apps/Draw"
#define Module_FullVersion "1.30"
#define Module_HelpVersion "1.30 (27 Oct 2016)"
#define Module_LibraryVersionInfo "1:30"
#define Module_FullVersion "1.31"
#define Module_HelpVersion "1.31 (09 Feb 2019)"
#define Module_LibraryVersionInfo "1:31"
......@@ -101,6 +101,7 @@
#include "DrawSelect.h"
#include "DrawTrans.h"
#include "DrawUndo.h"
#include "DrawClipb.h"
#define EMPTY(s) ((s) [0] == '\0')
#define CLEAR(s) ((s) [0] = '\0')
......@@ -553,9 +554,9 @@ os_error *draw_make_oserror (const char *token)
}
/*Make origin, typically from a wimp_openstr*/
static void make_origin (draw_objcoord *to, wimp_box *box, int *scroll)
void draw_make_origin (draw_objcoord *to, wimp_box *box, int *scroll)
{ ftracef0 ("make_origin\n");
{ ftracef0 ("draw_make_origin\n");
to->x = box->x0 - scroll [0];
to->y = box->y1 - scroll [1];
}
......@@ -975,7 +976,7 @@ static BOOL draw_null_event_handler (wimp_mousestr mouse)
}
/*draw_make_clip (&r, &org, &clip);*/
make_origin (&org, &r.o.box, &r.o.x);
draw_make_origin (&org, &r.o.box, &r.o.x);
draw_point_scale (&mouseD, (draw_objcoord *) &mouse.x, &org);
/*Snap mouse, except when dragging a zoom or printer box -- or a
......@@ -1130,7 +1131,7 @@ void draw_make_clip (wimp_redrawstr *r, draw_objcoord *orgO, draw_bboxtyp *clip)
{ draw_objcoord org;
ftracef0 ("draw_make_clip\n");
make_origin (&org, &r->box, &r->scx);
draw_make_origin (&org, &r->box, &r->scx);
orgO->x = draw_os_to_draw (org.x);
orgO->y = draw_os_to_draw (org.y);
......@@ -1384,7 +1385,7 @@ static void paper_but (wimp_mousestr *m, viewrec *vuue)
draw_displ_scalefactor = vuue->zoomfactor;
wimp_get_wind_state (m->w, &r);
make_origin (&org, &r.o.box, &r.o.x);
draw_make_origin (&org, &r.o.box, &r.o.x);
pt.x = draw_scaledown (m->x - org.x); /*mouse position relative to*/
pt.y = draw_scaledown (m->y - org.y); /*window (ie diagram) origin*/
......@@ -1559,12 +1560,12 @@ static BOOL check_filename (char *name, char *to, int maxlen)
/*Load operations*/
/*Creates the diagram if it is NULL. vuue should also be NULL if so.*/
/*If dataopen is TRUE, then only allow draw files to be loaded*/
static os_error *load_file (diagrec *diag, viewrec *vuue, draw_objcoord *pt,
os_error *draw_load_file (diagrec *diag, viewrec *vuue, draw_objcoord *pt,
BOOL dataopen)
{ int estsize, filetype = xferrecv_checkimport (&estsize);
ftracef0 ("load_file\n");
ftracef0 ("draw_load_file\n");
if (diag == NULL) vuue = NULL;
switch (filetype)
......@@ -1765,14 +1766,14 @@ static void draw_paper__wimp_event_handler (wimp_eventstr *e, void *handle)
wimp_get_wind_state (vuue->w, &r);
draw_displ_scalefactor = vuue->zoomfactor;
make_origin (&org, &r.o.box, &r.o.x);
draw_make_origin (&org, &r.o.box, &r.o.x);
draw_point_scale (&mouseD, (draw_objcoord *)&mouse.x, &org);
/*Gravitate to grid position*/
draw_grid_snap_if_locked (vuue, &mouseD);
/*Do the load*/
err = load_file (diag, vuue, &mouseD, FALSE);
err = draw_load_file (diag, vuue, &mouseD, FALSE);
}
break;
......@@ -2191,10 +2192,18 @@ static void draw_bkg_events (wimp_eventstr *e, void *handle)
draw_prequit ();
break;
case wimp_MDATAREQUEST:
draw_clipboard_rx_datarequest(e); /*someone wants our clipboard data*/
break;
case wimp_MCLAIMENTITY: /*clipboard claimed by another task?*/
draw_clipboard_claimed(e);
break;
case wimp_MDATASAVE:
case wimp_MDATALOAD:
case wimp_MDATAOPEN:
err = load_file (NULL, NULL, &zero, msg->hdr.action==wimp_MDATAOPEN);
err = draw_load_file (NULL, NULL, &zero, msg->hdr.action==wimp_MDATAOPEN);
break;
case wimp_SAVEDESK:
......@@ -2475,7 +2484,9 @@ int main (int argc, char **argv)
wimp_MPREQUIT,
wimp_PALETTECHANGE,
wimp_SAVEDESK,
wimp_MDATAREQUEST,
wimp_MDATASAVED,
wimp_MCLAIMENTITY,
wimp_MMENUWARN,
wimp_MMODECHANGE,
wimp_MHELPREQUEST,
......
This diff is collapsed.
......@@ -868,7 +868,7 @@ static os_error *do_objtrfmtext_system (draw_objptr hdrptr,
len = strlen (hdrptr.trfmtextp->text);
size_of_area = 10*1024; /*!!!*/
if ((area = Alloc (size_of_area)) == NULL)
{ ftracef1 ("-> out of memory\n");
{ ftracef0 ("-> out of memory\n");
return draw_make_oserror ("DrawNR");
}
......
......@@ -35,6 +35,7 @@
#include <ctype.h>
#include <swis.h>
#include "Global/FileTypes.h"
#include "Interface/HighFSI.h"
#include "os.h"
#include "bbc.h"
......@@ -68,6 +69,7 @@
#include "DrawSelect.h"
#include "DrawTextC.h"
#include "DrawUndo.h"
#include "DrawClipb.h"
static struct
{ diagrec *diag;
......@@ -883,6 +885,82 @@ static BOOL write_fontlist (int filehand, char *fontusedp, int *bytecount)
}
}
static BOOL write_fontlist_clipboard (char **store, char *fontusedp, int *bytecount)
{ int objsize = 0;
int padby;
/*The following: fonthdr,i (fontref),fournulls are passed to write_bytes,
this takes char** (ie a pointer to a flex_anchor) so it can output
data in any size chunks even if the source flex block shifts in the
process. fonthdrp,ip,fournullsp allow us to do this with
'write_bytes (...., &fonthdrp, ......);'*/
draw_fontliststrhdr fonthdr; /*header for a fontlist*/
int i; /*loop counter & fontref*/
char *ip = (char*)&i; /*pointer to it*/
int fournulls = 0; /*a useful source of four nulls*/
char *fournullsp = (char*)&fournulls; /*pointer to it*/
ftracef0 ("draw_file: write_fontlist_clipboard\n");
for (i = 1; i <= 255; i++)
if (fontusedp[i])
objsize += sizeof (draw_fontref) + strlen (draw_fontcat.name[i]) + 1;
if (objsize == 0) return TRUE; /*No fonts used - no fontlist needed*/
padby = (4 - objsize) & 3; /*0..3 bytes padding at EOobject*/
objsize += sizeof (draw_fontliststrhdr) + padby;
fonthdr.tag = draw_OBJFONTLIST; /*build, then output a fontlist hdr*/
fonthdr.size = objsize;
memcpy(*store + *bytecount, &fonthdr, sizeof (draw_fontliststrhdr));
*bytecount = *bytecount + sizeof (draw_fontliststrhdr);
for (i = 1; i <= 255; i++)/*output each fontref + fontname & terminator*/
if (fontusedp[i]) {
memcpy(*store + *bytecount, ip, sizeof(draw_fontref));
*bytecount = *bytecount + sizeof(draw_fontref);
memcpy(*store + *bytecount, draw_fontcat.name[i], 1 + strlen(draw_fontcat.name[i]));
*bytecount = *bytecount + 1 + strlen(draw_fontcat.name[i]);
}
memcpy(*store+*bytecount,fournullsp,padby);
*bytecount = *bytecount + padby;
return TRUE;
}
void draw_file_typemask(draw_objptr hdrptr, int *mask)
{ switch (hdrptr.objhdrp->tag) {
case draw_OBJTEXT:
case draw_OBJTEXTAREA:
case draw_OBJTRFMTEXT:
case draw_OBJTEXTCOL:
case draw_OBJTRFMTEXTAREA:
case draw_OBJTRFMTEXTCOL:
*mask=*mask | _tm_text;
break;
case draw_OBJGROUP:
{ draw_objptr objptr;
for (objptr.bytep = hdrptr.bytep + sizeof (draw_groustr);
objptr.bytep < hdrptr.bytep + hdrptr.objhdrp->size;
objptr.bytep += objptr.objhdrp->size)
draw_file_typemask (objptr, mask);
}
break;
case draw_OBJSPRITE:
case draw_OBJTRFMSPRITE:
*mask = *mask | _tm_sprite;
break;
case draw_OBJJPEG:
*mask = *mask | _tm_jpeg;
break;
}
}
void draw_file_fontuse_object (draw_objptr hdrptr, char *fontusetab)
{ ftracef0 ("draw_file_fontuse_object\n");
......@@ -1233,6 +1311,79 @@ static BOOL saveselection (diagrec *diag, char *filename, fileIO_method method,
return (ok);
}
BOOL draw_file_copy_selection(diagrec *diag)
{ /* Create in-memory version and move to clipboard */
draw_bboxtyp hdrbox;
char fontusetab[256]; /*slot 0..255 are valid fontrefs*/
int i, bytecount;
BOOL ok=TRUE;
draw_objptr hdrptr;
ftracef0 ("draw_file: draw_file_copy_selection\n");
/*Deselect all text columns -- they cannot be saved individually*/
if (draw_select_deselect_type (diag, draw_OBJTEXTCOL))
return TRUE; /*Nothing to save*/
draw_obj_bound_selection (&hdrbox);
/*find fonts used in each selected object*/
(void) memset (fontusetab, 0, 256); /*clear fontusetab*/
for (i = 0; hdrptr = draw_select_find (i), hdrptr.bytep != NULL; i++)
draw_file_fontuse_object (hdrptr, &fontusetab[0]);
/* First pass to determine file size. */
bytecount = 0;
(void) save_selected_data (&hdrbox, fontusetab, diag, 0, &bytecount);
/* Create somewhere to receive the data */
if (clipdata != NULL) {
FLEX_FREE((flex_ptr)&clipdata);
clipdata = NULL;
}
if (FLEX_ALLOC((flex_ptr)&clipdata, bytecount) == 0) {
/* Out of space */
return FALSE;
} else {
cliplength = bytecount;
}
int offset = 0;
int typemask = _tm_draw;
int typelist[5];
/* Drawfile header */
draw_fileheader header = draw_blank_header;
header.bbox = hdrbox;
memcpy(clipdata + offset, &header, sizeof(draw_fileheader));
offset += sizeof(draw_fileheader);
/* fontlist (if any) */
write_fontlist_clipboard(&clipdata, fontusetab, &offset);
/*do each selected object*/
for (i = 0; ok && (hdrptr = draw_select_find (i), hdrptr.bytep != NULL); i++)
{
memcpy(clipdata + offset, draw_selection->owner->paper + draw_selection->array[i], hdrptr.objhdrp->size);
/* File types... */
draw_file_typemask(hdrptr, &typemask);
offset += hdrptr.objhdrp->size;
}
offset = 0;
if (typemask & _tm_draw) typelist[offset++] = FileType_Draw;
if (typemask & _tm_sprite) typelist[offset++] = FileType_Sprite;
if (typemask & _tm_text) typelist[offset++] = FileType_Text;
if (typemask & _tm_jpeg) typelist[offset++] = FileType_JPEG;
typelist[offset] = wimp_MDATAREQUEST_types_end;
/* We have the clipboard */
draw_clipboard_claim(wimp_MCLAIMENTITY_flags_clipboard);
return ok;
}
BOOL draw_file_file_saveselection (char *filename, void *handle)
{ ftracef2 ("draw_file_file_saveselection: filename: %s; handle: 0x%X\n", filename, handle);
return saveselection ((diagrec*) handle, filename, via_FILE, 0);
......@@ -1472,62 +1623,71 @@ diagrec *draw_file_loadfile (diagrec *diag, viewrec *vuue, char *name,
ftracef0 ("draw_file_loadfile\n");
if (commandLine) method = via_FILE;
if (method == via_FILE)
{ os_filestr blk;
diagrec *rec;
switch (method) {
case via_FILE:
{ os_filestr blk;
diagrec *rec;
blk.action = 5; /*Read catalogue info*/
blk.name = name; /*for name*/
blk.action = OSFile_ReadInfo;
blk.name = name; /*for name*/
if (wimpt_complain (os_file (&blk)) != NULL)
return NULL;
if (wimpt_complain (os_file (&blk)) != NULL)
return NULL;
if (blk.action != 1) /*save two messages by using OS_File 19*/
{ blk.loadaddr = blk.action;
blk.action = 19;
#if TRACE
if (blk.action != object_file) /*save two messages by using OS_File 19*/
{ blk.loadaddr = blk.action;
blk.action = OSFile_MakeError;
#if TRACE
wimpt_noerr (os_file (&blk));
#else
#else
wimpt_complain (os_file (&blk));
#endif
return NULL;
}
#endif
return NULL;
}
ftracef1 ("draw_file_loadfile found file, size %d bytes\n",blk.start);
loadaddr = blk.loadaddr, execaddr = blk.execaddr;
ftracef1 ("draw_file_loadfile found file, size %d bytes\n",blk.start);
loadaddr = blk.loadaddr, execaddr = blk.execaddr;
if ((loadaddr & 0xFFF00000) != 0xFFF00000)
{ Error (0, "FileF2");
return NULL;
}
if ((loadaddr & 0xFFF00000) != 0xFFF00000)
{ Error (0, "FileF2");
return NULL;
}
filetype = (loadaddr & 0x000FFF00) >> 8;
filesize = blk.start;
/*See if this is an attempt to load a new file that's already open,
with the same date stamp, that's not modified, called the
same thing*/
for (rec = draw_startdiagchain; rec != NULL; rec = rec->nextdiag)
{ if ((diag == NULL) &&
(rec->misc->options.datestamped && (rec->misc->address.load == loadaddr) &&
(rec->misc->address.exec == execaddr)) &&
!rec->misc->options.modified &&
(strcmp (rec->misc->filename, name) == 0))
{ wimp_wstate state;
/*Pop to top and gain the caret*/
wimp_get_wind_state (rec->view->w, &state);
state.o.behind = -1;
draw_open_wind (&state.o, rec->view);
draw_enter_claim_focus (rec, rec->view);
return rec;
filetype = (loadaddr & 0x000FFF00) >> 8;
filesize = blk.start;
/*See if this is an attempt to load a new file that's already open,
with the same date stamp, that's not modified, called the
same thing*/
for (rec = draw_startdiagchain; rec != NULL; rec = rec->nextdiag)
{ if ((diag == NULL) &&
(rec->misc->options.datestamped && (rec->misc->address.load == loadaddr) &&
(rec->misc->address.exec == execaddr)) &&
!rec->misc->options.modified &&
(strcmp (rec->misc->filename, name) == 0))
{ wimp_wstate state;
/*Pop to top and gain the caret*/
wimp_get_wind_state (rec->view->w, &state);
state.o.behind = -1;
draw_open_wind (&state.o, rec->view);
draw_enter_claim_focus (rec, rec->view);
return rec;
}
}
break;
}
}
else
{ /*Filesize is a guess, but we can't allow transfer of zero bytes
into zero-sized buffer. 6 Aug 1991*/
if (filesize <= 0) filesize = 1024;
case via_CLIPBOARD:
case via_CLIPBOARD_INT:
/*We have the file size; name actually points to the file data already for us*/
break;
default:
/*Filesize is a guess, but we can't allow transfer of zero bytes
into zero-sized buffer. 6 Aug 1991*/
if (filesize <= 0) filesize = 1024;
break;
}
/*Create new diagram if diag is NULL*/
......@@ -1774,35 +1934,54 @@ BOOL draw_file_get (char *name, char **buffp, int offset, int *filelenp,
{ ftracef0 ("draw_file_get\n");
if (owner_xferrecv.method == via_FILE)
{ os_filestr blk;
switch (owner_xferrecv.method) {
case via_FILE:
{ os_filestr blk;
blk.action = 255; /*Load file into buffer*/
blk.name = name;
blk.loadaddr = (int) (*buffp + offset);
blk.execaddr = 0;
blk.action = 255; /*Load file into buffer*/
blk.name = name;
blk.loadaddr = (int) (*buffp + offset);
blk.execaddr = 0;
if (wimpt_complain (os_file (&blk)))
return FALSE;
}
else
{ int final;
if (wimpt_complain (os_file (&blk)))
return FALSE;
break;
}
case via_CLIPBOARD_INT:
/*Data is already present locally*/
if (clipdata == NULL) {
return FALSE;
} else {
memcpy(*buffp + offset, clipdata, *filelenp);
}
break;
case via_CLIPBOARD:
/*Data is already present. Copy it to our destination.*/
memcpy(*buffp + offset, name, *filelenp);
break;
owner_xferrecv.filelen = 0; /*updated by loadram_extend, if called*/
default:
{ int final;
ftracef2 ("loadfile calls xferrecv_doimport, "
"owner_xferrecv.diag->paper is %d, *filelenp is %d\n",
(int) owner_xferrecv.diag->paper, *filelenp);
owner_xferrecv.filelen = 0; /*updated by loadram_extend, if called*/
final = xferrecv_doimport (*buffp + offset, *filelenp,
extender != NULL? extender: &Extend_Diag);
ftracef2 ("loadfile calls xferrecv_doimport, "
"owner_xferrecv.diag->paper is %d, *filelenp is %d\n",
(int) owner_xferrecv.diag->paper, *filelenp);
ftracef1 ("returned to loadfile, final block transfer was %d bytes\n",
final);
final = xferrecv_doimport (*buffp + offset, *filelenp,
extender != NULL? extender: &Extend_Diag);
if (final < 0) return FALSE;
ftracef1 ("returned to loadfile, final block transfer was %d bytes\n",
final);
*filelenp = owner_xferrecv.filelen + final; /*total size*/
if (final < 0) return FALSE;
*filelenp = owner_xferrecv.filelen + final; /*total size*/
break;
}
}
return TRUE;
......
......@@ -49,6 +49,7 @@
#include "dbox.h"
#include "dboxtcol.h"
#include "event.h"
#include "flex.h"
#include "magnify.h"
#include "msgs.h"
#include "os.h"
......@@ -81,6 +82,7 @@
#include "DrawTextC.h"
#include "DrawTrans.h"
#include "DrawUndo.h"
#include "DrawClipb.h"
/*------------------------------------------------------------------------*/
/* The principal menus */
......@@ -1131,8 +1133,11 @@ static BOOL select_check (int which, int code, diagrec *diag, viewrec *vuue)
case s_Select_Front:
case s_Select_Back:
return owner && draw_selection->indx > 0;
case s_Select_Cut:
case s_Select_Copy:
return draw_selection->indx > 0;
case s_Select_Paste:
return draw_clipboard_check_paste();
case s_Select_Group:
return owner && draw_selection->indx > 1;
case s_Select_Ungroup:
......@@ -1207,12 +1212,17 @@ static void do_select (int which, int code, char *hit, diagrec *diag,
draw_select_clearall (sel);
break;
case s_Select_Cut:
draw_file_copy_selection(diag);
err=draw_select_delete(sel);
break;
case s_Select_Copy:
{ trans_str jog;
draw_file_copy_selection(diag);
break;
draw_grid_jog (vuue, &jog);
err = draw_select_copy (sel, diag, &jog);
}
case s_Select_Paste: