home *** CD-ROM | disk | FTP | other *** search
- /*
-
- File: search.c
- Author: Neil Cafferkey
- Copyright (C) 2000 Neil Cafferkey
-
- 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., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- */
-
- #include "viewer.h"
- #include <stdlib.h>
- #include <exec/memory.h>
- #include <intuition/screens.h>
- #include <libraries/gadtools.h>
-
- #include "search_protos.h"
- #include "general_protos.h"
- #include "article_protos.h"
- #include "index_protos.h"
- #include "paedia_protos.h"
- #include <proto/exec.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/gadtools.h>
-
-
- #define SUBJECT_LINE_COUNT 4
- #define MIN_ARTICLE_LINE_COUNT 4
- #define DEFAULT_SEARCH_WIDTH 250
- #define DEFAULT_SEARCH_HEIGHT 250
- enum {KEYWORD_BOX_ID=1,SEARCH_BUTTON_ID,SUBJECT_VIEW_ID,ARTICLE_VIEW_ID};
-
- const TEXT *keyword_box_label="Search Words";
- const TEXT *search_button_label="Search";
- const TEXT *subject_view_label="Subjects";
- const TEXT *article_view_label="Articles";
-
-
- /* Prototypes */
-
- static BOOL OpenSearchGadgets(Search search);
- static VOID CloseSearchGadgets(Search search);
-
-
-
- /* Function: CreateSearch
- * ======================
- * Creates a Search.
- */
-
- Search CreateSearch(struct MsgPort *msg_port,Paedia paedia,
- struct MinList *object_list,UWORD left,UWORD top)
- {
- Search search;
- BOOL success=TRUE;
- struct Screen *screen=NULL;
- struct IntuiText i_text;
- struct Window *window;
-
- if(search=AllocMem(sizeof(Search_imp),MEMF_CLEAR))
- {
-
- search->node.ln_Type=NT_SEARCH;
- search->paedia=paedia;
- search->object_list=object_list;
- search->msg_port=msg_port;
-
- /* Allocate memory for search string */
-
- if((search->keywords=AllocMem(64+1,MEMF_ANY))!=NULL)
- {
- *search->keywords='\0';
- }
- else
- {
- ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
- success=FALSE;
- }
-
- /* Open the search window */
-
- search->window=window=OpenWindowTags(NULL,
- WA_Left,left,
- WA_Top,top,
- WA_Width,DEFAULT_SEARCH_WIDTH,
- WA_Height,DEFAULT_SEARCH_HEIGHT,
- WA_Flags,WFLG_CLOSEGADGET|WFLG_DEPTHGADGET|WFLG_SIZEBBOTTOM|
- WFLG_SIZEGADGET|WFLG_ACTIVATE|WFLG_NEWLOOKMENUS|WFLG_DRAGBAR,
- WA_Title,"Index",
- WA_MinWidth,0,
- WA_MinHeight,0,
- WA_MaxWidth,-1,
- WA_MaxHeight,-1,
- TAG_END);
-
- /* Lock the screen so it can be examined during the life of this
- Search. */
-
- search->screen=screen=LockPubScreen(NULL);
-
- if(window)
- {
-
- /* Set the window's message port and IDCMP flags */
-
- window->UserPort=msg_port;
-
- ModifyIDCMP(window,IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE|
- IDCMP_CHANGEWINDOW|STRINGIDCMP|BUTTONIDCMP|LISTVIEWIDCMP);
-
- /* Store Search's pointer in its window */
-
- (Search)window->UserData=search;
-
- /* Calculate gadget positions and sizes */
-
- search->font_height=screen->Font->ta_YSize;
- search->gadget_left=window->BorderLeft+INTERWIDTH;
- search->gadget_top=window->BorderTop+INTERHEIGHT
- +search->font_height+INTERHEIGHT;
-
- search->gadget_rel_width=
- -window->BorderRight-INTERWIDTH-search->gadget_left;
-
- i_text.ITextFont=screen->Font;
- i_text.IText=search_button_label;
- i_text.NextText=NULL;
-
- search->search_button_width=IntuiTextLength(&i_text)+12;
- search->search_button_rel_left=-window->BorderLeft
- -INTERWIDTH-search->search_button_width;
-
- search->keyword_box_rel_width=
- -window->BorderRight-2*INTERWIDTH
- -search->search_button_width-search->gadget_left;
- search->keyword_box_height=search->font_height+6;
-
- search->subject_view_top=search->gadget_top
- +search->keyword_box_height+search->font_height+2*INTERHEIGHT;
- search->subject_view_height=search->font_height*SUBJECT_LINE_COUNT
- +4;
- search->article_view_top=search->subject_view_top
- +search->subject_view_height+search->font_height+2*INTERHEIGHT;
- search->article_view_rel_height=-search->article_view_top
- -window->BorderBottom-INTERHEIGHT;
-
- /* Set minimum window dimensions */
-
- i_text.IText=keyword_box_label;
- search->min_width=-search->search_button_rel_left
- +IntuiTextLength(&i_text)+2*INTERWIDTH+window->BorderLeft;
-
- search->min_height=search->article_view_top+search->font_height*
- MIN_ARTICLE_LINE_COUNT+4+INTERHEIGHT+window->BorderBottom;
-
-
- if(!WindowLimits(window,search->min_width,search->min_height,0,0))
- ChangeWindowBox(window,window->LeftEdge,window->TopEdge,
- search->min_width,search->min_height);
-
- /* Create gadgets */
-
- search->visual_info=GetVisualInfoA(screen,NULL);
- OpenSearchGadgets(search);
-
- }
- else
- {
- success=FALSE;
- }
-
- if(!success)
- {
- KillSearch(search);
- search=NULL;
- }
- }
- else
- ReportError(NULL,ERROR_REPORT_MEM,NULL,0);
-
- return search;
- }
-
-
-
- /* Function: OpenSearchGadgets
- * ===========================
- * Sets up a Search's gadgets. Returns a success flag.
- */
-
- static BOOL OpenSearchGadgets(Search search)
- {
- BOOL success=TRUE;
- struct Screen *screen=search->screen;
- struct NewGadget new_gadget;
- struct Window *window=search->window;
-
- /* Recalculate variable gadget positions and sizes */
-
-
-
- /* Create a gadtools context for this window */
-
- search->context=CreateContext(&search->gadgets);
-
- /* Create the keyword box */
-
- new_gadget.ng_LeftEdge=search->gadget_left;
- new_gadget.ng_TopEdge=search->gadget_top;
- new_gadget.ng_Width=window->Width+search->keyword_box_rel_width;
- new_gadget.ng_Height=search->keyword_box_height;
- new_gadget.ng_GadgetText=keyword_box_label;
- new_gadget.ng_TextAttr=screen->Font;
- new_gadget.ng_GadgetID=KEYWORD_BOX_ID;
- new_gadget.ng_Flags=PLACETEXT_ABOVE|NG_HIGHLABEL;
- new_gadget.ng_VisualInfo=search->visual_info;
- new_gadget.ng_UserData=0;
-
- search->keyword_box=CreateGadget(STRING_KIND,search->context,
- &new_gadget,GTST_String,search->keywords,TAG_END);
-
- /* Create the search button */
-
- new_gadget.ng_LeftEdge=window->Width+search->search_button_rel_left;
- new_gadget.ng_TopEdge=search->gadget_top;
- new_gadget.ng_Width=search->search_button_width;
- new_gadget.ng_Height=search->keyword_box_height;
- new_gadget.ng_GadgetText=search_button_label;
- new_gadget.ng_TextAttr=screen->Font;
- new_gadget.ng_GadgetID=SEARCH_BUTTON_ID;
- new_gadget.ng_Flags=0;
- new_gadget.ng_VisualInfo=search->visual_info;
- new_gadget.ng_UserData=0;
-
- search->search_button=CreateGadget(BUTTON_KIND,search->keyword_box,
- &new_gadget,TAG_END);
-
- /* Create the subject listview */
-
- new_gadget.ng_LeftEdge=search->gadget_left;
- new_gadget.ng_TopEdge=search->subject_view_top;
- new_gadget.ng_Width=window->Width+search->gadget_rel_width;
- new_gadget.ng_Height=search->subject_view_height;
- new_gadget.ng_GadgetText=subject_view_label;
- new_gadget.ng_TextAttr=screen->Font;
- new_gadget.ng_GadgetID=SUBJECT_VIEW_ID;
- new_gadget.ng_Flags=0;
- new_gadget.ng_VisualInfo=search->visual_info;
- new_gadget.ng_UserData=0;
-
- search->subject_view=CreateGadget(LISTVIEW_KIND,search->search_button,
- &new_gadget,GTLV_Labels,search->index_list,GTLV_Selected,
- search->selected_subject_no,GTLV_ShowSelected,NULL,
- GTLV_Top,search->top_subject_no,TAG_END);
-
- /* Create the article listview */
-
- new_gadget.ng_LeftEdge=search->gadget_left;
- new_gadget.ng_TopEdge=search->article_view_top;
- new_gadget.ng_Width=window->Width+search->gadget_rel_width;
- new_gadget.ng_Height=window->Height+search->article_view_rel_height;
- new_gadget.ng_GadgetText=article_view_label;
- new_gadget.ng_TextAttr=screen->Font;
- new_gadget.ng_GadgetID=ARTICLE_VIEW_ID;
- new_gadget.ng_Flags=0;
- new_gadget.ng_VisualInfo=search->visual_info;
- new_gadget.ng_UserData=0;
-
- if(search->current_subject!=NULL)
- {
- search->article_view=CreateGadget(LISTVIEW_KIND,search->subject_view,
- &new_gadget,GTLV_Labels,&search->current_subject->ref_list,
- GTLV_Top,search->top_article_no,TAG_END);
- }
- else
- {
- search->article_view=CreateGadget(LISTVIEW_KIND,search->subject_view,
- &new_gadget,GTLV_Labels,NULL,TAG_END);
- }
-
- /* Add gadgets to window and make them visible */
-
- if(search->gadgets!=NULL)
- {
- AddGList(window,search->gadgets,-1,-1,NULL);
- RefreshGList(search->gadgets,window,NULL,-1);
- GT_RefreshWindow(window,NULL);
- }
- else
- {
- success=FALSE;
- }
-
- if(!success)
- {
- KillSearch(search);
- search=NULL;
- }
-
- return success;
- }
-
-
-
- /* Function: CloseSearchGadgets
- * ============================
- * Destroys a Search's gadgets.
- */
-
- static VOID CloseSearchGadgets(Search search)
- {
- TEXT *keywords;
-
- /* Copy keyword string from gadget */
-
- GT_GetGadgetAttrs(search->keyword_box,search->window,NULL,GTST_String,
- &keywords,TAG_END);
- if(search->keywords)
- strcpy(search->keywords,keywords);
-
- /* Store listview attributes */
-
- GT_GetGadgetAttrs(search->subject_view,search->window,NULL,GTLV_Selected,
- &search->selected_subject_no,GTLV_Top,&search->top_subject_no,
- TAG_END);
-
- /*printf("search->selected_subject_no=%u\n",search->selected_subject_no);*/
-
- GT_GetGadgetAttrs(search->article_view,search->window,NULL,GTLV_Top,
- &search->top_article_no,TAG_END);
-
- /* Remove and free gadgets */
-
- RemoveGList(search->window,search->gadgets,-1);
- FreeGadgets(search->gadgets);
-
- /* Clear window */
-
- SetRast(search->window->RPort,0);
- RefreshWindowFrame(search->window);
-
- return;
- }
-
-
-
- /* Function: HandleSearchInput
- * ===========================
- */
-
- VOID HandleSearchInput(Search search,struct IntuiMessage *msg)
- {
- BOOL close=FALSE;
- ULONG article_no=0;
- struct IntuiMessage *mod_msg;
- struct Gadget *gadget=(struct Gadget *)msg->IAddress;
- TEXT *keywords;
- Article article;
- Reference ref;
- Sequence article_data;
-
- mod_msg=GT_FilterIMsg(msg);
- if(mod_msg!=NULL)
- {
-
- switch(mod_msg->Class)
- {
-
- case IDCMP_NEWSIZE:
- CloseSearchGadgets(search);
- OpenSearchGadgets(search);
- break;
-
- case IDCMP_CLOSEWINDOW:
- close=TRUE;
- break;
-
- case IDCMP_GADGETUP:
-
- switch(gadget->GadgetID)
- {
- case KEYWORD_BOX_ID:
- case SEARCH_BUTTON_ID:
-
- /* Copy keyword string from gadget */
-
- GT_GetGadgetAttrs(search->keyword_box,search->window,NULL,
- GTST_String,&keywords,TAG_END);
- strcpy(search->keywords,keywords);
-
- /* Remove subject and article lists from their gadgets */
-
- GT_SetGadgetAttrs(search->subject_view,search->window,NULL,
- GTLV_Labels,NULL,TAG_END);
-
- GT_SetGadgetAttrs(search->article_view,search->window,NULL,
- GTLV_Labels,NULL,TAG_END);
-
- /* Do a new index search */
-
- if(search->index_list)
- KillIndexResults(search->index_list);
-
- SetWindowPointer(search->window,WA_BusyPointer,TRUE,TAG_END);
-
- search->index_list=FindIndexRecords(search->paedia->index,
- search->keywords);
-
- /* Display new subjects */
-
- GT_SetGadgetAttrs(search->subject_view,search->window,NULL,
- GTLV_Labels,search->index_list,GTLV_Selected,0,TAG_END);
-
- SetWindowPointer(search->window,TAG_END);
-
- case SUBJECT_VIEW_ID:
-
- /* Get current subject number */
-
- GT_GetGadgetAttrs(search->subject_view,search->window,NULL,
- GTLV_Selected,&search->selected_subject_no,TAG_END);
-
- if(search->selected_subject_no!=~0)
- {
- search->current_subject=(IndexRecord)GetMinListNode(
- (struct MinList *)search->index_list,
- search->selected_subject_no);
-
- /* Display new article titles */
-
- GT_SetGadgetAttrs(search->article_view,search->window,NULL,
- GTLV_Labels,&search->current_subject->ref_list,TAG_END);
- }
- else
- {
- search->current_subject=NULL;
- }
-
- break;
-
- case ARTICLE_VIEW_ID:
-
- /* Display selected article */
-
- ref=(Reference)GetMinListNode(
- (struct MinList *)&search->current_subject->ref_list,
- mod_msg->Code);
-
- article_data=GetPaediaItem(search->paedia,ref->link_no);
- article=CreateArticle(article_data,search->msg_port);
- if(article)
- AddTail((struct List *)search->object_list,&article->node);
-
- default:
-
- }
-
- case IDCMP_CHANGEWINDOW:
- if(!WindowLimits(search->window,search->min_width,
- search->min_height,0,0))
- ChangeWindowBox(search->window,search->window->LeftEdge,
- search->window->TopEdge,search->min_width,
- search->min_height);
- break;
-
- default:
-
- }
-
- GT_PostFilterIMsg(mod_msg);
- }
-
- ReplyMsg((struct Message *)msg);
-
- if(close)
- {
- Remove(&search->node);
- KillSearch(search);
- }
-
- return;
- }
-
-
-
- /* Function: KillSearch
- * ====================
- * Destroys a Search.
- */
-
- VOID KillSearch(Search search)
- {
-
- if(search->index_list)
- KillIndexResults(search->index_list);
-
- if(search->window)
- {
-
- CloseSearchGadgets(search);
-
- Forbid();
- StripWindowMessages(search->window);
- search->window->UserPort=NULL;
- ModifyIDCMP(search->window,0);
- Permit();
- CloseWindow(search->window);
- UnlockPubScreen(NULL,search->screen);
- }
-
- FreeVisualInfo(search->visual_info);
-
- if(search->keywords!=NULL)
- FreeMem(search->keywords,64+1);
-
- /* Free search structure */
-
- FreeMem(search,sizeof(Search_imp));
-
- return;
- }
-
-
-