[winecfg 7] Bugfixes, implement add drive, partly reactive drive
edit dialog
Mike Hearn
mike at theoretic.com
Sun Sep 7 11:11:41 CDT 2003
ChangeLog:
- Bugfixes to the transaction system
- Better protection against incomplete config sections
- Implement "Add Drive"
- Partly reactivate edit drive dialog
Only in programs/winecfg: config.log
diff -ur --exclude-from=diff-exclusions ../head/programs/winecfg/drive.c programs/winecfg/drive.c
--- ../head/programs/winecfg/drive.c 2003-09-05 22:55:02.000000000 +0100
+++ programs/winecfg/drive.c 2003-09-07 16:12:34.000000000 +0100
@@ -50,7 +50,7 @@
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);
hr = RegOpenKeyEx(configKey, subKeyName, 0, KEY_READ, &hkDrive);
@@ -69,7 +69,14 @@
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;
char *subKeyName = malloc(MAX_NAME_LENGTH);
@@ -136,7 +143,7 @@
SendMessageA(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_SETITEMDATA, itemIndex, (LPARAM) driveLetter);
free(title);
- free(label);
+ if (label && (strcmp(label, "no label") != 0)) free(label);
driveCount++;
@@ -144,6 +151,7 @@
}
WINE_TRACE("loaded %d drives\n", driveCount);
+ SendMessageA(GetDlgItem(hDlg, IDC_LIST_DRIVES), LB_SETSEL, TRUE, 0);
free(subKeyName);
updatingUI = FALSE;
@@ -248,8 +256,8 @@
}
}
- result = ~result;
- result |= DRIVE_MASK_BIT(letter);
+ result = ~result;
+ if (letter) result |= DRIVE_MASK_BIT(letter);
WINE_TRACE( "finished drive letter loop with %lx\n", result );
return result;
@@ -324,10 +332,12 @@
SendDlgItemMessage(hDlg, IDC_EDIT_DEVICE, WM_SETTEXT, 0,(LPARAM)device);
} else WINE_WARN("no Device field?\n");
- if( strcmp("cdrom", type) == 0 ||
- strcmp("floppy", type) == 0) {
- if( (strlen( device ) == 0) &&
- ((strlen( serial ) > 0) || (strlen( label ) > 0)) ) {
+ selection = IDC_RADIO_ASSIGN;
+ if ((type && strcmp("cdrom", type) == 0) ||
+ (type && strcmp("floppy", type) == 0)) {
+
+ if( (type && (strlen( device ) == 0)) &&
+ ((serial && strlen( serial ) > 0) || (label && strlen( label ) > 0)) ) {
selection = IDC_RADIO_ASSIGN;
}
else {
@@ -342,7 +352,7 @@
}
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 (type) free(type);
@@ -350,12 +360,28 @@
if (serial) free(serial);
if (label) free(label);
if (device) free(device);
-
+
updatingUI = FALSE;
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 selection;
@@ -382,18 +408,47 @@
}
break;
- case ID_BUTTON_OK: break;
-
- /* Fall through. */
-
+ case ID_BUTTON_OK:
case ID_BUTTON_CANCEL:
EndDialog(hDlg, wParam);
return TRUE;
}
+ if (HIWORD(wParam) == EN_CHANGE) onEditChanged(hDlg, LOWORD(wParam));
+ break;
}
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
DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
@@ -409,9 +464,10 @@
selection = -1;
break;
}
+ break;
case IDC_BUTTON_ADD:
- /* temporarily disabled, awaiting rewrite for transactional design (need to fill in defaults smartly, wizard?) */
+ onAddDriveClicked(hDlg);
break;
case IDC_BUTTON_REMOVE:
@@ -438,7 +494,8 @@
SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
break;
case PSN_SETACTIVE:
- initDriveDlg (hDlg);
+ driveDlgHandle = hDlg;
+ refreshDriveDlg (driveDlgHandle);
break;
}
break;
Only in programs/winecfg: drive.c.old
Only in programs/winecfg: drive-mappings
Only in programs/winecfg: programs
diff -ur --exclude-from=diff-exclusions ../head/programs/winecfg/winecfg.c programs/winecfg/winecfg.c
--- ../head/programs/winecfg/winecfg.c 2003-09-05 22:55:02.000000000 +0100
+++ programs/winecfg/winecfg.c 2003-09-07 15:44:59.000000000 +0100
@@ -106,7 +106,7 @@
}
/*****************************************************************************
- * 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
* char *subKey : the name of the config section
@@ -209,9 +209,9 @@
assert( key != NULL );
if (action == ACTION_SET) assert( newValue != NULL );
- trans->section = section;
- trans->key = key;
- trans->newValue = newValue;
+ trans->section = strdup(section);
+ trans->key = strdup(key);
+ trans->newValue = strdup(newValue);
trans->action = action;
trans->next = NULL;
trans->prev = NULL;
@@ -225,7 +225,10 @@
tqhead = trans;
}
- if (instantApply) processTransaction(trans);
+ if (instantApply) {
+ processTransaction(trans);
+ destroyTransaction(trans);
+ }
}
void processTransaction(struct transaction *trans) {
@@ -235,16 +238,28 @@
} else if (trans->action == ACTION_REMOVE) {
WINE_TRACE("Removing %s\\%s", trans->section, trans->key);
removeConfigValue(trans->section, trans->key);
- }
+ }
/* TODO: implement notifications here */
}
void processTransQueue() {
WINE_TRACE("\n");
- while (tqhead != NULL) {
- processTransaction(tqhead);
- tqhead = tqhead->next;
- destroyTransaction(tqhead->prev);
+ while (tqtail != NULL) {
+ struct transaction *next = tqtail->next;
+ processTransaction(tqtail);
+ 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;
+}
diff -ur --exclude-from=diff-exclusions ../head/programs/winecfg/winecfg.h programs/winecfg/winecfg.h
--- ../head/programs/winecfg/winecfg.h 2003-09-05 22:55:02.000000000 +0100
+++ programs/winecfg/winecfg.h 2003-09-07 15:15:03.000000000 +0100
@@ -92,6 +92,10 @@
INT_PTR CALLBACK DriveDlgProc (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 WINEHQ_KEY_ROOT "Software\\Wine\\WineCfg\\Config"
#endif
More information about the wine-patches
mailing list