]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/extra/qe4/mru.c
Q2Tools source - didn't import this in initially
[xonotic/netradiant.git] / tools / quake2 / extra / qe4 / mru.c
1 /*
2 ===========================================================================
3 Copyright (C) 1997-2006 Id Software, Inc.
4
5 This file is part of Quake 2 Tools source code.
6
7 Quake 2 Tools source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake 2 Tools source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Quake 2 Tools source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 ===========================================================================
21 */
22
23 //*************************************************************
24 //  File name: mru.c
25 //
26 //  Description:
27 //
28 //      Routines for MRU support
29 //
30 //  Development Team:
31 //
32 //      Gilles Vollant (100144.2636@compuserve.com)
33 //
34 //*************************************************************
35
36 #include <windows.h>
37 #include <windowsx.h>
38 #include <string.h>
39
40 #include "mru.h"
41 // CreateMruMenu  : MRUMENU constructor
42 // wNbLruShowInit : nb of item showed in menu
43 // wNbLruMenuInit : nb of item stored in memory
44 // wMaxSizeLruItemInit : size max. of filename
45
46
47 //*************************************************************
48 //
49 //  CreateMruMenu()
50 //
51 //  Purpose:
52 //
53 //              Allocate and Initialize an MRU and return a pointer on it
54 //
55 //
56 //  Parameters:
57 //
58 //      WORD wNbLruShowInit -      Maximum number of item displayed on menu
59 //      WORD wNbLruMenuInit -      Maximum number of item stored in memory
60 //      WORD wMaxSizeLruItemInit - Maximum size of an item (ie size of pathname)
61 //      WORD wIdMruInit -          ID of the first item in the menu (default:IDMRU)
62 //
63 //
64 //  Return: (LPMRUMENU)
65 //
66 //      Pointer on a MRUMENU structure, used by other function
67 //
68 //
69 //  Comments:
70 //      wNbLruShowInit <= wNbLruMenuInit
71 //
72 //
73 //  History:    Date       Author       Comment
74 //              09/24/94   G. Vollant   Created
75 //
76 //*************************************************************
77
78 LPMRUMENU CreateMruMenu (WORD wNbLruShowInit,
79             WORD wNbLruMenuInit,WORD wMaxSizeLruItemInit,WORD wIdMruInit)
80 {
81 LPMRUMENU lpMruMenu;
82   lpMruMenu = (LPMRUMENU)GlobalAllocPtr(GHND,sizeof(MRUMENU));
83
84   lpMruMenu->wNbItemFill = 0;
85   lpMruMenu->wNbLruMenu = wNbLruMenuInit;
86   lpMruMenu->wNbLruShow = wNbLruShowInit;
87   lpMruMenu->wIdMru = wIdMruInit;
88   lpMruMenu->wMaxSizeLruItem = wMaxSizeLruItemInit;
89   lpMruMenu->lpMRU = (LPSTR)GlobalAllocPtr(GHND,
90                       lpMruMenu->wNbLruMenu*(UINT)lpMruMenu->wMaxSizeLruItem);
91   if (lpMruMenu->lpMRU == NULL)
92      {
93        GlobalFreePtr(lpMruMenu);
94        lpMruMenu =  NULL;
95      }
96   return lpMruMenu;
97 }
98
99 //*************************************************************
100 //
101 //  CreateMruMenuDefault()
102 //
103 //  Purpose:
104 //
105 //              Allocate and Initialize an MRU and return a pointer on it
106 //              Use default parameter
107 //
108 //
109 //  Parameters:
110 //
111 //
112 //  Return: (LPMRUMENU)
113 //
114 //      Pointer on a MRUMENU structure, used by other function
115 //
116 //
117 //  Comments:
118 //
119 //
120 //  History:    Date       Author       Comment
121 //              09/24/94   G. Vollant   Created
122 //
123 //*************************************************************
124
125 LPMRUMENU CreateMruMenuDefault()
126 {
127   return CreateMruMenu (NBMRUMENUSHOW,NBMRUMENU,MAXSIZEMRUITEM,IDMRU);
128 }
129
130
131 //*************************************************************
132 //
133 //  DeleteMruMenu()
134 //
135 //  Purpose:
136 //              Destructor :
137 //              Clean and free a MRUMENU structure
138 //
139 //  Parameters:
140 //
141 //      LPMRUMENU lpMruMenu -      pointer on MRUMENU, allocated
142 //             by CreateMruMenu() or CreateMruMenuDefault()
143 //
144 //
145 //  Return: void
146 //
147 //
148 //  Comments:
149 //
150 //
151 //  History:    Date       Author       Comment
152 //              09/24/94   G. Vollant   Created
153 //
154 //*************************************************************
155 void DeleteMruMenu(LPMRUMENU lpMruMenu)
156 {
157   GlobalFreePtr(lpMruMenu->lpMRU);
158   GlobalFreePtr(lpMruMenu);
159 }
160
161 //*************************************************************
162 //
163 //  SetNbLruShow()
164 //
165 //  Purpose:
166 //              Change the maximum number of item displayed on menu
167 //
168 //  Parameters:
169 //      LPMRUMENU lpMruMenu -      pointer on MRUMENU
170 //      WORD wNbLruShowInit -      Maximum number of item displayed on menu
171 //
172 //
173 //  Return: void
174 //
175 //
176 //  Comments:
177 //
178 //
179 //  History:    Date       Author       Comment
180 //              09/24/94   G. Vollant   Created
181 //
182 //*************************************************************
183 void SetNbLruShow   (LPMRUMENU lpMruMenu,WORD wNbLruShowInit)
184 {
185   lpMruMenu->wNbLruShow = min(wNbLruShowInit,lpMruMenu->wNbLruMenu);
186 }
187
188 //*************************************************************
189 //
190 //  SetMenuItem()
191 //
192 //  Purpose:
193 //              Set the filename of an item
194 //
195 //  Parameters:
196 //      LPMRUMENU lpMruMenu -      pointer on MRUMENU
197 //      WORD wItem -               Number of Item to set, zero based
198 //      LPSTR lpItem -             String, contain the filename of the item
199 //
200 //
201 //  Return: (BOOL)
202 //      TRUE  - Function run successfully
203 //      FALSE - Function don't run successfully
204 //
205 //
206 //  Comments:
207 //      used when load .INI or reg database
208 //
209 //  History:    Date       Author       Comment
210 //              09/24/94   G. Vollant   Created
211 //
212 //*************************************************************
213 BOOL SetMenuItem    (LPMRUMENU lpMruMenu,WORD wItem,LPSTR lpItem)
214 {
215   if (wItem >= NBMRUMENU)
216     return FALSE;
217   _fstrncpy((lpMruMenu->lpMRU) +
218             ((lpMruMenu->wMaxSizeLruItem) * (UINT)wItem),
219             lpItem,lpMruMenu->wMaxSizeLruItem-1);
220   lpMruMenu->wNbItemFill = max(lpMruMenu->wNbItemFill,wItem+1);
221   return TRUE;
222 }
223
224 //*************************************************************
225 //
226 //  GetMenuItem()
227 //
228 //  Purpose:
229 //              Get the filename of an item
230 //
231 //  Parameters:
232 //      LPMRUMENU lpMruMenu -      pointer on MRUMENU
233 //      WORD wItem -               Number of Item to set, zero based
234 //      BOOL fIDMBased -           TRUE :  wItem is based on ID menu item
235 //                                 FALSE : wItem is zero-based
236 //      LPSTR lpItem -             String where the filename of the item will be
237 //                                   stored by GetMenuItem()
238 //      UINT  uiSize -             Size of the lpItem buffer
239 //
240 //
241 //  Return: (BOOL)
242 //      TRUE  - Function run successfully
243 //      FALSE - Function don't run successfully
244 //
245 //
246 //  Comments:
247 //      Used for saving in .INI or reg database, or when user select
248 //        an MRU in File menu
249 //
250 //  History:    Date       Author       Comment
251 //              09/24/94   G. Vollant   Created
252 //
253 //*************************************************************
254 BOOL GetMenuItem    (LPMRUMENU lpMruMenu,WORD wItem,
255                      BOOL fIDMBased,LPSTR lpItem,UINT uiSize)
256 {
257   if (fIDMBased)
258     wItem -= (lpMruMenu->wIdMru + 1);
259   if (wItem >= lpMruMenu->wNbItemFill)
260     return FALSE;
261   _fstrncpy(lpItem,(lpMruMenu->lpMRU) +
262                 ((lpMruMenu->wMaxSizeLruItem) * (UINT)(wItem)),uiSize);
263   *(lpItem+uiSize-1) = '\0';
264   return TRUE;
265 }
266
267 //*************************************************************
268 //
269 //  AddNewItem()
270 //
271 //  Purpose:
272 //              Add an item at the begin of the list
273 //
274 //  Parameters:
275 //      LPMRUMENU lpMruMenu -      pointer on MRUMENU
276 //      LPSTR lpItem -             String contain the filename to add
277 //
278 //  Return: (BOOL)
279 //      TRUE  - Function run successfully
280 //      FALSE - Function don't run successfully
281 //
282 //
283 //  Comments:
284 //      Used when used open a file (using File Open common
285 //        dialog, Drag and drop or MRU)
286 //
287 //  History:    Date       Author       Comment
288 //              09/24/94   G. Vollant   Created
289 //
290 //*************************************************************
291 void AddNewItem     (LPMRUMENU lpMruMenu,LPSTR lpItem)
292 {
293 WORD i,j;
294   for (i=0;i<lpMruMenu->wNbItemFill;i++)
295     if (lstrcmpi(lpItem,(lpMruMenu->lpMRU) +
296         ((lpMruMenu->wMaxSizeLruItem) * (UINT)i)) == 0)
297       {
298         // Shift the other items
299         for (j=i;j>0;j--)
300          lstrcpy((lpMruMenu->lpMRU) + (lpMruMenu->wMaxSizeLruItem * (UINT)j),
301                  (lpMruMenu->lpMRU) + (lpMruMenu->wMaxSizeLruItem * (UINT)(j-1)));
302         _fstrncpy(lpMruMenu->lpMRU,lpItem,lpMruMenu->wMaxSizeLruItem-1);
303         return ;
304       }
305   lpMruMenu->wNbItemFill = min(lpMruMenu->wNbItemFill+1,lpMruMenu->wNbLruMenu);
306   for (i=lpMruMenu->wNbItemFill-1;i>0;i--)
307      lstrcpy(lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)i),
308              lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)(i-1)));
309   _fstrncpy(lpMruMenu->lpMRU,lpItem,lpMruMenu->wMaxSizeLruItem-1);
310 }
311
312 //*************************************************************
313 //
314 //  DelMenuItem()
315 //
316 //  Purpose:
317 //              Delete an item
318 //
319 //  Parameters:
320 //      LPMRUMENU lpMruMenu -      pointer on MRUMENU
321 //      WORD wItem -               Number of Item to set, zero based
322 //      BOOL fIDMBased -           TRUE :  wItem is based on ID menu item
323 //                                 FALSE : wItem is zero-based
324 //
325 //  Return: (BOOL)
326 //      TRUE  - Function run successfully
327 //      FALSE - Function don't run successfully
328 //
329 //
330 //  Comments:
331 //      Used when used open a file, using MRU, and when an error
332 //         occured (by example, when file was deleted)
333 //
334 //  History:    Date       Author       Comment
335 //              09/24/94   G. Vollant   Created
336 //
337 //*************************************************************
338 BOOL DelMenuItem(LPMRUMENU lpMruMenu,WORD wItem,BOOL fIDMBased)
339 {
340 WORD i;
341   if (fIDMBased)
342     wItem -= (lpMruMenu->wIdMru + 1);
343   if (lpMruMenu->wNbItemFill <= wItem)
344     return FALSE;
345   lpMruMenu->wNbItemFill--;
346   for (i=wItem;i<lpMruMenu->wNbItemFill;i++)
347      lstrcpy(lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)i),
348              lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)(i+1)));
349   return TRUE;
350 }
351
352 //*************************************************************
353 //
354 //  PlaceMenuMRUItem()
355 //
356 //  Purpose:
357 //              Add MRU at the end of a menu
358 //
359 //  Parameters:
360 //      LPMRUMENU lpMruMenu -      pointer on MRUMENU
361 //      HMENU hMenu -              Handle of menu where MRU must be added
362 //      UINT uiItem -              Item of menu entry where MRU must be added
363 //
364 //  Return: void
365 //
366 //
367 //  Comments:
368 //      Used MRU is modified, for refresh the File menu
369 //
370 //  History:    Date       Author       Comment
371 //              09/24/94   G. Vollant   Created
372 //
373 //*************************************************************
374 void PlaceMenuMRUItem(LPMRUMENU lpMruMenu,HMENU hMenu,UINT uiItem)
375 {
376 int  i;
377 WORD wNbShow;
378   if (hMenu == NULL)
379     return;
380   // remove old MRU in menu
381   for (i=0;i<=(int)(lpMruMenu->wNbLruMenu);i++)
382     RemoveMenu(hMenu,i+lpMruMenu->wIdMru,MF_BYCOMMAND);
383
384   if (lpMruMenu->wNbItemFill == 0)
385     return;
386
387   // If they are item, insert a separator before the files
388   InsertMenu(hMenu,uiItem,MF_SEPARATOR,lpMruMenu->wIdMru,NULL);
389
390   wNbShow = min(lpMruMenu->wNbItemFill,lpMruMenu->wNbLruShow);
391   for (i=(int)wNbShow-1;i>=0;i--)
392   {
393   LPSTR lpTxt;
394     if (lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20))
395       {
396         wsprintf(lpTxt,"&%lu %s",
397                  (DWORD)(i+1),lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem*(UINT)i));
398         InsertMenu(hMenu,(((WORD)i)!=(wNbShow-1)) ? (lpMruMenu->wIdMru+i+2) : lpMruMenu->wIdMru,
399                    MF_STRING,lpMruMenu->wIdMru+i+1,lpTxt);
400         GlobalFreePtr(lpTxt);
401       }
402   }
403
404 }
405
406 ///////////////////////////////////////////
407
408
409
410 //*************************************************************
411 //
412 //  SaveMruInIni()
413 //
414 //  Purpose:
415 //              Save MRU in a private .INI
416 //
417 //  Parameters:
418 //      LPMRUMENU lpMruMenu -      pointer on MRUMENU
419 //      LPSTR lpszSection  -       Points to a null-terminated string containing
420 //                                      the name of the section
421 //      LPSTR lpszFile -           Points to a null-terminated string that names
422 //                                      the initialization file.
423 //
424 //  Return: (BOOL)
425 //      TRUE  - Function run successfully
426 //      FALSE - Function don't run successfully
427 //
428 //
429 //  Comments:
430 //      See WritePrivateProfileString API for more info on lpszSection and lpszFile
431 //
432 //  History:    Date       Author       Comment
433 //              09/24/94   G. Vollant   Created
434 //
435 //*************************************************************
436 BOOL SaveMruInIni(LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile)
437 {
438 LPSTR lpTxt;
439 WORD i;
440
441   lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
442   if (lpTxt == NULL)
443     return FALSE;
444
445   for (i=0;i<lpMruMenu->wNbLruMenu;i++)
446     {
447     char szEntry[16];
448       wsprintf(szEntry,"File%lu",(DWORD)i+1);
449       if (!GetMenuItem(lpMruMenu,i,FALSE,lpTxt,lpMruMenu->wMaxSizeLruItem + 10))
450         *lpTxt = '\0';
451       WritePrivateProfileString(lpszSection,szEntry,lpTxt,lpszFile);
452     }
453   GlobalFreePtr(lpTxt);
454   WritePrivateProfileString(NULL,NULL,NULL,lpszFile); // flush cache
455   return TRUE;
456 }
457
458
459 //*************************************************************
460 //
461 //  LoadMruInIni()
462 //
463 //  Purpose:
464 //              Load MRU from a private .INI
465 //
466 //  Parameters:
467 //      LPMRUMENU lpMruMenu -      pointer on MRUMENU
468 //      LPSTR lpszSection  -       Points to a null-terminated string containing
469 //                                      the name of the section
470 //      LPSTR lpszFile -           Points to a null-terminated string that names
471 //                                      the initialization file.
472 //
473 //  Return: (BOOL)
474 //      TRUE  - Function run successfully
475 //      FALSE - Function don't run successfully
476 //
477 //
478 //  Comments:
479 //      See GetPrivateProfileString API for more info on lpszSection and lpszFile
480 //
481 //  History:    Date       Author       Comment
482 //              09/24/94   G. Vollant   Created
483 //
484 //*************************************************************
485 BOOL LoadMruInIni(LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile)
486 {
487 LPSTR lpTxt;
488 WORD i;
489   lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
490   if (lpTxt == NULL)
491     return FALSE;
492
493   for (i=0;i<lpMruMenu->wNbLruMenu;i++)
494     {
495     char szEntry[16];
496
497       wsprintf(szEntry,"File%lu",(DWORD)i+1);
498       GetPrivateProfileString(lpszSection,szEntry,"",lpTxt,
499                               lpMruMenu->wMaxSizeLruItem + 10,lpszFile);
500       if (*lpTxt == '\0')
501         break;
502       SetMenuItem(lpMruMenu,i,lpTxt);
503     }
504   GlobalFreePtr(lpTxt);
505   return TRUE;
506 }
507
508 #ifdef WIN32
509
510 BOOL IsWin395OrHigher(void)
511 {
512   WORD wVer;
513
514   wVer = LOWORD(GetVersion());
515   wVer = (((WORD)LOBYTE(wVer)) << 8) | (WORD)HIBYTE(wVer);
516
517   return (wVer >= 0x035F);              // 5F = 95 dec
518 }
519
520
521 //*************************************************************
522 //
523 //  SaveMruInReg()
524 //
525 //  Purpose:
526 //              Save MRU in the registry
527 //
528 //  Parameters:
529 //      LPMRUMENU lpMruMenu -      pointer on MRUMENU
530 //      LPSTR lpszKey  -           Points to a null-terminated string
531 //                                      specifying  the name of a key that
532 //                                      this function opens or creates.
533 //
534 //  Return: (BOOL)
535 //      TRUE  - Function run successfully
536 //      FALSE - Function don't run successfully
537 //
538 //
539 //  Comments:
540 //      Win32 function designed for Windows NT and Windows 95
541 //      See RegCreateKeyEx API for more info on lpszKey
542 //
543 //  History:    Date       Author       Comment
544 //              09/24/94   G. Vollant   Created
545 //
546 //*************************************************************
547 BOOL SaveMruInReg(LPMRUMENU lpMruMenu,LPSTR lpszKey)
548 {
549 LPSTR lpTxt;
550 WORD i;
551 HKEY hCurKey;
552 DWORD dwDisp;
553
554   lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
555   if (lpTxt == NULL)
556     return FALSE;
557
558   RegCreateKeyEx(HKEY_CURRENT_USER,lpszKey,0,NULL,
559                   REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hCurKey,&dwDisp);
560
561   for (i=0;i<lpMruMenu->wNbLruMenu;i++)
562     {
563     char szEntry[16];
564       wsprintf(szEntry,"File%lu",(DWORD)i+1);
565       if (!GetMenuItem(lpMruMenu,i,FALSE,lpTxt,lpMruMenu->wMaxSizeLruItem + 10))
566         *lpTxt = '\0';
567       RegSetValueEx(hCurKey,szEntry,0,REG_SZ,lpTxt,lstrlen(lpTxt));
568     }
569   RegCloseKey(hCurKey);
570   GlobalFreePtr(lpTxt);
571   return TRUE;
572 }
573
574 //*************************************************************
575 //
576 //  LoadMruInReg()
577 //
578 //  Purpose:
579 //              Load MRU from the registry
580 //
581 //  Parameters:
582 //      LPMRUMENU lpMruMenu -      pointer on MRUMENU
583 //      LPSTR lpszKey  -           Points to a null-terminated string
584 //                                      specifying  the name of a key that
585 //                                      this function opens or creates.
586 //
587 //  Return: (BOOL)
588 //      TRUE  - Function run successfully
589 //      FALSE - Function don't run successfully
590 //
591 //
592 //  Comments:
593 //      Win32 function designed for Windows NT and Windows 95
594 //      See RegOpenKeyEx API for more info on lpszKey
595 //
596 //  History:    Date       Author       Comment
597 //              09/24/94   G. Vollant   Created
598 //
599 //*************************************************************
600 BOOL LoadMruInReg(LPMRUMENU lpMruMenu,LPSTR lpszKey)
601 {
602 LPSTR lpTxt;
603 WORD i;
604 HKEY hCurKey;
605 DWORD dwType;
606   lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
607   if (lpTxt == NULL)
608     return FALSE;
609
610   RegOpenKeyEx(HKEY_CURRENT_USER,lpszKey,0,KEY_READ,&hCurKey);
611
612
613   for (i=0;i<lpMruMenu->wNbLruMenu;i++)
614     {
615     char szEntry[16];
616     DWORD dwSizeBuf;
617       wsprintf(szEntry,"File%lu",(DWORD)i+1);
618       *lpTxt = '\0';
619       dwSizeBuf = lpMruMenu->wMaxSizeLruItem + 10;
620       RegQueryValueEx(hCurKey,szEntry,NULL,&dwType,(LPBYTE)lpTxt,&dwSizeBuf);
621       *(lpTxt+dwSizeBuf)='\0';
622       if (*lpTxt == '\0')
623         break;
624       SetMenuItem(lpMruMenu,i,lpTxt);
625     }
626   RegCloseKey(hCurKey);
627   GlobalFreePtr(lpTxt);
628   return TRUE;
629 }
630
631
632 //*************************************************************
633 //
634 //  GetWin32Kind()
635 //
636 //  Purpose:
637 //              Get the Win32 platform
638 //
639 //  Parameters:
640 //
641 //  Return: (WIN32KIND)
642 //      WINNT -           Run under Windows NT
643 //      WIN32S -          Run under Windows 3.1x + Win32s
644 //      WIN95ORGREATHER - Run under Windows 95
645 //
646 //
647 //  Comments:
648 //      Win32 function designed for Windows NT and Windows 95
649 //      See RegOpenKeyEx API for more info on lpszKey
650 //
651 //  History:    Date       Author       Comment
652 //              09/24/94   G. Vollant   Created
653 //
654 //*************************************************************
655 WIN32KIND GetWin32Kind()
656 {
657 BOOL IsWin395OrHigher(void);
658
659   WORD wVer;
660
661   if ((GetVersion() & 0x80000000) == 0)
662     return WINNT;
663   wVer = LOWORD(GetVersion());
664   wVer = (((WORD)LOBYTE(wVer)) << 8) | (WORD)HIBYTE(wVer);
665
666   if (wVer >= 0x035F)
667     return WIN95ORGREATHER;
668   else
669     return WIN32S;
670 }
671 #endif