emu48-mirror/Sources/Emu48/MRU.C
Gwenhael Le Moine 04a295b23d
2022-07-31: Updated to version 1.65
Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
2024-03-20 08:15:25 +01:00

380 lines
8.8 KiB
C

/*
* mru.c
*
* This file is part of Emu48
*
* Copyright (C) 2007 Christoph Gießelink
*
*/
#include "pch.h"
#include "resource.h"
#include "Emu48.h"
static TCHAR szOriginal[MAX_PATH] = _T("");
static LPTSTR *ppszFiles = NULL; // pointer to MRU table
static UINT nEntry = 0; // no. of MRU entries
static BOOL GetMenuPosForId(HMENU hMenu, UINT nItem, HMENU *phMruMenu, UINT *pnMruPos)
{
HMENU hSubMenu;
UINT i,nID,nMaxID;
nMaxID = GetMenuItemCount(hMenu);
for (i = 0; i < nMaxID; ++i)
{
nID = GetMenuItemID(hMenu,i); // get ID
if (nID == 0) continue; // separator or invalid command
if (nID == (UINT)-1) // possibly a popup menu
{
hSubMenu = GetSubMenu(hMenu,i); // try to get handle to popup menu
if (hSubMenu != NULL) // it's a popup menu
{
// recursive search
if (GetMenuPosForId(hSubMenu,nItem,phMruMenu,pnMruPos))
return TRUE;
}
continue;
}
if (nID == nItem) // found ID
{
*phMruMenu = hMenu; // remember menu and position
*pnMruPos = i;
return TRUE;
}
}
return FALSE;
}
BOOL MruInit(UINT nNum)
{
HMENU hMenu = GetMenu(hWnd); // main menu
if (hMenu == NULL) return FALSE; // failed, no menu bar
_ASSERT(ppszFiles == NULL); // MRU already initialized
// no. of files in MRU list
nEntry = ReadSettingsInt(_T("MRU"),_T("FileCount"),nNum);
if (nEntry > 0) // allocate MRU table
{
// create MRU table
if ((ppszFiles = (LPTSTR *) malloc(nEntry * sizeof(*ppszFiles))) == NULL)
return FALSE;
// fill each entry
for (nNum = 0; nNum < nEntry; ++nNum)
ppszFiles[nNum] = NULL;
MruReadList(); // read actual MRU list
}
return TRUE;
}
VOID MruCleanup(VOID)
{
UINT i;
MruWriteList(); // write actual MRU list
if (ppszFiles != NULL) // table defined
{
for (i = 0; i < nEntry; ++i) // cleanup each entry
{
if (ppszFiles[i] != NULL) // valid entry
free(ppszFiles[i]); // cleanup entry
}
free(ppszFiles); // free table
ppszFiles = NULL;
}
return;
}
VOID MruAdd(LPCTSTR lpszEntry)
{
TCHAR szFilename[MAX_PATH];
LPTSTR lpFilePart;
UINT i;
if (ppszFiles != NULL) // MRU initialized
{
_ASSERT(nEntry > 0); // must have entries
// get full path name
GetFullPathName(lpszEntry,ARRAYSIZEOF(szFilename),szFilename,&lpFilePart);
// look if entry is already in table
for (i = 0; i < nEntry; ++i)
{
// already in table -> quit
if ( ppszFiles[i] != NULL // valid entry
&& lstrcmpi(ppszFiles[i],szFilename) == 0)
{
MruMoveTop(i); // move to top and update menu
return;
}
}
i = nEntry - 1; // last index
if (ppszFiles[i] != NULL) // valid entry
free(ppszFiles[i]); // free oldest entry
for (; i > 0; --i) // move old entries 1 line down
{
ppszFiles[i] = ppszFiles[i-1];
}
// add new entry to top
ppszFiles[0] = DuplicateString(szFilename);
}
return;
}
VOID MruRemove(UINT nIndex)
{
// MRU initialized and index inside valid range
if (ppszFiles != NULL && nIndex < nEntry)
{
free(ppszFiles[nIndex]); // free entry
for (; nIndex < nEntry - 1; ++nIndex) // move below entries 1 line up
{
ppszFiles[nIndex] = ppszFiles[nIndex+1];
}
ppszFiles[nIndex] = NULL; // clear last line
}
return;
}
VOID MruMoveTop(UINT nIndex)
{
// MRU initialized and index inside valid range
if (ppszFiles != NULL && nIndex < nEntry)
{
LPTSTR lpszEntry = ppszFiles[nIndex];// remember selected entry
for (; nIndex > 0; --nIndex) // move above entries 1 line down
{
ppszFiles[nIndex] = ppszFiles[nIndex-1];
}
ppszFiles[0] = lpszEntry; // insert entry on top
}
return;
}
UINT MruEntries(VOID)
{
return nEntry;
}
UINT MruID(LPCTSTR lpszEntry)
{
TCHAR szFilename[MAX_PATH];
LPTSTR lpFilePart;
UINT i;
if (ppszFiles != NULL) // MRU initialized
{
_ASSERT(nEntry > 0); // must have entries
// get full path name
GetFullPathName(lpszEntry,ARRAYSIZEOF(szFilename),szFilename,&lpFilePart);
// look if entry is already in table
for (i = 0; i < nEntry; ++i)
{
if ( ppszFiles[i] != NULL // valid entry
&& lstrcmpi(ppszFiles[i],szFilename) == 0)
{
return i; // return ID
}
}
}
return (UINT) -1; // not found
}
VOID MruFilename(UINT nIndex, LPTSTR szFilename, UINT nBuffersize)
{
*szFilename = 0; // not found
// MRU initialized and index inside valid range
if (ppszFiles != NULL && nIndex < nEntry)
{
_ASSERT(ppszFiles[nIndex] != NULL); // valid entry
lstrcpyn(szFilename,ppszFiles[nIndex],nBuffersize);
}
return;
}
VOID MruUpdateMenu(HMENU hMenu)
{
TCHAR szCurPath[MAX_PATH];
BOOL bEmpty;
UINT i;
if (hMenu != NULL) // have menu
{
HMENU hMruMenu; // menu handle for MRU list
UINT nMruPos; // insert position for MRU list
_ASSERT(IsMenu(hMenu)); // validate menu handle
// search for menu position of ID_FILE_MRU_FILE1
if (GetMenuPosForId(hMenu,ID_FILE_MRU_FILE1,&hMruMenu,&nMruPos))
{
if (*szOriginal == 0) // get orginal value of first MRU entry
{
VERIFY(GetMenuString(hMruMenu,nMruPos,szOriginal,ARRAYSIZEOF(szOriginal),MF_BYPOSITION));
}
if (nEntry == 0) // kill MRU menu entry
{
// delete MRU menu
DeleteMenu(hMruMenu,nMruPos,MF_BYPOSITION);
// delete the following separator
_ASSERT((GetMenuState(hMruMenu,nMruPos,MF_BYPOSITION) & MF_SEPARATOR) != 0);
DeleteMenu(hMruMenu,nMruPos,MF_BYPOSITION);
}
if (ppszFiles != NULL) // MRU initialized
{
_ASSERT(nEntry > 0); // must have entries
// delete all menu entries
for (i = 0; DeleteMenu(hMenu,ID_FILE_MRU_FILE1+i,MF_BYCOMMAND) != FALSE; ++i) { }
// check if MRU list is empty
for (bEmpty = TRUE, i = 0; bEmpty && i < nEntry; ++i)
{
bEmpty = (ppszFiles[i] == NULL);
}
if (bEmpty) // MRU list is empty
{
// fill with orginal string
VERIFY(InsertMenu(hMruMenu,nMruPos,MF_STRING|MF_BYPOSITION|MF_GRAYED,ID_FILE_MRU_FILE1,szOriginal));
return;
}
// current directory
GetCurrentDirectory(ARRAYSIZEOF(szCurPath),szCurPath);
for (i = 0; i < nEntry; ++i) // add menu entries
{
if (ppszFiles[i] != NULL) // valid entry
{
TCHAR szMenuname[2*MAX_PATH+3];
TCHAR szFilename[MAX_PATH];
LPTSTR lpFilePart,lpszPtr;
// check if file path and current path is identical
if (GetFullPathName(ppszFiles[i],ARRAYSIZEOF(szFilename),szFilename,&lpFilePart))
{
TCHAR szCutname[MAX_PATH];
*(lpFilePart-1) = 0; // devide path and name
// name is current directory -> use only name
if (lstrcmpi(szCurPath,szFilename) == 0)
{
// short name view
}
else
{
// full name view
lpFilePart = ppszFiles[i];
}
// cut filename to fit into menu
GetCutPathName(lpFilePart,szCutname,ARRAYSIZEOF(szCutname),36);
lpFilePart = szCutname;
// adding accelerator key
lpszPtr = szMenuname;
*lpszPtr++ = _T('&');
*lpszPtr++ = _T('0') + ((i + 1) % 10);
*lpszPtr++ = _T(' ');
// copy file to view buffer and expand & to &&
while (*lpFilePart != 0)
{
if (*lpFilePart == _T('&'))
{
*lpszPtr++ = *lpFilePart;
}
*lpszPtr++ = *lpFilePart++;
}
*lpszPtr = 0;
VERIFY(InsertMenu(hMruMenu,nMruPos+i,
MF_STRING|MF_BYPOSITION,ID_FILE_MRU_FILE1+i,
szMenuname));
}
}
}
}
}
}
return;
}
VOID MruWriteList(VOID)
{
TCHAR szItemname[32];
UINT i;
if (nEntry > 0)
{
// no. of files in MRU list
WriteSettingsInt(_T("MRU"),_T("FileCount"),nEntry);
for (i = 0; i < nEntry; ++i) // add menu entries
{
_ASSERT(ppszFiles != NULL); // MRU not initialized
wsprintf(szItemname,_T("File%d"),i+1);
if (ppszFiles[i] != NULL) // valid entry
{
WriteSettingsString(_T("MRU"),szItemname,ppszFiles[i]);
}
else
{
DelSettingsKey(_T("MRU"),szItemname);
}
}
}
return;
}
VOID MruReadList(VOID)
{
TCHAR szFilename[MAX_PATH];
TCHAR szItemname[32];
UINT i;
for (i = 0; i < nEntry; ++i) // add menu entries
{
_ASSERT(ppszFiles != NULL); // MRU not initialized
wsprintf(szItemname,_T("File%d"),i+1);
ReadSettingsString(_T("MRU"),szItemname,_T(""),szFilename,ARRAYSIZEOF(szFilename));
if (ppszFiles[i] != NULL) // valid entry
{
free(ppszFiles[i]); // free entry
ppszFiles[i] = NULL; // clear last line
}
if (*szFilename) // read a valid entry
{
ppszFiles[i] = DuplicateString(szFilename);
}
}
return;
}