home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magazyn Exec 3
/
CD_Magazyn_EXEC_nr_3.iso
/
Recent
/
misc
/
edu
/
WhirlDisc.lha
/
WhirlDisc
/
Source
/
search.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-08-13
|
15KB
|
538 lines
/*
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;
}