... | ... |
@@ -467,13 +467,14 @@ redata_fix_nl(redata_t *redata, int chunkno) |
467 | 467 |
} |
468 | 468 |
|
469 | 469 |
int |
470 |
-redata_load(redata_t *redata, char *filename, int use_unsaved) |
|
470 |
+redata_load(redata_t *redata, char *filename, int (*callback_question)(/*char *title, char *body, int nopts, char *opts[],void *userptr*/), void *userptr) |
|
471 | 471 |
{ |
472 | 472 |
int fd,nread,totalread; |
473 | 473 |
int chunkno, avail; |
474 | 474 |
struct stat statbuf; |
475 | 475 |
rechunk_t *chunk; |
476 | 476 |
int i; |
477 |
+ int reply; |
|
477 | 478 |
if(redata==NULL || filename==NULL) |
478 | 479 |
return(-1); /* sanity check failed */ |
479 | 480 |
redata_wipe(redata); |
... | ... |
@@ -520,18 +521,20 @@ redata_load(redata_t *redata, char *filename, int use_unsaved) |
520 | 521 |
redata_fix_nl(redata,chunkno); |
521 | 522 |
for(chunkno=0;chunkno<redata->sizechunks;chunkno++) |
522 | 523 |
redata_whatin_refresh(redata,chunkno); |
523 |
- /* unsaved */ |
|
524 |
+ /* unsaved and other plugins */ |
|
524 | 525 |
for(i=0;i<redata->sizeplugins;i++) { |
525 |
- if(use_unsaved) { |
|
526 |
- /* apply missing changes and append new changes to unsaved */ |
|
527 |
- if(redata->plugins[i].postload!=NULL) |
|
528 |
- redata->plugins[i].postload(redata,redata->plugins+i,filename); |
|
529 |
- } else { |
|
530 |
- /* nuke existing unsaved (if exists) and prepare new unsaved */ |
|
531 |
- /* _trunc() fills itself redata->initialhash */ |
|
532 |
- if(redata->plugins[i].truncload!=NULL) |
|
533 |
- redata->plugins[i].truncload(redata,redata->plugins+i,filename); |
|
526 |
+ if(!redata->plugins[i].active) |
|
527 |
+ continue; |
|
528 |
+ reply=-1; |
|
529 |
+ if(redata->plugins[i].loadquestion!=NULL && callback_question!=NULL) { |
|
530 |
+ char *title, *body; |
|
531 |
+ int nopts; |
|
532 |
+ char **opts; |
|
533 |
+ if(redata->plugins[i].loadquestion(redata,redata->plugins+i,filename,&title,&body,&nopts,&opts)!=-1) |
|
534 |
+ reply=callback_question(title,body,nopts,opts,userptr); |
|
534 | 535 |
} |
536 |
+ if(redata->plugins[i].postload!=NULL) |
|
537 |
+ redata->plugins[i].postload(redata,redata->plugins+i,filename,reply); |
|
535 | 538 |
} |
536 | 539 |
/* all done */ |
537 | 540 |
return(0); |
... | ... |
@@ -13,6 +13,8 @@ |
13 | 13 |
|
14 | 14 |
#include <limits.h> |
15 | 15 |
|
16 |
+#define MAXPLUGINNAME 32 |
|
17 |
+ |
|
16 | 18 |
typedef struct whatin_t { |
17 | 19 |
int nlcount; |
18 | 20 |
} whatin_t; |
... | ... |
@@ -43,22 +45,19 @@ typedef struct undostack_t { |
43 | 45 |
char *buf; |
44 | 46 |
} undostack_t; |
45 | 47 |
|
46 |
-#define PLUGIN_CHECKUSERCONFIRM 1 /* if check is Ok, confirm with user whether to postload or go inactive */ |
|
47 |
- |
|
48 | 48 |
typedef struct redata_plugin_t { |
49 | 49 |
int active; |
50 |
+ char name[MAXPLUGINNAME]; |
|
50 | 51 |
int (*unregister)(/*redata_t *redata, redata_plugin_t *plugin,char *filename*/); |
51 |
- /* checkload returns 0:Ok, 1:Not needed, -1: error, go inactive */ |
|
52 | 52 |
int (*wipe)(/*redata_t *redata, redata_plugin_t *plugin,char *filename*/); |
53 |
- int (*checkload)(/*redata_t *redata, redata_plugin_t *plugin,char *filename*/); |
|
54 |
- int (*postload)(/*redata_t *redata, redata_plugin_t *plugin,char *filename*/); |
|
55 |
- int (*truncload)(/*redata_t *redata, redata_plugin_t *plugin,char *filename*/); |
|
53 |
+ /* loadquestion returns -1 if no question needed */ |
|
54 |
+ int (*loadquestion)(/*redata_t *redata, redata_plugin_t *plugin,char *filename, char **title, char **body, int *nopts, char **opts[] */); |
|
55 |
+ int (*postload)(/*redata_t *redata, redata_plugin_t *plugin,char *filename,int questionreply */); |
|
56 | 56 |
int (*postsave)(/*redata_t *redata, redata_plugin_t *plugin,char *oldfilename,char *newfilename*/); |
57 | 57 |
int (*add)(/*redata_t *redata, redata_plugin_t *plugin,undo_t *undo*/); |
58 | 58 |
int (*unadd)(/*redata_t *redata, redata_plugin_t *plugin,undo_t *undo*/); |
59 | 59 |
int (*commit)(/*redata_t *redata, redata_plugin_t *plugin,char *filename*/); |
60 | 60 |
void *userptr; |
61 |
- int flags; |
|
62 | 61 |
} redata_plugin_t; |
63 | 62 |
|
64 | 63 |
typedef struct redata_t { |
... | ... |
@@ -77,7 +76,6 @@ typedef struct redata_t { |
77 | 76 |
redata_plugin_t plugins[1]; |
78 | 77 |
} redata_t; |
79 | 78 |
|
80 |
-#warning TODO: Make redata_xxx call the plugins |
|
81 | 79 |
redata_t *redata_init( int (*pluginregisterfn)(redata_t *redata, redata_plugin_t *slot), ...); |
82 | 80 |
void redata_free(redata_t *redata); |
83 | 81 |
|
... | ... |
@@ -111,7 +109,7 @@ int redata_undo_inactivatelast(redata_t *redata, undostack_t *stack); |
111 | 109 |
int redata_undo_reactivatelast(redata_t *redata, undostack_t *stack); |
112 | 110 |
|
113 | 111 |
/* high level stuff */ |
114 |
-int redata_load(redata_t *redata, char *filename, int use_unsaved); |
|
112 |
+int redata_load(redata_t *redata, char *filename, int (*callback_question)(/*char *title, char *body, int nopts, char *opts[],void *userptr*/), void *userptr); |
|
115 | 113 |
int redata_save(redata_t *redata, char *filename); |
116 | 114 |
|
117 | 115 |
int redata_op_add(redata_t *redata, long pos, char *buf, long buflen, undostack_t *fromhere); |
... | ... |
@@ -28,6 +28,8 @@ |
28 | 28 |
|
29 | 29 |
|
30 | 30 |
|
31 |
+static int redata_unsaved_loadquestion(redata_t *redata, redata_plugin_t *slot,char *filename, char **title, char **body, int *nopts, char **opts[]); |
|
32 |
+static int redata_unsaved_postload(redata_t *redata, redata_plugin_t *slot,char *filename,int questionreply); |
|
31 | 33 |
static int redata_unsaved_check_gen(redata_t *redata, redata_plugin_t *slot, char *filename); |
32 | 34 |
static char *unsaved_genname(char *filename, char *buf, int bufsize); |
33 | 35 |
static char *ptr_getlong(char *ptr,char *endptr,long *data); |
... | ... |
@@ -46,15 +48,16 @@ redata_unsaved_register(redata_t *redata, redata_plugin_t *slot) |
46 | 48 |
memset(unsaved,0,sizeof(unsaved_t)); |
47 | 49 |
unsaved->unsavedfd=-1; |
48 | 50 |
unsaved->sizebuf=unsaved->usedbuf=0; |
51 |
+ strncpy(slot->name,"unsaved",sizeof(slot->name)); |
|
52 |
+ slot->name[sizeof(slot->name)-1]='\0'; |
|
49 | 53 |
slot->unregister=redata_unsaved_unregister; |
50 |
- slot->checkload=redata_unsaved_check; |
|
54 |
+ slot->loadquestion=redata_unsaved_loadquestion; |
|
51 | 55 |
slot->wipe=redata_unsaved_wipe; |
52 |
- slot->postload=redata_unsaved_loadappend; |
|
53 |
- slot->truncload=redata_unsaved_truncload; |
|
56 |
+ slot->postload=redata_unsaved_postload; |
|
54 | 57 |
slot->postsave=redata_unsaved_trunc; |
55 | 58 |
slot->add=redata_unsaved_add; |
56 | 59 |
slot->unadd=redata_unsaved_unadd; |
57 |
- slot->flags=PLUGIN_CHECKUSERCONFIRM; |
|
60 |
+ slot->commit=redata_unsaved_commit; |
|
58 | 61 |
return(0); |
59 | 62 |
} |
60 | 63 |
|
... | ... |
@@ -484,6 +487,35 @@ redata_unsaved_commit(redata_t *redata, redata_plugin_t *slot,char *filename) |
484 | 487 |
return(0); |
485 | 488 |
} |
486 | 489 |
|
490 |
+static int |
|
491 |
+redata_unsaved_loadquestion(redata_t *redata, redata_plugin_t *slot,char *filename, char **title, char **body, int *nopts, char **opts[]) |
|
492 |
+{ |
|
493 |
+ static char mytitle[]={"Unsaved data from a previous session detected"}; |
|
494 |
+ static char mybody[]={"The file you're trying to load has some unsaved data from a previous session. I can recover the data. What do you want to do?"}; |
|
495 |
+ static char *myopts[]={"Recover unsaved data (safest option)","Don't use old unsaved data, delete old unsaved data (if you're sure what you're doing)"}; |
|
496 |
+ if(redata==NULL || slot==NULL || filename==NULL || title==NULL || body==NULL || nopts==NULL || opts==NULL) |
|
497 |
+ return(-1); /* sanity check failed */ |
|
498 |
+ if(redata_unsaved_check(redata,slot,filename)==-1) |
|
499 |
+ return(-1); /* no unsaved data on disk */ |
|
500 |
+ *title=mytitle; |
|
501 |
+ *body=mybody; |
|
502 |
+ *opts=myopts; |
|
503 |
+ *nopts=2; |
|
504 |
+ return(0); |
|
505 |
+} |
|
506 |
+ |
|
507 |
+static int |
|
508 |
+redata_unsaved_postload(redata_t *redata, redata_plugin_t *slot,char *filename,int questionreply) |
|
509 |
+{ |
|
510 |
+ /* questionreply is from loadquestion, specifically the selected element in the array "opts" */ |
|
511 |
+ if(questionreply==0) /* recover */ |
|
512 |
+ return(redata_unsaved_loadappend(redata, slot, filename)); |
|
513 |
+ else if(questionreply==1 || questionreply==-1) /* delete unsaved data */ |
|
514 |
+ return(redata_unsaved_truncload(redata, slot, filename)); |
|
515 |
+ return(-1); |
|
516 |
+} |
|
517 |
+ |
|
518 |
+ |
|
487 | 519 |
static char * |
488 | 520 |
unsaved_genname(char *filename, char *buf, int bufsize) |
489 | 521 |
{ |
... | ... |
@@ -154,7 +154,7 @@ fprintf(stderr,"\ntest_newfile(%s%s%s,%s%s%s,%i,%i);\nResult: ",(filename!=NULL) |
154 | 154 |
redata_filehash(redata,filename,hash129_pre); |
155 | 155 |
free(mem),mem=NULL; |
156 | 156 |
/* load file */ |
157 |
- if(redata_load(redata,filename,0)!=0) { |
|
157 |
+ if(redata_load(redata,filename,NULL,NULL)!=0) { |
|
158 | 158 |
unlink(filename); |
159 | 159 |
return("couldn't load file"); |
160 | 160 |
} |
... | ... |
@@ -359,7 +359,7 @@ redata_save(redata,"test.redo"); |
359 | 359 |
return("insuf. mem. for temp. buffer"); |
360 | 360 |
if(write_file(filename,mem,filesize)==-1) |
361 | 361 |
return("couldn't create temporary file"); |
362 |
- if(redata_load(redata,filename,0)!=0) { |
|
362 |
+ if(redata_load(redata,filename,NULL,NULL)!=0) { |
|
363 | 363 |
unlink(filename); |
364 | 364 |
return("couldn't load file"); |
365 | 365 |
} |