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;
38 char* lpcWinelookSection;
41 static LPAPPL CreateAppl(BOOL isGlobal, char* application, char* version_section, char* winelook_section)
44 WINE_TRACE("application: '%s', version_section: '%s', winelook_section: '%s'\n", application,
45 version_section, winelook_section);
46 out = HeapAlloc(GetProcessHeap(),0,sizeof(APPL));
47 out->lpcApplication = strdup(application);
48 out->lpcVersionSection = strdup(version_section);
49 out->lpcWinelookSection = strdup(winelook_section);
50 out->isGlobal = isGlobal;
54 static VOID FreeAppl(LPAPPL lpAppl)
56 /* The strings were strdup-ped, so we use "free" */
57 if (lpAppl->lpcApplication) free(lpAppl->lpcApplication);
58 if (lpAppl->lpcVersionSection) free(lpAppl->lpcVersionSection);
59 if (lpAppl->lpcWinelookSection) free(lpAppl->lpcWinelookSection);
60 HeapFree(GetProcessHeap(),0,lpAppl);
63 /* section can be "Version" or "Tweak.Layout" */
64 /* key can be "Windows"/"Dos"/"WineLook" */
65 /* value can be appropriate values for the above keys */
66 typedef struct _APPSETTING
71 } APPSETTING, *LPAPPSETTING;
73 static LPAPPSETTING CreateAppSetting(char* lpcKey, char* value)
75 LPAPPSETTING out = HeapAlloc(GetProcessHeap(),0,sizeof(APPSETTING));
76 out->lpcKey = strdup (lpcKey);
77 out->value = strdup(value);
81 static VOID FreeAppSetting(LPAPPSETTING las)
83 if (las->lpcKey) free(las->lpcKey);
84 if (las->value) free(las->value);
85 HeapFree(GetProcessHeap(),0,las);
88 typedef struct _ITEMTAG
91 LPAPPSETTING lpSetting;
92 } ITEMTAG, *LPITEMTAG;
94 static LPITEMTAG CreateItemTag()
97 out = HeapAlloc(GetProcessHeap(),0,sizeof(ITEMTAG));
103 static VOID FreeItemTag(LPITEMTAG lpit)
105 /* if child, only free the lpSetting, the lpAppl will be freed when we free the parents item tag */
108 FreeAppSetting(lpit->lpSetting);
112 FreeAppl(lpit->lpAppl);
114 HeapFree(GetProcessHeap(), 0, lpit);
117 static VOID LoadAppSettings(LPAPPL appl /*DON'T FREE, treeview will own this*/, HWND hDlg, HWND hwndTV)
131 WINE_TRACE("opening '%s' and '%s'\n", appl->lpcVersionSection, appl->lpcWinelookSection);
132 if ((RegOpenKey (configKey, appl->lpcVersionSection, &key) == ERROR_SUCCESS) ||
133 (RegOpenKey (configKey, appl->lpcWinelookSection, &key) == ERROR_SUCCESS))
139 lpIt = CreateItemTag();
143 tis.hInsertAfter = TVI_LAST;
144 tis.u.item.mask = TVIF_TEXT | TVIF_PARAM;
145 tis.u.item.pszText = appl->lpcApplication;
146 tis.u.item.lParam = (LPARAM)lpIt;
147 hParent = TreeView_InsertItem(hwndTV,&tis);
148 tis.hParent = hParent;
150 /* insert version entries */
151 if(RegOpenKey (configKey, appl->lpcVersionSection, &key) == ERROR_SUCCESS)
153 while (RegEnumValue(key, i, name, &size, NULL, NULL, read, &readSize) == ERROR_SUCCESS)
157 WINE_TRACE("Reading value %s, namely %s\n", name, read);
159 lpIt = CreateItemTag();
160 lpas = CreateAppSetting(name, read);
161 lpIt->lpSetting = lpas;
163 tis.u.item.lParam = (LPARAM)lpIt;
165 /* convert the value for 'dosver or winver' to human readable form */
166 description = getDescriptionFromVersion(getWinVersions(), read);
169 description = getDescriptionFromVersion(getDOSVersions(), read);
171 description = "Not found";
174 sprintf(itemtext, "%s - %s", name, description);
175 tis.u.item.pszText = itemtext;
177 TreeView_InsertItem(hwndTV,&tis);
178 i++; size = 255; readSize = 255;
183 WINE_TRACE("no version section found\n");
186 i = 0; /* reset i to 0 before calling RegEnumValue() again */
188 /* insert winelook entries */
189 if(RegOpenKey (configKey, appl->lpcWinelookSection, &key) == ERROR_SUCCESS)
191 while (RegEnumValue(key, i, name, &size, NULL, NULL, read, &readSize) == ERROR_SUCCESS)
195 WINE_TRACE("Reading value %s, namely %s\n", name, read);
197 lpIt = CreateItemTag();
198 lpas = CreateAppSetting(name, read);
199 lpIt->lpSetting = lpas;
201 tis.u.item.lParam = (LPARAM)lpIt;
203 /* convert the value for 'winelook' to human readable form */
204 description = getDescriptionFromVersion(getWinelook(), read);
205 if(!description) description = "Not found";
207 sprintf(itemtext, "%s - %s", name, description);
208 tis.u.item.pszText = itemtext;
210 TreeView_InsertItem(hwndTV,&tis);
211 i++; size = 255; readSize = 255;
216 WINE_TRACE("no winelook section found\n");
221 static VOID SetEnabledAppControls(HWND dialog)
225 static VOID UpdateComboboxes(HWND hDlg, LPAPPL lpAppl)
228 const VERSION_DESC *pVer = NULL;
230 /* retrieve the registry values for this application */
231 char *curWinVer = getConfigValue(lpAppl->lpcVersionSection, "Windows", "");
232 char *curDOSVer = getConfigValue(lpAppl->lpcVersionSection, "DOS", "");
233 char *curWineLook = getConfigValue(lpAppl->lpcWinelookSection, "WineLook", "");
235 if(curWinVer) WINE_TRACE("curWinVer is '%s'\n", curWinVer);
236 else WINE_TRACE("curWinVer is null\n");
237 if(curDOSVer) WINE_TRACE("curDOSVer is '%s'\n", curDOSVer);
238 else WINE_TRACE("curDOSVer is null\n");
239 if(curWineLook) WINE_TRACE("curWineLook is '%s'\n", curWineLook);
240 else WINE_TRACE("curWineLook is null\n");
242 /* normalize the version strings */
243 if(strlen(curWinVer) != 0)
245 if ((pVer = getWinVersions ()))
247 WINE_TRACE("Windows version\n");
248 for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++)
250 WINE_TRACE("pVer->szVersion == %s\n", pVer->szVersion);
251 if (!strcasecmp (pVer->szVersion, curWinVer))
253 SendDlgItemMessage (hDlg, IDC_WINVER, CB_SETCURSEL,
255 WINE_TRACE("match with %s\n", pVer->szVersion);
259 } else /* clear selection */
261 WINE_TRACE("setting winver to nothing\n");
262 SendDlgItemMessage (hDlg, IDC_WINVER, CB_SETCURSEL,
266 if(strlen(curDOSVer) != 0)
268 if ((pVer = getDOSVersions ()))
270 WINE_TRACE("DOS version\n");
271 for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++)
273 WINE_TRACE("pVer->szVersion == %s\n", pVer->szVersion);
274 if (!strcasecmp (pVer->szVersion, curDOSVer))
276 SendDlgItemMessage (hDlg, IDC_DOSVER, CB_SETCURSEL,
278 WINE_TRACE("match with %s\n", pVer->szVersion);
284 WINE_TRACE("setting dosver to nothing\n");
285 SendDlgItemMessage (hDlg, IDC_DOSVER, CB_SETCURSEL,
289 if(strlen(curWineLook) != 0)
291 if ((pVer = getWinelook ()))
293 WINE_TRACE("Winelook\n");
295 for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++)
297 WINE_TRACE("pVer->szVersion == %s\n", pVer->szVersion);
298 if (!strcasecmp (pVer->szVersion, curWineLook))
300 SendDlgItemMessage (hDlg, IDC_WINELOOK, CB_SETCURSEL,
302 WINE_TRACE("match with %s\n", pVer->szVersion);
308 WINE_TRACE("setting winelook to nothing\n");
309 SendDlgItemMessage (hDlg, IDC_WINELOOK, CB_SETCURSEL,
313 if(curWinVer) free(curWinVer);
314 if(curDOSVer) free(curDOSVer);
315 if(curWineLook) free(curWineLook);
319 initAppDlgComboboxes (HWND hDlg)
322 const VERSION_DESC *pVer = NULL;
324 if ((pVer = getWinVersions ()))
326 for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++)
328 SendDlgItemMessage (hDlg, IDC_WINVER, CB_ADDSTRING,
329 0, (LPARAM) pVer->szDescription);
332 if ((pVer = getDOSVersions ()))
334 for (i = 0; *pVer->szVersion || *pVer->szDescription ; i++, pVer++)
336 SendDlgItemMessage (hDlg, IDC_DOSVER, CB_ADDSTRING,
337 0, (LPARAM) pVer->szDescription);
340 if ((pVer = getWinelook ()))
342 for (i = 0; *pVer->szVersion || *pVer->szDescription; i++, pVer++)
344 SendDlgItemMessage (hDlg, IDC_WINELOOK, CB_ADDSTRING,
345 0, (LPARAM) pVer->szDescription);
351 static VOID OnInitAppDlg(HWND hDlg)
359 char lpcVersionKey [255];
360 char lpcWinelookKey [255];
363 hwndTV = GetDlgItem(hDlg,IDC_APP_TREEVIEW);
364 lpAppl = CreateAppl(TRUE, "Global Settings", "Version", "Tweak.Layout");
365 LoadAppSettings(lpAppl, hDlg, hwndTV);
367 /*And now the application specific stuff:*/
368 if (RegOpenKey(configKey, "AppDefaults", &applKey) == ERROR_SUCCESS)
372 while (RegEnumKeyEx(applKey, i, appl, &size, NULL, NULL, NULL, &ft) == ERROR_SUCCESS)
374 sprintf(lpcVersionKey, "AppDefaults\\%s\\Version", appl);
375 sprintf(lpcWinelookKey, "AppDefaults\\%s\\Tweak.Layout", appl);
376 lpAppl = CreateAppl(FALSE, appl, lpcVersionKey, lpcWinelookKey);
377 LoadAppSettings(lpAppl, hDlg, hwndTV);
380 RegCloseKey(applKey);
382 SetEnabledAppControls(hDlg);
385 static VOID OnTreeViewChangeItem(HWND hDlg, HWND hTV)
390 ti.mask = TVIF_PARAM;
391 ti.hItem = TreeView_GetSelection(hTV);
392 if (TreeView_GetItem (hTV, &ti))
394 lpit = (LPITEMTAG) ti.lParam;
397 WINE_TRACE("lpit->lpAppl is non-null\n");
398 /* update comboboxes to reflect settings for this app */
399 UpdateComboboxes(hDlg, lpit->lpAppl);
402 WINE_TRACE("lpit->lpAppl is null\n");
407 static VOID OnTreeViewDeleteItem(NMTREEVIEW* nmt)
409 FreeItemTag((LPITEMTAG)(nmt->itemOld.lParam));
412 static VOID OnAddApplicationClick(HWND hDlg)
414 char szFileTitle [255];
416 char lpcVersionKey [255];
417 char lpcWinelookKey [255];
421 OPENFILENAME ofn = { sizeof(OPENFILENAME),
422 0, /*hInst*/0, "Wine Programs (*.exe,*.exe.so)\0*.exe;*.exe.so\0", NULL, 0, 0, NULL,
423 0, NULL, 0, NULL, NULL,
424 OFN_SHOWHELP, 0, 0, NULL, 0, NULL };
426 ofn.lpstrFileTitle = szFileTitle;
427 ofn.lpstrFileTitle[0] = '\0';
428 ofn.nMaxFileTitle = sizeof(szFileTitle);
429 ofn.lpstrFile = szFile;
430 ofn.lpstrFile[0] = '\0';
431 ofn.nMaxFile = sizeof(szFile);
433 if (GetOpenFileName(&ofn))
436 tis.hInsertAfter = TVI_LAST;
437 tis.u.item.mask = TVIF_TEXT | TVIF_PARAM;
438 tis.u.item.pszText = szFileTitle;
439 lpit = CreateItemTag();
440 sprintf(lpcVersionKey, "AppDefaults\\%s\\Version", szFileTitle);
441 sprintf(lpcWinelookKey, "AppDefaults\\%s\\Tweak.Layout", szFileTitle);
442 lpit->lpAppl = CreateAppl(FALSE, szFileTitle, lpcVersionKey, lpcWinelookKey);
443 tis.u.item.lParam = (LPARAM)lpit;
444 TreeView_InsertItem(GetDlgItem(hDlg, IDC_APP_TREEVIEW), &tis);
446 /* add the empty entries for the Version and Winelook sections for this app */
447 setConfigValue(lpcVersionKey,NULL,NULL);
448 setConfigValue(lpcWinelookKey,NULL,NULL);
452 static VOID OnRemoveApplicationClick(HWND hDlg)
458 hTV = GetDlgItem(hDlg, IDC_APP_TREEVIEW);
459 ti.mask = TVIF_PARAM;
460 ti.hItem = TreeView_GetSelection(hTV);
461 if (TreeView_GetItem (hTV, &ti))
463 lpit = (LPITEMTAG) ti.lParam;
466 /* add transactions to remove all entries for this application */
467 addTransaction(lpit->lpAppl->lpcVersionSection, NULL, ACTION_REMOVE, NULL);
468 addTransaction(lpit->lpAppl->lpcWinelookSection, NULL, ACTION_REMOVE, NULL);
469 TreeView_DeleteItem(hTV,ti.hItem);
474 static void UpdateWinverSelection(HWND hDlg, int selection)
478 VERSION_DESC *pVer = NULL;
479 HWND hTV = GetDlgItem(hDlg, IDC_APP_TREEVIEW);
481 ti.mask = TVIF_PARAM;
482 ti.hItem = TreeView_GetSelection(hTV);
483 if (TreeView_GetItem (hTV, &ti))
485 lpit = (LPITEMTAG) ti.lParam;
489 pVer = getWinVersions();
491 /* if no item is selected OR if our version string is null */
492 /* remove this applications setting */
493 if((selection == CB_ERR) || !(*pVer[selection].szVersion))
495 WINE_TRACE("removing section '%s'\n", lpit->lpAppl->lpcWinelookSection);
496 addTransaction(lpit->lpAppl->lpcVersionSection, "Windows", ACTION_REMOVE, NULL); /* change registry entry */
499 WINE_TRACE("setting section '%s', key '%s', value '%s'\n", lpit->lpAppl->lpcVersionSection, "Windows", pVer[selection].szVersion);
500 addTransaction(lpit->lpAppl->lpcVersionSection, "Windows", ACTION_SET, pVer[selection].szVersion); /* change registry entry */
503 TreeView_DeleteAllItems(hTV); /* delete all items from the treeview */
509 static void UpdateDosverSelection(HWND hDlg, int selection)
513 VERSION_DESC *pVer = NULL;
514 HWND hTV = GetDlgItem(hDlg, IDC_APP_TREEVIEW);
516 ti.mask = TVIF_PARAM;
517 ti.hItem = TreeView_GetSelection(hTV);
518 if (TreeView_GetItem (hTV, &ti))
520 lpit = (LPITEMTAG) ti.lParam;
524 pVer = getDOSVersions();
526 /* if no item is selected OR if our version string is null */
527 /* remove this applications setting */
528 if((selection == CB_ERR) || !(*pVer[selection].szVersion))
530 WINE_TRACE("removing section '%s'\n", lpit->lpAppl->lpcWinelookSection);
531 addTransaction(lpit->lpAppl->lpcVersionSection, "DOS", ACTION_REMOVE, NULL); /* change registry entry */
534 WINE_TRACE("setting section '%s', key '%s', value '%s'\n", lpit->lpAppl->lpcVersionSection, "DOS", pVer[selection].szVersion);
535 addTransaction(lpit->lpAppl->lpcVersionSection, "DOS", ACTION_SET, pVer[selection].szVersion); /* change registry entry */
538 TreeView_DeleteAllItems(hTV); /* delete all items from the treeview */
544 static void UpdateWinelookSelection(HWND hDlg, int selection)
548 VERSION_DESC *pVer = NULL;
549 HWND hTV = GetDlgItem(hDlg, IDC_APP_TREEVIEW);
551 ti.mask = TVIF_PARAM;
552 ti.hItem = TreeView_GetSelection(hTV);
553 if (TreeView_GetItem (hTV, &ti))
555 lpit = (LPITEMTAG) ti.lParam;
559 pVer = getWinelook();
561 /* if no item is selected OR if our version string is null */
562 /* remove this applications setting */
563 if((selection == CB_ERR) || !(*pVer[selection].szVersion))
565 WINE_TRACE("removing section '%s'\n", lpit->lpAppl->lpcWinelookSection);
566 addTransaction(lpit->lpAppl->lpcWinelookSection, "WineLook", ACTION_REMOVE, NULL); /* change registry entry */
569 WINE_TRACE("setting section '%s', key '%s', value '%s'\n", lpit->lpAppl->lpcWinelookSection, "WineLook", pVer[selection].szVersion);
570 addTransaction(lpit->lpAppl->lpcWinelookSection, "WineLook", ACTION_SET, pVer[selection].szVersion); /* change registry entry */
573 TreeView_DeleteAllItems(hTV); /* delete all items from the treeview */
582 AppDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
589 initAppDlgComboboxes(hDlg);
592 switch (((LPNMHDR)lParam)->code) {
593 case TVN_SELCHANGED: {
594 switch(LOWORD(wParam)) {
595 case IDC_APP_TREEVIEW:
596 OnTreeViewChangeItem(hDlg, GetDlgItem(hDlg,IDC_APP_TREEVIEW));
602 OnTreeViewDeleteItem ((LPNMTREEVIEW)lParam);
607 switch(HIWORD(wParam)) {
609 switch(LOWORD(wParam)) {
611 selection = SendDlgItemMessage( hDlg, IDC_WINVER, CB_GETCURSEL, 0, 0);
612 UpdateWinverSelection(hDlg, selection);
615 selection = SendDlgItemMessage( hDlg, IDC_DOSVER, CB_GETCURSEL, 0, 0);
616 UpdateDosverSelection(hDlg, selection);
619 selection = SendDlgItemMessage( hDlg, IDC_WINELOOK, CB_GETCURSEL, 0, 0);
620 UpdateWinelookSelection(hDlg, selection);
624 switch(LOWORD(wParam)) {
626 OnAddApplicationClick(hDlg);
628 case IDC_APP_REMOVEAPP:
629 OnRemoveApplicationClick(hDlg);