850 lines
16 KiB
C
850 lines
16 KiB
C
/*
|
|
* bookmark.c
|
|
*
|
|
* Copyright (c) 1996-1997, John Kilburg <john@cs.unlv.edu>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#include "port_before.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#ifdef HAVE_STRING_H
|
|
#include <string.h>
|
|
#endif
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include <X11/Intrinsic.h>
|
|
#include <X11/StringDefs.h>
|
|
#include <X11/Shell.h>
|
|
|
|
#include <X11/Xaw/Label.h>
|
|
#include <X11/Xaw/List.h>
|
|
#include <X11/Xaw/Form.h>
|
|
#include <X11/Xaw/Command.h>
|
|
#include <X11/Xaw/Viewport.h>
|
|
|
|
#include "port_after.h"
|
|
|
|
#include "ChimeraP.h"
|
|
#include "ml.h"
|
|
|
|
#include "MyDialog.h"
|
|
|
|
typedef struct
|
|
{
|
|
char *title;
|
|
char *url;
|
|
} BMark;
|
|
|
|
typedef struct
|
|
{
|
|
char *name;
|
|
GList mlist;
|
|
} BGroup;
|
|
|
|
struct BookmarkContextP
|
|
{
|
|
MemPool mp;
|
|
GList glist;
|
|
GList nel; /* name element list <h3></h3> or <a></a> */
|
|
bool is_group_element;
|
|
bool is_mark_element;
|
|
MLState ml;
|
|
char *filename; /* bookmark filename */
|
|
Widget bw; /* bookmark shell widget */
|
|
Widget glw;
|
|
Widget mlw;
|
|
Widget ampop;
|
|
bool ampopped;
|
|
Widget agpop;
|
|
bool agpopped;
|
|
char **gnames; /* group name array for list widget */
|
|
int glen;
|
|
char **mnames; /* bookmark array for list widget */
|
|
int mlen;
|
|
char *header;
|
|
char *footer;
|
|
ChimeraResources cres;
|
|
};
|
|
|
|
static BGroup *GroupCreate _ArgProto((BookmarkContext, char *, bool));
|
|
static void BMChangeGroupList _ArgProto((BookmarkContext));
|
|
static void BMChangeMarkList _ArgProto((BookmarkContext));
|
|
static BGroup *BMFindGroup _ArgProto((BookmarkContext));
|
|
static BMark *BMFindMark _ArgProto((BookmarkContext));
|
|
static void BMWrite _ArgProto((BookmarkContext));
|
|
static void BMCreate _ArgProto((BookmarkContext, BGroup *,
|
|
char *, char *));
|
|
static void BMElementHandler _ArgProto((void *, MLElement));
|
|
static char *BMGetText _ArgProto((MemPool, GList));
|
|
|
|
static void BMDAddGroup _ArgProto((Widget, XtPointer, XtPointer));
|
|
static void BMDAddMark _ArgProto((Widget, XtPointer, XtPointer));
|
|
|
|
/*
|
|
* BMChangeGroupList
|
|
*/
|
|
static void
|
|
BMChangeGroupList(bc)
|
|
BookmarkContext bc;
|
|
{
|
|
int cnt;
|
|
BGroup *g;
|
|
|
|
for (cnt = 0, g = (BGroup *)GListGetHead(bc->glist); g != NULL;
|
|
cnt++, g = (BGroup *)GListGetNext(bc->glist))
|
|
{
|
|
;
|
|
}
|
|
if (bc->gnames == NULL)
|
|
{
|
|
bc->gnames = (char **)alloc_mem(sizeof(char *) * (cnt + 1));
|
|
bc->glen = cnt;
|
|
}
|
|
else if (bc->glen < cnt)
|
|
{
|
|
bc->gnames = (char **)realloc_mem(bc->gnames, sizeof(char *) * (cnt + 1));
|
|
bc->glen = cnt;
|
|
}
|
|
for (g = (BGroup *)GListGetHead(bc->glist), cnt = 0; g != NULL;
|
|
g = (BGroup *)GListGetNext(bc->glist))
|
|
{
|
|
bc->gnames[cnt++] = g->name;
|
|
}
|
|
bc->gnames[cnt] = NULL;
|
|
XawListChange(bc->glw, bc->gnames, 0, 0, True);
|
|
if (cnt > 0) XawListHighlight(bc->glw, 0);
|
|
|
|
BMChangeMarkList(bc);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BMChangeMarkList
|
|
*/
|
|
static void
|
|
BMChangeMarkList(bc)
|
|
BookmarkContext bc;
|
|
{
|
|
int cnt;
|
|
BMark *m;
|
|
BGroup *g;
|
|
|
|
if ((g = BMFindGroup(bc)) == NULL) return;
|
|
|
|
for (cnt = 0, m = (BMark *)GListGetHead(g->mlist); m != NULL;
|
|
cnt++, m = (BMark *)GListGetNext(g->mlist))
|
|
{
|
|
;
|
|
}
|
|
if (bc->mnames == NULL)
|
|
{
|
|
bc->mnames = (char **)alloc_mem(sizeof(char *) * (cnt + 2));
|
|
bc->mlen = cnt;
|
|
}
|
|
else if (bc->mlen < cnt)
|
|
{
|
|
bc->mnames = (char **)realloc_mem(bc->mnames, sizeof(char *) * (cnt + 2));
|
|
bc->mlen = cnt;
|
|
}
|
|
for (m = (BMark *)GListGetHead(g->mlist), cnt = 0; m != NULL;
|
|
m = (BMark *)GListGetNext(g->mlist))
|
|
{
|
|
bc->mnames[cnt++] = m->title;
|
|
}
|
|
if (cnt > 0)
|
|
{
|
|
bc->mnames[cnt] = NULL;
|
|
XawListChange(bc->mlw, bc->mnames, 0, 0, True);
|
|
XawListHighlight(bc->mlw, 0);
|
|
}
|
|
else
|
|
{
|
|
bc->mnames[cnt] = "";
|
|
bc->mnames[cnt + 1] = NULL;
|
|
XawListChange(bc->mlw, bc->mnames, 0, 0, True);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BMWrite
|
|
*/
|
|
static void
|
|
BMWrite(bc)
|
|
BookmarkContext bc;
|
|
{
|
|
FILE *fp;
|
|
const char *brec = "<li><a href=\"%s\">%s</a>\n";
|
|
BMark *c;
|
|
BGroup *g;
|
|
|
|
if ((fp = fopen(bc->filename, "w")) != NULL)
|
|
{
|
|
fprintf (fp, bc->header);
|
|
fprintf (fp, "\n");
|
|
for (g = (BGroup *)GListGetHead(bc->glist); g != NULL;
|
|
g = (BGroup *)GListGetNext(bc->glist))
|
|
{
|
|
fprintf (fp, "<h3>%s</h3>\n<ul>\n", g->name);
|
|
for (c = (BMark *)GListGetHead(g->mlist); c != NULL;
|
|
c = (BMark *)GListGetNext(g->mlist))
|
|
{
|
|
fprintf (fp, brec, c->url, c->title);
|
|
}
|
|
fprintf (fp, "</ul>\n");
|
|
}
|
|
fprintf (fp, bc->footer);
|
|
fprintf (fp, "\n");
|
|
fclose(fp);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* GroupCreate
|
|
*/
|
|
static BGroup *
|
|
GroupCreate(bc, group, top)
|
|
BookmarkContext bc;
|
|
char *group;
|
|
bool top;
|
|
{
|
|
BGroup *g;
|
|
|
|
g = (BGroup *)MPCGet(bc->mp, sizeof(BGroup));
|
|
g->name = MPStrDup(bc->mp, group);
|
|
g->mlist = GListCreateX(bc->mp);
|
|
|
|
if (top) GListAddHead(bc->glist, g);
|
|
else GListAddTail(bc->glist, g);
|
|
|
|
BMChangeGroupList(bc);
|
|
|
|
return(g);
|
|
}
|
|
|
|
/*
|
|
* BMCreate
|
|
*/
|
|
static void
|
|
BMCreate(bc, g, title, url)
|
|
BookmarkContext bc;
|
|
BGroup *g;
|
|
char *title;
|
|
char *url;
|
|
{
|
|
BMark *n;
|
|
|
|
n = (BMark *)MPCGet(bc->mp, sizeof(BMark));
|
|
n->url = MPStrDup(bc->mp, url);
|
|
if (title == NULL) n->title = MPStrDup(bc->mp, url);
|
|
else n->title = MPStrDup(bc->mp, title);
|
|
|
|
GListAddTail(g->mlist, n);
|
|
|
|
BMChangeMarkList(bc);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BMGetText
|
|
*/
|
|
static char *
|
|
BMGetText(mp, list)
|
|
MemPool mp;
|
|
GList list;
|
|
{
|
|
MLElement c;
|
|
char *text, *str;
|
|
size_t tlen = 0;
|
|
size_t len;
|
|
|
|
if (GListEmpty(list)) return(NULL);
|
|
|
|
/* Skip first element...it is the opening tag */
|
|
GListGetHead(list);
|
|
for (c = (MLElement)GListGetNext(list); c != NULL;
|
|
c = (MLElement)GListGetNext(list))
|
|
{
|
|
MLGetText(c, &str, &len);
|
|
tlen += len;
|
|
}
|
|
|
|
text = MPGet(mp, tlen + 1);
|
|
|
|
tlen = 0;
|
|
GListGetHead(list);
|
|
for (c = (MLElement)GListGetNext(list); c != NULL;
|
|
c = (MLElement)GListGetNext(list))
|
|
{
|
|
MLGetText(c, &str, &len);
|
|
strncpy(text + tlen, str, len);
|
|
tlen += len;
|
|
}
|
|
text[tlen] = '\0';
|
|
|
|
return(text);
|
|
}
|
|
|
|
/*
|
|
* BMElementHandler
|
|
*/
|
|
static void
|
|
BMElementHandler(closure, p)
|
|
void *closure;
|
|
MLElement p;
|
|
{
|
|
BookmarkContext bc = (BookmarkContext)closure;
|
|
char *value;
|
|
char *title;
|
|
char *name;
|
|
MLElementType mt;
|
|
MLElement h;
|
|
|
|
mt = MLGetType(p);
|
|
if (mt == ML_EOF) return;
|
|
|
|
if ((name = MLTagName(p)) == NULL)
|
|
{
|
|
if (bc->is_group_element || bc->is_mark_element) GListAddTail(bc->nel, p);
|
|
return;
|
|
}
|
|
|
|
if (strlen(name) == 2 && strcasecmp("h3", name) == 0)
|
|
{
|
|
if (MLGetType(p) == ML_ENDTAG)
|
|
{
|
|
if (bc->is_group_element)
|
|
{
|
|
GroupCreate(bc, BMGetText(bc->mp, bc->nel), false);
|
|
bc->is_group_element = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bc->is_group_element = true;
|
|
GListClear(bc->nel);
|
|
GListAddHead(bc->nel, p);
|
|
}
|
|
}
|
|
else if (strlen(name) == 1 && strcasecmp("a", name) == 0)
|
|
{
|
|
if (MLGetType(p) == ML_ENDTAG)
|
|
{
|
|
if (bc->is_mark_element)
|
|
{
|
|
bc->is_mark_element = false;
|
|
h = (MLElement)GListGetHead(bc->nel);
|
|
if (h == NULL) return;
|
|
if ((value = MLFindAttribute(h, "href")) != NULL)
|
|
{
|
|
title = BMGetText(bc->mp, bc->nel);
|
|
if (title == NULL || title[0] == '\0')
|
|
{
|
|
title = MPStrDup(bc->mp, value);
|
|
}
|
|
if (GListEmpty(bc->glist)) GroupCreate(bc, "default", true);
|
|
BMCreate(bc, (BGroup *)GListGetTail(bc->glist),
|
|
title, MPStrDup(bc->mp, value));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bc->is_mark_element = true;
|
|
GListClear(bc->nel);
|
|
GListAddHead(bc->nel, p);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BookmarkAdd
|
|
*/
|
|
void
|
|
BookmarkAdd(bc, title, url)
|
|
BookmarkContext bc;
|
|
char *title;
|
|
char *url;
|
|
{
|
|
BGroup *g;
|
|
|
|
if ((g = BMFindGroup(bc)) == NULL) return;
|
|
|
|
BMCreate(bc, g, title, url);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BookmarkDestroyContext
|
|
*/
|
|
void
|
|
BookmarkDestroyContext(bc)
|
|
BookmarkContext bc;
|
|
{
|
|
XtDestroyWidget(bc->bw);
|
|
if (bc->mnames != NULL) free_mem(bc->mnames);
|
|
if (bc->gnames != NULL) free_mem(bc->gnames);
|
|
MPDestroy(bc->mp);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BookmarkShow
|
|
*/
|
|
void
|
|
BookmarkShow(bc)
|
|
BookmarkContext bc;
|
|
{
|
|
XtMapWidget(bc->bw);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BMFindGroup
|
|
*/
|
|
static BGroup *
|
|
BMFindGroup(bc)
|
|
BookmarkContext bc;
|
|
{
|
|
int i;
|
|
BGroup *g;
|
|
XawListReturnStruct *lrs;
|
|
|
|
if ((lrs = XawListShowCurrent(bc->glw)) == NULL) return(NULL);
|
|
if (lrs->list_index < 0) return(NULL);
|
|
|
|
for (i = 0, g = (BGroup *)GListGetHead(bc->glist);
|
|
i < lrs->list_index && g != NULL;
|
|
i++, g = (BGroup *)GListGetNext(bc->glist))
|
|
{
|
|
;
|
|
}
|
|
return(g);
|
|
}
|
|
|
|
/*
|
|
* BMFindMark
|
|
*/
|
|
static BMark *
|
|
BMFindMark(bc)
|
|
BookmarkContext bc;
|
|
{
|
|
int i;
|
|
BMark *m;
|
|
BGroup *g;
|
|
XawListReturnStruct *lrs;
|
|
|
|
if ((g = BMFindGroup(bc)) == NULL) return(NULL);
|
|
if ((lrs = XawListShowCurrent(bc->mlw)) == NULL) return(NULL);
|
|
if (lrs->list_index < 0) return(NULL);
|
|
|
|
for (i = 0, m = (BMark *)GListGetHead(g->mlist);
|
|
i < lrs->list_index && m != NULL;
|
|
i++, m = (BMark *)GListGetNext(g->mlist))
|
|
{
|
|
;
|
|
}
|
|
return(m);
|
|
}
|
|
|
|
/*
|
|
* BMDAddGroup
|
|
*/
|
|
static void
|
|
BMDAddGroup(w, cldata, cbdata)
|
|
Widget w;
|
|
XtPointer cldata, cbdata;
|
|
{
|
|
BookmarkContext bc = (BookmarkContext)cldata;
|
|
|
|
XtPopdown(bc->agpop);
|
|
bc->agpopped = false;
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BMOAddGroup
|
|
*/
|
|
static void
|
|
BMOAddGroup(w, cldata, cbdata)
|
|
Widget w;
|
|
XtPointer cldata, cbdata;
|
|
{
|
|
BookmarkContext bc = (BookmarkContext)cldata;
|
|
char *name;
|
|
|
|
if ((name = MyDialogGetValue(GetDialogWidget(bc->agpop))) == NULL ||
|
|
name[0] == '\0')
|
|
{
|
|
return;
|
|
}
|
|
|
|
GroupCreate(bc, name, true);
|
|
|
|
BMDAddGroup(w, cldata, cbdata);
|
|
|
|
BMWrite(bc);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BMAddGroup
|
|
*/
|
|
static void
|
|
BMAddGroup(w, cldata, cbdata)
|
|
Widget w;
|
|
XtPointer cldata, cbdata;
|
|
{
|
|
BookmarkContext bc = (BookmarkContext)cldata;
|
|
|
|
if (bc->agpopped) return;
|
|
|
|
if (bc->agpop == NULL)
|
|
{
|
|
bc->agpop = CreateDialog(bc->bw, "agpop",
|
|
BMOAddGroup, BMDAddGroup, BMOAddGroup, bc);
|
|
}
|
|
MyDialogSetValue(GetDialogWidget(bc->agpop), "");
|
|
|
|
XtPopup(bc->agpop, XtGrabNone);
|
|
bc->agpopped = true;
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BMRMGroup
|
|
*/
|
|
static void
|
|
BMRMGroup(w, cldata, cbdata)
|
|
Widget w;
|
|
XtPointer cldata, cbdata;
|
|
{
|
|
BookmarkContext bc = (BookmarkContext)cldata;
|
|
BGroup *g;
|
|
|
|
if ((g = BMFindGroup(bc)) != NULL)
|
|
{
|
|
GListRemoveItem(bc->glist, g);
|
|
if (GListEmpty(bc->glist)) GroupCreate(bc, "default", true);
|
|
|
|
BMChangeGroupList(bc);
|
|
BMChangeMarkList(bc);
|
|
|
|
BMWrite(bc);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BMDAddMark
|
|
*/
|
|
static void
|
|
BMDAddMark(w, cldata, cbdata)
|
|
Widget w;
|
|
XtPointer cldata, cbdata;
|
|
{
|
|
BookmarkContext bc = (BookmarkContext)cldata;
|
|
|
|
XtPopdown(bc->ampop);
|
|
bc->ampopped = false;
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BMOAddMark
|
|
*/
|
|
static void
|
|
BMOAddMark(w, cldata, cbdata)
|
|
Widget w;
|
|
XtPointer cldata, cbdata;
|
|
{
|
|
BookmarkContext bc = (BookmarkContext)cldata;
|
|
char *name;
|
|
char *url;
|
|
|
|
if ((name = MyDialogGetValue(GetDialogWidget(bc->ampop))) == NULL ||
|
|
name[0] == '\0')
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ((url = StackGetCurrentURL(bc->cres->bmcontext->tstack)) != NULL)
|
|
{
|
|
BookmarkAdd(bc, name, url);
|
|
}
|
|
|
|
BMDAddMark(w, cldata, cbdata);
|
|
|
|
BMWrite(bc);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BMAddMark
|
|
*/
|
|
static void
|
|
BMAddMark(w, cldata, cbdata)
|
|
Widget w;
|
|
XtPointer cldata, cbdata;
|
|
{
|
|
BookmarkContext bc = (BookmarkContext)cldata;
|
|
char *title;
|
|
ChimeraRender wn;
|
|
|
|
if (bc->ampopped) return;
|
|
|
|
if (bc->cres->bmcontext == NULL) return;
|
|
|
|
wn = StackToRender(bc->cres->bmcontext->tstack);
|
|
if ((title = RenderQuery(wn, "title")) == NULL)
|
|
{
|
|
if ((title = StackGetCurrentURL(bc->cres->bmcontext->tstack)) == NULL)
|
|
{
|
|
title = "unknown";
|
|
}
|
|
}
|
|
if (bc->ampop == NULL)
|
|
{
|
|
bc->ampop = CreateDialog(bc->bw, "ampop",
|
|
BMOAddMark, BMDAddMark, BMOAddMark, bc);
|
|
}
|
|
MyDialogSetValue(GetDialogWidget(bc->ampop), title);
|
|
|
|
XtPopup(bc->ampop, XtGrabNone);
|
|
bc->ampopped = true;
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BMRMMark
|
|
*/
|
|
static void
|
|
BMRMMark(w, cldata, cbdata)
|
|
Widget w;
|
|
XtPointer cldata, cbdata;
|
|
{
|
|
BookmarkContext bc = (BookmarkContext)cldata;
|
|
BMark *m;
|
|
BGroup *g;
|
|
|
|
if ((g = BMFindGroup(bc)) == NULL) return;
|
|
|
|
if ((m = BMFindMark(bc)) != NULL)
|
|
{
|
|
GListRemoveItem(g->mlist, m);
|
|
BMChangeMarkList(bc);
|
|
|
|
BMWrite(bc);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BMDismiss
|
|
*/
|
|
static void
|
|
BMDismiss(w, cldata, cbdata)
|
|
Widget w;
|
|
XtPointer cldata, cbdata;
|
|
{
|
|
BookmarkContext bc = (BookmarkContext)cldata;
|
|
|
|
if (bc->ampop != NULL) XtPopdown(bc->ampop);
|
|
if (bc->agpop != NULL) XtPopdown(bc->agpop);
|
|
XtUnmapWidget(bc->bw);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BMGroupList
|
|
*/
|
|
static void
|
|
BMGroupList(w, cldata, cbdata)
|
|
Widget w;
|
|
XtPointer cldata, cbdata;
|
|
{
|
|
BookmarkContext bc = (BookmarkContext)cldata;
|
|
|
|
BMChangeMarkList(bc);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BMMarkList
|
|
*/
|
|
static void
|
|
BMMarkList(w, cldata, cbdata)
|
|
Widget w;
|
|
XtPointer cldata, cbdata;
|
|
{
|
|
BookmarkContext bc = (BookmarkContext)cldata;
|
|
BMark *m;
|
|
|
|
if ((m = BMFindMark(bc)) == NULL) return;
|
|
|
|
StackOpen(bc->cres->bmcontext->tstack,
|
|
RequestCreate(bc->cres, m->url, NULL));
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* BookmarkCreateContext
|
|
*/
|
|
BookmarkContext
|
|
BookmarkCreateContext(cres)
|
|
ChimeraResources cres;
|
|
{
|
|
Widget fw, w, gvw, mvw;
|
|
BookmarkContext bc;
|
|
struct stat s;
|
|
FILE *fp;
|
|
char *bdata;
|
|
char *filename;
|
|
MemPool mp;
|
|
Window rw, cw;
|
|
int rx, ry, wx, wy;
|
|
unsigned int mask;
|
|
|
|
if ((filename = ResourceGetString(cres, "bookmark.filename")) == NULL)
|
|
{
|
|
return(NULL);
|
|
}
|
|
|
|
mp = MPCreate();
|
|
bc = (BookmarkContext)MPCGet(mp, sizeof(struct BookmarkContextP));
|
|
bc->mp = mp;
|
|
bc->cres = cres;
|
|
|
|
XQueryPointer(cres->dpy, DefaultRootWindow(cres->dpy),
|
|
&rw, &cw,
|
|
&rx, &ry,
|
|
&wx, &wy,
|
|
&mask);
|
|
bc->bw = XtVaAppCreateShell("bookmark", "Bookmark",
|
|
transientShellWidgetClass, cres->dpy,
|
|
XtNx, rx, XtNy, ry,
|
|
NULL);
|
|
|
|
/* group widgets */
|
|
fw = XtVaCreateManagedWidget("form",
|
|
formWidgetClass, bc->bw,
|
|
NULL);
|
|
gvw = XtVaCreateManagedWidget("groupview",
|
|
viewportWidgetClass, fw,
|
|
NULL);
|
|
bc->glw = XtVaCreateManagedWidget("grouplist",
|
|
listWidgetClass, gvw,
|
|
NULL);
|
|
XtAddCallback(bc->glw, XtNcallback, BMGroupList, (XtPointer)bc);
|
|
w = XtVaCreateManagedWidget("addgroup",
|
|
commandWidgetClass, fw,
|
|
XtNfromVert, gvw,
|
|
NULL);
|
|
XtAddCallback(w, XtNcallback, BMAddGroup, (XtPointer)bc);
|
|
w = XtVaCreateManagedWidget("rmgroup",
|
|
commandWidgetClass, fw,
|
|
XtNfromVert, gvw,
|
|
XtNfromHoriz, w,
|
|
NULL);
|
|
XtAddCallback(w, XtNcallback, BMRMGroup, (XtPointer)bc);
|
|
|
|
/* Mark widgets */
|
|
mvw = XtVaCreateManagedWidget("markview",
|
|
viewportWidgetClass, fw,
|
|
XtNfromVert, w,
|
|
NULL);
|
|
bc->mlw = XtVaCreateManagedWidget("marklist",
|
|
listWidgetClass, mvw,
|
|
NULL);
|
|
XtAddCallback(bc->mlw, XtNcallback, BMMarkList, (XtPointer)bc);
|
|
w = XtVaCreateManagedWidget("addmark",
|
|
commandWidgetClass, fw,
|
|
XtNfromVert, mvw,
|
|
NULL);
|
|
XtAddCallback(w, XtNcallback, BMAddMark, (XtPointer)bc);
|
|
w = XtVaCreateManagedWidget("rmmark",
|
|
commandWidgetClass, fw,
|
|
XtNfromVert, mvw,
|
|
XtNfromHoriz, w,
|
|
NULL);
|
|
XtAddCallback(w, XtNcallback, BMRMMark, (XtPointer)bc);
|
|
w = XtVaCreateManagedWidget("dismiss",
|
|
commandWidgetClass, fw,
|
|
XtNfromVert, mvw,
|
|
XtNfromHoriz, w,
|
|
NULL);
|
|
XtAddCallback(w, XtNcallback, BMDismiss, (XtPointer)bc);
|
|
|
|
if ((bc->header = ResourceGetString(cres, "bookmark.header")) == NULL)
|
|
{
|
|
bc->header = "";
|
|
}
|
|
if ((bc->footer = ResourceGetString(cres, "bookmark.footer")) == NULL)
|
|
{
|
|
bc->footer = "";
|
|
}
|
|
|
|
bc->glist = GListCreateX(bc->mp);
|
|
bc->nel = GListCreateX(bc->mp);
|
|
|
|
bc->filename = FixPath(bc->mp, filename);
|
|
if (stat(bc->filename, &s) == 0)
|
|
{
|
|
if ((fp = fopen(bc->filename, "r")) != NULL)
|
|
{
|
|
bdata = (char *)alloc_mem(s.st_size);
|
|
if (fread(bdata, 1, s.st_size, fp) == s.st_size)
|
|
{
|
|
bc->ml = MLInit(BMElementHandler, bc);
|
|
MLEndData(bc->ml, bdata, s.st_size);
|
|
MLDestroy(bc->ml);
|
|
}
|
|
free_mem(bdata);
|
|
fclose(fp);
|
|
}
|
|
}
|
|
|
|
if (GListEmpty(bc->glist)) GroupCreate(bc, "default", true);
|
|
|
|
XtSetMappedWhenManaged(bc->bw, False);
|
|
XtRealizeWidget(bc->bw);
|
|
|
|
return(bc);
|
|
}
|