/* * Copyright (c) 2001-2007 Hypertriton, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Properties dialog for AG_Object. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef AG_NETWORK #include #endif #include "dev.h" #include const AG_FlagDescr devObjectFlags[] = { { AG_OBJECT_DEBUG, N_("Debugging"), 1 }, { AG_OBJECT_READONLY, N_("Read-only"), 1 }, { AG_OBJECT_INDESTRUCTIBLE, N_("Indestructible"), 1 }, { AG_OBJECT_NON_PERSISTENT, N_("Non-persistent"), 1 }, { AG_OBJECT_RELOAD_PROPS, N_("Don't clear props on load"), 1 }, { AG_OBJECT_PRESERVE_DEPS, N_("Preserve null dependencies"), 1 }, { AG_OBJECT_REMAIN_DATA, N_("Keep data resident"), 1 }, { AG_OBJECT_RESIDENT, N_("Data part is resident"), 0 }, { AG_OBJECT_STATIC, N_("Statically allocated"), 0 }, { AG_OBJECT_REOPEN_ONLOAD, N_("Recreate UI on load"), 0 }, { AG_OBJECT_NAME_ONATTACH, N_("Generate name upon attach"), 0 }, { 0, "", 0 } }; static void PollDeps(AG_Event *event) { char path[AG_OBJECT_PATH_MAX]; AG_Tlist *tl = AG_SELF(); AG_Object *ob = AG_PTR(1); AG_ObjectDep *dep; AG_TlistClear(tl); AG_LockVFS(ob); TAILQ_FOREACH(dep, &ob->deps, deps) { char label[AG_TLIST_LABEL_MAX]; if (dep->obj != NULL) { AG_ObjectCopyName(dep->obj, path, sizeof(path)); } else { Strlcpy(path, "(NULL)", sizeof(path)); } if (dep->count == AG_OBJECT_DEP_MAX) { Snprintf(label, sizeof(label), "%s (wired)", path); } else { Snprintf(label, sizeof(label), "%s (%u)", path, (Uint)dep->count); } AG_TlistAddPtr(tl, AG_ObjectIcon(dep->obj), label, dep); } AG_UnlockVFS(ob); AG_TlistRestore(tl); } static void PollVariables(AG_Event *event) { AG_Tlist *tl = AG_SELF(); AG_Object *ob = AG_PTR(1); Uint i; AG_TlistClear(tl); for (i = 0; i < ob->nVars; i++) { AG_Variable *V = &ob->vars[i]; AG_TlistItem *ti; AG_LockVariable(V); if (V->fn.fnVoid != NULL && AG_EvalVariable(ob, V) == -1) { ti = AG_TlistAdd(tl, NULL, "%s = ", V->name); } else { char val[256]; AG_PrintVariable(val, sizeof(val), V); ti = AG_TlistAdd(tl, NULL, "%s = %s", V->name, val); } ti->p1 = V; AG_UnlockVariable(V); } AG_TlistRestore(tl); } #if defined(AG_THREADS) && defined(AG_LOCKDEBUG) static void PollLocks(AG_Event *event) { AG_Tlist *tl = AG_SELF(); AG_Object *ob = AG_PTR(1); int i; AG_TlistClear(tl); for (i = 0; i < ob->nlockinfo; i++) { AG_TlistAdd(tl, NULL, "%s", ob->lockinfo[i]); } AG_TlistRestore(tl); } #endif /* AG_THREADS and AG_LOCKDEBUG */ static void PollEvents(AG_Event *event) { AG_Tlist *tl = AG_SELF(); AG_Object *ob = AG_PTR(1); AG_Event *ev; AG_TlistClear(tl); TAILQ_FOREACH(ev, &ob->events, events) { char args[AG_TLIST_LABEL_MAX], arg[64]; int i; args[0] = '('; args[1] = '\0'; for (i = 1; i < ev->argc; i++) { AG_Variable *V = &ev->argv[i]; AG_LockVariable(V); if (V->name != NULL && V->name[0] != '\0') { Strlcat(args, V->name, sizeof(args)); Strlcat(args, "=", sizeof(args)); } AG_PrintVariable(arg, sizeof(arg), &ev->argv[i]); AG_UnlockVariable(V); Strlcat(args, arg, sizeof(args)); if (i < ev->argc-1) Strlcat(args, ", ", sizeof(args)); } Strlcat(args, ")", sizeof(args)); AG_TlistAdd(tl, NULL, "%s%s%s %s", ev, (ev->flags & AG_EVENT_ASYNC) ? " " : "", (ev->flags & AG_EVENT_PROPAGATE) ? " " : "", args); } AG_TlistRestore(tl); } static void RenameObject(AG_Event *event) { AG_Textbox *tb = AG_SELF(); AG_Object *ob = AG_PTR(1); if (AG_ObjectPageIn(ob) == 0) { AG_ObjectUnlinkDatafiles(ob); Strlcpy(ob->name, tb->ed->string, sizeof(ob->name)); AG_ObjectPageOut(ob); } AG_PostEvent(NULL, ob, "renamed", NULL); } static void RefreshSums(AG_Event *event) { char checksum[128]; AG_Object *ob = AG_PTR(1); AG_Textbox *tbMD5 = AG_PTR(2); AG_Textbox *tbSHA1 = AG_PTR(3); AG_Textbox *tbRMD160 = AG_PTR(4); if (AG_ObjectCopyChecksum(ob, AG_OBJECT_MD5, checksum) > 0) { AG_TextboxPrintf(tbMD5, "%s", checksum); } else { AG_TextboxPrintf(tbMD5, "(%s)", AG_GetError()); } if (AG_ObjectCopyChecksum(ob, AG_OBJECT_SHA1, checksum) > 0) { AG_TextboxPrintf(tbSHA1, "%s", checksum); } else { AG_TextboxPrintf(tbSHA1, "(%s)", AG_GetError()); } if (AG_ObjectCopyChecksum(ob, AG_OBJECT_RMD160, checksum) > 0) { AG_TextboxPrintf(tbRMD160, "%s", checksum); } else { AG_TextboxPrintf(tbRMD160, "(%s)", AG_GetError()); } } #ifdef AG_NETWORK static void RefreshRepoStatus(AG_Event *event) { char objdir[AG_OBJECT_PATH_MAX]; char digest[AG_OBJECT_DIGEST_MAX]; AG_Object *ob = AG_PTR(1); AG_Label *lblStatus = AG_PTR(2); AG_Tlist *tl = AG_PTR(3); extern const char *agRcsStatusStrings[]; enum ag_rcs_status status; AG_RCSLog log; size_t len; Uint working_rev, repo_rev; int i; if (AG_ObjectCopyName(ob, objdir, sizeof(objdir)) == -1 || AG_ObjectCopyDigest(ob, &len, digest) == -1) { return; } if (AG_RcsConnect() == -1) { return; } status = AG_RcsStatus(ob, objdir, digest, NULL, NULL, &repo_rev, &working_rev); AG_LabelPrintf(lblStatus, _("RCS status: %s\n" "Working revision: #%u\n" "Repository revision: #%u\n"), agRcsStatusStrings[status], (status!=AG_RCS_UNKNOWN && status!=AG_RCS_ERROR) ? working_rev : 0, (status!=AG_RCS_UNKNOWN && status!=AG_RCS_ERROR) ? repo_rev: 0); if (AG_RcsGetLog(objdir, &log) == -1) goto out; AG_TlistClear(tl); for (i = 0; i < log.nEnts; i++) { AG_RCSLogEntry *lent = &log.ents[i]; AG_TlistAdd(tl, NULL, "[#%s.%s] %s", lent->rev, lent->author, lent->msg); } AG_TlistRestore(tl); AG_RcsFreeLog(&log); out: AG_RcsDisconnect(); } #endif /* AG_NETWORK */ void * DEV_ObjectEdit(void *p) { AG_Object *ob = p; AG_Window *win; AG_Textbox *tbox; AG_Notebook *nb; AG_NotebookTab *ntab; AG_Tlist *tl; AG_Box *box; AG_Button *btn; win = AG_WindowNew(0); AG_WindowSetCaption(win, _("Object %s"), ob->name); AG_WindowSetPosition(win, AG_WINDOW_UPPER_RIGHT, 1); nb = AG_NotebookNew(win, AG_NOTEBOOK_HFILL|AG_NOTEBOOK_VFILL); ntab = AG_NotebookAddTab(nb, _("Infos"), AG_BOX_VERT); { AG_Textbox *tbMD5, *tbSHA1, *tbRMD160; tbox = AG_TextboxNew(ntab, 0, _("Name: ")); AG_TextboxPrintf(tbox, ob->name); AG_WidgetFocus(tbox); AG_SetEvent(tbox, "textbox-return", RenameObject, "%p", ob); AG_SeparatorNew(ntab, AG_SEPARATOR_HORIZ); AG_LabelNew(ntab, 0, _("Class: %s"), ob->cls->hier); AG_CheckboxSetFromFlags(ntab, 0, &ob->flags, devObjectFlags); #if 0 AG_LabelNewPolledMT(ntab, AG_LABEL_HFILL, &agLinkageLock, _("Parent: %[obj]"), &ob->parent); #endif AG_LabelNew(ntab, 0, _("Save prefix: %s"), ob->save_pfx != NULL ? ob->save_pfx : AG_PATHSEP); AG_SeparatorNew(ntab, AG_SEPARATOR_HORIZ); tbMD5 = AG_TextboxNew(ntab, AG_TEXTBOX_READONLY, "MD5: "); AG_WidgetDisable(tbMD5); tbSHA1 = AG_TextboxNew(ntab, AG_TEXTBOX_READONLY, "SHA1: "); AG_WidgetDisable(tbSHA1); tbRMD160 = AG_TextboxNew(ntab, AG_TEXTBOX_READONLY, "RMD160: "); AG_WidgetDisable(tbRMD160); AG_TextboxSizeHint(tbMD5, "888888888888888888888888888888888"); box = AG_BoxNew(ntab, AG_BOX_HORIZ, AG_BOX_HOMOGENOUS| AG_BOX_HFILL); { btn = AG_ButtonNewFn(box, 0, _("Refresh checksums"), RefreshSums, "%p,%p,%p,%p", ob, tbMD5, tbSHA1, tbRMD160); AG_PostEvent(NULL, btn, "button-pushed", NULL); } } #ifdef AG_NETWORK ntab = AG_NotebookAddTab(nb, _("RCS"), AG_BOX_VERT); { AG_Label *lblStatus; AG_Tlist *tl; lblStatus = AG_LabelNewString(ntab, AG_LABEL_HFILL, "..."); AG_LabelSizeHint(lblStatus, 3, _("Repository revision: #0000")); AG_LabelNewString(ntab, 0, _("Revision history:")); tl = AG_TlistNew(ntab, AG_TLIST_EXPAND); btn = AG_ButtonNewFn(ntab, AG_BUTTON_HFILL, _("Refresh status"), RefreshRepoStatus, "%p,%p,%p", ob, lblStatus, tl); if (agRcsMode) AG_PostEvent(NULL, btn, "button-pushed", NULL); } #endif /* AG_NETWORK */ ntab = AG_NotebookAddTab(nb, _("Deps"), AG_BOX_VERT); { tl = AG_TlistNew(ntab, AG_TLIST_POLL|AG_TLIST_EXPAND); AG_TlistSizeHint(tl, "XXXXXXXXXXXX", 6); AG_SetEvent(tl, "tlist-poll", PollDeps, "%p", ob); } ntab = AG_NotebookAddTab(nb, _("Events"), AG_BOX_VERT); { tl = AG_TlistNew(ntab, AG_TLIST_POLL|AG_TLIST_EXPAND); AG_SetEvent(tl, "tlist-poll", PollEvents, "%p", ob); } ntab = AG_NotebookAddTab(nb, _("Variables"), AG_BOX_VERT); { tl = AG_TlistNew(ntab, AG_TLIST_POLL|AG_TLIST_EXPAND); AG_SetEvent(tl, "tlist-poll", PollVariables, "%p", ob); } #if defined(AG_THREADS) && defined(AG_LOCKDEBUG) ntab = AG_NotebookAddTab(nb, _("Locks"), AG_BOX_VERT); { tl = AG_TlistNew(ntab, AG_TLIST_POLL|AG_TLIST_EXPAND); AG_SetEvent(tl, "tlist-poll", PollLocks, "%p", ob); } #endif return (win); }