OSDN Git Service

implement external bbs managing functions.
authorornse01 <ornse01@users.sourceforge.jp>
Sun, 29 Apr 2012 09:56:04 +0000 (09:56 +0000)
committerornse01 <ornse01@users.sourceforge.jp>
Sun, 29 Apr 2012 09:56:04 +0000 (09:56 +0000)
git-svn-id: http://svn.sourceforge.jp/svnroot/bchan/bchanl/trunk@448 20a0b8eb-f62a-4a12-8fe1-b598822500fb

src/extbbslist.c
src/extbbslist.h

index fd0af8e..645fd27 100644 (file)
@@ -66,6 +66,17 @@ LOCAL VOID extbbslist_item_QueInsert(extbbslist_item_t *entry, extbbslist_item_t
        QueInsert(&entry->que, &que->que);
 }
 
+LOCAL VOID extbbslist_item_QueRemove(extbbslist_item_t *entry)
+{
+       QueRemove(&entry->que);
+       QueInit(&entry->que);
+}
+
+LOCAL Bool extbbslist_item_isQueEmpty(extbbslist_item_t *entry)
+{
+       return isQueEmpty(&entry->que);
+}
+
 LOCAL Bool extbbslist_item_titlecheck(extbbslist_item_t *entry, TC *title, W title_len)
 {
        W cmp;
@@ -107,6 +118,47 @@ LOCAL VOID extbbslist_item_replaceascurl(extbbslist_item_t *item, UB *url, W url
        item->url.asc_len = url_len;
 }
 
+LOCAL W extbbslist_item_assigntitle(extbbslist_item_t *item, CONST TC *title, W title_len)
+{
+       TC *str;
+       str = malloc(sizeof(TC)*(title_len+1));
+       if (str == NULL) {
+               return -1; /* TODO */
+       }
+       memcpy(str, title, sizeof(TC)*title_len);
+       str[title_len] = TNULL;
+       extbbslist_item_replacetitle(item, str, title_len);
+       return 0;
+}
+
+LOCAL W extbbslist_item_assignurl(extbbslist_item_t *item, CONST TC *url, W url_len)
+{
+       TC *str;
+       UB *str_ac;
+       W len;
+
+       str = malloc(sizeof(TC)*(url_len+1));
+       if (str == NULL) {
+               return -1; /* TODO */
+       }
+       memcpy(str, url, sizeof(TC)*url_len);
+       str[url_len] = TNULL;
+
+       len = tcstosjs(NULL, url);
+       str_ac = malloc(sizeof(UB)*(len+1));
+       if (str_ac == NULL) {
+               free(str);
+               return -1; /* TODO */
+       }
+       tcstosjs(str_ac, url);
+       str_ac[len] = '\0';
+
+       extbbslist_item_replaceTCurl(item, str, url_len);
+       extbbslist_item_replaceascurl(item, str_ac, len);
+
+       return 0;
+}
+
 LOCAL W extbbslist_item_initialize(extbbslist_item_t *item)
 {
        QueInit(&item->que);
@@ -160,6 +212,7 @@ LOCAL VOID extbbslist_item_delete(extbbslist_item_t *item)
 struct extbbslist_t_ {
        QUEUE sentinel;
        extbbslist_readcontext_t *ctx;
+       extbbslist_editcontext_t *edit;
        W num;
        LINK *lnk;
        W rectype;
@@ -267,6 +320,21 @@ EXPORT W extbbslist_deleteitem(extbbslist_t *list, TC *title, W title_len)
        return 0; /* TODO */
 }
 
+LOCAL VOID extbbslist_clear(extbbslist_t *list)
+{
+       extbbslist_item_t *item;
+       Bool empty;
+
+       for (;;) {
+               empty = isQueEmpty(&list->sentinel);
+               if (empty == True) {
+                       break;
+               }
+               item = (extbbslist_item_t*)list->sentinel.prev;
+               extbbslist_item_delete(item);
+       }
+}
+
 EXPORT W extbbslist_number(extbbslist_t *list)
 {
        return list->num;
@@ -280,6 +348,402 @@ EXPORT W extbbslist_readfile(extbbslist_t *list)
 {
 }
 
+struct extbbslist_editcontext_t_ {
+       QUEUE sentinel;
+       W view_l, view_t, view_r, view_b;
+       W num;
+       struct {
+               extbbslist_item_t *item;
+               W index;
+       } selected;
+};
+
+#define EXTBBSLIST_ENTRY_HEIGHT 20
+#define EXTBBSLIST_ENTRY_PADDING_TOP 1
+
+#define EXTBBSLIST_TITLE_WIDTH 128
+
+LOCAL extbbslist_item_t* extbbslist_editcontext_sentinelnode(extbbslist_editcontext_t *ctx)
+{
+       return (extbbslist_item_t*)&ctx->sentinel;
+}
+
+LOCAL extbbslist_item_t *extbbslist_editcontext_searchitembyindex(extbbslist_editcontext_t *ctx, W index)
+{
+       W i;
+       extbbslist_item_t *senti, *item;
+
+       senti = extbbslist_editcontext_sentinelnode(ctx);
+       item = extbbslist_item_nextnode(senti);
+       for (i = 0; item != senti; i++) {
+               if (i == index) {
+                       return item;
+               }
+               item = extbbslist_item_nextnode(item);
+       }
+       return NULL;
+}
+
+EXPORT W extbbslist_editcontext_append(extbbslist_editcontext_t *ctx, CONST TC *title, W title_len, CONST TC *url, W url_len)
+{
+       extbbslist_item_t *item, *senti;
+       W err;
+
+       item = extbbslist_item_new();
+       if (item == NULL) {
+               return -1; /* TODO */
+       }
+
+       err = extbbslist_item_assigntitle(item, title, title_len);
+       if (err < 0) {
+               extbbslist_item_delete(item);
+               return err;
+       }
+
+       err = extbbslist_item_assignurl(item, url, url_len);
+       if (err < 0) {
+               extbbslist_item_delete(item);
+               return err;
+       }
+
+       senti = extbbslist_editcontext_sentinelnode(ctx);
+       extbbslist_item_QueInsert(item, senti);
+       ctx->num++;
+
+       return 0;
+}
+
+EXPORT W extbbslist_editcontext_update(extbbslist_editcontext_t *ctx, W i, CONST TC *title, W title_len, CONST TC *url, W url_len)
+{
+       extbbslist_item_t *item;
+       W err;
+
+       item = extbbslist_editcontext_searchitembyindex(ctx, i);
+       if (item == NULL) {
+               return -1; /* TODO */
+       }
+
+       err = extbbslist_item_assigntitle(item, title, title_len);
+       if (err < 0) {
+               return err;
+       }
+
+       err = extbbslist_item_assignurl(item, url, url_len);
+       if (err < 0) {
+               return err;
+       }
+
+       return 0;
+}
+
+LOCAL W extbbslist_editcontext_drawcolseparater(extbbslist_editcontext_t *ctx, GID target, W x_start, W y, W height, PAT *lnpat)
+{
+       PNT p1, p2;
+
+       p1.y = y;
+       p2.y = p1.y + height - 1;
+
+       p1.x = x_start + EXTBBSLIST_TITLE_WIDTH + 4;
+       p2.x = p1.x;
+       gdra_lin(target, p1, p2, 1, lnpat, G_STORE);
+
+       return 0;
+}
+
+LOCAL W extbbslist_editcontext_drawitemtext(extbbslist_editcontext_t *ctx, GID target, W x_start, W y, PAT *lnpat, extbbslist_item_t *item)
+{
+       SIZE sz;
+       FSSPEC fspec;
+       W y2;
+
+       gset_scr(target, 0x21);
+
+       gget_fon(target, &fspec, NULL);
+       sz = fspec.size;
+       fspec.size.h = fspec.size.v;
+       gset_fon(target, &fspec);
+
+       y2 = y + sz.v + EXTBBSLIST_ENTRY_PADDING_TOP;
+       gdra_stp(target, x_start, y2, item->title, item->title_len, G_STORE);
+
+       gset_scr(target, 0x21);
+
+       fspec.size.h = fspec.size.v / 2;
+       gset_fon(target, &fspec);
+
+       gdra_stp(target, x_start + EXTBBSLIST_TITLE_WIDTH + 8 , y2, item->url.tc, item->url.tc_len, G_STORE);
+
+       extbbslist_editcontext_drawcolseparater(ctx, target, x_start, y, EXTBBSLIST_ENTRY_HEIGHT, lnpat);
+
+       return 0;
+}
+
+EXPORT W extbbslist_editcontext_draw(extbbslist_editcontext_t *ctx, GID target, RECT *r)
+{
+       W i, x, y;
+       extbbslist_item_t *senti, *item;
+       PAT bgpat = {{
+               0,
+               16, 16,
+               0x10efefef,
+               0x10efefef,
+               FILL100
+       }};
+       PAT lnpat = {{
+               0,
+               16, 16,
+               0x10000000,
+               0x10efefef,
+               FILL100
+       }};
+       RECT bgr;
+
+       senti = extbbslist_editcontext_sentinelnode(ctx);
+       item = extbbslist_item_nextnode(senti);
+       for (i = 0; ; i++) {
+               if (item == senti) {
+                       break;
+               }
+               if ((ctx->view_t <= (i + 1) * EXTBBSLIST_ENTRY_HEIGHT)&&(i * EXTBBSLIST_ENTRY_HEIGHT <= ctx->view_b)) {
+                       if (ctx->selected.item == item) {
+                               bgpat.spat.fgcol = 0x10000000;
+                               lnpat.spat.fgcol = 0x10FFFFFF;
+                               gset_chc(target, 0x10FFFFFF, 0x10000000);
+                       } else {
+                               bgpat.spat.fgcol = 0x10FFFFFF;
+                               lnpat.spat.fgcol = 0x10000000;
+                               gset_chc(target, 0x10000000, 0x10FFFFFF);
+                       }
+                       bgr.c.left = ctx->view_l;
+                       bgr.c.top = i * EXTBBSLIST_ENTRY_HEIGHT - ctx->view_t;
+                       bgr.c.right = ctx->view_r;
+                       bgr.c.bottom = (i+1) * EXTBBSLIST_ENTRY_HEIGHT - ctx->view_t;
+                       gfil_rec(target, bgr, &bgpat, 0, G_STORE);
+
+                       x = 0 - ctx->view_l;
+                       y = i * EXTBBSLIST_ENTRY_HEIGHT - ctx->view_t;
+                       extbbslist_editcontext_drawitemtext(ctx, target, x, y, &lnpat, item);
+               }
+
+               item = extbbslist_item_nextnode(item);
+       }
+
+       return 0;
+}
+
+EXPORT Bool extbbslist_editcontext_finditem(extbbslist_editcontext_t *ctx, PNT rel_pos, W *index)
+{
+       W n;
+       n = (rel_pos.y + ctx->view_t) / EXTBBSLIST_ENTRY_HEIGHT;
+       if (n < ctx->num) {
+               *index = n;
+               return True;
+       }
+       return False;
+}
+
+IMPORT W extbbslist_editcontext_swapitem(extbbslist_editcontext_t *ctx, W i0, W i1)
+{
+       extbbslist_item_t *item0, *item1, *item0_next, *item1_next;
+       W buf;
+
+       if (i0 == i1) {
+               return 0;
+       }
+       if (i1 > i0) {
+               buf = i1;
+               i1 = i0;
+               i0 = buf;
+       }
+
+       item0 = extbbslist_editcontext_searchitembyindex(ctx, i0);
+       if (item0 == NULL) {
+               return -1;
+       }
+       item0_next = extbbslist_item_nextnode(item0);
+       item1 = extbbslist_editcontext_searchitembyindex(ctx, i1);
+       if (item1 == NULL) {
+               return -1;
+       }
+       item1_next = extbbslist_item_nextnode(item1);
+
+       if (i0 + 1 == i1) {
+               extbbslist_item_QueRemove(item1);
+               extbbslist_item_QueInsert(item1, item0);
+               return 0;
+       }
+
+       extbbslist_item_QueRemove(item1);
+       extbbslist_item_QueInsert(item1, item0_next);
+       extbbslist_item_QueRemove(item0);
+       extbbslist_item_QueInsert(item0, item1_next);
+
+       return 0;
+}
+
+IMPORT W extbbslist_editcontext_deleteitem(extbbslist_editcontext_t *ctx, W i)
+{
+       extbbslist_item_t *item;
+
+       item = extbbslist_editcontext_searchitembyindex(ctx, i);
+       if (item == NULL) {
+               return -1; /* TODO */
+       }
+       ctx->num--;
+       if (ctx->selected.index == i) {
+               ctx->selected.item = NULL;
+               ctx->selected.index = -1;
+       }
+       ctx->selected.item = item;
+       ctx->selected.index = i;
+       return 0;
+}
+
+IMPORT VOID extbbslist_editcontext_setselect(extbbslist_editcontext_t *ctx, W i)
+{
+       extbbslist_item_t *item;
+
+       item = extbbslist_editcontext_searchitembyindex(ctx, i);
+       if (item == NULL) {
+               ctx->selected.item = NULL;
+               ctx->selected.index = -1;
+               return;
+       }
+       ctx->selected.item = item;
+       ctx->selected.index = i;
+}
+
+IMPORT W extbbslist_editcontext_getselect(extbbslist_editcontext_t *ctx)
+{
+       return ctx->selected.index;
+}
+
+EXPORT VOID extbbslist_editcontext_setviewrect(extbbslist_editcontext_t *ctx, W l, W t, W r, W b)
+{
+       ctx->view_l = l;
+       ctx->view_t = t;
+       ctx->view_r = r;
+       ctx->view_b = b;
+}
+
+EXPORT VOID extbbslist_editcontext_getviewrect(extbbslist_editcontext_t *ctx, W *l, W *t, W *r, W *b)
+{
+       *l = ctx->view_l;
+       *t = ctx->view_t;
+       *r = ctx->view_r;
+       *b = ctx->view_b;
+}
+
+EXPORT VOID extbbslist_editcontext_scrollviewrect(extbbslist_editcontext_t *ctx, W dh, W dv)
+{
+       ctx->view_l += dh;
+       ctx->view_t += dv;
+       ctx->view_r += dh;
+       ctx->view_b += dv;
+}
+
+EXPORT VOID extbbslist_editcontext_getdrawrect(extbbslist_editcontext_t *ctx, W *l, W *t, W *r, W *b)
+{
+       *l = 0;
+       *t = 0;
+       *r = 200;
+       *b = EXTBBSLIST_ENTRY_HEIGHT * ctx->num;
+}
+
+LOCAL extbbslist_editcontext_t* extbbslist_editcontext_new()
+{
+       extbbslist_editcontext_t *ctx;
+
+       ctx = (extbbslist_editcontext_t*)malloc(sizeof(extbbslist_editcontext_t));
+       if (ctx == NULL) {
+               return NULL;
+       }
+       QueInit(&ctx->sentinel);
+       ctx->view_l = 0;
+       ctx->view_t = 0;
+       ctx->view_r = 0;
+       ctx->view_b = 0;
+       ctx->num = 0;
+       ctx->selected.item = NULL;
+       ctx->selected.index = -1;
+
+       return ctx;
+}
+
+LOCAL VOID extbbslist_editcontext_delete(extbbslist_editcontext_t *ctx)
+{
+       extbbslist_item_t *item;
+       Bool empty;
+
+       for (;;) {
+               empty = isQueEmpty(&ctx->sentinel);
+               if (empty == True) {
+                       break;
+               }
+               item = (extbbslist_item_t*)ctx->sentinel.prev;
+               extbbslist_item_delete(item);
+       }
+       free(ctx);
+}
+
+EXPORT extbbslist_editcontext_t* extbbslist_startedit(extbbslist_t *list)
+{
+       extbbslist_editcontext_t *ctx;
+       extbbslist_item_t *senti, *item;
+       W err;
+
+       if (list->ctx != NULL) {
+               return NULL;
+       }
+       if (list->edit != NULL) {
+               return NULL;
+       }
+
+       ctx = extbbslist_editcontext_new();
+       if (ctx == NULL) {
+               return NULL;
+       }
+
+       senti = extbbslist_sentinelnode(list);
+       item = extbbslist_item_nextnode(senti);
+       for (; item != senti;) {
+               err = extbbslist_editcontext_append(ctx, item->title, item->title_len, item->url.tc, item->url.tc_len);
+               if (err < 0) {
+                       extbbslist_editcontext_delete(ctx);
+                       return NULL;
+               }
+               item = extbbslist_item_nextnode(item);
+       }
+
+       list->edit = ctx;
+
+       return ctx;
+}
+
+EXPORT VOID extbbslist_endedit(extbbslist_t *list, extbbslist_editcontext_t *ctx, Bool update)
+{
+       extbbslist_item_t *sentinel, *next;
+       Bool empty;
+
+       if (update != False) {
+               extbbslist_clear(list);
+
+               sentinel = extbbslist_editcontext_sentinelnode(ctx);
+
+               empty = extbbslist_item_isQueEmpty(sentinel);
+               if (empty == False) {
+                       next = extbbslist_item_nextnode(sentinel);
+                       extbbslist_item_QueRemove(sentinel);
+
+                       sentinel = extbbslist_sentinelnode(list);
+                       extbbslist_item_QueInsert(sentinel, next);
+               }
+       }
+
+       list->edit = NULL;
+       extbbslist_editcontext_delete(ctx);
+}
+
 struct extbbslist_readcontext_t_ {
        extbbslist_item_t *sentinel;
        extbbslist_item_t *curr;
@@ -342,6 +806,7 @@ LOCAL VOID extbbslist_initialize(extbbslist_t *list, LINK *db_link, W rectype, U
 {
        QueInit(&list->sentinel);
        list->ctx = NULL;
+       list->edit = NULL;
        list->num = 0;
        list->lnk = db_link;
        list->rectype = rectype;
@@ -350,17 +815,7 @@ LOCAL VOID extbbslist_initialize(extbbslist_t *list, LINK *db_link, W rectype, U
 
 LOCAL VOID extbbslist_finalize(extbbslist_t *list)
 {
-       extbbslist_item_t *item;
-       Bool empty;
-
-       for (;;) {
-               empty = isQueEmpty(&list->sentinel);
-               if (empty == True) {
-                       break;
-               }
-               item = (extbbslist_item_t*)list->sentinel.prev;
-               extbbslist_item_delete(item);
-       }
+       extbbslist_clear(list);
 }
 
 EXPORT extbbslist_t* extbbslist_new(LINK *db_link, W rectype, UH subtype)
index 5d10ca0..ec92b81 100644 (file)
  */
 
 #include       <basic.h>
+#include       <btron/dp.h>
 
 #ifndef __EXTBBSLIST_H__
 #define __EXTBBSLIST_H__
 
 typedef struct extbbslist_t_ extbbslist_t;
 typedef struct extbbslist_readcontext_t_ extbbslist_readcontext_t;
+typedef struct extbbslist_editcontext_t_ extbbslist_editcontext_t;
 
 IMPORT extbbslist_t* extbbslist_new(LINK *db_link, W rectype, UH subtype);
 IMPORT VOID extbbslist_delete(extbbslist_t *list);
@@ -44,4 +46,19 @@ IMPORT extbbslist_readcontext_t* extbbslist_startread(extbbslist_t *list);
 IMPORT VOID extbbslist_endread(extbbslist_t *list, extbbslist_readcontext_t *ctx);
 IMPORT Bool extbbslist_readcontext_getnext(extbbslist_readcontext_t *ctx, TC **title, W *title_len, UB **url, W *url_len);
 
+IMPORT extbbslist_editcontext_t* extbbslist_startedit(extbbslist_t *list);
+IMPORT VOID extbbslist_endedit(extbbslist_t *list, extbbslist_editcontext_t *ctx, Bool update);
+IMPORT W extbbslist_editcontext_append(extbbslist_editcontext_t *ctx, CONST TC *title, W title_len, CONST TC *url, W url_len);
+IMPORT W extbbslist_editcontext_update(extbbslist_editcontext_t *ctx, W i, CONST TC *title, W title_len, CONST TC *url, W url_len);
+IMPORT W extbbslist_editcontext_draw(extbbslist_editcontext_t *ctx, GID target, RECT *r);
+IMPORT Bool extbbslist_editcontext_finditem(extbbslist_editcontext_t *ctx, PNT rel_pos, W *index);
+IMPORT W extbbslist_editcontext_swapitem(extbbslist_editcontext_t *ctx, W i0, W i1);
+IMPORT W extbbslist_editcontext_deleteitem(extbbslist_editcontext_t *ctx, W i);
+IMPORT VOID extbbslist_editcontext_setselect(extbbslist_editcontext_t *ctx, W i);
+IMPORT W extbbslist_editcontext_getselect(extbbslist_editcontext_t *ctx);
+IMPORT VOID extbbslist_editcontext_setviewrect(extbbslist_editcontext_t *ctx, W l, W t, W r, W b);
+IMPORT VOID extbbslist_editcontext_getviewrect(extbbslist_editcontext_t *ctx, W *l, W *t, W *r, W *b);
+IMPORT VOID extbbslist_editcontext_scrollviewrect(extbbslist_editcontext_t *ctx, W dh, W dv);
+IMPORT VOID extbbslist_editcontext_getdrawrect(extbbslist_editcontext_t *ctx, W *l, W *t, W *r, W *b);
+
 #endif