/* ** Amster - Navigator ** by Jacob Laursen */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "include/config.h" #include "include/gui.h" #include "include/info.h" #include "include/mui.h" #include "include/navigator.h" #include "include/prefs.h" #include "include/protos.h" #include "amster_Cat.h" /* Global variables */ BOOL ServerListChanged = FALSE; /* Private prototypes */ void LoadServerList(struct NavigatorData *data); void SaveServerList(struct NavigatorData *data); void MarkServerOnline(struct NavigatorData *data, char *server); MUIF ServerListDisplay(REG(a2) char **array, REG(a1) struct ServerEntry *entry); MUIF ServerListCompare(REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct NList_CompareMessage *ncm); MUIF ServerListDestruct(REG(a2) APTR pool, REG(a1) struct ServerEntry *entry); MUIF ServerString(REG(a0) struct Hook *hook, REG(a1) APTR *contents); MUIF NavigatorDispatch(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg) { struct NavigatorData *data; struct ServerEntry *entry; char *buf; switch (msg->MethodID) { case OM_NEW: return(NavigatorNew(cl, obj, (APTR)msg)); case NAVI_CONNECT: data = INST_DATA(cl, obj); if (gui_napon) nap_logout(); get(data->ST_Server, MUIA_String_Contents, &buf); if (!gui_napon) { nap_login_fromlist(buf); } return(NULL); case NAVI_GETSERVER: data = INST_DATA(cl, obj); DoMethod(data->LV_Server, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &entry); if (entry) { set(data->ST_Server, MUIA_String_Contents, entry->Name); set(data->ST_Comment, MUIA_String_Contents, entry->Comment); } return(NULL); case NAVI_ADDSERVER: { BOOL selected = FALSE; data = INST_DATA(cl, obj); DoMethod(data->LV_Server, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &entry); if (entry) selected = TRUE; /* One entry is already selected */ if (entry = malloc(sizeof(struct ServerEntry))) { entry->LastOnline = 0; if (selected) { /* We clear the fields instead of dublicating selected entry */ entry->Name = strdup(MSG_NAVIGATOR_NEW); entry->Comment = strdup(""); } else { get(data->ST_Server, MUIA_String_Contents, &buf); entry->Name = strdup(buf); get(data->ST_Comment, MUIA_String_Contents, &buf); entry->Comment = strdup(buf); } DoMethod(data->LV_Server, MUIM_NList_InsertSingle, entry, MUIV_NList_Insert_Sorted); /* DoMethod(data->LV_Server, MUIM_NList_Jump, MUIV_NList_Jump_Active);*/ ServerListChanged = TRUE; } } return(NULL); case NAVI_REMOVESERVER: data = INST_DATA(cl, obj); DoMethod(data->LV_Server, MUIM_NList_Remove, MUIV_NList_Remove_Active); ServerListChanged = TRUE; return(NULL); case NAVI_REDRAWSERVER: { struct ServerEntry *entry; APTR *contents = (APTR)(((muimsg)msg)->arg1); data = INST_DATA(cl, obj); DoMethod(data->LV_Server, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &entry); if (entry) { if (*(contents+1) == 0) entry->Name = strdup(*contents); else entry->Comment = strdup(*contents); DoMethod(data->LV_Server, MUIM_NList_Redraw, MUIV_NList_Redraw_Active); ServerListChanged = TRUE; } return(NULL); } case NAVI_LOAD: data = INST_DATA(cl, obj); LoadServerList(data); return(NULL); case NAVI_SAVE: data = INST_DATA(cl, obj); SaveServerList(data); return(NULL); case NAVI_MARKSERVER: data = INST_DATA(cl, obj); MarkServerOnline(data, (char *)(((muimsg)msg)->arg1)); return(NULL); } return(DoSuperMethodA(cl, obj, msg)); } ULONG NavigatorNew(struct IClass *cl, Object *obj, struct opSet *msg) { static const struct Hook ServerListDispHook = { {NULL, NULL}, &ServerListDisplay, NULL, NULL }; static const struct Hook ServerListCompHook = { {NULL, NULL}, &ServerListCompare, NULL, NULL }; static const struct Hook ServerListDestHook = { {NULL, NULL}, &ServerListDestruct, NULL, NULL }; static const struct Hook ServerStringHook = { {NULL, NULL}, &ServerString, NULL, NULL }; struct NavigatorData *data; Object *LV_Server, *ST_Server, *ST_Comment; Object *BT_ConnectConnect, *BT_ConnectAdd, *BT_ConnectRemove; if (obj = (Object *)DoSuperNew(cl, obj, MUIA_HelpNode, "navi", MUIA_Window_Title, MSG_NAVIGATOR_TITLE, MUIA_Window_ID, MAKE_ID('N','A','V','I'), WindowContents, VGroup, Child, LV_Server = NListviewObject, MUIA_NList_Input, TRUE, MUIA_NListview_NList, NListObject, InputListFrame, MUIA_NList_ListBackground, MUII_ListBack, MUIA_NList_TitleBackground, MUII_ListBack, MUIA_NList_Title, TRUE, MUIA_NList_Format, "BAR,BAR,BAR", MUIA_NList_DisplayHook, &ServerListDispHook, MUIA_NList_CompareHook2, &ServerListCompHook, MUIA_NList_DestructHook, &ServerListDestHook, End, End, Child, ColGroup(2), Child, Label2(MSG_NAVIGATOR_SERVER), Child, ST_Server = StringObject, MUIA_HorizWeight, 400, StringFrame, End, Child, Label2(MSG_NAVIGATOR_COMMENT), Child, ST_Comment = StringObject, MUIA_HorizWeight, 400, StringFrame, End, End, Child, RectangleObject, MUIA_FixHeight, 8, MUIA_Rectangle_HBar, TRUE, End, Child, HGroup, Child, BT_ConnectConnect = SimpleButton(MSG_NAVIGATOR_CONNECT_GAD), Child, BT_ConnectRemove = SimpleButton(MSG_NAVIGATOR_REMOVE_GAD), Child, BT_ConnectAdd = SimpleButton(MSG_NAVIGATOR_ADD_GAD), /* Child, HGroup, Child, BT_Update = SimpleButton(MSG_NAVIGATOR_UPDATE_GAD), MUIA_ShortHelp, MSG_NAVIGATOR_UPDATE_HELP, End, */ End, End, TAG_MORE, msg->ops_AttrList)) { data = INST_DATA(cl, obj); data->LV_Server = LV_Server; data->ST_Server = ST_Server; data->ST_Comment = ST_Comment; DoMethod(obj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, obj, 3, MUIM_Set, MUIA_Window_Open, FALSE); DoMethod(LV_Server, MUIM_Notify, MUIA_NList_TitleClick, MUIV_EveryTime, LV_Server, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both); DoMethod(LV_Server, MUIM_Notify, MUIA_NList_TitleClick2, MUIV_EveryTime, LV_Server, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_2); DoMethod(LV_Server, MUIM_Notify, MUIA_NList_SortType, MUIV_EveryTime, LV_Server, 3, MUIM_Set, MUIA_NList_TitleMark, MUIV_TriggerValue); DoMethod(LV_Server, MUIM_Notify, MUIA_NList_SortType2, MUIV_EveryTime, LV_Server, 3, MUIM_Set, MUIA_NList_TitleMark2, MUIV_TriggerValue); /* DoMethod(LV_Server, MUIM_NList_Sort3, 1, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both);*/ DoMethod(BT_ConnectConnect, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, NAVI_CONNECT); DoMethod(BT_ConnectRemove, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, NAVI_REMOVESERVER); DoMethod(BT_ConnectAdd, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, NAVI_ADDSERVER); /* DoMethod(BT_Update, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, NAVI_GETNAPIGATOR);*/ DoMethod(LV_Server, MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime, obj, 1, NAVI_CONNECT); LoadServerList(data); DoMethod(LV_Server, MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, obj, 1, NAVI_GETSERVER); set(ST_Server, MUIA_String_AttachedList, LV_Server); DoMethod(ST_Server, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, ST_Server, 4, MUIM_CallHook, &ServerStringHook, MUIV_TriggerValue, 0); DoMethod(ST_Comment, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, ST_Server, 4, MUIM_CallHook, &ServerStringHook, MUIV_TriggerValue, 1); return((ULONG)obj); } return(0); } void LoadServerList(struct NavigatorData *data) { BPTR fh; char buf[1024]; int line = 0; struct ServerEntry *entry; LONG argarray[] = { NULL, NULL, NULL }; UBYTE *argstr = "HOST/A,LASTUSED/A/N,COMMENT/K"; struct RDArgs *rdargs; if (fh = Open("PROGDIR:Amster.servers", MODE_OLDFILE)) { while (FGets(fh, buf, sizeof(buf))) { line++; if (rdargs = AllocDosObject(DOS_RDARGS, NULL)) { rdargs->RDA_Buffer = NULL; rdargs->RDA_Source.CS_Buffer = buf; rdargs->RDA_Source.CS_Length = strlen(buf); argarray[2] = 0; if (ReadArgs(argstr, argarray, rdargs)) { if (entry = malloc(sizeof(struct ServerEntry))) { entry->Name = strdup((char *)argarray[0]); entry->LastOnline = *((long *)argarray[1]); if (argarray[2]) entry->Comment = strdup((char *)argarray[2]); else entry->Comment = strdup(""); entry->Ping = -1; DoMethod(data->LV_Server, MUIM_NList_InsertSingle, entry, MUIV_NList_Insert_Sorted); } } else gui_debugf("Error parsing '%s' line #%ld\n", "PROGDIR:Amster.servers", line); FreeDosObject(DOS_RDARGS, rdargs); } } Close(fh); DoMethod(data->LV_Server, MUIM_NList_Sort); } } void SaveServerList(struct NavigatorData *data) { struct ServerEntry *entry; BPTR fh; char buf[1024]; int i; fh = Open("PROGDIR:Amster.servers", MODE_NEWFILE); if (!fh) return; for (i=0; ; i++) { DoMethod(data->LV_Server, MUIM_NList_GetEntry, i, &entry); if (!entry) break; if (entry->Comment) { if (entry->Comment[0] != '\0') sprintf(buf, "%s %ld COMMENT \"%s\"\n", entry->Name, entry->LastOnline, entry->Comment); else sprintf(buf, "%s %ld\n", entry->Name, entry->LastOnline); } else sprintf(buf, "%s %ld\n", entry->Name, entry->LastOnline); Write(fh, buf, strlen(buf)); /* Should be buffered, check FWrite */ } Close(fh); ServerListChanged = FALSE; } void MarkServerOnline(struct NavigatorData *data, char *server) { struct ServerEntry *entry=0; struct DateStamp *ds, *rds; int i; BOOL new = FALSE; for (i=0; ; i++) { DoMethod(data->LV_Server, MUIM_NList_GetEntry, i, &entry); if (!entry) break; if (strcmp(server, entry->Name) == 0) break; } if (!entry) { /* Server not already on list */ if (prf->ServerList < 2) return; if (entry = malloc(sizeof(struct ServerEntry))) { entry->Name = strdup(server); entry->LastOnline = 0; /* In case we don't succeed later on... */ entry->Comment = strdup(""); entry->Ping = -1; new = TRUE; } } if (ds = malloc(sizeof(struct DateStamp))) { memset(ds, 0, sizeof(struct DateStamp)); if (rds = DateStamp(ds)) { entry->LastOnline = rds->ds_Days*24*60*60 + rds->ds_Minute*60 + rds->ds_Tick/50; if (new) DoMethod(data->LV_Server, MUIM_NList_InsertSingle, entry, MUIV_NList_Insert_Sorted); else DoMethod(data->LV_Server, MUIM_NList_Redraw, i); ServerListChanged = TRUE; } free(ds); } } MUIF ServerListDisplay(REG(a2) char **array, REG(a1) struct ServerEntry *entry) { struct ClockData *cd; static char buf[20], buf2[20]; if (entry) { *array++ = entry->Name; if (entry->LastOnline == 0) *array++ = "-"; else { if (cd = malloc(sizeof(struct ClockData))) { Amiga2Date(entry->LastOnline, cd); sprintf(buf, "%02d/%02d/%d %02d:%02d:%02d", cd->month, cd->mday, cd->year, cd->hour, cd->min, cd->sec); *array++ = buf; free(cd); } else *array++ = "-"; } *array++ = entry->Comment; if (entry->Ping >= 0) { sprintf(buf2, "%ld", entry->Ping); *array = buf2; } else *array = "-"; } else { *array++ = (char *)MSG_NAVIGATOR_LIST_SERVER; *array++ = (char *)MSG_NAVIGATOR_LIST_LASTONLINE; *array++ = (char *)MSG_NAVIGATOR_LIST_COMMENT; *array = (char *)MSG_NAVIGATOR_LIST_PING; } return 0; } MUIF ServerListCompare(REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct NList_CompareMessage *ncm) { struct ServerEntry *entry1 = ncm->entry1; struct ServerEntry *entry2 = ncm->entry2; LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask; LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask; ULONG result = 0; if (ncm->sort_type == MUIV_NList_SortType_None) return (0); if (col1 == 0) { if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) result = (LONG) stricmp(entry2->Name, entry1->Name); else result = (LONG) stricmp(entry1->Name, entry2->Name); } else if (col1 == 1) { if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) result = entry2->LastOnline - entry1->LastOnline; else result = entry1->LastOnline - entry2->LastOnline; } else if (col1 == 2) { if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) result = (LONG) stricmp(entry2->Comment, entry1->Comment); else result = (LONG) stricmp(entry1->Comment, entry2->Comment); } else if (col1 == 3) { if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask) result = entry2->Ping - entry1->Ping; else result = entry1->Ping - entry2->Ping; } if ((result != 0) || (col1 == col2)) return (result); if (col2 == 0) { if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask) result = (LONG) stricmp(entry2->Name, entry1->Name); else result = (LONG) stricmp(entry1->Name, entry2->Name); } else if (col2 == 1) { if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask) result = entry2->LastOnline - entry1->LastOnline; else result = entry1->LastOnline - entry2->LastOnline; } else if (col2 == 2) { if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask) result = (LONG) stricmp(entry2->Comment, entry1->Comment); else result = (LONG) stricmp(entry1->Comment, entry2->Comment); } else if (col2 == 3) { if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask) result = entry2->Ping - entry1->Ping; else result = entry1->Ping - entry2->Ping; } return (result); } MUIF ServerListDestruct(REG(a2) APTR pool, REG(a1) struct ServerEntry *entry) { free(entry); return(0); } MUIF ServerString(REG(a0) struct Hook *hook, REG(a1) APTR *contents) { DoMethod(gui->WI_Navigator, NAVI_REDRAWSERVER, contents); return(0); }