src/mui/MainMailListGroup.c
/***************************************************************************
YAM - Yet Another Mailer
Copyright (C) 1995-2000 Marcel Beck
Copyright (C) 2000-2022 YAM Open Source Team
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
YAM Official Support Site : http://www.yam.ch
YAM OpenSource project : http://sourceforge.net/projects/yamos/
$Id$
Superclass: MUIC_Group
Description: Groups multiple 'MainMailList' objects into one PageGroup
***************************************************************************/
#include "MainMailListGroup_cl.h"
#include <proto/muimaster.h>
#include <libraries/iffparse.h>
#include <mui/NList_mcc.h>
#include <mui/NListview_mcc.h>
#include "YAM.h"
#include "mui/MainMailList.h"
#include "mui/QuickSearchBar.h"
#include "Config.h"
#include "MUIObjects.h"
#include "Debug.h"
/* CLASSDATA
struct Data
{
Object *mainListviewObjects[LT_COUNT];
Object *mainListObjects[LT_COUNT];
struct Mail *lastActiveMail;
ULONG activeList;
BOOL setupDone;
BOOL listIsFreezed; // if set to true the list is hard freezed (cannot be unquite via NList_Quiet)
};
*/
/* EXPORT
enum MainListType
{
LT_MAIN=0,
LT_QUICKVIEW,
LT_COUNT
};
*/
/* Private Functions */
/* Overloaded Methods */
/// OVERLOAD(OM_NEW)
OVERLOAD(OM_NEW)
{
Object *mainListviewObjects[LT_COUNT];
Object *mainListObjects[LT_COUNT];
if((obj = DoSuperNew(cl, obj,
MUIA_Group_PageMode, TRUE,
Child, mainListviewObjects[LT_MAIN] = NListviewObject,
MUIA_CycleChain, TRUE,
MUIA_NListview_NList, mainListObjects[LT_MAIN] = MainMailListObject,
MUIA_ObjectID, MAKE_ID('N','L','0','2'),
MUIA_ContextMenu, C->MessageCntMenu ? MUIV_NList_ContextMenu_Always : MUIV_NList_ContextMenu_Never,
MUIA_NList_DragType, MUIV_NList_DragType_Default,
MUIA_NList_Exports, MUIV_NList_Exports_ColWidth|MUIV_NList_Exports_ColOrder,
MUIA_NList_Imports, MUIV_NList_Imports_ColWidth|MUIV_NList_Imports_ColOrder,
End,
End,
Child, mainListviewObjects[LT_QUICKVIEW] = NListviewObject,
MUIA_CycleChain, TRUE,
MUIA_NListview_NList, mainListObjects[LT_QUICKVIEW] = MainMailListObject,
MUIA_ContextMenu, C->MessageCntMenu ? MUIV_NList_ContextMenu_Always : MUIV_NList_ContextMenu_Never,
MUIA_NList_DragType, MUIV_NList_DragType_Default,
End,
End,
TAG_MORE, inittags(msg))) != NULL)
{
GETDATA;
data->mainListviewObjects[LT_MAIN] = mainListviewObjects[LT_MAIN];
data->mainListviewObjects[LT_QUICKVIEW] = mainListviewObjects[LT_QUICKVIEW];
data->mainListObjects[LT_MAIN] = mainListObjects[LT_MAIN];
data->mainListObjects[LT_QUICKVIEW] = mainListObjects[LT_QUICKVIEW];
}
return (IPTR)obj;
}
///
/// OVERLOAD(OM_GET)
// this is to delegate the OM_GET to the correct NLists
OVERLOAD(OM_GET)
{
GETDATA;
IPTR *store = ((struct opGet *)msg)->opg_Storage;
switch(((struct opGet *)msg)->opg_AttrID)
{
case ATTR(ActiveList): *store = data->activeList; return TRUE;
case ATTR(ActiveListviewObject): *store = (ULONG)data->mainListviewObjects[data->activeList]; return TRUE;
case ATTR(ActiveListObject): *store = (ULONG)data->mainListObjects[data->activeList]; return TRUE;
case ATTR(MainList): *store = (ULONG)data->mainListObjects[LT_MAIN]; return TRUE;
case ATTR(LastActiveMail): *store = (ULONG)data->lastActiveMail; return TRUE;
case ATTR(Freeze): *store = (BOOL)data->listIsFreezed; return TRUE;
// we also return foreign attributes
case MUIA_NList_Active:
case MUIA_NList_Entries:
case MUIA_MainMailList_SortOrderReversed:
{
*store = xget(data->mainListObjects[data->activeList], ((struct opGet *)msg)->opg_AttrID);
return TRUE;
}
break;
}
return DoSuperMethodA(cl, obj, msg);
}
///
/// OVERLOAD(OM_SET)
OVERLOAD(OM_SET)
{
GETDATA;
struct TagItem *tags = inittags(msg), *tag;
while((tag = NextTagItem((APTR)&tags)) != NULL)
{
switch(tag->ti_Tag)
{
case ATTR(Freeze):
{
// mark the list as freezed or unfreezed for the LISTFREEZE/LISTUNFREEZE Arexx Command
data->listIsFreezed = tag->ti_Data;
// make sure to freeze/unfreeze
set(obj, MUIA_NList_Quiet, data->listIsFreezed);
// make the superMethod call ignore those tags
tag->ti_Tag = TAG_IGNORE;
}
break;
case MUIA_Group_ActivePage:
{
if(data->activeList != tag->ti_Data)
{
// set the new mainlist as the default object of the window it belongs to
// but only if not another one is yet active
if(data->setupDone == TRUE && (Object*)xget(_win(obj), MUIA_Window_DefaultObject) == data->mainListviewObjects[data->activeList])
set(_win(obj), MUIA_Window_DefaultObject, data->mainListviewObjects[tag->ti_Data]);
data->activeList = tag->ti_Data;
}
}
break;
case MUIA_NList_Active:
{
// make the entry the active one and center the list on it
DoMethod(data->mainListObjects[data->activeList], MUIM_NList_SetActive, tag->ti_Data, MUIV_NList_SetActive_Jump_Center);
// make the superMethod call ignore those tags
tag->ti_Tag = TAG_IGNORE;
}
break;
case MUIA_NList_Quiet:
{
if(tag->ti_Data == TRUE || data->listIsFreezed == FALSE)
{
set(data->mainListObjects[LT_MAIN], MUIA_NList_Quiet, tag->ti_Data);
set(data->mainListObjects[LT_QUICKVIEW], MUIA_NList_Quiet, tag->ti_Data);
}
// make the superMethod call ignore those tags
tag->ti_Tag = TAG_IGNORE;
}
break;
case MUIA_ContextMenu:
case MUIA_NList_DisplayRecall:
case MUIA_NList_SortType:
case MUIA_NList_SortType2:
case MUIA_NList_KeyLeftFocus:
{
set(data->mainListObjects[LT_MAIN], tag->ti_Tag, tag->ti_Data);
set(data->mainListObjects[LT_QUICKVIEW], tag->ti_Tag, tag->ti_Data);
// make the superMethod call ignore those tags
tag->ti_Tag = TAG_IGNORE;
}
break;
}
}
return DoSuperMethodA(cl, obj, msg);
}
///
/// OVERLOAD(MUIM_Setup)
OVERLOAD(MUIM_Setup)
{
GETDATA;
IPTR result;
ENTER();
if((result = DoSuperMethodA(cl, obj, msg)) != 0)
{
data->setupDone = TRUE;
}
RETURN(result);
return result;
}
///
/// OVERLOAD(MUIM_Cleanup)
OVERLOAD(MUIM_Cleanup)
{
GETDATA;
IPTR result;
ENTER();
data->setupDone = FALSE;
result = DoSuperMethodA(cl, obj, msg);
RETURN(result);
return result;
}
///
/// OVERLOAD(MUIM_GoActive)
OVERLOAD(MUIM_GoActive)
{
GETDATA;
ENTER();
// we don't forward the GoActive() call to our own
// superclass but forward it to the activeList object itself
set(_win(obj), MUIA_Window_ActiveObject, data->mainListviewObjects[data->activeList]);
RETURN(0);
return 0;
}
///
/// OVERLOAD(MUIM_NList_Clear)
OVERLOAD(MUIM_NList_Clear)
{
GETDATA;
IPTR result;
// delegate this method to the currently active NList only
result = DoMethodA(data->mainListObjects[data->activeList], msg);
return result;
}
///
/// OVERLOAD(MUIM_NList_GetEntry)
OVERLOAD(MUIM_NList_GetEntry)
{
GETDATA;
IPTR result;
// delegate this method to the currently active NList only
result = DoMethodA(data->mainListObjects[data->activeList], msg);
return result;
}
///
/// OVERLOAD(MUIM_NList_GetPos)
OVERLOAD(MUIM_NList_GetPos)
{
GETDATA;
IPTR result;
// delegate this method to the currently active NList only
result = DoMethodA(data->mainListObjects[data->activeList], msg);
return result;
}
///
/// OVERLOAD(MUIM_NList_Insert)
OVERLOAD(MUIM_NList_Insert)
{
GETDATA;
IPTR result;
// delegate this method to the currently active NList only
result = DoMethodA(data->mainListObjects[data->activeList], msg);
return result;
}
///
/// OVERLOAD(MUIM_NList_InsertSingle)
OVERLOAD(MUIM_NList_InsertSingle)
{
GETDATA;
IPTR result;
// we always add the mail to the main list
result = DoMethodA(data->mainListObjects[LT_MAIN], msg);
// the InsertSignal method is used by all internal parties
// to put a mail into a main listview. But in case we have a
// quicksearchbar we have to check whether this also matches
// any criteria of it and also put it in there
if(data->activeList == LT_QUICKVIEW)
{
struct MUIP_NList_InsertSingle* m = (struct MUIP_NList_InsertSingle*)msg;
// check if mail matches the search/view criteria of the quicksearchbar
if(DoMethod(G->MA->GUI.GR_QUICKSEARCHBAR, MUIM_QuickSearchBar_MatchMail, m->entry) == TRUE)
{
result = DoMethodA(data->mainListObjects[LT_QUICKVIEW], msg);
// make sure the statistics of the quicksearchbar are updated.
DoMethod(G->MA->GUI.GR_QUICKSEARCHBAR, MUIM_QuickSearchBar_UpdateStats, FALSE);
}
}
return result;
}
///
/// OVERLOAD(MUIM_NList_NextSelected)
OVERLOAD(MUIM_NList_NextSelected)
{
GETDATA;
IPTR result;
// delegate this method to the currently active NList only
result = DoMethodA(data->mainListObjects[data->activeList], msg);
return result;
}
///
/// OVERLOAD(MUIM_NList_Redraw)
OVERLOAD(MUIM_NList_Redraw)
{
GETDATA;
IPTR result;
// delegate this method to the currently active NList only
result = DoMethodA(data->mainListObjects[data->activeList], msg);
return result;
}
///
/// OVERLOAD(MUIM_NList_Select)
OVERLOAD(MUIM_NList_Select)
{
GETDATA;
IPTR result;
// delegate this method to the currently active NList only
result = DoMethodA(data->mainListObjects[data->activeList], msg);
return result;
}
///
/// OVERLOAD(MUIM_NList_Sort)
OVERLOAD(MUIM_NList_Sort)
{
GETDATA;
// delegate this method call to all subNLists
DoMethodA(data->mainListObjects[LT_MAIN], msg);
DoMethodA(data->mainListObjects[LT_QUICKVIEW], msg);
return 0;
}
///
/* Public Methods */
/// DECLARE(MakeFormat)
DECLARE(MakeFormat)
{
GETDATA;
// forward the MakeFormat message call to all our sublists as well
DoMethod(data->mainListObjects[LT_MAIN], MUIM_MainMailList_MakeFormat);
DoMethod(data->mainListObjects[LT_QUICKVIEW], MUIM_MainMailList_MakeFormat);
return 0;
}
///
/// DECLARE(SwitchToList)
DECLARE(SwitchToList) // enum MainListType type
{
GETDATA;
ENTER();
// refresh the last active information
DoMethod(data->mainListObjects[data->activeList], MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &data->lastActiveMail);
if(data->activeList != msg->type)
{
int i;
BOOL listWasActive = FALSE;
// before we switch the activePage of the group object we
// have to set the individual column width of the two NLists as we only save
// the width of one.
for(i=0; i < NUMBER_MAILLIST_COLUMNS; i++)
{
LONG colWidth = DoMethod(data->mainListObjects[data->activeList], MUIM_NList_ColWidth, i, MUIV_NList_ColWidth_Get);
// set the column width of the LT_QUICKVIEW maillist also the same
DoMethod(data->mainListObjects[msg->type], MUIM_NList_ColWidth, i, colWidth != -1 ? colWidth : MUIV_NList_ColWidth_Default);
}
// see if we have to make the switched object as the new active one
if(data->setupDone == TRUE && ((Object *)xget(_win(obj), MUIA_Window_ActiveObject)) == data->mainListviewObjects[data->activeList])
listWasActive = TRUE;
// switch the page of the group now
set(obj, MUIA_Group_ActivePage, msg->type);
if(msg->type == LT_MAIN)
{
LONG pos = MUIV_NList_GetPos_Start;
// in case we are switching from LT_QUICKVIEW->LT_MAIN we go and set the
// last active mail as well.
if(data->lastActiveMail != NULL)
{
// retrieve the number of the lastActive entry within the main mail list
DoMethod(data->mainListObjects[LT_MAIN], MUIM_NList_GetPos, data->lastActiveMail, &pos);
}
if(pos == MUIV_NList_GetPos_End || pos == MUIV_NList_GetPos_Start)
pos = MUIV_NList_Active_Top;
// make sure to set a new message so that the mail view is updated
DoMethod(data->mainListObjects[LT_MAIN], MUIM_NList_SetActive, pos, MUIV_NList_SetActive_Jump_Center);
set(data->mainListObjects[LT_MAIN], MUIA_NList_SelectChange, TRUE);
}
if(listWasActive == TRUE)
set(_win(obj), MUIA_Window_ActiveObject, data->mainListviewObjects[data->activeList]);
}
// no matter what, we always clear the quickview list on a switch.
DoMethod(data->mainListObjects[LT_QUICKVIEW], MUIM_NList_Clear);
RETURN(0);
return 0;
}
///
/// DECLARE(AddMailToList)
// add a mail to a specific list
DECLARE(AddMailToList) // enum MainListType type, struct Mail* mail
{
GETDATA;
ENTER();
// we add the mail to a specific list of our group
DoMethod(data->mainListObjects[msg->type], MUIM_NList_InsertSingle, msg->mail, MUIV_NList_Insert_Sorted);
// update the searchbar statistics if necessary
if(data->activeList == LT_QUICKVIEW)
DoMethod(G->MA->GUI.GR_QUICKSEARCHBAR, MUIM_QuickSearchBar_UpdateStats, FALSE);
RETURN(0);
return 0;
}
///
/// DECLARE(RemoveMail)
// properly removes a mail from both lists
DECLARE(RemoveMail) // struct Mail* mail
{
GETDATA;
IPTR result;
ENTER();
// first we check whether the active one was the quickview and if so we also remove
// the mail from the main list
if(data->activeList == LT_QUICKVIEW)
{
// forward the command to the list itself
DoMethod(data->mainListObjects[LT_MAIN], MUIM_MainMailList_RemoveMail, msg->mail);
}
// now also remove the mail from the currently active list
result = DoMethod(data->mainListObjects[data->activeList], MUIM_MainMailList_RemoveMail, msg->mail);
RETURN(result);
return result;
}
///
/// DECLARE(RedrawMail)
// redraws the mail on our currently active list
DECLARE(RedrawMail) // struct Mail* mail
{
GETDATA;
LONG pos = MUIV_NList_GetPos_Start;
BOOL result = FALSE;
ENTER();
DoMethod(data->mainListObjects[data->activeList], MUIM_NList_GetPos, msg->mail, &pos);
if(pos != MUIV_NList_GetPos_End)
{
DoMethod(data->mainListObjects[data->activeList], MUIM_NList_Redraw, pos);
result = TRUE;
}
RETURN(result);
return result;
}
///
/// DECLARE(IsMailList)
// checks if a passed object pointer is one of our maillists (for checking dragdrop requests)
DECLARE(IsMailList) // Object *list
{
GETDATA;
ASSERT(msg->list != NULL);
return (ULONG)(msg->list == data->mainListObjects[LT_MAIN] ||
msg->list == data->mainListObjects[LT_QUICKVIEW]);
}
///
/// DECLARE(JumpToFirstNewMailOfFolder)
// jump to the first "new" mail of a folder
DECLARE(JumpToFirstNewMailOfFolder) // struct Folder *folder
{
GETDATA;
BOOL jumped;
ENTER();
jumped = DoMethod(data->mainListObjects[data->activeList], MUIM_MainMailList_JumpToFirstNewMailOfFolder, msg->folder);
RETURN(jumped);
return jumped;
}
///
/// DECLARE(JumpToRecentMailOfFolder)
// jump to the most recent mail of a folder
DECLARE(JumpToRecentMailOfFolder) // struct Folder *folder
{
GETDATA;
BOOL jumped;
ENTER();
jumped = DoMethod(data->mainListObjects[data->activeList], MUIM_MainMailList_JumpToRecentMailOfFolder, msg->folder);
RETURN(jumped);
return jumped;
}
///
/// DECLARE(DisplayMailsOfFolder)
// display the mails of the given folder
DECLARE(DisplayMailsOfFolder) // struct Folder *folder
{
GETDATA;
ENTER();
DoMethod(data->mainListObjects[data->activeList], MUIM_MainMailList_DisplayMailsOfFolder, msg->folder);
// make sure the maillist is enabled
set(obj, MUIA_Disabled, FALSE);
RETURN(0);
return 0;
}
///