2 * WineCfg app settings tabsheet
4 * Copyright 2004 Robert van Herk
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define NONAMELESSUNION
26 #include <wine/debug.h>
31 WINE_DEFAULT_DEBUG_CHANNEL(winecfg
);
37 char* lpcVersionSection
;
40 static LPAPPL
CreateAppl(BOOL isGlobal
, char* application
, char* version_section
)
43 WINE_TRACE("application: '%s', version_section: '%s'\n", application
, version_section
);
44 out
= HeapAlloc(GetProcessHeap(),0,sizeof(APPL
));
45 out
->lpcApplication
= strdup(application
);
46 out
->lpcVersionSection
= strdup(version_section
);
47 out
->isGlobal
= isGlobal
;
51 static VOID
FreeAppl(LPAPPL lpAppl
)
53 /* The strings were strdup-ped, so we use "free" */
54 if (lpAppl
->lpcApplication
) free(lpAppl
->lpcApplication
);
55 if (lpAppl
->lpcVersionSection
) free(lpAppl
->lpcVersionSection
);
56 HeapFree(GetProcessHeap(),0,lpAppl
);
59 /* section can be "Version" */
60 /* key can be "Windows"/"Dos" */
61 /* value can be appropriate values for the above keys */
62 typedef struct _APPSETTING
67 } APPSETTING
, *LPAPPSETTING
;
69 static LPAPPSETTING
CreateAppSetting(char* lpcKey
, char* value
)
71 LPAPPSETTING out
= HeapAlloc(GetProcessHeap(),0,sizeof(APPSETTING
));
72 out
->lpcKey
= strdup (lpcKey
);
73 out
->value
= strdup(value
);
77 static VOID
FreeAppSetting(LPAPPSETTING las
)
79 if (las
->lpcKey
) free(las
->lpcKey
);
80 if (las
->value
) free(las
->value
);
81 HeapFree(GetProcessHeap(),0,las
);
84 typedef struct _ITEMTAG
87 LPAPPSETTING lpSetting
;
88 } ITEMTAG
, *LPITEMTAG
;
90 static LPITEMTAG
CreateItemTag()
93 out
= HeapAlloc(GetProcessHeap(),0,sizeof(ITEMTAG
));
99 static VOID
FreeItemTag(LPITEMTAG lpit
)
101 /* if child, only free the lpSetting, the lpAppl will be freed when we free the parents item tag */
104 FreeAppSetting(lpit
->lpSetting
);
108 FreeAppl(lpit
->lpAppl
);
110 HeapFree(GetProcessHeap(), 0, lpit
);
113 static VOID
LoadAppSettings(LPAPPL appl
/*DON'T FREE, treeview will own this*/, HWND hDlg
, HWND hwndTV
)
127 WINE_TRACE("opening '%s'\n", appl
->lpcVersionSection
);
128 if (RegOpenKey (configKey
, appl
->lpcVersionSection
, &key
) == ERROR_SUCCESS
)
134 lpIt
= CreateItemTag();
138 tis
.hInsertAfter
= TVI_LAST
;
139 tis
.u
.item
.mask
= TVIF_TEXT
| TVIF_PARAM
;
140 tis
.u
.item
.pszText
= appl
->lpcApplication
;
141 tis
.u
.item
.lParam
= (LPARAM
)lpIt
;
142 hParent
= TreeView_InsertItem(hwndTV
,&tis
);
143 tis
.hParent
= hParent
;
145 /* insert version entries */
146 if(RegOpenKey (configKey
, appl
->lpcVersionSection
, &key
) == ERROR_SUCCESS
)
148 while (RegEnumValue(key
, i
, name
, &size
, NULL
, NULL
, read
, &readSize
) == ERROR_SUCCESS
)
152 WINE_TRACE("Reading value %s, namely %s\n", name
, read
);
154 lpIt
= CreateItemTag();
155 lpas
= CreateAppSetting(name
, read
);
156 lpIt
->lpSetting
= lpas
;
158 tis
.u
.item
.lParam
= (LPARAM
)lpIt
;
160 /* convert the value for 'dosver or winver' to human readable form */
161 description
= getDescriptionFromVersion(getWinVersions(), read
);
164 description
= getDescriptionFromVersion(getDOSVersions(), read
);
166 description
= "Not found";
169 sprintf(itemtext
, "%s - %s", name
, description
);
170 tis
.u
.item
.pszText
= itemtext
;
172 TreeView_InsertItem(hwndTV
,&tis
);
173 i
++; size
= 255; readSize
= 255;
178 WINE_TRACE("no version section found\n");
183 static VOID
SetEnabledAppControls(HWND dialog
)
187 static VOID
UpdateComboboxes(HWND hDlg
, LPAPPL lpAppl
)
190 const VERSION_DESC
*pVer
= NULL
;
192 /* retrieve the registry values for this application */
193 char *curWinVer
= getConfigValue(lpAppl
->lpcVersionSection
, "Windows", "");
194 char *curDOSVer
= getConfigValue(lpAppl
->lpcVersionSection
, "DOS", "");
196 if(curWinVer
) WINE_TRACE("curWinVer is '%s'\n", curWinVer
);
197 else WINE_TRACE("curWinVer is null\n");
198 if(curDOSVer
) WINE_TRACE("curDOSVer is '%s'\n", curDOSVer
);
199 else WINE_TRACE("curDOSVer is null\n");
201 /* normalize the version strings */
202 if(strlen(curWinVer
) != 0)
204 if ((pVer
= getWinVersions ()))
206 WINE_TRACE("Windows version\n");
207 for (i
= 0; *pVer
->szVersion
|| *pVer
->szDescription
; i
++, pVer
++)
209 WINE_TRACE("pVer->szVersion == %s\n", pVer
->szVersion
);
210 if (!strcasecmp (pVer
->szVersion
, curWinVer
))
212 SendDlgItemMessage (hDlg
, IDC_WINVER
, CB_SETCURSEL
,
214 WINE_TRACE("match with %s\n", pVer
->szVersion
);
218 } else /* clear selection */
220 WINE_TRACE("setting winver to nothing\n");
221 SendDlgItemMessage (hDlg
, IDC_WINVER
, CB_SETCURSEL
,
225 if(strlen(curDOSVer
) != 0)
227 if ((pVer
= getDOSVersions ()))
229 WINE_TRACE("DOS version\n");
230 for (i
= 0; *pVer
->szVersion
|| *pVer
->szDescription
; i
++, pVer
++)
232 WINE_TRACE("pVer->szVersion == %s\n", pVer
->szVersion
);
233 if (!strcasecmp (pVer
->szVersion
, curDOSVer
))
235 SendDlgItemMessage (hDlg
, IDC_DOSVER
, CB_SETCURSEL
,
237 WINE_TRACE("match with %s\n", pVer
->szVersion
);
243 WINE_TRACE("setting dosver to nothing\n");
244 SendDlgItemMessage (hDlg
, IDC_DOSVER
, CB_SETCURSEL
,
248 if(curWinVer
) free(curWinVer
);
249 if(curDOSVer
) free(curDOSVer
);
253 initAppDlgComboboxes (HWND hDlg
)
256 const VERSION_DESC
*pVer
= NULL
;
258 if ((pVer
= getWinVersions ()))
260 for (i
= 0; *pVer
->szVersion
|| *pVer
->szDescription
; i
++, pVer
++)
262 SendDlgItemMessage (hDlg
, IDC_WINVER
, CB_ADDSTRING
,
263 0, (LPARAM
) pVer
->szDescription
);
266 if ((pVer
= getDOSVersions ()))
268 for (i
= 0; *pVer
->szVersion
|| *pVer
->szDescription
; i
++, pVer
++)
270 SendDlgItemMessage (hDlg
, IDC_DOSVER
, CB_ADDSTRING
,
271 0, (LPARAM
) pVer
->szDescription
);
277 static VOID
OnInitAppDlg(HWND hDlg
)
285 char lpcVersionKey
[255];
288 hwndTV
= GetDlgItem(hDlg
,IDC_APP_TREEVIEW
);
289 lpAppl
= CreateAppl(TRUE
, "Global Settings", "Version");
290 LoadAppSettings(lpAppl
, hDlg
, hwndTV
);
292 /*And now the application specific stuff:*/
293 if (RegOpenKey(configKey
, "AppDefaults", &applKey
) == ERROR_SUCCESS
)
297 while (RegEnumKeyEx(applKey
, i
, appl
, &size
, NULL
, NULL
, NULL
, &ft
) == ERROR_SUCCESS
)
299 sprintf(lpcVersionKey
, "AppDefaults\\%s\\Version", appl
);
300 lpAppl
= CreateAppl(FALSE
, appl
, lpcVersionKey
);
301 LoadAppSettings(lpAppl
, hDlg
, hwndTV
);
304 RegCloseKey(applKey
);
306 SetEnabledAppControls(hDlg
);
309 static VOID
OnTreeViewChangeItem(HWND hDlg
, HWND hTV
)
314 ti
.mask
= TVIF_PARAM
;
315 ti
.hItem
= TreeView_GetSelection(hTV
);
316 if (TreeView_GetItem (hTV
, &ti
))
318 lpit
= (LPITEMTAG
) ti
.lParam
;
321 WINE_TRACE("lpit->lpAppl is non-null\n");
322 /* update comboboxes to reflect settings for this app */
323 UpdateComboboxes(hDlg
, lpit
->lpAppl
);
326 WINE_TRACE("lpit->lpAppl is null\n");
331 static VOID
OnTreeViewDeleteItem(NMTREEVIEW
* nmt
)
333 FreeItemTag((LPITEMTAG
)(nmt
->itemOld
.lParam
));
336 static VOID
OnAddApplicationClick(HWND hDlg
)
338 char szFileTitle
[255];
340 char lpcVersionKey
[255];
344 OPENFILENAME ofn
= { sizeof(OPENFILENAME
),
345 0, /*hInst*/0, "Wine Programs (*.exe,*.exe.so)\0*.exe;*.exe.so\0", NULL
, 0, 0, NULL
,
346 0, NULL
, 0, NULL
, NULL
,
347 OFN_SHOWHELP
, 0, 0, NULL
, 0, NULL
};
349 ofn
.lpstrFileTitle
= szFileTitle
;
350 ofn
.lpstrFileTitle
[0] = '\0';
351 ofn
.nMaxFileTitle
= sizeof(szFileTitle
);
352 ofn
.lpstrFile
= szFile
;
353 ofn
.lpstrFile
[0] = '\0';
354 ofn
.nMaxFile
= sizeof(szFile
);
356 if (GetOpenFileName(&ofn
))
359 tis
.hInsertAfter
= TVI_LAST
;
360 tis
.u
.item
.mask
= TVIF_TEXT
| TVIF_PARAM
;
361 tis
.u
.item
.pszText
= szFileTitle
;
362 lpit
= CreateItemTag();
363 sprintf(lpcVersionKey
, "AppDefaults\\%s\\Version", szFileTitle
);
364 lpit
->lpAppl
= CreateAppl(FALSE
, szFileTitle
, lpcVersionKey
);
365 tis
.u
.item
.lParam
= (LPARAM
)lpit
;
366 TreeView_InsertItem(GetDlgItem(hDlg
, IDC_APP_TREEVIEW
), &tis
);
368 /* add the empty entries for the Version section for this app */
369 setConfigValue(lpcVersionKey
,NULL
,NULL
);
373 static VOID
OnRemoveApplicationClick(HWND hDlg
)
379 hTV
= GetDlgItem(hDlg
, IDC_APP_TREEVIEW
);
380 ti
.mask
= TVIF_PARAM
;
381 ti
.hItem
= TreeView_GetSelection(hTV
);
382 if (TreeView_GetItem (hTV
, &ti
))
384 lpit
= (LPITEMTAG
) ti
.lParam
;
387 /* add transactions to remove all entries for this application */
388 addTransaction(lpit
->lpAppl
->lpcVersionSection
, NULL
, ACTION_REMOVE
, NULL
);
389 TreeView_DeleteItem(hTV
,ti
.hItem
);
394 static void UpdateWinverSelection(HWND hDlg
, int selection
)
398 VERSION_DESC
*pVer
= NULL
;
399 HWND hTV
= GetDlgItem(hDlg
, IDC_APP_TREEVIEW
);
401 ti
.mask
= TVIF_PARAM
;
402 ti
.hItem
= TreeView_GetSelection(hTV
);
403 if (TreeView_GetItem (hTV
, &ti
))
405 lpit
= (LPITEMTAG
) ti
.lParam
;
409 pVer
= getWinVersions();
411 /* if no item is selected OR if our version string is null */
412 /* remove this applications setting */
413 if((selection
== CB_ERR
) || !(*pVer
[selection
].szVersion
))
415 WINE_TRACE("removing section '%s'\n", lpit
->lpAppl
->lpcVersionSection
);
416 addTransaction(lpit
->lpAppl
->lpcVersionSection
, "Windows", ACTION_REMOVE
, NULL
); /* change registry entry */
419 WINE_TRACE("setting section '%s', key '%s', value '%s'\n", lpit
->lpAppl
->lpcVersionSection
, "Windows", pVer
[selection
].szVersion
);
420 addTransaction(lpit
->lpAppl
->lpcVersionSection
, "Windows", ACTION_SET
, pVer
[selection
].szVersion
); /* change registry entry */
423 TreeView_DeleteAllItems(hTV
); /* delete all items from the treeview */
429 static void UpdateDosverSelection(HWND hDlg
, int selection
)
433 VERSION_DESC
*pVer
= NULL
;
434 HWND hTV
= GetDlgItem(hDlg
, IDC_APP_TREEVIEW
);
436 ti
.mask
= TVIF_PARAM
;
437 ti
.hItem
= TreeView_GetSelection(hTV
);
438 if (TreeView_GetItem (hTV
, &ti
))
440 lpit
= (LPITEMTAG
) ti
.lParam
;
444 pVer
= getDOSVersions();
446 /* if no item is selected OR if our version string is null */
447 /* remove this applications setting */
448 if((selection
== CB_ERR
) || !(*pVer
[selection
].szVersion
))
450 WINE_TRACE("removing section '%s'\n", lpit
->lpAppl
->lpcVersionSection
);
451 addTransaction(lpit
->lpAppl
->lpcVersionSection
, "DOS", ACTION_REMOVE
, NULL
); /* change registry entry */
454 WINE_TRACE("setting section '%s', key '%s', value '%s'\n", lpit
->lpAppl
->lpcVersionSection
, "DOS", pVer
[selection
].szVersion
);
455 addTransaction(lpit
->lpAppl
->lpcVersionSection
, "DOS", ACTION_SET
, pVer
[selection
].szVersion
); /* change registry entry */
458 TreeView_DeleteAllItems(hTV
); /* delete all items from the treeview */
465 AppDlgProc (HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
472 initAppDlgComboboxes(hDlg
);
475 switch (((LPNMHDR
)lParam
)->code
) {
476 case TVN_SELCHANGED
: {
477 switch(LOWORD(wParam
)) {
478 case IDC_APP_TREEVIEW
:
479 OnTreeViewChangeItem(hDlg
, GetDlgItem(hDlg
,IDC_APP_TREEVIEW
));
485 OnTreeViewDeleteItem ((LPNMTREEVIEW
)lParam
);
490 switch(HIWORD(wParam
)) {
492 switch(LOWORD(wParam
)) {
494 selection
= SendDlgItemMessage( hDlg
, IDC_WINVER
, CB_GETCURSEL
, 0, 0);
495 UpdateWinverSelection(hDlg
, selection
);
498 selection
= SendDlgItemMessage( hDlg
, IDC_DOSVER
, CB_GETCURSEL
, 0, 0);
499 UpdateDosverSelection(hDlg
, selection
);
503 switch(LOWORD(wParam
)) {
505 OnAddApplicationClick(hDlg
);
507 case IDC_APP_REMOVEAPP
:
508 OnRemoveApplicationClick(hDlg
);