src/mui/ThemeListGroup.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: Provides GUI elements and routines for showing the currently
available themes for YAM.
***************************************************************************/
#include "ThemeListGroup_cl.h"
#include <string.h>
#include <proto/dos.h>
#include <proto/muimaster.h>
#include <mui/NBalance_mcc.h>
#include <mui/NList_mcc.h>
#include <mui/NListview_mcc.h>
#include "YAM.h"
#include "mui/ImageArea.h"
#include "mui/ThemeList.h"
#include "Config.h"
#include "Locale.h"
#include "MUIObjects.h"
#include "Requesters.h"
#include "Debug.h"
/* CLASSDATA
struct Data
{
Object *NL_THEMELIST;
Object *TX_THEMELABEL;
Object *GR_PREVIEW;
Object *IM_PREVIEW;
Object *BT_ACTIVATE;
Object *TX_AUTHOR;
Object *TX_URL;
char themeName[SIZE_DEFAULT];
};
*/
/* Overloaded Methods */
/// OVERLOAD(OM_NEW)
OVERLOAD(OM_NEW)
{
Object *themeListObject;
Object *themeTextObject;
Object *previewImageObject;
Object *imageGroupObject;
Object *activateButtonObject;
Object *authorTextObject;
Object *urlTextObject;
ENTER();
if((obj = DoSuperNew(cl, obj,
GroupSpacing(0),
MUIA_Group_Horiz, TRUE,
MUIA_ContextMenu, FALSE,
Child, VGroup,
MUIA_HorizWeight, 30,
Child, HBarT(tr(MSG_CO_LOOKFEEL_TITLE_THEME)), End,
Child, NListviewObject,
MUIA_CycleChain, TRUE,
MUIA_Weight, 60,
MUIA_NListview_NList, themeListObject = ThemeListObject,
End,
End,
Child, activateButtonObject = MakeButton(tr(MSG_CO_THEME_ACTIVATE)),
End,
Child, NBalanceObject,
MUIA_Balance_Quiet, TRUE,
End,
Child, VGroup,
GroupFrameT(tr(MSG_CO_LOOKFEEL_TITLE_INFO)),
MUIA_HorizWeight, 70,
Child, themeTextObject = TextObject,
MUIA_Text_PreParse, "\033b\033c",
MUIA_Text_Copy, FALSE,
End,
Child, RectangleObject,
MUIA_Rectangle_HBar, TRUE,
MUIA_FixHeight, 4,
End,
Child, HGroup,
Child, HSpace(0),
Child, TextObject,
MUIA_Font, MUIV_Font_Tiny,
MUIA_HorizWeight, 0,
MUIA_Text_Contents, tr(MSG_CO_THEME_PREVIEW),
MUIA_Text_Copy, FALSE,
End,
Child, HSpace(0),
End,
Child, HVSpace,
Child, HGroup,
Child, HSpace(0),
Child, imageGroupObject = VGroup,
Child, previewImageObject = ImageAreaObject,
MUIA_ImageArea_ShowLabel, FALSE,
MUIA_ImageArea_MaxWidth, 300,
MUIA_ImageArea_MaxHeight, 200,
MUIA_ImageArea_NoMinHeight, FALSE,
End,
End,
Child, HSpace(0),
End,
Child, HVSpace,
Child, RectangleObject,
MUIA_Rectangle_HBar, TRUE,
MUIA_FixHeight, 4,
End,
Child, ColGroup(2),
Child, Label2(tr(MSG_CO_THEME_AUTHOR)),
Child, authorTextObject = TextObject,
TextFrame,
MUIA_Background, MUII_TextBack,
MUIA_Text_SetMin, TRUE,
MUIA_Text_Copy, FALSE,
End,
Child, Label2(tr(MSG_CO_THEME_URL)),
Child, urlTextObject = TextObject,
TextFrame,
MUIA_Background, MUII_TextBack,
MUIA_Text_SetMin, TRUE,
MUIA_Text_Copy, FALSE,
End,
End,
End,
TAG_MORE, inittags(msg))) != NULL)
{
GETDATA;
data->NL_THEMELIST = themeListObject;
data->TX_THEMELABEL = themeTextObject;
data->GR_PREVIEW = imageGroupObject;
data->IM_PREVIEW = previewImageObject;
data->BT_ACTIVATE = activateButtonObject;
data->TX_AUTHOR = authorTextObject;
data->TX_URL = urlTextObject;
// set notifies
DoMethod(themeListObject, MUIM_Notify, MUIA_NList_SelectChange, TRUE, obj, 1, METHOD(SelectionChanged));
DoMethod(themeListObject, MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime, obj, 1, METHOD(ActivateTheme));
DoMethod(activateButtonObject, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, METHOD(ActivateTheme));
}
RETURN((IPTR)obj);
return (IPTR)obj;
}
///
/* Public Methods */
/// DECLARE(Update)
DECLARE(Update)
{
GETDATA;
BOOL result = FALSE;
APTR context;
ENTER();
// clear the NList
DoMethod(data->NL_THEMELIST, MUIM_NList_Clear);
// prepare for an ExamineDir()
if((context = ObtainDirContextTags(EX_StringName, (ULONG)G->ThemesDir,
EX_DataFields, EXF_TYPE|EXF_NAME,
TAG_DONE)) != NULL)
{
struct ExamineData *ed;
LONG error;
// iterate through the entries of the Themes directory
while((ed = ExamineDir(context)) != NULL)
{
// check that this entry is a drawer
// because we don't accept any file here
if(EXD_IS_DIRECTORY(ed))
{
struct Theme theme;
char filename[SIZE_PATHFILE];
D(DBF_CONFIG, "found dir '%s' in themes drawer", ed->Name);
// clear our temporary themes structure
memset(&theme, 0, sizeof(struct Theme));
// now we check whether this is a drawer which contains a
// ".theme" file which should be a sign that this is a YAM theme
AddPath(theme.directory, G->ThemesDir, ed->Name, sizeof(theme.directory));
AddPath(filename, theme.directory, ".theme", sizeof(filename));
// parse the .theme file to check wheter this
// is a valid theme or not.
if(ParseThemeFile(filename, &theme) > 0)
{
D(DBF_CONFIG, "found valid .theme file '%s'", filename);
// add the theme to our NList which in fact will allocate/free everything the
// ParseThemeFile() function did allocate previously.
DoMethod(data->NL_THEMELIST, MUIM_NList_InsertSingle, &theme, MUIV_NList_Insert_Sorted);
result = TRUE;
}
else
{
W(DBF_CONFIG, "couldn't parse .theme file '%s'", filename);
FreeTheme(&theme);
}
}
else
W(DBF_CONFIG, "unknown file '%s' in themes directory ignored", ed->Name);
}
error = IoErr();
if(error != 0 && error != ERROR_NO_MORE_ENTRIES)
E(DBF_CONFIG, "ExamineDir() failed, error %ld", error);
// now we have to check which item we should set active
if(xget(data->NL_THEMELIST, MUIA_NList_Entries) > 1)
{
// walk through our list and check if the theme is the currently
// active one, and if so we go and make it the currently selected one.
ULONG pos;
BOOL found = FALSE;
for(pos=0;;pos++)
{
struct Theme *theme = NULL;
DoMethod(data->NL_THEMELIST, MUIM_NList_GetEntry, pos, &theme);
if(theme == NULL)
break;
if(stricmp(FilePart(theme->directory), CE->ThemeName) == 0)
{
set(data->NL_THEMELIST, MUIA_NList_Active, pos);
found = TRUE;
break;
}
}
if(found == FALSE)
set(data->NL_THEMELIST, MUIA_NList_Active, MUIV_NList_Active_Top);
}
else
set(data->NL_THEMELIST, MUIA_NList_Active, MUIV_NList_Active_Top);
ReleaseDirContext(context);
}
else
E(DBF_CONFIG, "No themes directory found!");
RETURN(result);
return result;
}
///
/// DECLARE(SelectionChanged)
DECLARE(SelectionChanged)
{
GETDATA;
struct Theme *theme = NULL;
ENTER();
// get the currently selected entry
DoMethod(data->NL_THEMELIST, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &theme);
if(theme != NULL)
{
if(DoMethod(data->GR_PREVIEW, MUIM_Group_InitChange))
{
char filename[SIZE_PATHFILE];
AddPath(filename, theme->directory, "preview", sizeof(filename));
// set the new attributes, the old image will be deleted from the cache
xset(data->IM_PREVIEW, MUIA_ImageArea_ID, filename,
MUIA_ImageArea_Filename, filename);
// and force a cleanup/setup pair
DoMethod(data->GR_PREVIEW, OM_REMMEMBER, data->IM_PREVIEW);
DoMethod(data->GR_PREVIEW, OM_ADDMEMBER, data->IM_PREVIEW);
DoMethod(data->GR_PREVIEW, MUIM_Group_ExitChange);
}
snprintf(data->themeName, sizeof(data->themeName), "%s - %s", theme->name, theme->version);
set(data->TX_THEMELABEL, MUIA_Text_Contents, data->themeName);
set(data->TX_AUTHOR, MUIA_Text_Contents, theme->author);
set(data->TX_URL, MUIA_Text_Contents, theme->url);
}
RETURN(0);
return 0;
}
///
/// DECLARE(ActivateTheme)
DECLARE(ActivateTheme)
{
GETDATA;
struct Theme *theme = NULL;
ENTER();
// get the currently selected entry
DoMethod(data->NL_THEMELIST, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &theme);
if(theme != NULL)
{
const char *themeName = FilePart(theme->directory);
// check that this theme isn't already the
// active one.
if(stricmp(themeName, CE->ThemeName) != 0)
{
// now we activate the theme and we warn the user about
// the fact that a restart is required for the new theme to
// be activated.
strlcpy(CE->ThemeName, themeName, sizeof(CE->ThemeName));
// redraw the NList.
DoMethod(data->NL_THEMELIST, MUIM_NList_Redraw, MUIV_NList_Redraw_All);
// remind the users to save the configuration and
// restart yam.
MUI_Request(_app(obj), _win(obj), MUIF_NONE, tr(MSG_ER_THEME_ACTIVATED_TITLE),
tr(MSG_OkayReq),
tr(MSG_ER_THEME_ACTIVATED));
}
else
W(DBF_THEME, "theme '%s' is already the currently active one!", themeName);
}
RETURN(0);
return 0;
}
///