Commit 0f4c6c97 authored by Mike Hearn's avatar Mike Hearn Committed by Alexandre Julliard

- Bugfixes to the transaction system.

- Better protection against incomplete config sections. - Implement "Add Drive". - Partly reactivate edit drive dialog.
parent 20c169e0
...@@ -55,7 +55,7 @@ char *getDriveValue(char letter, char *valueName) { ...@@ -55,7 +55,7 @@ char *getDriveValue(char letter, char *valueName) {
WINE_TRACE("letter=%c, valueName=%s\n", letter, valueName); WINE_TRACE("letter=%c, valueName=%s\n", letter, valueName);
subKeyName = malloc(strlen("Drive X")); subKeyName = malloc(strlen("Drive X")+1);
sprintf(subKeyName, "Drive %c", letter); sprintf(subKeyName, "Drive %c", letter);
hr = RegOpenKeyEx(configKey, subKeyName, 0, KEY_READ, &hkDrive); hr = RegOpenKeyEx(configKey, subKeyName, 0, KEY_READ, &hkDrive);
...@@ -74,7 +74,14 @@ end: ...@@ -74,7 +74,14 @@ end:
return result; return result;
} }
void initDriveDlg (HWND hDlg) void setDriveValue(char letter, char *valueName, char *newValue) {
char *driveSection = malloc(strlen("Drive X")+1);
sprintf(driveSection, "Drive %c", letter);
addTransaction(driveSection, valueName, ACTION_SET, newValue);
free(driveSection);
}
void refreshDriveDlg (HWND hDlg)
{ {
int i; int i;
char *subKeyName = malloc(MAX_NAME_LENGTH); char *subKeyName = malloc(MAX_NAME_LENGTH);
...@@ -141,7 +148,7 @@ void initDriveDlg (HWND hDlg) ...@@ -141,7 +148,7 @@ void initDriveDlg (HWND hDlg)
SendMessageA(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_SETITEMDATA, itemIndex, (LPARAM) driveLetter); SendMessageA(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_SETITEMDATA, itemIndex, (LPARAM) driveLetter);
free(title); free(title);
free(label); if (label && (strcmp(label, "no label") != 0)) free(label);
driveCount++; driveCount++;
...@@ -149,6 +156,7 @@ void initDriveDlg (HWND hDlg) ...@@ -149,6 +156,7 @@ void initDriveDlg (HWND hDlg)
} }
WINE_TRACE("loaded %d drives\n", driveCount); WINE_TRACE("loaded %d drives\n", driveCount);
SendMessageA(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_SETSEL, TRUE, 0);
free(subKeyName); free(subKeyName);
updatingUI = FALSE; updatingUI = FALSE;
...@@ -253,8 +261,8 @@ long drive_available_mask(char letter) ...@@ -253,8 +261,8 @@ long drive_available_mask(char letter)
} }
} }
result = ~result; result = ~result;
result |= DRIVE_MASK_BIT(letter); if (letter) result |= DRIVE_MASK_BIT(letter);
WINE_TRACE( "finished drive letter loop with %lx\n", result ); WINE_TRACE( "finished drive letter loop with %lx\n", result );
return result; return result;
...@@ -329,10 +337,12 @@ void refreshDriveEditDialog(HWND hDlg) { ...@@ -329,10 +337,12 @@ void refreshDriveEditDialog(HWND hDlg) {
SendDlgItemMessage(hDlg, IDC_EDIT_DEVICE, WM_SETTEXT, 0,(LPARAM)device); SendDlgItemMessage(hDlg, IDC_EDIT_DEVICE, WM_SETTEXT, 0,(LPARAM)device);
} else WINE_WARN("no Device field?\n"); } else WINE_WARN("no Device field?\n");
if( strcmp("cdrom", type) == 0 || selection = IDC_RADIO_ASSIGN;
strcmp("floppy", type) == 0) { if ((type && strcmp("cdrom", type) == 0) ||
if( (strlen( device ) == 0) && (type && strcmp("floppy", type) == 0)) {
((strlen( serial ) > 0) || (strlen( label ) > 0)) ) {
if( (type && (strlen( device ) == 0)) &&
((serial && strlen( serial ) > 0) || (label && strlen( label ) > 0)) ) {
selection = IDC_RADIO_ASSIGN; selection = IDC_RADIO_ASSIGN;
} }
else { else {
...@@ -347,7 +357,7 @@ void refreshDriveEditDialog(HWND hDlg) { ...@@ -347,7 +357,7 @@ void refreshDriveEditDialog(HWND hDlg) {
} }
CheckRadioButton( hDlg, IDC_RADIO_AUTODETECT, IDC_RADIO_ASSIGN, selection ); CheckRadioButton( hDlg, IDC_RADIO_AUTODETECT, IDC_RADIO_ASSIGN, selection );
SendDlgItemMessage(hDlg, IDC_EDIT_PATH, WM_SETTEXT, 0,(LPARAM)path); if (path) SendDlgItemMessage(hDlg, IDC_EDIT_PATH, WM_SETTEXT, 0,(LPARAM)path);
if (path) free(path); if (path) free(path);
if (type) free(type); if (type) free(type);
...@@ -355,12 +365,28 @@ void refreshDriveEditDialog(HWND hDlg) { ...@@ -355,12 +365,28 @@ void refreshDriveEditDialog(HWND hDlg) {
if (serial) free(serial); if (serial) free(serial);
if (label) free(label); if (label) free(label);
if (device) free(device); if (device) free(device);
updatingUI = FALSE; updatingUI = FALSE;
return; return;
} }
/* storing the drive propsheet HWND here is a bit ugly, but the simplest solution for now */
static HWND driveDlgHandle;
void onEditChanged(HWND hDlg, WORD controlID) {
WINE_TRACE("controlID=%d\n", controlID);
switch (controlID) {
case IDC_EDIT_LABEL: { /* drive label edit box */
char *label = getDialogItemText(hDlg, controlID);
setDriveValue(editWindowLetter, "Label", label);
refreshDriveDlg(driveDlgHandle);
free(label);
break;
}
}
}
INT_PTR CALLBACK DriveEditDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) INT_PTR CALLBACK DriveEditDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
int selection; int selection;
...@@ -387,18 +413,47 @@ INT_PTR CALLBACK DriveEditDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM l ...@@ -387,18 +413,47 @@ INT_PTR CALLBACK DriveEditDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM l
} }
break; break;
case ID_BUTTON_OK: break; case ID_BUTTON_OK:
/* Fall through. */
case ID_BUTTON_CANCEL: case ID_BUTTON_CANCEL:
EndDialog(hDlg, wParam); EndDialog(hDlg, wParam);
return TRUE; return TRUE;
} }
if (HIWORD(wParam) == EN_CHANGE) onEditChanged(hDlg, LOWORD(wParam));
break;
} }
return FALSE; return FALSE;
} }
void onAddDriveClicked(HWND hDlg) {
/* we should allocate a drive letter automatically. We also need some way to let the user choose the mapping point,
for now we will just force them to enter a path automatically, with / being the default. In future we should
be able to temporarily map / then invoke the directory chooser dialog. */
char newLetter = 'D'; /* we skip A, B and of course C is already mapped, right? */
long mask = ~drive_available_mask(0); /* the mask is now which drives aren't available */
char *sectionName;
while (mask & (1 << (newLetter - 'A'))) {
newLetter++;
if (newLetter > 'Z') {
MessageBox(NULL, "You cannot add any more drives.\n\nEach drive must have a letter, from A to Z, so you cannot have more than 26", "", MB_OK | MB_ICONEXCLAMATION);
return;
}
}
WINE_TRACE("allocating drive letter %c\n", newLetter);
sectionName = malloc(strlen("Drive X") + 1);
sprintf(sectionName, "Drive %c", newLetter);
addTransaction(sectionName, "Path", ACTION_SET, "/"); /* default to root path */
addTransaction(sectionName, "Type", ACTION_SET, "hd");
processTransQueue(); /* make sure the drive has been added, even if we are not in instant apply mode */
free(sectionName);
refreshDriveDlg(driveDlgHandle);
DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DRIVE_EDIT2), NULL, (DLGPROC) DriveEditDlgProc, (LPARAM) newLetter);
}
INT_PTR CALLBACK INT_PTR CALLBACK
DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
...@@ -414,9 +469,10 @@ DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) ...@@ -414,9 +469,10 @@ DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
selection = -1; selection = -1;
break; break;
} }
break;
case IDC_BUTTON_ADD: case IDC_BUTTON_ADD:
/* temporarily disabled, awaiting rewrite for transactional design (need to fill in defaults smartly, wizard?) */ onAddDriveClicked(hDlg);
break; break;
case IDC_BUTTON_REMOVE: case IDC_BUTTON_REMOVE:
...@@ -443,7 +499,8 @@ DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) ...@@ -443,7 +499,8 @@ DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR); SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
break; break;
case PSN_SETACTIVE: case PSN_SETACTIVE:
initDriveDlg (hDlg); driveDlgHandle = hDlg;
refreshDriveDlg (driveDlgHandle);
break; break;
} }
break; break;
......
...@@ -106,7 +106,7 @@ end: ...@@ -106,7 +106,7 @@ end:
} }
/***************************************************************************** /*****************************************************************************
* setConfigValue : Sets a configuration key in the registry * setConfigValue : Sets a configuration key in the registry. Section will be created if it doesn't already exist
* *
* HKEY hCurrent : the registry key that the configuration is rooted at * HKEY hCurrent : the registry key that the configuration is rooted at
* char *subKey : the name of the config section * char *subKey : the name of the config section
...@@ -209,9 +209,9 @@ void addTransaction(char *section, char *key, enum transaction_action action, ch ...@@ -209,9 +209,9 @@ void addTransaction(char *section, char *key, enum transaction_action action, ch
assert( key != NULL ); assert( key != NULL );
if (action == ACTION_SET) assert( newValue != NULL ); if (action == ACTION_SET) assert( newValue != NULL );
trans->section = section; trans->section = strdup(section);
trans->key = key; trans->key = strdup(key);
trans->newValue = newValue; trans->newValue = strdup(newValue);
trans->action = action; trans->action = action;
trans->next = NULL; trans->next = NULL;
trans->prev = NULL; trans->prev = NULL;
...@@ -225,7 +225,10 @@ void addTransaction(char *section, char *key, enum transaction_action action, ch ...@@ -225,7 +225,10 @@ void addTransaction(char *section, char *key, enum transaction_action action, ch
tqhead = trans; tqhead = trans;
} }
if (instantApply) processTransaction(trans); if (instantApply) {
processTransaction(trans);
destroyTransaction(trans);
}
} }
void processTransaction(struct transaction *trans) { void processTransaction(struct transaction *trans) {
...@@ -239,11 +242,25 @@ void processTransaction(struct transaction *trans) { ...@@ -239,11 +242,25 @@ void processTransaction(struct transaction *trans) {
/* TODO: implement notifications here */ /* TODO: implement notifications here */
} }
void processTransQueue() { void processTransQueue(void)
{
WINE_TRACE("\n"); WINE_TRACE("\n");
while (tqhead != NULL) { while (tqtail != NULL) {
processTransaction(tqhead); struct transaction *next = tqtail->next;
tqhead = tqhead->next; processTransaction(tqtail);
destroyTransaction(tqhead->prev); destroyTransaction(tqtail);
tqtail = next;
} }
} }
/* ================================== utility functions ============================ */
/* returns a string with the window text of the dialog item. user is responsible for freeing the result */
char *getDialogItemText(HWND hDlg, WORD controlID) {
HWND item = GetDlgItem(hDlg, controlID);
int len = GetWindowTextLength(item) + 1;
char *result = malloc(len);
if (GetWindowText(item, result, len) == 0) return NULL;
return result;
}
...@@ -99,6 +99,9 @@ void saveDriveSettings (HWND hDlg); ...@@ -99,6 +99,9 @@ void saveDriveSettings (HWND hDlg);
INT_PTR CALLBACK DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK DriveEditDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK DriveEditDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
/* some basic utilities to make win32 suck less */
char *getDialogItemText(HWND hDlg, WORD controlID);
#define WINE_KEY_ROOT "Software\\Wine\\WineCfg\\Config" #define WINE_KEY_ROOT "Software\\Wine\\WineCfg\\Config"
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment