emu48plus-mirror/source/MRU.C

336 lines
7.6 KiB
C
Raw Normal View History

/*
* mru.c
*
* This file is part of Emu48
*
* Copyright (C) 2007 Christoph Gie<EFBFBD>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 INT nEntry = 0; // no. of MRU entries
static HMENU hMruMenu = NULL; // menu handle for MRU list
static INT nMruPos; // insert position for MRU list
static BOOL GetMenuPosForId(HMENU hMenu, UINT nItem)
{
HMENU hSubMenu;
UINT nID;
INT i,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))
return TRUE;
}
continue;
}
if (nID == nItem) // found ID
{
hMruMenu = hMenu; // remember menu and position
nMruPos = i;
return TRUE;
}
}
return FALSE;
}
BOOL MruInit(INT nNum)
{
HMENU hMenu = GetMenu(hWnd); // main menu
_ASSERT(ppszFiles == NULL); // MRU already initialized
if (*szOriginal == 0) // get orginal value of first MRU entry
{
VERIFY(GetMenuString(hMenu,ID_FILE_MRU_FILE1,szOriginal,ARRAYSIZEOF(szOriginal),MF_BYCOMMAND));
}
// no. of files in MRU list
nEntry = ReadSettingsInt(_T("MRU"),_T("FileCount"),nNum);
// look for menu position of ID_FILE_MRU_FILE1
VERIFY(GetMenuPosForId(hMenu,ID_FILE_MRU_FILE1));
if (nEntry > 0) // allocate MRU table
{
// create MRU table
if ((ppszFiles = HeapAlloc(hHeap,0,nEntry * sizeof(*ppszFiles))) == NULL)
return TRUE;
// fill each entry
for (nNum = 0; nNum < nEntry; ++nNum)
ppszFiles[nNum] = NULL;
MruReadList(); // read actual MRU list
MruUpdateMenu(); // update menu
}
else // kill MRU menu entries
{
// delete MRU menu
DeleteMenu(hMruMenu,nMruPos,MF_BYPOSITION);
// delete following separator
_ASSERT((GetMenuState(hMruMenu,nMruPos,MF_BYPOSITION) & MF_SEPARATOR) != 0);
DeleteMenu(hMruMenu,nMruPos,MF_BYPOSITION);
}
return FALSE;
}
VOID MruCleanup(VOID)
{
INT i;
MruWriteList(); // write actual MRU list
for (i = 0; i < nEntry; ++i) // cleanup each entry
{
if (ppszFiles[i] != NULL)
HeapFree(hHeap,0,ppszFiles[i]); // cleanup entry
}
if (ppszFiles != NULL) // table defined
{
HeapFree(hHeap,0,ppszFiles); // free table
ppszFiles = NULL;
}
return;
}
VOID MruAdd(LPCTSTR lpszEntry)
{
TCHAR szFilename[MAX_PATH];
LPTSTR lpFilePart;
INT i;
if (nEntry == 0) return; // no 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
&& lstrcmpi(ppszFiles[i],szFilename) == 0)
{
MruMoveTop(i); // move to top and update menu
return;
}
}
i = nEntry - 1; // last index
if (ppszFiles[i] != NULL)
HeapFree(hHeap,0,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);
MruUpdateMenu(); // update menu
return;
}
VOID MruRemove(INT nIndex)
{
HeapFree(hHeap,0,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
MruUpdateMenu(); // update menu
return;
}
VOID MruMoveTop(INT nIndex)
{
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
MruUpdateMenu(); // update menu
return;
}
INT MruEntries(VOID)
{
return nEntry;
}
LPCTSTR MruFilename(INT nIndex)
{
_ASSERT(ppszFiles != NULL); // MRU not initialized
_ASSERT(nIndex >= 0 && nIndex < nEntry); // inside range
return ppszFiles[nIndex];
}
VOID MruUpdateMenu(VOID)
{
TCHAR szCurPath[MAX_PATH];
HANDLE hMenu;
BOOL bEmpty;
INT i;
if (nEntry == 0) return; // no entries
_ASSERT(ppszFiles != NULL); // MRU not initialized
_ASSERT(hWnd != NULL);
VERIFY(hMenu = GetMenu(hWnd)); // main menu
bEmpty = TRUE; // MRU list empty
for (i = 0; i < nEntry; ++i) // delete all menu entries
{
DeleteMenu(hMenu,ID_FILE_MRU_FILE1+i,MF_BYCOMMAND);
if (ppszFiles[i] != NULL) // valid entry
bEmpty = FALSE; // MRU list not empty
}
if (bEmpty) // empty MRU list
{
// 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;
lpszPtr = szMenuname; // adding accelerator key
*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];
INT i;
// 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)
{
WriteSettingsString(_T("MRU"),szItemname,ppszFiles[i]);
}
else
{
DelSettingsKey(_T("MRU"),szItemname);
}
}
return;
}
VOID MruReadList(VOID)
{
TCHAR szFilename[MAX_PATH];
TCHAR szItemname[32];
LPTSTR lpszValue;
INT i;
_ASSERT(ppszFiles != NULL); // MRU not initialized
for (i = 0; i < nEntry; ++i) // add menu entries
{
wsprintf(szItemname,_T("File%d"),i+1);
ReadSettingsString(_T("MRU"),szItemname,_T(""),szFilename,ARRAYSIZEOF(szFilename));
if (ppszFiles[i] != NULL) // already filled
{
HeapFree(hHeap,0,ppszFiles[i]); // free entry
ppszFiles[i] = NULL; // clear last line
lpszValue = _T("");
}
if (*szFilename) // read a valid entry
{
ppszFiles[i] = DuplicateString(szFilename);
}
}
return;
}