0218951158
Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
380 lines
8.8 KiB
C
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;
|
|
}
|