1/*
2 *  dsnchooser.c
3 *
4 *  $Id: dsnchooser.c,v 1.16 2007/02/02 11:58:14 source Exp $
5 *
6 *  The iODBC driver manager.
7 *
8 *  Copyright (C) 1996-2006 by OpenLink Software <iodbc@openlinksw.com>
9 *  All Rights Reserved.
10 *
11 *  This software is released under the terms of either of the following
12 *  licenses:
13 *
14 *      - GNU Library General Public License (see LICENSE.LGPL)
15 *      - The BSD License (see LICENSE.BSD).
16 *
17 *  Note that the only valid version of the LGPL license as far as this
18 *  project is concerned is the original GNU Library General Public License
19 *  Version 2, dated June 1991.
20 *
21 *  While not mandated by the BSD license, any patches you make to the
22 *  iODBC source code may be contributed back into the iODBC project
23 *  at your discretion. Contributions will benefit the Open Source and
24 *  Data Access community as a whole. Submissions may be made at:
25 *
26 *      http://www.iodbc.org
27 *
28 *
29 *  GNU Library Generic Public License Version 2
30 *  ============================================
31 *  This library is free software; you can redistribute it and/or
32 *  modify it under the terms of the GNU Library General Public
33 *  License as published by the Free Software Foundation; only
34 *  Version 2 of the License dated June 1991.
35 *
36 *  This library is distributed in the hope that it will be useful,
37 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
38 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
39 *  Library General Public License for more details.
40 *
41 *  You should have received a copy of the GNU Library General Public
42 *  License along with this library; if not, write to the Free
43 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
44 *
45 *
46 *  The BSD License
47 *  ===============
48 *  Redistribution and use in source and binary forms, with or without
49 *  modification, are permitted provided that the following conditions
50 *  are met:
51 *
52 *  1. Redistributions of source code must retain the above copyright
53 *     notice, this list of conditions and the following disclaimer.
54 *  2. Redistributions in binary form must reproduce the above copyright
55 *     notice, this list of conditions and the following disclaimer in
56 *     the documentation and/or other materials provided with the
57 *     distribution.
58 *  3. Neither the name of OpenLink Software Inc. nor the names of its
59 *     contributors may be used to endorse or promote products derived
60 *     from this software without specific prior written permission.
61 *
62 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
63 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
64 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
65 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR
66 *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
67 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
68 *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
69 *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
70 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
71 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73 */
74
75#include <iodbc.h>
76
77#include <stdio.h>
78#include <sys/types.h>
79#include <sys/stat.h>
80#include <sys/param.h>
81#include <dirent.h>
82#include <errno.h>
83
84#include <sqltypes.h>
85#include <dlproc.h>
86
87#include "../gui.h"
88#include "odbc4.xpm"
89
90
91#ifndef MAXPATHLEN
92#define MAXPATHLEN	1024
93#endif
94
95/*
96 *  Linux glibc has the function, but does not have the prototype
97 *  with the default header files.
98 */
99#if defined(HAVE_ASPRINTF) && defined(__GLIBC__)
100extern int asprintf (char **ret, const char *format, ...);
101#endif
102
103
104char *szDSNColumnNames[] = {
105  "Name",
106  "Description",
107  "Driver"
108};
109
110char *szTabNames[] = {
111  "User DSN",
112  "System DSN",
113  "File DSN",
114  "ODBC Drivers",
115  "Connection Pooling",
116  "Tracing",
117  "About"
118};
119
120char *szDSNButtons[] = {
121  "_Add",
122  "_Remove",
123  "Confi_gure",
124  "_Test",
125  "_Set Dir",
126};
127
128
129void
130addlistofdir_to_optionmenu (GtkWidget *widget, LPCSTR path,
131    TDSNCHOOSER *choose_t)
132{
133  GtkWidget *menu, *menu_item;
134  char *curr_dir, *prov, *dir;
135  void **array;
136
137  if (!path || !GTK_IS_OPTION_MENU (widget) || !(prov = strdup (path)))
138    return;
139
140  if (prov[STRLEN (prov) - 1] == '/' && STRLEN (prov) > 1)
141    prov[STRLEN (prov) - 1] = 0;
142
143  /* Add the root directory */
144  menu = gtk_menu_new ();
145  menu_item = gtk_menu_item_new_with_label ("/");
146  gtk_widget_show (menu_item);
147  gtk_menu_prepend (GTK_MENU (menu), menu_item);
148  if (!(array = (void **) malloc (sizeof (void *) * 2)))
149    return;
150  array[0] = g_strdup ("/");
151  array[1] = choose_t;
152  gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
153      GTK_SIGNAL_FUNC (filedsn_lookin_clicked), array);
154
155  for (curr_dir = prov, dir = NULL; curr_dir;
156      curr_dir = strchr (curr_dir + 1, '/'))
157    {
158      if (strchr (curr_dir + 1, '/'))
159	{
160	  dir = strchr (curr_dir + 1, '/');
161	  *dir = 0;
162	}
163
164      menu_item = gtk_menu_item_new_with_label (prov);
165      gtk_widget_show (menu_item);
166      gtk_menu_prepend (GTK_MENU (menu), menu_item);
167      if (!(array = (void **) malloc (sizeof (void *) * 2)))
168	return;
169      array[0] = g_strdup (prov);
170      array[1] = choose_t;
171      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
172	  GTK_SIGNAL_FUNC (filedsn_lookin_clicked), array);
173      if (dir)
174	*dir = '/';
175    }
176
177  gtk_option_menu_remove_menu (GTK_OPTION_MENU (widget));
178  gtk_option_menu_set_menu (GTK_OPTION_MENU (widget), menu);
179
180  free (prov);
181}
182
183
184void
185adddirectories_to_list (HWND hwnd, GtkWidget *widget, LPCSTR path)
186{
187  DIR *dir;
188#if defined (HAVE_ASPRINTF)
189  char *path_buf;
190#else
191  char path_buf[MAXPATHLEN];
192#endif
193  struct dirent *dir_entry;
194  struct stat fstat;
195  char *data[1];
196
197  if (!path || !GTK_IS_CLIST (widget))
198    return;
199
200  if ((dir = opendir (path)))
201    {
202      /* Remove all the entries */
203      gtk_clist_clear (GTK_CLIST (widget));
204
205      while ((dir_entry = readdir (dir)))
206	{
207#if defined (HAVE_ASPRINTF)
208	  asprintf (&path_buf, "%s/%s", path, dir_entry->d_name);
209#elif defined (HAVE_SNPRINTF)
210	  snprintf (path_buf, sizeof (path_buf), "%s/%s",
211	      path, dir_entry->d_name);
212#else
213	  STRCPY (path_buf, path);
214	  if (path[STRLEN (path) - 1] != '/')
215	    STRCAT (path_buf, "/");
216	  STRCAT (path_buf, dir_entry->d_name);
217#endif
218
219	  if (stat ((LPCSTR) path_buf, &fstat) >= 0
220	      && S_ISDIR (fstat.st_mode))
221	    if (strcmp (path, "/") || strcmp (dir_entry->d_name, ".."))
222	      {
223		data[0] = dir_entry->d_name;
224		gtk_clist_append (GTK_CLIST (widget), data);
225	      }
226
227#if defined (HAVE_ASPRINTF)
228	  free (path_buf);
229#endif
230	}
231
232      /* Close the directory entry */
233      closedir (dir);
234
235      if (GTK_CLIST (widget)->rows > 0)
236	gtk_clist_sort (GTK_CLIST (widget));
237    }
238  else
239    create_error (hwnd, NULL, "Error during accessing directory information:",
240	strerror (errno));
241}
242
243
244void
245addfiles_to_list (HWND hwnd, GtkWidget *widget, LPCSTR path)
246{
247  DIR *dir;
248#if defined (HAVE_ASPRINTF)
249  char *path_buf;
250#else
251  char path_buf[MAXPATHLEN];
252#endif
253  struct dirent *dir_entry;
254  struct stat fstat;
255  char *data[1];
256
257  if (!path || !GTK_IS_CLIST (widget))
258    return;
259
260  if ((dir = opendir (path)))
261    {
262      /* Remove all the entries */
263      gtk_clist_clear (GTK_CLIST (widget));
264
265      while ((dir_entry = readdir (dir)))
266	{
267#if defined (HAVE_ASPRINTF)
268	  asprintf (&path_buf, "%s/%s", path, dir_entry->d_name);
269#elif defined (HAVE_SNPRINTF)
270	  snprintf (path_buf, sizeof (path_buf), "%s/%s",
271	      path, dir_entry->d_name);
272#else
273	  STRCPY (path_buf, path);
274	  if (path[STRLEN (path) - 1] != '/')
275	    STRCAT (path_buf, "/");
276	  STRCAT (path_buf, dir_entry->d_name);
277#endif
278
279	  if (stat ((LPCSTR) path_buf, &fstat) >= 0
280	      && !S_ISDIR (fstat.st_mode)
281	      && strstr (dir_entry->d_name, ".dsn"))
282	    {
283	      data[0] = dir_entry->d_name;
284	      gtk_clist_append (GTK_CLIST (widget), data);
285	    }
286
287#if defined (HAVE_ASPRINTF)
288	  free (path_buf);
289#endif
290	}
291
292      /* Close the directory entry */
293      closedir (dir);
294
295      if (GTK_CLIST (widget)->rows > 0)
296	gtk_clist_sort (GTK_CLIST (widget));
297    }
298}
299
300
301void
302adddsns_to_list (GtkWidget *widget, BOOL systemDSN)
303{
304  char *curr, *buffer = (char *) malloc (sizeof (char) * 65536);
305  char diz[1024], driver[1024];
306  char *data[3];
307  int len, _case = 0;
308
309  if (!buffer || !GTK_IS_CLIST (widget))
310    return;
311  gtk_clist_clear (GTK_CLIST (widget));
312
313  /* Get the list of DSN in the user context */
314  SQLSetConfigMode (systemDSN ? ODBC_SYSTEM_DSN : ODBC_USER_DSN);
315  len =
316      SQLGetPrivateProfileString ("ODBC Data Sources", NULL, "", buffer,
317      65536, NULL);
318  if (len)
319    goto process;
320
321  _case = 1;
322  SQLSetConfigMode (systemDSN ? ODBC_SYSTEM_DSN : ODBC_USER_DSN);
323  len =
324      SQLGetPrivateProfileString ("ODBC 32 bit Data Sources", NULL, "",
325      buffer, 65536, NULL);
326  if (len)
327    goto process;
328
329  goto end;
330
331process:
332  for (curr = buffer; *curr; curr += (STRLEN (curr) + 1))
333    {
334      SQLSetConfigMode (systemDSN ? ODBC_SYSTEM_DSN : ODBC_USER_DSN);
335      SQLGetPrivateProfileString (curr, "Description", "", diz, sizeof (diz),
336	  NULL);
337      SQLSetConfigMode (systemDSN ? ODBC_SYSTEM_DSN : ODBC_USER_DSN);
338      switch (_case)
339	{
340	case 0:
341	  SQLGetPrivateProfileString ("ODBC Data Sources", curr, "", driver,
342	      sizeof (driver), NULL);
343	  break;
344	case 1:
345	  SQLGetPrivateProfileString ("ODBC 32 bit Data Sources", curr, "",
346	      driver, sizeof (driver), NULL);
347	  break;
348	};
349
350      if (STRLEN (curr) && STRLEN (driver))
351	{
352	  data[0] = curr;
353	  data[1] = diz;
354	  data[2] = driver;
355	  gtk_clist_append (GTK_CLIST (widget), data);
356	}
357    }
358
359end:
360  SQLSetConfigMode (ODBC_BOTH_DSN);
361
362  if (GTK_CLIST (widget)->rows > 0)
363    {
364      gtk_clist_columns_autosize (GTK_CLIST (widget));
365      gtk_clist_sort (GTK_CLIST (widget));
366    }
367
368  /* Make the clean up */
369  free (buffer);
370}
371
372
373static void
374dsnchooser_switch_page (GtkNotebook *notebook, GtkNotebookPage *page,
375    gint page_num, TDSNCHOOSER *choose_t)
376{
377  switch (page_num)
378    {
379    case 0:
380      if (choose_t)
381	{
382	  choose_t->type_dsn = USER_DSN;
383	  adddsns_to_list (choose_t->udsnlist, FALSE);
384	}
385      break;
386
387    case 1:
388      if (choose_t)
389	{
390	  choose_t->type_dsn = SYSTEM_DSN;
391	  adddsns_to_list (choose_t->sdsnlist, TRUE);
392	}
393      break;
394
395    case 2:
396      if (choose_t)
397	{
398	  choose_t->type_dsn = FILE_DSN;
399          addlistofdir_to_optionmenu(choose_t->dir_combo,
400	      choose_t->curr_dir, choose_t);
401          adddirectories_to_list(choose_t->mainwnd,
402	      choose_t->dir_list, choose_t->curr_dir);
403          addfiles_to_list(choose_t->mainwnd,
404	      choose_t->file_list, choose_t->curr_dir);
405	}
406      break;
407    };
408
409  if (choose_t)
410    {
411      if (choose_t->uremove)
412	gtk_widget_set_sensitive (choose_t->uremove, FALSE);
413      if (choose_t->uconfigure)
414	gtk_widget_set_sensitive (choose_t->uconfigure, FALSE);
415      if (choose_t->utest)
416	gtk_widget_set_sensitive (choose_t->utest, FALSE);
417      if (choose_t->sremove)
418	gtk_widget_set_sensitive (choose_t->sremove, FALSE);
419      if (choose_t->sconfigure)
420	gtk_widget_set_sensitive (choose_t->sconfigure, FALSE);
421      if (choose_t->stest)
422	gtk_widget_set_sensitive (choose_t->stest, FALSE);
423      if (choose_t->fremove)
424        gtk_widget_set_sensitive(choose_t->fremove, FALSE);
425      if (choose_t->fconfigure)
426        gtk_widget_set_sensitive(choose_t->fconfigure, FALSE);
427      if (choose_t->ftest)
428        gtk_widget_set_sensitive(choose_t->ftest, FALSE);
429    }
430}
431
432
433static BOOL
434test_driver_connect (TDSNCHOOSER *choose_t, char *connstr)
435{
436  HENV henv;
437  HDBC hdbc;
438
439#if (ODBCVER < 0x300)
440  if (SQLAllocEnv (&henv) != SQL_SUCCESS)
441#else
442  if (SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv) != SQL_SUCCESS)
443#endif
444    {
445      _iodbcdm_nativeerrorbox (choose_t->mainwnd,
446	  henv, SQL_NULL_HDBC, SQL_NULL_HSTMT);
447      return FALSE;
448    }
449
450#if (ODBCVER < 0x300)
451  if (SQLAllocConnect (henv, &hdbc) != SQL_SUCCESS)
452#else
453  SQLSetEnvAttr (henv, SQL_ATTR_ODBC_VERSION,
454      (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_UINTEGER);
455  if (SQLAllocHandle (SQL_HANDLE_DBC, henv, &hdbc) != SQL_SUCCESS)
456#endif
457    {
458      _iodbcdm_nativeerrorbox (choose_t->mainwnd, henv, hdbc, SQL_NULL_HSTMT);
459      SQLFreeEnv (henv);
460      return FALSE;
461    }
462
463  switch (choose_t->type_dsn)
464    {
465    case USER_DSN:
466      SQLSetConfigMode (ODBC_USER_DSN);
467      break;
468    case SYSTEM_DSN:
469      SQLSetConfigMode (ODBC_SYSTEM_DSN);
470      break;
471    case FILE_DSN:
472      SQLSetConfigMode (ODBC_BOTH_DSN);
473      break;
474    }
475  if (SQLDriverConnect (hdbc, choose_t->mainwnd, connstr, SQL_NTS,
476          NULL, 0, NULL, SQL_DRIVER_PROMPT) != SQL_SUCCESS)
477    {
478      _iodbcdm_nativeerrorbox (choose_t->mainwnd, henv, hdbc, SQL_NULL_HSTMT);
479      SQLFreeEnv (henv);
480      return FALSE;
481    }
482  else
483    SQLDisconnect (hdbc);
484
485#if (ODBCVER < 0x300)
486  SQLFreeConnect (hdbc);
487  SQLFreeEnv (henv);
488#else
489  SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
490  SQLFreeHandle (SQL_HANDLE_ENV, henv);
491#endif
492
493  return TRUE;
494}
495
496
497void
498userdsn_add_clicked (GtkWidget *widget, TDSNCHOOSER *choose_t)
499{
500  char connstr[4096] = { "" };
501  char drv[1024] = { ""};
502  int sqlstat;
503  DWORD error;
504
505  if (choose_t)
506    {
507      /* Try first to get the driver name */
508      SQLSetConfigMode (ODBC_USER_DSN);
509      if (_iodbcdm_drvchoose_dialbox (choose_t->mainwnd, drv,
510      	sizeof (drv), &sqlstat) == SQL_SUCCESS)
511	{
512	  SQLSetConfigMode (ODBC_USER_DSN);
513	  if (!SQLConfigDataSource (choose_t->mainwnd, ODBC_ADD_DSN,
514		  drv + STRLEN ("DRIVER="), connstr))
515	    {
516	      if (SQLInstallerError (1, &error, connstr,
517	         sizeof (connstr), NULL) != SQL_NO_DATA)
518		_iodbcdm_errorbox (choose_t->mainwnd, NULL,
519		    "An error occured when trying to add the DSN : ");
520	      goto done;
521	    }
522
523	  adddsns_to_list (choose_t->udsnlist, FALSE);
524	}
525
526    done:
527      if (GTK_CLIST (choose_t->udsnlist)->selection == NULL)
528	{
529	  if (choose_t->uremove)
530	    gtk_widget_set_sensitive (choose_t->uremove, FALSE);
531	  if (choose_t->uconfigure)
532	    gtk_widget_set_sensitive (choose_t->uconfigure, FALSE);
533	  if (choose_t->utest)
534	    gtk_widget_set_sensitive (choose_t->utest, FALSE);
535	}
536    }
537
538  return;
539}
540
541
542void
543userdsn_remove_clicked (GtkWidget *widget, TDSNCHOOSER *choose_t)
544{
545  char dsn[1024] = { "\0" };
546  char *szDSN = NULL, *szDriver = NULL;
547
548  if (choose_t)
549    {
550      /* Retrieve the DSN name */
551      if (GTK_CLIST (choose_t->udsnlist)->selection != NULL)
552	{
553	  gtk_clist_get_text (GTK_CLIST (choose_t->udsnlist),
554	      GPOINTER_TO_INT (GTK_CLIST (choose_t->udsnlist)->selection->
555		  data), 0, &szDSN);
556	  gtk_clist_get_text (GTK_CLIST (choose_t->udsnlist),
557	      GPOINTER_TO_INT (GTK_CLIST (choose_t->udsnlist)->selection->
558		  data), 2, &szDriver);
559	}
560
561      /* Call the right function */
562      if (szDSN
563	  && create_confirm (choose_t->mainwnd, szDSN,
564	      "Are you sure you want to remove this DSN ?"))
565	{
566	  sprintf (dsn, "DSN=%s", szDSN);
567	  if (!SQLConfigDataSource (choose_t->mainwnd, ODBC_REMOVE_DSN,
568		  szDriver, dsn))
569	    _iodbcdm_errorbox (choose_t->mainwnd, szDSN,
570		"An error occured when trying to remove the DSN : ");
571	  adddsns_to_list (choose_t->udsnlist, FALSE);
572	}
573
574      if (GTK_CLIST (choose_t->udsnlist)->selection == NULL)
575	{
576	  if (choose_t->uremove)
577	    gtk_widget_set_sensitive (choose_t->uremove, FALSE);
578	  if (choose_t->uconfigure)
579	    gtk_widget_set_sensitive (choose_t->uconfigure, FALSE);
580	  if (choose_t->utest)
581	    gtk_widget_set_sensitive (choose_t->utest, FALSE);
582	}
583    }
584}
585
586
587void
588userdsn_configure_clicked (GtkWidget *widget, TDSNCHOOSER *choose_t)
589{
590  char connstr[4096] = { 0 };
591  char tokenstr[4096] = { 0 };
592  char *szDSN = NULL, *szDriver = NULL, *curr, *cour;
593  int size = sizeof (connstr);
594  DWORD error;
595
596  if (choose_t)
597    {
598      /* Retrieve the DSN name */
599      if (GTK_CLIST (choose_t->udsnlist)->selection != NULL)
600	{
601	  gtk_clist_get_text (GTK_CLIST (choose_t->udsnlist),
602	      GPOINTER_TO_INT (GTK_CLIST (choose_t->udsnlist)->selection->
603		  data), 0, &szDSN);
604	  gtk_clist_get_text (GTK_CLIST (choose_t->udsnlist),
605	      GPOINTER_TO_INT (GTK_CLIST (choose_t->udsnlist)->selection->
606		  data), 2, &szDriver);
607	}
608
609      /* Call the right function */
610      if (szDSN)
611	{
612	  sprintf (connstr, "DSN=%s", szDSN);
613	  size -= (STRLEN (connstr) + 1);
614
615	  SQLSetConfigMode (ODBC_USER_DSN);
616	  if (!SQLGetPrivateProfileString (szDSN, NULL, "", tokenstr,
617		  sizeof (tokenstr), NULL))
618	    {
619	      _iodbcdm_errorbox (choose_t->mainwnd, szDSN,
620		  "An error occured when trying to configure the DSN : ");
621	      goto done;
622	    }
623
624	  for (curr = tokenstr, cour = connstr + STRLEN (connstr) + 1; *curr;
625	      curr += (STRLEN (curr) + 1), cour += (STRLEN (cour) + 1))
626	    {
627	      STRCPY (cour, curr);
628	      cour[STRLEN (curr)] = '=';
629	      SQLSetConfigMode (ODBC_USER_DSN);
630	      SQLGetPrivateProfileString (szDSN, curr, "",
631		  cour + STRLEN (curr) + 1, size - STRLEN (curr) - 1, NULL);
632	      size -= (STRLEN (cour) + 1);
633	    }
634
635	  *cour = 0;
636
637	  SQLSetConfigMode (ODBC_USER_DSN);
638	  if (!SQLConfigDataSource (choose_t->mainwnd, ODBC_CONFIG_DSN,
639		  szDriver, connstr))
640	    {
641	      if (SQLInstallerError (1, &error, connstr, sizeof (connstr),
642		      NULL) != SQL_NO_DATA
643		  && error != ODBC_ERROR_REQUEST_FAILED)
644		_iodbcdm_errorbox (choose_t->mainwnd, szDSN,
645		    "An error occured when trying to configure the DSN : ");
646	      goto done;
647	    }
648
649	  adddsns_to_list (choose_t->udsnlist, FALSE);
650	}
651
652    done:
653      if (GTK_CLIST (choose_t->udsnlist)->selection == NULL)
654	{
655	  if (choose_t->uremove)
656	    gtk_widget_set_sensitive (choose_t->uremove, FALSE);
657	  if (choose_t->uconfigure)
658	    gtk_widget_set_sensitive (choose_t->uconfigure, FALSE);
659	  if (choose_t->utest)
660	    gtk_widget_set_sensitive (choose_t->utest, FALSE);
661	}
662    }
663
664  return;
665}
666
667
668void
669userdsn_test_clicked (GtkWidget *widget, TDSNCHOOSER *choose_t)
670{
671  HENV henv;
672  HDBC hdbc;
673  SWORD buflen;
674  char connstr[4096] = { 0 };
675  char outconnstr[4096] = { 0 };
676  char *szDSN;
677
678  if (choose_t)
679    {
680      /* Retrieve the DSN name */
681      if (GTK_CLIST (choose_t->udsnlist)->selection != NULL)
682	gtk_clist_get_text (GTK_CLIST (choose_t->udsnlist),
683	    GPOINTER_TO_INT (GTK_CLIST (choose_t->udsnlist)->selection->data),
684	    0, &szDSN);
685
686      if (szDSN && STRLEN (szDSN))
687	{
688	  snprintf (connstr, sizeof (connstr), "DSN=%s", szDSN);
689	  if (test_driver_connect (choose_t, connstr))
690	    {
691	      _iodbcdm_messagebox (choose_t->mainwnd, szDSN,
692		  "The connection DSN was tested successfully, and can be used at this time.");
693	    }
694	}
695
696      if (GTK_CLIST (choose_t->udsnlist)->selection == NULL)
697	{
698	  if (choose_t->uremove)
699	    gtk_widget_set_sensitive (choose_t->uremove, FALSE);
700	  if (choose_t->uconfigure)
701	    gtk_widget_set_sensitive (choose_t->uconfigure, FALSE);
702	  if (choose_t->utest)
703	    gtk_widget_set_sensitive (choose_t->utest, FALSE);
704	}
705    }
706}
707
708
709void
710systemdsn_add_clicked (GtkWidget *widget, TDSNCHOOSER *choose_t)
711{
712  char connstr[4096] = { 0 };
713  char drv[1024] = { 0 };
714  int sqlstat;
715  DWORD error;
716
717  if (choose_t)
718    {
719      /* Try first to get the driver name */
720      SQLSetConfigMode (ODBC_SYSTEM_DSN);
721      if (_iodbcdm_drvchoose_dialbox (choose_t->mainwnd, drv, sizeof (drv),
722	      &sqlstat) == SQL_SUCCESS)
723	{
724	  if (!SQLConfigDataSource (choose_t->mainwnd, ODBC_ADD_SYS_DSN,
725		  drv + STRLEN ("DRIVER="), connstr))
726	    {
727	      if (SQLInstallerError (1, &error, connstr, sizeof (connstr),
728		      NULL) != SQL_NO_DATA)
729		_iodbcdm_errorbox (choose_t->mainwnd, NULL,
730		    "An error occured when trying to add the DSN : ");
731	      goto done;
732	    }
733
734	  adddsns_to_list (choose_t->sdsnlist, TRUE);
735	}
736
737    done:
738      if (GTK_CLIST (choose_t->sdsnlist)->selection == NULL)
739	{
740	  if (choose_t->sremove)
741	    gtk_widget_set_sensitive (choose_t->sremove, FALSE);
742	  if (choose_t->sconfigure)
743	    gtk_widget_set_sensitive (choose_t->sconfigure, FALSE);
744	  if (choose_t->stest)
745	    gtk_widget_set_sensitive (choose_t->stest, FALSE);
746	}
747    }
748
749  return;
750}
751
752
753void
754systemdsn_remove_clicked (GtkWidget *widget, TDSNCHOOSER *choose_t)
755{
756  char dsn[1024] = { 0 };
757  char *szDSN = NULL, *szDriver = NULL;
758
759  if (choose_t)
760    {
761      /* Retrieve the DSN name */
762      if (GTK_CLIST (choose_t->sdsnlist)->selection != NULL)
763	{
764	  gtk_clist_get_text (GTK_CLIST (choose_t->sdsnlist),
765	      GPOINTER_TO_INT (GTK_CLIST (choose_t->sdsnlist)->selection->
766		  data), 0, &szDSN);
767	  gtk_clist_get_text (GTK_CLIST (choose_t->sdsnlist),
768	      GPOINTER_TO_INT (GTK_CLIST (choose_t->sdsnlist)->selection->
769		  data), 2, &szDriver);
770	}
771
772      /* Call the right function */
773      if (szDSN
774	  && create_confirm (choose_t->mainwnd, szDSN,
775	      "Are you sure you want to remove this DSN ?"))
776	{
777	  sprintf (dsn, "DSN=%s", szDSN);
778	  if (!SQLConfigDataSource (choose_t->mainwnd, ODBC_REMOVE_SYS_DSN,
779		  szDriver, dsn))
780	    _iodbcdm_errorbox (choose_t->mainwnd, szDSN,
781		"An error occured when trying to remove the DSN : ");
782	  adddsns_to_list (choose_t->sdsnlist, TRUE);
783	}
784
785      if (GTK_CLIST (choose_t->sdsnlist)->selection == NULL)
786	{
787	  if (choose_t->sremove)
788	    gtk_widget_set_sensitive (choose_t->sremove, FALSE);
789	  if (choose_t->sconfigure)
790	    gtk_widget_set_sensitive (choose_t->sconfigure, FALSE);
791	  if (choose_t->stest)
792	    gtk_widget_set_sensitive (choose_t->stest, FALSE);
793	}
794    }
795}
796
797
798void
799systemdsn_configure_clicked (GtkWidget *widget, TDSNCHOOSER *choose_t)
800{
801  char connstr[4096] = { 0 };
802  char tokenstr[4096] = { 0 };
803  char *szDSN = NULL, *szDriver = NULL, *curr, *cour;
804  int size = sizeof (connstr);
805  DWORD error;
806
807  if (choose_t)
808    {
809      /* Retrieve the DSN name */
810      if (GTK_CLIST (choose_t->sdsnlist)->selection != NULL)
811	{
812	  gtk_clist_get_text (GTK_CLIST (choose_t->sdsnlist),
813	      GPOINTER_TO_INT (GTK_CLIST (choose_t->sdsnlist)->selection->
814		  data), 0, &szDSN);
815	  gtk_clist_get_text (GTK_CLIST (choose_t->sdsnlist),
816	      GPOINTER_TO_INT (GTK_CLIST (choose_t->sdsnlist)->selection->
817		  data), 2, &szDriver);
818	}
819
820      /* Call the right function */
821      if (szDSN)
822	{
823	  sprintf (connstr, "DSN=%s", szDSN);
824	  size -= (STRLEN (connstr) + 1);
825
826	  SQLSetConfigMode (ODBC_SYSTEM_DSN);
827	  if (!SQLGetPrivateProfileString (szDSN, NULL, "", tokenstr,
828		  sizeof (tokenstr), NULL))
829	    {
830	      _iodbcdm_errorbox (choose_t->mainwnd, szDSN,
831		  "An error occured when trying to configure the DSN : ");
832	      goto done;
833	    }
834
835	  for (curr = tokenstr, cour = connstr + STRLEN (connstr) + 1; *curr;
836	      curr += (STRLEN (curr) + 1), cour += (STRLEN (cour) + 1))
837	    {
838	      STRCPY (cour, curr);
839	      cour[STRLEN (curr)] = '=';
840	      SQLSetConfigMode (ODBC_SYSTEM_DSN);
841	      SQLGetPrivateProfileString (szDSN, curr, "",
842		  cour + STRLEN (curr) + 1, size - STRLEN (curr) - 1, NULL);
843	      size -= (STRLEN (cour) + 1);
844	    }
845
846	  *cour = 0;
847
848	  if (!SQLConfigDataSource (choose_t->mainwnd, ODBC_CONFIG_SYS_DSN,
849		  szDriver, connstr))
850	    {
851	      if (SQLInstallerError (1, &error, connstr, sizeof (connstr),
852		      NULL) != SQL_NO_DATA
853		  && error != ODBC_ERROR_REQUEST_FAILED)
854		_iodbcdm_errorbox (choose_t->mainwnd, szDSN,
855		    "An error occured when trying to configure the DSN : ");
856	      goto done;
857	    }
858
859	  adddsns_to_list (choose_t->sdsnlist, TRUE);
860	}
861
862    done:
863      if (GTK_CLIST (choose_t->sdsnlist)->selection == NULL)
864	{
865	  if (choose_t->sremove)
866	    gtk_widget_set_sensitive (choose_t->sremove, FALSE);
867	  if (choose_t->sconfigure)
868	    gtk_widget_set_sensitive (choose_t->sconfigure, FALSE);
869	  if (choose_t->stest)
870	    gtk_widget_set_sensitive (choose_t->stest, FALSE);
871	}
872    }
873
874  return;
875}
876
877
878void
879systemdsn_test_clicked (GtkWidget * widget, TDSNCHOOSER * choose_t)
880{
881  HENV henv;
882  HDBC hdbc;
883  SWORD buflen;
884  SQLCHAR connstr[4096] = { 0 };
885  SQLCHAR outconnstr[4096] = { 0 };
886  char *szDSN = NULL;
887
888  if (choose_t)
889    {
890      /* Retrieve the DSN name */
891      if (GTK_CLIST (choose_t->sdsnlist)->selection != NULL)
892	gtk_clist_get_text (GTK_CLIST (choose_t->sdsnlist),
893	    GPOINTER_TO_INT (GTK_CLIST (choose_t->sdsnlist)->selection->data),
894	    0, &szDSN);
895
896      if (szDSN && STRLEN (szDSN))
897	{
898	  snprintf (connstr, sizeof (connstr), "DSN=%s", szDSN);
899	  if (test_driver_connect (choose_t, connstr))
900	    {
901	      _iodbcdm_messagebox (choose_t->mainwnd, szDSN,
902		  "The connection DSN was tested successfully, and can be used at this time.");
903	    }
904        }
905
906      if (GTK_CLIST (choose_t->sdsnlist)->selection == NULL)
907	{
908	  if (choose_t->sremove)
909	    gtk_widget_set_sensitive (choose_t->sremove, FALSE);
910	  if (choose_t->sconfigure)
911	    gtk_widget_set_sensitive (choose_t->sconfigure, FALSE);
912	  if (choose_t->stest)
913	    gtk_widget_set_sensitive (choose_t->stest, FALSE);
914	}
915
916    }
917}
918
919
920static void
921filedsn_get_dsn (char *filename, char *dsn, size_t dsn_sz)
922{
923  char *p;
924
925  /* Cut everything up to the last slash */
926  p = strrchr (filename, '/');
927  if (p != NULL)
928    p++;
929  else
930    p = filename;
931  snprintf (dsn, dsn_sz, "%s", p);
932
933  /* Cut .dsn extension */
934  p = strrchr (dsn, '.');
935  if (p != NULL && !strcasecmp (p, ".dsn"))
936    *p = '\0';
937}
938
939
940static BOOL _CheckDriverLoginDlg (char *drv);
941
942static void
943filedsn_configure (TDSNCHOOSER *choose_t, char *drv, char *dsn, char *in_attrs,
944	BOOL b_add, BOOL verify_conn)
945{
946  char *connstr = NULL;
947  size_t len;			/* current connstr len    */
948  size_t add_len;		/* len of appended string */
949  LPSTR attrs = NULL, curr, tmp, attr_lst = NULL;
950  BOOL b_Save = TRUE;
951
952  attrs = in_attrs;
953
954  if (!b_add && !_CheckDriverLoginDlg(drv + STRLEN("DRIVER=")))
955    {
956      /*  Get DSN name and additional attributes  */
957      attr_lst = create_fgensetup (choose_t->mainwnd, dsn, in_attrs,
958         b_add, &verify_conn);
959      attrs = attr_lst;
960    }
961
962  if (!attrs)
963    {
964      create_error (choose_t->mainwnd, NULL, "Error adding File DSN:",
965          strerror (ENOMEM));
966      return;
967    }
968  if (attrs == (LPSTR) - 1L)
969    return;
970
971  /* Build the connection string */
972  connstr = strdup (drv);
973  len = strlen (connstr);
974  for (curr = attrs; *curr; curr += (STRLEN (curr) + 1))
975    {
976      if (!strncasecmp (curr, "DSN=", STRLEN ("DSN=")))
977        {
978          if (dsn == NULL)
979            {
980	      /* got dsn name */
981              dsn = curr + STRLEN ("DSN=");
982            }
983	  continue;
984	}
985
986      /* append attr */
987      add_len = 1 + strlen (curr);			/* +1 for ';' */
988      tmp = realloc (connstr, len + add_len + 1);	/* +1 for NUL */
989      if (tmp == NULL)
990        {
991          create_error (choose_t->mainwnd, NULL, "Error adding File DSN:",
992	      strerror (errno));
993	  goto done;
994	}
995      connstr = tmp;
996      snprintf (connstr + len, add_len + 1, ";%s", curr);
997      len += add_len;
998    }
999
1000  /* Nothing to do if no DSN */
1001  if (!dsn || STRLEN (dsn) == 0)
1002    goto done;
1003
1004  if (verify_conn)
1005    {
1006      BOOL ret;
1007
1008      /* Append SAVEFILE */
1009      add_len = strlen (";SAVEFILE=") + strlen (dsn);
1010      tmp = realloc (connstr, len + add_len + 1);		/* +1 for NUL */
1011      if (tmp == NULL)
1012        {
1013          create_error (choose_t->mainwnd, NULL, "Error adding file DSN:",
1014	      strerror (errno));
1015          goto done;
1016        }
1017      connstr = tmp;
1018      snprintf (connstr + len, add_len + 1, ";SAVEFILE=%s", dsn);
1019      len += add_len;
1020
1021      /* Connect to data source */
1022      ret = test_driver_connect (choose_t, connstr);
1023      if (!ret && b_add)
1024        {
1025	  if (create_confirm (choose_t->mainwnd, dsn,
1026	      "Can't check the connection. Do you want to store the FileDSN without verification ?"))
1027            b_Save = TRUE;
1028          else
1029            b_Save = FALSE;
1030        }
1031      else
1032        b_Save = FALSE;
1033    }
1034
1035  if (b_Save)
1036    {
1037      char key[512];
1038      char *p;
1039      size_t sz;
1040
1041      if (drv)
1042        {
1043	  p = strchr(drv, '=');
1044          if (!SQLWriteFileDSN (dsn, "ODBC", "DRIVER", p + 1))
1045            {
1046              create_error (choose_t->mainwnd, NULL, "Error writing File DSN:",
1047	          strerror (errno));
1048	      goto done;
1049	    }
1050        }
1051
1052      for (curr = attrs; *curr; curr += (STRLEN (curr) + 1))
1053        {
1054          if (!strncasecmp (curr, "DSN=", STRLEN ("DSN=")))
1055	    continue;
1056	  else if (!strncasecmp (curr, "PWD=", STRLEN ("PWD=")))
1057	    continue;
1058	  else if (!strncasecmp (curr, "SAVEFILE=", STRLEN ("SAVEFILE=")))
1059	    continue;
1060	  else if (!strncasecmp (curr, "FILEDSN=", STRLEN ("FILEDSN=")))
1061	    continue;
1062
1063	  p = strchr(curr, '=');
1064	  sz = p - curr < sizeof(key) ? p - curr : sizeof(key);
1065	  memset(key, 0, sizeof(key));
1066	  strncpy(key, curr, sz);
1067
1068          if (!SQLWriteFileDSN (dsn, "ODBC", key, p + 1))
1069            {
1070              create_error (choose_t->mainwnd, NULL, "Error writing File DSN:",
1071	          strerror (errno));
1072	      goto done;
1073	    }
1074        }
1075    }
1076
1077
1078done:
1079  if (attr_lst != NULL)
1080    free (attr_lst);
1081  if (connstr != NULL)
1082    free (connstr);
1083}
1084
1085
1086static void
1087filedsn_update_file_list (TDSNCHOOSER *choose_t)
1088{
1089  /* Reset current file */
1090  gtk_entry_set_text (GTK_ENTRY (choose_t->file_entry), "");
1091  if (choose_t->fremove)
1092    gtk_widget_set_sensitive(choose_t->fremove, FALSE);
1093  if (choose_t->fconfigure)
1094    gtk_widget_set_sensitive(choose_t->fconfigure, FALSE);
1095  if (choose_t->ftest)
1096    gtk_widget_set_sensitive(choose_t->ftest, FALSE);
1097
1098  /* Update file list */
1099  addfiles_to_list (choose_t->mainwnd, choose_t->file_list,
1100    choose_t->curr_dir);
1101}
1102
1103
1104void
1105filedsn_add_clicked (GtkWidget *widget, TDSNCHOOSER *choose_t)
1106{
1107  SQLCHAR drv[1024] = { 0 };
1108  int sqlstat;
1109  LPSTR s, attrs;
1110  TFDRIVERCHOOSER drvchoose_t;
1111
1112  if (!choose_t)
1113    return;
1114
1115  /* Try first to get the driver name */
1116  SQLSetConfigMode (ODBC_USER_DSN);
1117
1118  drvchoose_t.attrs = NULL;
1119  drvchoose_t.dsn = NULL;
1120  drvchoose_t.driver = NULL;
1121  drvchoose_t.curr_dir = choose_t->curr_dir;
1122
1123  create_fdriverchooser (choose_t->mainwnd, &drvchoose_t);
1124
1125  /* Check output parameters */
1126  if (drvchoose_t.ok)
1127    {
1128      if (sizeof(drv) > strlen(drvchoose_t.driver) + strlen("DRIVER="))
1129	{
1130          s = strcpy(drv, "DRIVER=");
1131          s += strlen("DRIVER=");
1132          dm_strcpy_W2A(s, drvchoose_t.driver);
1133          attrs = drvchoose_t.attrs;
1134
1135          filedsn_configure(choose_t, drv, drvchoose_t.dsn,
1136          	attrs ? attrs :"\0\0", TRUE, drvchoose_t.verify_conn);
1137          filedsn_update_file_list(choose_t);
1138	}
1139    }
1140
1141  if (drvchoose_t.driver)
1142    free (drvchoose_t.driver);
1143  if (drvchoose_t.attrs)
1144    free (drvchoose_t.attrs);
1145  if (drvchoose_t.dsn)
1146    free (drvchoose_t.dsn);
1147
1148
1149}
1150
1151
1152void
1153filedsn_remove_clicked (GtkWidget *widget, TDSNCHOOSER *choose_t)
1154{
1155  char msg[4096];
1156  gchar *filedsn;
1157
1158  if (!choose_t)
1159    return;
1160
1161  /* Retrieve filedsn file name */
1162  filedsn = gtk_entry_get_text (GTK_ENTRY (choose_t->file_entry));
1163
1164  /* Confirm removing a file dsn */
1165  snprintf (msg, sizeof (msg),
1166      "Are you sure you want to remove the '%s' data source?",
1167      filedsn);
1168  if (!create_confirm (choose_t->mainwnd, NULL, msg))
1169    return;
1170
1171  /* Remove file */
1172  if (unlink (filedsn) < 0)
1173    {
1174      create_error (choose_t->mainwnd, NULL, "Error removing file DSN:",
1175	  strerror (errno));
1176      return;
1177    }
1178
1179  /* Update file list */
1180  filedsn_update_file_list(choose_t);
1181}
1182
1183
1184void
1185filedsn_configure_clicked (GtkWidget *widget, TDSNCHOOSER *choose_t)
1186{
1187  char dsn[1024];
1188  gchar *filedsn;
1189  char *drv = NULL;
1190  char *attrs = NULL;
1191  char *_attrs = NULL;	/* attr list */
1192  size_t len = 0;	/* current attr list length (w/o list-terminating NUL) */
1193  char *p, *p_next;
1194  WORD read_len;
1195  char entries[1024];
1196
1197  if (!choose_t)
1198    return;
1199
1200  /* Retrieve filedsn file name */
1201  filedsn = gtk_entry_get_text (GTK_ENTRY (choose_t->file_entry));
1202  filedsn_get_dsn (filedsn, dsn, sizeof (dsn));
1203
1204  /* Get list of entries in .dsn file */
1205  if (!SQLReadFileDSN (filedsn, "ODBC", NULL,
1206		       entries, sizeof (entries), &read_len))
1207    {
1208      create_error (choose_t->mainwnd, NULL, "SQLReadFileDSN failed", NULL);
1209      goto done;
1210    }
1211
1212  /* add params from the .dsn file */
1213  for (p = entries; *p != '\0'; p = p_next)
1214    {
1215      char *tmp;
1216      size_t add_len;		/* length of added attribute */
1217      char value[1024];
1218
1219      /* get next entry */
1220      p_next = strchr (p, ';');
1221      if (p_next)
1222        *p_next++ = '\0';
1223
1224      if (!SQLReadFileDSN (filedsn, "ODBC", p, value, sizeof(value), &read_len))
1225        {
1226          create_error (choose_t->mainwnd, NULL, "SQLReadFileDSN failed", NULL);
1227          goto done;
1228	}
1229
1230      if (!strcasecmp (p, "DRIVER"))
1231        {
1232          /* got driver keyword */
1233          add_len = strlen ("DRIVER=") + strlen (value) + 1;
1234          drv = malloc (add_len);
1235	  snprintf (drv, add_len, "DRIVER=%s", value);
1236	  continue;
1237	}
1238
1239      /* +1 for '=', +1 for NUL */
1240      add_len = strlen (p) + 1 + strlen (value) + 1;
1241      /* +1 for list-terminating NUL */;
1242      tmp = realloc (attrs, len + add_len + 1);
1243      if (tmp == NULL)
1244        {
1245          create_error (choose_t->mainwnd, NULL, "Error adding file DSN:",
1246              strerror (errno));
1247          goto done;
1248        }
1249      attrs = tmp;
1250      snprintf (attrs + len, add_len, "%s=%s", p, value);
1251      len += add_len;
1252    }
1253
1254  if (drv == NULL)
1255    {
1256      /* no driver found, probably unshareable file data source */
1257      create_error (choose_t->mainwnd, NULL,
1258	  "Can't configure file DSN without DRIVER keyword (probably unshareable data source?)", NULL);
1259      goto done;
1260    }
1261
1262  if (attrs == NULL)
1263    attrs = "\0\0";
1264  else
1265    {
1266      /* NUL-terminate the list */
1267      attrs[len] = '\0';
1268      _attrs = attrs;
1269    }
1270
1271  /* Configure file DSN */
1272  filedsn_configure (choose_t, drv, dsn, attrs, FALSE, TRUE);
1273
1274done:
1275  if (drv != NULL)
1276    free (drv);
1277  if (_attrs != NULL)
1278    free (_attrs);
1279}
1280
1281
1282void
1283filedsn_test_clicked (GtkWidget *widget, TDSNCHOOSER *choose_t)
1284{
1285  char dsn[1024];
1286  char connstr[4096] = { 0 };
1287  gchar *filedsn;
1288
1289  if (!choose_t)
1290    return;
1291
1292  /* Retrieve filedsn file name */
1293  filedsn = gtk_entry_get_text (GTK_ENTRY (choose_t->file_entry));
1294  filedsn_get_dsn (filedsn, dsn, sizeof (dsn));
1295
1296  /* Create connection string and connect to data source */
1297  snprintf (connstr, sizeof (connstr), "FILEDSN=%s", filedsn);
1298  if (test_driver_connect(choose_t, connstr))
1299    {
1300      _iodbcdm_messagebox (choose_t->mainwnd, filedsn,
1301        "The connection DSN was tested successfully, and can be used at this time.");
1302    }
1303}
1304
1305
1306void
1307filedsn_setdir_clicked (GtkWidget *widget, TDSNCHOOSER *choose_t)
1308{
1309  char msg[4096];
1310
1311  if (!choose_t)
1312    return;
1313
1314  /* confirm setting a directory */
1315  snprintf (msg, sizeof (msg),
1316      "Are you sure that you want to make '%s' the default file DSN directory?",
1317      choose_t->curr_dir);
1318  if (!create_confirm (choose_t->mainwnd, NULL, msg))
1319    return;
1320
1321  /* write FileDSNPath value */
1322  if (!SQLWritePrivateProfileString ("ODBC", "FileDSNPath",
1323	   choose_t->curr_dir, "odbcinst.ini"))
1324    {
1325      create_error (choose_t->mainwnd, NULL,
1326	  "Error setting default file DSN directory", NULL);
1327      return;
1328    }
1329}
1330
1331
1332void
1333filedsn_filelist_select (GtkWidget *widget, gint row, gint column,
1334    GdkEvent *event, TDSNCHOOSER *choose_t)
1335{
1336  LPSTR filename = NULL, temp = NULL;
1337
1338  if (choose_t)
1339    {
1340      /* Get the file name */
1341      gtk_clist_get_text (GTK_CLIST (choose_t->file_list), row, 0, &filename);
1342
1343      /* Update the directory and file list */
1344      temp =
1345	  (LPSTR) malloc (STRLEN (filename) + STRLEN (choose_t->curr_dir) +
1346	  2);
1347
1348      if (temp)
1349	{
1350	  STRCPY (temp, choose_t->curr_dir);
1351	  if (temp[STRLEN (temp) - 1] != '/')
1352	    STRCAT (temp, "/");
1353	  STRCAT (temp, filename);
1354
1355	  /* Check if it's a valid file */
1356	  gtk_entry_set_text (GTK_ENTRY (choose_t->file_entry), temp);
1357
1358	  /* And activate buttons */
1359	  if (choose_t->fremove)
1360	    gtk_widget_set_sensitive (choose_t->fremove, TRUE);
1361	  if (choose_t->fconfigure)
1362	    gtk_widget_set_sensitive (choose_t->fconfigure, TRUE);
1363	  if (choose_t->ftest)
1364	    gtk_widget_set_sensitive (choose_t->ftest, TRUE);
1365
1366	  free (temp);
1367	}
1368    }
1369}
1370
1371
1372void
1373filedsn_filelist_unselect (GtkWidget *widget, gint row, gint column,
1374    GdkEvent *event, TDSNCHOOSER *choose_t)
1375{
1376  if (choose_t)
1377    {
1378      /* Check if it's a valid file */
1379      gtk_entry_set_text (GTK_ENTRY (choose_t->file_entry), "");
1380
1381      /* And des-activate buttons */
1382      if (choose_t->fremove)
1383	gtk_widget_set_sensitive (choose_t->fremove, FALSE);
1384      if (choose_t->fconfigure)
1385	gtk_widget_set_sensitive (choose_t->fconfigure, FALSE);
1386      if (choose_t->ftest)
1387	gtk_widget_set_sensitive (choose_t->ftest, FALSE);
1388    }
1389}
1390
1391
1392void
1393filedsn_dirlist_select (GtkWidget *widget, gint row, gint column,
1394    GdkEvent *event, TDSNCHOOSER *choose_t)
1395{
1396  LPSTR filename = NULL, temp = NULL;
1397  int i;
1398
1399  if (choose_t)
1400    {
1401      /* Get the directory name */
1402      gtk_clist_get_text (GTK_CLIST (choose_t->dir_list), row, 0, &filename);
1403
1404      if (filename && event && event->type == GDK_2BUTTON_PRESS)
1405	{
1406	  /* Update the directory and file list */
1407	  temp =
1408	      (LPSTR) malloc (STRLEN (filename) +
1409	      STRLEN (choose_t->curr_dir) + 2);
1410
1411	  if (temp)
1412	    {
1413	      if (!strcmp (filename, "."))
1414		STRCPY (temp, choose_t->curr_dir);
1415	      else if (!strcmp (filename, ".."))
1416		{
1417		  STRCPY (temp, choose_t->curr_dir);
1418		  for (i = STRLEN (temp) - 1; i - 1 && temp[i] != '/'; i--);
1419		  temp[i] = 0;
1420		}
1421	      else
1422		{
1423		  STRCPY (temp, choose_t->curr_dir);
1424		  if (temp[STRLEN (temp) - 1] != '/')
1425		    STRCAT (temp, "/");
1426		  STRCAT (temp, filename);
1427		}
1428
1429	      strncpy(choose_t->curr_dir, temp, sizeof(choose_t->curr_dir));
1430	      addlistofdir_to_optionmenu (choose_t->dir_combo,
1431		  choose_t->curr_dir, choose_t);
1432	      adddirectories_to_list (choose_t->mainwnd, choose_t->dir_list,
1433		  choose_t->curr_dir);
1434	      addfiles_to_list (choose_t->mainwnd, choose_t->file_list,
1435		  choose_t->curr_dir);
1436	    }
1437	}
1438    }
1439}
1440
1441
1442void
1443filedsn_lookin_clicked (GtkWidget *widget, void **array)
1444{
1445  if (array && array[0] && array[1] && ((TDSNCHOOSER *) array[1])->curr_dir
1446      && strcmp (((TDSNCHOOSER *) array[1])->curr_dir, array[0]))
1447    {
1448      TDSNCHOOSER *choose_t = (TDSNCHOOSER *) array[1];
1449      /* Update the directory and file list */
1450      strncpy(choose_t->curr_dir, array[0], sizeof(choose_t->curr_dir));
1451      addlistofdir_to_optionmenu (choose_t->dir_combo,
1452	  (LPCSTR) array[0], choose_t);
1453      adddirectories_to_list (choose_t->mainwnd,
1454	  choose_t->dir_list, (LPCSTR) array[0]);
1455      addfiles_to_list (choose_t->mainwnd, choose_t->file_list, (LPCSTR) array[0]);
1456    }
1457}
1458
1459
1460void
1461userdsn_list_select (GtkWidget *widget, gint row, gint column,
1462    GdkEvent *event, TDSNCHOOSER *choose_t)
1463{
1464  char *szDSN = NULL;
1465
1466  if (choose_t)
1467    {
1468      if (GTK_CLIST (choose_t->udsnlist)->selection != NULL)
1469	gtk_clist_get_text (GTK_CLIST (choose_t->udsnlist),
1470	    GPOINTER_TO_INT (GTK_CLIST (choose_t->udsnlist)->selection->data),
1471	    0, &szDSN);
1472
1473      if (szDSN && event && event->type == GDK_2BUTTON_PRESS)
1474	gtk_signal_emit_by_name (GTK_OBJECT (choose_t->uconfigure), "clicked",
1475	    choose_t);
1476
1477      gtk_widget_set_sensitive (choose_t->uremove, TRUE);
1478      gtk_widget_set_sensitive (choose_t->uconfigure, TRUE);
1479      gtk_widget_set_sensitive (choose_t->utest, TRUE);
1480    }
1481}
1482
1483
1484void
1485userdsn_list_unselect (GtkWidget *widget, gint row, gint column,
1486    GdkEvent *event, TDSNCHOOSER *choose_t)
1487{
1488  if (choose_t)
1489    {
1490      gtk_widget_set_sensitive (choose_t->uremove, FALSE);
1491      gtk_widget_set_sensitive (choose_t->uconfigure, FALSE);
1492      gtk_widget_set_sensitive (choose_t->utest, FALSE);
1493    }
1494}
1495
1496
1497void
1498systemdsn_list_select (GtkWidget *widget, gint row, gint column,
1499    GdkEvent *event, TDSNCHOOSER *choose_t)
1500{
1501  char *szDSN = NULL;
1502
1503  if (choose_t)
1504    {
1505      if (GTK_CLIST (choose_t->sdsnlist)->selection != NULL)
1506	gtk_clist_get_text (GTK_CLIST (choose_t->sdsnlist),
1507	    GPOINTER_TO_INT (GTK_CLIST (choose_t->sdsnlist)->selection->data),
1508	    0, &szDSN);
1509
1510      if (szDSN && event && event->type == GDK_2BUTTON_PRESS)
1511	gtk_signal_emit_by_name (GTK_OBJECT (choose_t->sconfigure), "clicked",
1512	    choose_t);
1513
1514      gtk_widget_set_sensitive (choose_t->sremove, TRUE);
1515      gtk_widget_set_sensitive (choose_t->sconfigure, TRUE);
1516      gtk_widget_set_sensitive (choose_t->stest, TRUE);
1517    }
1518}
1519
1520
1521void
1522systemdsn_list_unselect (GtkWidget *widget, gint row, gint column,
1523    GdkEvent *event, TDSNCHOOSER *choose_t)
1524{
1525  if (choose_t)
1526    {
1527      gtk_widget_set_sensitive (choose_t->sremove, FALSE);
1528      gtk_widget_set_sensitive (choose_t->sconfigure, FALSE);
1529      gtk_widget_set_sensitive (choose_t->stest, FALSE);
1530    }
1531}
1532
1533
1534static void
1535dsnchooser_ok_clicked (GtkWidget *widget, TDSNCHOOSER *choose_t)
1536{
1537  char *szDSN;
1538
1539  if (choose_t)
1540    {
1541      switch (choose_t->type_dsn)
1542	{
1543	case USER_DSN:
1544	  if (GTK_CLIST (choose_t->udsnlist)->selection != NULL)
1545	    {
1546	      gtk_clist_get_text (GTK_CLIST (choose_t->udsnlist),
1547		  GPOINTER_TO_INT (GTK_CLIST (choose_t->udsnlist)->selection->
1548		      data), 0, &szDSN);
1549	      choose_t->dsn = dm_SQL_A2W(szDSN, SQL_NTS);
1550	    }
1551	  else
1552	    choose_t->dsn = NULL;
1553	  break;
1554
1555	case SYSTEM_DSN:
1556	  if (GTK_CLIST (choose_t->sdsnlist)->selection != NULL)
1557	    {
1558	      gtk_clist_get_text (GTK_CLIST (choose_t->sdsnlist),
1559		  GPOINTER_TO_INT (GTK_CLIST (choose_t->sdsnlist)->selection->
1560		      data), 0, &szDSN);
1561	      choose_t->dsn = dm_SQL_A2W (szDSN, SQL_NTS);
1562	    }
1563	  else
1564	    choose_t->dsn = NULL;
1565	  break;
1566
1567	default:
1568	  choose_t->dsn = NULL;
1569	  break;
1570	};
1571
1572    done:
1573      choose_t->udsnlist = choose_t->sdsnlist = NULL;
1574      choose_t->uadd = choose_t->uremove = choose_t->utest =
1575	  choose_t->uconfigure = NULL;
1576      choose_t->sadd = choose_t->sremove = choose_t->stest =
1577	  choose_t->sconfigure = NULL;
1578
1579      gtk_signal_disconnect_by_func (GTK_OBJECT (choose_t->mainwnd),
1580	  GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
1581      gtk_main_quit ();
1582      gtk_widget_destroy (choose_t->mainwnd);
1583    }
1584}
1585
1586
1587static void
1588dsnchooser_cancel_clicked (GtkWidget *widget, TDSNCHOOSER *choose_t)
1589{
1590  if (choose_t)
1591    {
1592      choose_t->udsnlist = choose_t->sdsnlist = NULL;
1593      choose_t->uadd = choose_t->uremove = choose_t->utest =
1594	  choose_t->uconfigure = NULL;
1595      choose_t->sadd = choose_t->sremove = choose_t->stest =
1596	  choose_t->sconfigure = NULL;
1597      choose_t->type_dsn = -1;
1598      choose_t->dsn = NULL;
1599
1600      gtk_signal_disconnect_by_func (GTK_OBJECT (choose_t->mainwnd),
1601	  GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
1602      gtk_main_quit ();
1603      gtk_widget_destroy (choose_t->mainwnd);
1604    }
1605}
1606
1607
1608static gint
1609delete_event (GtkWidget *widget, GdkEvent *event, TDSNCHOOSER *choose_t)
1610{
1611  dsnchooser_cancel_clicked (widget, choose_t);
1612
1613  return FALSE;
1614}
1615
1616
1617void
1618create_dsnchooser (HWND hwnd, TDSNCHOOSER * choose_t)
1619{
1620  GtkWidget *dsnchooser, *dialog_vbox1, *notebook1, *vbox1, *fixed1,
1621      *scrolledwindow1;
1622  GtkWidget *clist1, *l_name, *l_description, *l_driver, *l_usdsn, *frame1,
1623      *table1;
1624  GtkWidget *l_explanation, *pixmap1, *vbuttonbox1, *b_add, *b_remove,
1625      *b_configure;
1626  GtkWidget *b_test, *udsn, *fixed2, *scrolledwindow2, *clist2;
1627  GtkWidget *l_sdsn, *frame2, *table2, *pixmap2, *vbuttonbox2, *sdsn,
1628      *dialog_action_area1;
1629  GtkWidget *pixmap3, *clist3, *clist4, *l_files, *l_selected, *scrolledwindow4;
1630  GtkWidget *t_fileselected, *l_lookin, *optionmenu1, *frame3, *table3, *fdsn,
1631      *l_directory, *fixed3;
1632  GtkWidget *optionmenu1_menu, *scrolledwindow3, *vbuttonbox3, *b_setdir;
1633  GtkWidget *hbuttonbox1, *b_ok, *b_cancel;
1634  GdkPixmap *pixmap;
1635  GdkBitmap *mask;
1636  GtkStyle *style;
1637  GtkAccelGroup *accel_group;
1638  guint b_key;
1639
1640  if (!GTK_IS_WIDGET (hwnd))
1641    {
1642      gtk_init (0, NULL);
1643      hwnd = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1644    }
1645
1646  if (hwnd == NULL || !GTK_IS_WIDGET (hwnd))
1647    return;
1648
1649  accel_group = gtk_accel_group_new ();
1650
1651  dsnchooser = gtk_dialog_new ();
1652  gtk_object_set_data (GTK_OBJECT (dsnchooser), "dsnchooser", dsnchooser);
1653  gtk_widget_set_usize (dsnchooser, 565, 415);
1654  gtk_window_set_title (GTK_WINDOW (dsnchooser), "Select Data Source");
1655  gtk_window_set_position (GTK_WINDOW (dsnchooser), GTK_WIN_POS_CENTER);
1656  gtk_window_set_modal (GTK_WINDOW (dsnchooser), TRUE);
1657  gtk_window_set_policy (GTK_WINDOW (dsnchooser), FALSE, FALSE, FALSE);
1658
1659#if GTK_CHECK_VERSION(2,0,0)
1660  gtk_widget_show (dsnchooser);
1661#endif
1662
1663  dialog_vbox1 = GTK_DIALOG (dsnchooser)->vbox;
1664  gtk_object_set_data (GTK_OBJECT (dsnchooser), "dialog_vbox1", dialog_vbox1);
1665  gtk_widget_show (dialog_vbox1);
1666
1667  notebook1 = gtk_notebook_new ();
1668  gtk_widget_ref (notebook1);
1669  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "notebook1", notebook1,
1670      (GtkDestroyNotify) gtk_widget_unref);
1671  gtk_widget_show (notebook1);
1672  gtk_box_pack_start (GTK_BOX (dialog_vbox1), notebook1, TRUE, TRUE, 0);
1673
1674  vbox1 = gtk_vbox_new (FALSE, 0);
1675  gtk_widget_ref (vbox1);
1676  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "vbox1", vbox1,
1677      (GtkDestroyNotify) gtk_widget_unref);
1678  gtk_widget_show (vbox1);
1679  gtk_container_add (GTK_CONTAINER (notebook1), vbox1);
1680
1681  /* User DSN panel */
1682  fixed1 = gtk_fixed_new ();
1683  gtk_widget_ref (fixed1);
1684  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "fixed1", fixed1,
1685      (GtkDestroyNotify) gtk_widget_unref);
1686  gtk_widget_show (fixed1);
1687  gtk_box_pack_start (GTK_BOX (vbox1), fixed1, TRUE, TRUE, 0);
1688  gtk_container_set_border_width (GTK_CONTAINER (fixed1), 6);
1689
1690  scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
1691  gtk_widget_ref (scrolledwindow1);
1692  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "scrolledwindow1",
1693      scrolledwindow1, (GtkDestroyNotify) gtk_widget_unref);
1694  gtk_widget_show (scrolledwindow1);
1695  gtk_widget_set_usize (scrolledwindow1, 456, 232);
1696  gtk_fixed_put (GTK_FIXED (fixed1), scrolledwindow1, 3, 19);
1697
1698  clist1 = gtk_clist_new (3);
1699  gtk_widget_ref (clist1);
1700  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "clist1", clist1,
1701      (GtkDestroyNotify) gtk_widget_unref);
1702  gtk_widget_show (clist1);
1703  gtk_container_add (GTK_CONTAINER (scrolledwindow1), clist1);
1704  gtk_clist_set_column_width (GTK_CLIST (clist1), 0, 100);
1705  gtk_clist_set_column_width (GTK_CLIST (clist1), 1, 162);
1706  gtk_clist_set_column_width (GTK_CLIST (clist1), 2, 80);
1707  gtk_clist_column_titles_show (GTK_CLIST (clist1));
1708
1709  l_name = gtk_label_new (szDSNColumnNames[0]);
1710  gtk_widget_ref (l_name);
1711  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_name", l_name,
1712      (GtkDestroyNotify) gtk_widget_unref);
1713  gtk_widget_show (l_name);
1714  gtk_clist_set_column_widget (GTK_CLIST (clist1), 0, l_name);
1715
1716  l_description = gtk_label_new (szDSNColumnNames[1]);
1717  gtk_widget_ref (l_description);
1718  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_description",
1719      l_description, (GtkDestroyNotify) gtk_widget_unref);
1720  gtk_widget_show (l_description);
1721  gtk_clist_set_column_widget (GTK_CLIST (clist1), 1, l_description);
1722
1723  l_driver = gtk_label_new (szDSNColumnNames[2]);
1724  gtk_widget_ref (l_driver);
1725  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_driver", l_driver,
1726      (GtkDestroyNotify) gtk_widget_unref);
1727  gtk_widget_show (l_driver);
1728  gtk_clist_set_column_widget (GTK_CLIST (clist1), 2, l_driver);
1729
1730  l_usdsn = gtk_label_new ("User Data Sources :");
1731  gtk_widget_ref (l_usdsn);
1732  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_usdsn", l_usdsn,
1733      (GtkDestroyNotify) gtk_widget_unref);
1734  gtk_widget_show (l_usdsn);
1735  gtk_fixed_put (GTK_FIXED (fixed1), l_usdsn, 8, 8);
1736#if GTK_CHECK_VERSION(2,0,0)
1737  gtk_widget_set_uposition (l_usdsn, 12, 35);
1738  gtk_widget_set_usize (l_usdsn, 120, 16);
1739#else
1740  gtk_widget_set_uposition (l_usdsn, 8, 8);
1741  gtk_widget_set_usize (l_usdsn, 112, 16);
1742#endif
1743  gtk_label_set_justify (GTK_LABEL (l_usdsn), GTK_JUSTIFY_LEFT);
1744
1745  frame1 = gtk_frame_new (NULL);
1746  gtk_widget_ref (frame1);
1747  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "frame1", frame1,
1748      (GtkDestroyNotify) gtk_widget_unref);
1749  gtk_widget_show (frame1);
1750#if GTK_CHECK_VERSION(2,0,0)
1751  gtk_fixed_put (GTK_FIXED (fixed1), frame1, 8, 295);
1752  gtk_widget_set_uposition (frame1, 8, 295);
1753#else
1754  gtk_fixed_put (GTK_FIXED (fixed1), frame1, 8, 264);
1755  gtk_widget_set_uposition (frame1, 8, 264);
1756#endif
1757  gtk_widget_set_usize (frame1, 546, 64);
1758
1759  table1 = gtk_table_new (1, 2, FALSE);
1760  gtk_widget_ref (table1);
1761  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "table1", table1,
1762      (GtkDestroyNotify) gtk_widget_unref);
1763  gtk_widget_show (table1);
1764  gtk_container_add (GTK_CONTAINER (frame1), table1);
1765  gtk_container_set_border_width (GTK_CONTAINER (table1), 6);
1766  gtk_table_set_row_spacings (GTK_TABLE (table1), 6);
1767  gtk_table_set_col_spacings (GTK_TABLE (table1), 6);
1768
1769  l_explanation =
1770      gtk_label_new
1771      ("An ODBC User data source stores information about how to connect to\nthe indicated data provider. A User data source is only available to you,\nand can only be used on the current machine.");
1772  gtk_widget_ref (l_explanation);
1773  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_explanation",
1774      l_explanation, (GtkDestroyNotify) gtk_widget_unref);
1775  gtk_widget_show (l_explanation);
1776  gtk_table_attach (GTK_TABLE (table1), l_explanation, 1, 2, 0, 1,
1777      (GtkAttachOptions) (0), (GtkAttachOptions) (0), 0, 0);
1778  gtk_label_set_justify (GTK_LABEL (l_explanation), GTK_JUSTIFY_LEFT);
1779
1780#if GTK_CHECK_VERSION(2,0,0)
1781  style = gtk_widget_get_style (dsnchooser);
1782  pixmap =
1783      gdk_pixmap_create_from_xpm_d (dsnchooser->window, &mask,
1784      &style->bg[GTK_STATE_NORMAL], (gchar **) odbc4_xpm);
1785#else
1786  style = gtk_widget_get_style (GTK_WIDGET (hwnd));
1787  pixmap =
1788      gdk_pixmap_create_from_xpm_d (GTK_WIDGET (hwnd)->window, &mask,
1789      &style->bg[GTK_STATE_NORMAL], (gchar **) odbc4_xpm);
1790#endif
1791
1792  pixmap1 = gtk_pixmap_new (pixmap, mask);
1793  gtk_widget_ref (pixmap1);
1794  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "pixmap1", pixmap1,
1795      (GtkDestroyNotify) gtk_widget_unref);
1796  gtk_widget_show (pixmap1);
1797  gtk_table_attach (GTK_TABLE (table1), pixmap1, 0, 1, 0, 1,
1798      (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0);
1799
1800  vbuttonbox1 = gtk_vbutton_box_new ();
1801  gtk_widget_ref (vbuttonbox1);
1802  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "vbuttonbox1",
1803      vbuttonbox1, (GtkDestroyNotify) gtk_widget_unref);
1804  gtk_widget_show (vbuttonbox1);
1805  gtk_fixed_put (GTK_FIXED (fixed1), vbuttonbox1, 472, 16);
1806#if GTK_CHECK_VERSION(2,0,0)
1807  gtk_widget_set_uposition (vbuttonbox1, 472, 52);
1808#else
1809  gtk_widget_set_uposition (vbuttonbox1, 472, 16);
1810#endif
1811  gtk_widget_set_usize (vbuttonbox1, 85, 135);
1812
1813  b_add = gtk_button_new_with_label ("");
1814  b_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_add)->child),
1815      szDSNButtons[0]);
1816  gtk_widget_add_accelerator (b_add, "clicked", accel_group,
1817      b_key, GDK_MOD1_MASK, 0);
1818  gtk_widget_ref (b_add);
1819  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_add", b_add,
1820      (GtkDestroyNotify) gtk_widget_unref);
1821  gtk_widget_show (b_add);
1822  gtk_container_add (GTK_CONTAINER (vbuttonbox1), b_add);
1823  GTK_WIDGET_SET_FLAGS (b_add, GTK_CAN_DEFAULT);
1824  gtk_widget_add_accelerator (b_add, "clicked", accel_group,
1825      'A', GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
1826
1827  b_remove = gtk_button_new_with_label ("");
1828  b_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_remove)->child),
1829      szDSNButtons[1]);
1830  gtk_widget_add_accelerator (b_remove, "clicked", accel_group,
1831      b_key, GDK_MOD1_MASK, 0);
1832  gtk_widget_ref (b_remove);
1833  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_remove", b_remove,
1834      (GtkDestroyNotify) gtk_widget_unref);
1835  gtk_widget_show (b_remove);
1836  gtk_container_add (GTK_CONTAINER (vbuttonbox1), b_remove);
1837  GTK_WIDGET_SET_FLAGS (b_remove, GTK_CAN_DEFAULT);
1838  gtk_widget_add_accelerator (b_remove, "clicked", accel_group,
1839      'R', GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
1840  gtk_widget_set_sensitive (b_remove, FALSE);
1841
1842  b_configure = gtk_button_new_with_label ("");
1843  b_key =
1844      gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_configure)->child),
1845      szDSNButtons[2]);
1846  gtk_widget_add_accelerator (b_configure, "clicked", accel_group,
1847      b_key, GDK_MOD1_MASK, 0);
1848  gtk_widget_ref (b_configure);
1849  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_configure",
1850      b_configure, (GtkDestroyNotify) gtk_widget_unref);
1851  gtk_widget_show (b_configure);
1852  gtk_container_add (GTK_CONTAINER (vbuttonbox1), b_configure);
1853  GTK_WIDGET_SET_FLAGS (b_configure, GTK_CAN_DEFAULT);
1854  gtk_widget_add_accelerator (b_configure, "clicked", accel_group,
1855      'G', GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
1856  gtk_widget_set_sensitive (b_configure, FALSE);
1857
1858  b_test = gtk_button_new_with_label ("");
1859  b_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_test)->child),
1860      szDSNButtons[3]);
1861  gtk_widget_add_accelerator (b_test, "clicked", accel_group,
1862      b_key, GDK_MOD1_MASK, 0);
1863  gtk_widget_ref (b_test);
1864  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_test", b_test,
1865      (GtkDestroyNotify) gtk_widget_unref);
1866  gtk_widget_show (b_test);
1867  gtk_container_add (GTK_CONTAINER (vbuttonbox1), b_test);
1868  GTK_WIDGET_SET_FLAGS (b_test, GTK_CAN_DEFAULT);
1869  gtk_widget_add_accelerator (b_test, "clicked", accel_group,
1870      'T', GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
1871  gtk_widget_set_sensitive (b_test, FALSE);
1872
1873  choose_t->uadd = b_add;
1874  choose_t->uremove = b_remove;
1875  choose_t->utest = b_test;
1876  choose_t->uconfigure = b_configure;
1877
1878  udsn = gtk_label_new (szTabNames[0]);
1879  gtk_widget_ref (udsn);
1880  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "udsn", udsn,
1881      (GtkDestroyNotify) gtk_widget_unref);
1882  gtk_widget_show (udsn);
1883  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1),
1884      gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 0), udsn);
1885
1886  /* System DSN panel */
1887  fixed2 = gtk_fixed_new ();
1888  gtk_widget_ref (fixed2);
1889  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "fixed2", fixed2,
1890      (GtkDestroyNotify) gtk_widget_unref);
1891  gtk_widget_show (fixed2);
1892  gtk_container_add (GTK_CONTAINER (notebook1), fixed2);
1893  gtk_container_set_border_width (GTK_CONTAINER (fixed2), 6);
1894
1895  scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL);
1896  gtk_widget_ref (scrolledwindow2);
1897  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "scrolledwindow2",
1898      scrolledwindow2, (GtkDestroyNotify) gtk_widget_unref);
1899  gtk_widget_show (scrolledwindow2);
1900  gtk_widget_set_usize (scrolledwindow2, 456, 232);
1901  gtk_fixed_put (GTK_FIXED (fixed2), scrolledwindow2, 3, 19);
1902
1903  clist2 = gtk_clist_new (3);
1904  gtk_widget_ref (clist2);
1905  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "clist2", clist2,
1906      (GtkDestroyNotify) gtk_widget_unref);
1907  gtk_widget_show (clist2);
1908  gtk_container_add (GTK_CONTAINER (scrolledwindow2), clist2);
1909  gtk_clist_set_column_width (GTK_CLIST (clist2), 0, 100);
1910  gtk_clist_set_column_width (GTK_CLIST (clist2), 1, 163);
1911  gtk_clist_set_column_width (GTK_CLIST (clist2), 2, 80);
1912  gtk_clist_column_titles_show (GTK_CLIST (clist2));
1913
1914  l_name = gtk_label_new (szDSNColumnNames[0]);
1915  gtk_widget_ref (l_name);
1916  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_name", l_name,
1917      (GtkDestroyNotify) gtk_widget_unref);
1918  gtk_widget_show (l_name);
1919  gtk_clist_set_column_widget (GTK_CLIST (clist2), 0, l_name);
1920
1921  l_description = gtk_label_new (szDSNColumnNames[1]);
1922  gtk_widget_ref (l_description);
1923  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_description",
1924      l_description, (GtkDestroyNotify) gtk_widget_unref);
1925  gtk_widget_show (l_description);
1926  gtk_clist_set_column_widget (GTK_CLIST (clist2), 1, l_description);
1927
1928  l_driver = gtk_label_new (szDSNColumnNames[2]);
1929  gtk_widget_ref (l_driver);
1930  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_driver", l_driver,
1931      (GtkDestroyNotify) gtk_widget_unref);
1932  gtk_widget_show (l_driver);
1933  gtk_clist_set_column_widget (GTK_CLIST (clist2), 2, l_driver);
1934
1935  l_sdsn = gtk_label_new ("System Data Sources :");
1936  gtk_widget_ref (l_sdsn);
1937  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_sdsn", l_sdsn,
1938      (GtkDestroyNotify) gtk_widget_unref);
1939  gtk_widget_show (l_sdsn);
1940  gtk_fixed_put (GTK_FIXED (fixed2), l_sdsn, 8, 8);
1941#if GTK_CHECK_VERSION(2,0,0)
1942  gtk_widget_set_uposition (l_sdsn, 12, 35);
1943  gtk_widget_set_usize (l_sdsn, 138, 16);
1944#else
1945  gtk_widget_set_uposition (l_sdsn, 8, 8);
1946  gtk_widget_set_usize (l_sdsn, 130, 16);
1947#endif
1948  gtk_label_set_justify (GTK_LABEL (l_sdsn), GTK_JUSTIFY_LEFT);
1949
1950  frame2 = gtk_frame_new (NULL);
1951  gtk_widget_ref (frame2);
1952  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "frame2", frame2,
1953      (GtkDestroyNotify) gtk_widget_unref);
1954  gtk_widget_show (frame2);
1955#if GTK_CHECK_VERSION(2,0,0)
1956  gtk_fixed_put (GTK_FIXED (fixed2), frame2, 8, 295);
1957  gtk_widget_set_uposition (frame2, 8, 295);
1958#else
1959  gtk_fixed_put (GTK_FIXED (fixed2), frame2, 8, 264);
1960  gtk_widget_set_uposition (frame2, 8, 264);
1961#endif
1962  gtk_widget_set_usize (frame2, 546, 64);
1963
1964  table2 = gtk_table_new (1, 2, FALSE);
1965  gtk_widget_ref (table2);
1966  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "table2", table2,
1967      (GtkDestroyNotify) gtk_widget_unref);
1968  gtk_widget_show (table2);
1969  gtk_container_add (GTK_CONTAINER (frame2), table2);
1970  gtk_container_set_border_width (GTK_CONTAINER (table2), 6);
1971  gtk_table_set_row_spacings (GTK_TABLE (table2), 6);
1972  gtk_table_set_col_spacings (GTK_TABLE (table2), 6);
1973
1974  l_explanation =
1975      gtk_label_new
1976      ("An ODBC System data source stores information about how to connect\nto the indicated data provider. A system data source is visible to all\nusers on this machine, including daemons.");
1977  gtk_widget_ref (l_explanation);
1978  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_explanation",
1979      l_explanation, (GtkDestroyNotify) gtk_widget_unref);
1980  gtk_widget_show (l_explanation);
1981  gtk_table_attach (GTK_TABLE (table2), l_explanation, 1, 2, 0, 1,
1982      (GtkAttachOptions) (0), (GtkAttachOptions) (0), 0, 0);
1983  gtk_label_set_justify (GTK_LABEL (l_explanation), GTK_JUSTIFY_LEFT);
1984
1985  pixmap2 = gtk_pixmap_new (pixmap, mask);
1986  gtk_widget_ref (pixmap2);
1987  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "pixmap2", pixmap2,
1988      (GtkDestroyNotify) gtk_widget_unref);
1989  gtk_widget_show (pixmap2);
1990  gtk_table_attach (GTK_TABLE (table2), pixmap2, 0, 1, 0, 1,
1991      (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0);
1992
1993  vbuttonbox2 = gtk_vbutton_box_new ();
1994  gtk_widget_ref (vbuttonbox2);
1995  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "vbuttonbox2",
1996      vbuttonbox2, (GtkDestroyNotify) gtk_widget_unref);
1997  gtk_widget_show (vbuttonbox2);
1998  gtk_fixed_put (GTK_FIXED (fixed2), vbuttonbox2, 472, 16);
1999#if GTK_CHECK_VERSION(2,0,0)
2000  gtk_widget_set_uposition (vbuttonbox2, 472, 52);
2001#else
2002  gtk_widget_set_uposition (vbuttonbox2, 472, 16);
2003#endif
2004  gtk_widget_set_usize (vbuttonbox2, 85, 135);
2005
2006  b_add = gtk_button_new_with_label ("");
2007  b_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_add)->child),
2008      szDSNButtons[0]);
2009  gtk_widget_add_accelerator (b_add, "clicked", accel_group,
2010      b_key, GDK_MOD1_MASK, 0);
2011  gtk_widget_ref (b_add);
2012  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_add", b_add,
2013      (GtkDestroyNotify) gtk_widget_unref);
2014  gtk_widget_show (b_add);
2015  gtk_container_add (GTK_CONTAINER (vbuttonbox2), b_add);
2016  GTK_WIDGET_SET_FLAGS (b_add, GTK_CAN_DEFAULT);
2017  gtk_widget_add_accelerator (b_add, "clicked", accel_group,
2018      'A', GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
2019
2020  b_remove = gtk_button_new_with_label ("");
2021  b_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_remove)->child),
2022      szDSNButtons[1]);
2023  gtk_widget_add_accelerator (b_remove, "clicked", accel_group,
2024      b_key, GDK_MOD1_MASK, 0);
2025  gtk_widget_ref (b_remove);
2026  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_remove", b_remove,
2027      (GtkDestroyNotify) gtk_widget_unref);
2028  gtk_widget_show (b_remove);
2029  gtk_container_add (GTK_CONTAINER (vbuttonbox2), b_remove);
2030  GTK_WIDGET_SET_FLAGS (b_remove, GTK_CAN_DEFAULT);
2031  gtk_widget_add_accelerator (b_remove, "clicked", accel_group,
2032      'R', GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
2033  gtk_widget_set_sensitive (b_remove, FALSE);
2034
2035  b_configure = gtk_button_new_with_label ("");
2036  b_key =
2037      gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_configure)->child),
2038      szDSNButtons[2]);
2039  gtk_widget_add_accelerator (b_configure, "clicked", accel_group,
2040      b_key, GDK_MOD1_MASK, 0);
2041  gtk_widget_ref (b_configure);
2042  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_configure",
2043      b_configure, (GtkDestroyNotify) gtk_widget_unref);
2044  gtk_widget_show (b_configure);
2045  gtk_container_add (GTK_CONTAINER (vbuttonbox2), b_configure);
2046  GTK_WIDGET_SET_FLAGS (b_configure, GTK_CAN_DEFAULT);
2047  gtk_widget_add_accelerator (b_configure, "clicked", accel_group,
2048      'G', GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
2049  gtk_widget_set_sensitive (b_configure, FALSE);
2050
2051  b_test = gtk_button_new_with_label ("");
2052  b_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_test)->child),
2053      szDSNButtons[3]);
2054  gtk_widget_add_accelerator (b_test, "clicked", accel_group,
2055      b_key, GDK_MOD1_MASK, 0);
2056  gtk_widget_ref (b_test);
2057  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_test", b_test,
2058      (GtkDestroyNotify) gtk_widget_unref);
2059  gtk_widget_show (b_test);
2060  gtk_container_add (GTK_CONTAINER (vbuttonbox2), b_test);
2061  GTK_WIDGET_SET_FLAGS (b_test, GTK_CAN_DEFAULT);
2062  gtk_widget_add_accelerator (b_test, "clicked", accel_group,
2063      'T', GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
2064  gtk_widget_set_sensitive (b_test, FALSE);
2065
2066  choose_t->sadd = b_add;
2067  choose_t->sremove = b_remove;
2068  choose_t->stest = b_test;
2069  choose_t->sconfigure = b_configure;
2070
2071  sdsn = gtk_label_new (szTabNames[1]);
2072  gtk_widget_ref (sdsn);
2073  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "sdsn", sdsn,
2074      (GtkDestroyNotify) gtk_widget_unref);
2075  gtk_widget_show (sdsn);
2076  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1),
2077      gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 1), sdsn);
2078
2079  /* File DSN panel */
2080  fixed3 = gtk_fixed_new ();
2081  gtk_widget_ref (fixed3);
2082  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "fixed3", fixed3,
2083     (GtkDestroyNotify) gtk_widget_unref);
2084  gtk_widget_show (fixed3);
2085  gtk_container_add (GTK_CONTAINER (notebook1), fixed3);
2086  gtk_container_set_border_width (GTK_CONTAINER (fixed3), 6);
2087
2088  l_lookin = gtk_label_new ("Look in : ");
2089  gtk_widget_ref (l_lookin);
2090  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_lookin", l_lookin,
2091     (GtkDestroyNotify) gtk_widget_unref);
2092  gtk_widget_show (l_lookin);
2093#if GTK_CHECK_VERSION(2,0,0)
2094  gtk_fixed_put (GTK_FIXED (fixed3), l_lookin, 16, 44);
2095  gtk_widget_set_uposition (l_lookin, 16, 44);
2096#else
2097  gtk_fixed_put (GTK_FIXED (fixed3), l_lookin, 16, 16);
2098  gtk_widget_set_uposition (l_lookin, 16, 16);
2099#endif
2100  gtk_widget_set_usize (l_lookin, 57, 16);
2101  gtk_label_set_justify (GTK_LABEL (l_lookin), GTK_JUSTIFY_LEFT);
2102
2103  optionmenu1 = gtk_option_menu_new ();
2104  gtk_widget_ref (optionmenu1);
2105  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "optionmenu1", optionmenu1,
2106     (GtkDestroyNotify) gtk_widget_unref);
2107  gtk_widget_show (optionmenu1);
2108#if GTK_CHECK_VERSION(2,0,0)
2109  gtk_fixed_put (GTK_FIXED (fixed3), optionmenu1, 72, 40);
2110  gtk_widget_set_uposition (optionmenu1, 72, 40);
2111#else
2112  gtk_fixed_put (GTK_FIXED (fixed3), optionmenu1, 72, 16);
2113  gtk_widget_set_uposition (optionmenu1, 72, 16);
2114#endif
2115  gtk_widget_set_usize (optionmenu1, 392, 24);
2116  optionmenu1_menu = gtk_menu_new ();
2117  gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu1), optionmenu1_menu);
2118
2119  scrolledwindow3 = gtk_scrolled_window_new (NULL, NULL);
2120  gtk_widget_ref (scrolledwindow3);
2121  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "scrolledwindow3", scrolledwindow3,
2122     (GtkDestroyNotify) gtk_widget_unref);
2123  gtk_widget_show (scrolledwindow3);
2124#if GTK_CHECK_VERSION(2,0,0)
2125  gtk_fixed_put (GTK_FIXED (fixed3), scrolledwindow3, 8, 74);
2126  gtk_widget_set_uposition (scrolledwindow3, 8, 74);
2127#else
2128  gtk_fixed_put (GTK_FIXED (fixed3), scrolledwindow3, 8, 48);
2129  gtk_widget_set_uposition (scrolledwindow3, 8, 48);
2130#endif
2131  gtk_widget_set_usize (scrolledwindow3, 224, 176);
2132
2133  clist3 = gtk_clist_new (1);
2134  gtk_widget_ref (clist3);
2135  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "clist3", clist3,
2136     (GtkDestroyNotify) gtk_widget_unref);
2137  gtk_widget_show (clist3);
2138  gtk_container_add (GTK_CONTAINER (scrolledwindow3), clist3);
2139  gtk_widget_set_usize (clist3, 144, 168);
2140  gtk_clist_set_column_width (GTK_CLIST (clist3), 0, 80);
2141  gtk_clist_column_titles_show (GTK_CLIST (clist3));
2142
2143  l_directory = gtk_label_new ("Directories");
2144  gtk_widget_ref (l_directory);
2145  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_directory", l_directory,
2146     (GtkDestroyNotify) gtk_widget_unref);
2147  gtk_widget_show (l_directory);
2148  gtk_clist_set_column_widget (GTK_CLIST (clist3), 0, l_directory);
2149  gtk_label_set_justify (GTK_LABEL (l_directory), GTK_JUSTIFY_LEFT);
2150
2151  scrolledwindow4 = gtk_scrolled_window_new (NULL, NULL);
2152  gtk_widget_ref (scrolledwindow4);
2153  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "scrolledwindow4", scrolledwindow4,
2154     (GtkDestroyNotify) gtk_widget_unref);
2155  gtk_widget_show (scrolledwindow4);
2156#if GTK_CHECK_VERSION(2,0,0)
2157  gtk_fixed_put (GTK_FIXED (fixed3), scrolledwindow4, 240, 74);
2158  gtk_widget_set_uposition (scrolledwindow4, 240, 74);
2159#else
2160  gtk_fixed_put (GTK_FIXED (fixed3), scrolledwindow4, 240, 48);
2161  gtk_widget_set_uposition (scrolledwindow4, 240, 48);
2162#endif
2163  gtk_widget_set_usize (scrolledwindow4, 224, 176);
2164
2165  clist4 = gtk_clist_new (1);
2166  gtk_widget_ref (clist4);
2167  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "clist4", clist4,
2168     (GtkDestroyNotify) gtk_widget_unref);
2169  gtk_widget_show (clist4);
2170  gtk_container_add (GTK_CONTAINER (scrolledwindow4), clist4);
2171  gtk_clist_set_column_width (GTK_CLIST (clist4), 0, 80);
2172  gtk_clist_column_titles_show (GTK_CLIST (clist4));
2173
2174  l_files = gtk_label_new ("Files");
2175  gtk_widget_ref (l_files);
2176  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_files", l_files,
2177     (GtkDestroyNotify) gtk_widget_unref);
2178  gtk_widget_show (l_files);
2179  gtk_clist_set_column_widget (GTK_CLIST (clist4), 0, l_files);
2180  gtk_label_set_justify (GTK_LABEL (l_files), GTK_JUSTIFY_LEFT);
2181
2182  t_fileselected = gtk_entry_new ();
2183  gtk_widget_ref (t_fileselected);
2184  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "t_fileselected", t_fileselected,
2185     (GtkDestroyNotify) gtk_widget_unref);
2186  gtk_widget_show (t_fileselected);
2187#if GTK_CHECK_VERSION(2,0,0)
2188  gtk_fixed_put (GTK_FIXED (fixed3), t_fileselected, 95, 260);
2189  gtk_widget_set_uposition (t_fileselected, 95, 260);
2190#else
2191  gtk_fixed_put (GTK_FIXED (fixed3), t_fileselected, 95, 234);
2192  gtk_widget_set_uposition (t_fileselected, 95, 234);
2193#endif
2194  gtk_widget_set_usize (t_fileselected, 370, 22);
2195
2196  frame3 = gtk_frame_new (NULL);
2197  gtk_widget_ref (frame3);
2198  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "frame3", frame3,
2199     (GtkDestroyNotify) gtk_widget_unref);
2200  gtk_widget_show (frame3);
2201#if GTK_CHECK_VERSION(2,0,0)
2202  gtk_fixed_put (GTK_FIXED (fixed3), frame3, 8, 295);
2203  gtk_widget_set_uposition (frame3, 8, 295);
2204#else
2205  gtk_fixed_put (GTK_FIXED (fixed3), frame3, 8, 264);
2206  gtk_widget_set_uposition (frame3, 8, 264);
2207#endif
2208  gtk_widget_set_usize (frame3, 546, 64);
2209
2210  table3 = gtk_table_new (1, 2, FALSE);
2211  gtk_widget_ref (table3);
2212  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "table3", table3,
2213     (GtkDestroyNotify) gtk_widget_unref);
2214  gtk_widget_show (table3);
2215  gtk_container_add (GTK_CONTAINER (frame3), table3);
2216  gtk_container_set_border_width (GTK_CONTAINER (table3), 6);
2217  gtk_table_set_row_spacings (GTK_TABLE (table3), 6);
2218  gtk_table_set_col_spacings (GTK_TABLE (table3), 6);
2219
2220  l_explanation = gtk_label_new ("Select the file data source that describes the driver that you wish to\nconnect to. You can use any file data source that refers to an ODBC\ndriver which is installed on your machine.");
2221  gtk_widget_ref (l_explanation);
2222  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_explanation", l_explanation,
2223     (GtkDestroyNotify) gtk_widget_unref);
2224  gtk_widget_show (l_explanation);
2225  gtk_table_attach (GTK_TABLE (table3), l_explanation, 1, 2, 0, 1,
2226     (GtkAttachOptions) (0),
2227     (GtkAttachOptions) (0), 0, 0);
2228  gtk_label_set_justify (GTK_LABEL (l_explanation), GTK_JUSTIFY_LEFT);
2229
2230  pixmap3 = gtk_pixmap_new (pixmap, mask);
2231  gtk_widget_ref (pixmap3);
2232  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "pixmap3", pixmap3,
2233     (GtkDestroyNotify) gtk_widget_unref);
2234  gtk_widget_show (pixmap3);
2235  gtk_table_attach (GTK_TABLE (table3), pixmap3, 0, 1, 0, 1,
2236     (GtkAttachOptions) (GTK_FILL),
2237     (GtkAttachOptions) (GTK_FILL), 0, 0);
2238
2239  l_selected = gtk_label_new ("File selected : ");
2240  gtk_widget_ref (l_selected);
2241  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "l_selected", l_selected,
2242     (GtkDestroyNotify) gtk_widget_unref);
2243  gtk_widget_show (l_selected);
2244#if GTK_CHECK_VERSION(2,0,0)
2245  gtk_fixed_put (GTK_FIXED (fixed3), l_selected, 8, 263);
2246  gtk_widget_set_uposition (l_selected, 8, 263);
2247#else
2248  gtk_fixed_put (GTK_FIXED (fixed3), l_selected, 8, 237);
2249  gtk_widget_set_uposition (l_selected, 8, 237);
2250#endif
2251  gtk_widget_set_usize (l_selected, 85, 16);
2252
2253  vbuttonbox3 = gtk_vbutton_box_new ();
2254  gtk_widget_ref (vbuttonbox3);
2255  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "vbuttonbox3", vbuttonbox3,
2256     (GtkDestroyNotify) gtk_widget_unref);
2257  gtk_widget_show (vbuttonbox3);
2258  gtk_fixed_put (GTK_FIXED (fixed3), vbuttonbox3, 472, 16);
2259#if GTK_CHECK_VERSION(2,0,0)
2260  gtk_widget_set_uposition (vbuttonbox3, 472, 52);
2261#else
2262  gtk_widget_set_uposition (vbuttonbox3, 472, 16);
2263#endif
2264  gtk_widget_set_usize (vbuttonbox3, 85, 165);
2265
2266  b_add = gtk_button_new_with_label ("");
2267  b_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_add)->child),
2268     szDSNButtons[0]);
2269  gtk_widget_add_accelerator (b_add, "clicked", accel_group,
2270     b_key, GDK_MOD1_MASK, 0);
2271  gtk_widget_ref (b_add);
2272  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_add", b_add,
2273     (GtkDestroyNotify) gtk_widget_unref);
2274  gtk_widget_show (b_add);
2275  gtk_container_add (GTK_CONTAINER (vbuttonbox3), b_add);
2276  GTK_WIDGET_SET_FLAGS (b_add, GTK_CAN_DEFAULT);
2277  gtk_widget_add_accelerator (b_add, "clicked", accel_group,
2278     'A', GDK_MOD1_MASK,
2279     GTK_ACCEL_VISIBLE);
2280
2281  b_remove = gtk_button_new_with_label ("");
2282  b_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_remove)->child),
2283     szDSNButtons[1]);
2284  gtk_widget_add_accelerator (b_remove, "clicked", accel_group,
2285     b_key, GDK_MOD1_MASK, 0);
2286  gtk_widget_ref (b_remove);
2287  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_remove", b_remove,
2288     (GtkDestroyNotify) gtk_widget_unref);
2289  gtk_widget_show (b_remove);
2290  gtk_container_add (GTK_CONTAINER (vbuttonbox3), b_remove);
2291  GTK_WIDGET_SET_FLAGS (b_remove, GTK_CAN_DEFAULT);
2292  gtk_widget_add_accelerator (b_remove, "clicked", accel_group,
2293     'R', GDK_MOD1_MASK,
2294     GTK_ACCEL_VISIBLE);
2295
2296  b_configure = gtk_button_new_with_label ("");
2297  b_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_configure)->child),
2298     szDSNButtons[2]);
2299  gtk_widget_add_accelerator (b_configure, "clicked", accel_group,
2300  b_key, GDK_MOD1_MASK, 0);
2301  gtk_widget_ref (b_configure);
2302  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_configure", b_configure,
2303     (GtkDestroyNotify) gtk_widget_unref);
2304  gtk_widget_show (b_configure);
2305  gtk_container_add (GTK_CONTAINER (vbuttonbox3), b_configure);
2306  GTK_WIDGET_SET_FLAGS (b_configure, GTK_CAN_DEFAULT);
2307  gtk_widget_add_accelerator (b_configure, "clicked", accel_group,
2308     'C', GDK_MOD1_MASK,
2309     GTK_ACCEL_VISIBLE);
2310
2311  b_test = gtk_button_new_with_label ("");
2312  b_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_test)->child),
2313     szDSNButtons[3]);
2314  gtk_widget_add_accelerator (b_test, "clicked", accel_group,
2315     b_key, GDK_MOD1_MASK, 0);
2316  gtk_widget_ref (b_test);
2317  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_test", b_test,
2318     (GtkDestroyNotify) gtk_widget_unref);
2319  gtk_widget_show (b_test);
2320  gtk_container_add (GTK_CONTAINER (vbuttonbox3), b_test);
2321  GTK_WIDGET_SET_FLAGS (b_test, GTK_CAN_DEFAULT);
2322  gtk_widget_add_accelerator (b_test, "clicked", accel_group,
2323     'T', GDK_MOD1_MASK,
2324     GTK_ACCEL_VISIBLE);
2325
2326  b_setdir = gtk_button_new_with_label ("");
2327  b_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_setdir)->child),
2328     szDSNButtons[4]);
2329  gtk_widget_add_accelerator (b_setdir, "clicked", accel_group,
2330     b_key, GDK_MOD1_MASK, 0);
2331  gtk_widget_ref (b_setdir);
2332  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_setdir", b_setdir,
2333     (GtkDestroyNotify) gtk_widget_unref);
2334  gtk_widget_show (b_setdir);
2335  gtk_container_add (GTK_CONTAINER (vbuttonbox3), b_setdir);
2336  GTK_WIDGET_SET_FLAGS (b_setdir, GTK_CAN_DEFAULT);
2337  gtk_widget_add_accelerator (b_setdir, "clicked", accel_group,
2338     'S', GDK_MOD1_MASK,
2339     GTK_ACCEL_VISIBLE);
2340
2341  choose_t->fadd = b_add; choose_t->fremove = b_remove; choose_t->fconfigure = b_configure;
2342  choose_t->ftest = b_test; choose_t->dir_list = clist3; choose_t->dir_combo = optionmenu1;
2343  choose_t->file_list = clist4; choose_t->file_entry = t_fileselected;
2344  choose_t->fsetdir = b_setdir;
2345
2346  fdsn = gtk_label_new (szTabNames[2]);
2347  gtk_widget_ref (fdsn);
2348  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "fdsn", fdsn,
2349     (GtkDestroyNotify) gtk_widget_unref);
2350  gtk_widget_show (fdsn);
2351  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1),
2352      gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 2), fdsn);
2353
2354
2355  dialog_action_area1 = GTK_DIALOG (dsnchooser)->action_area;
2356  gtk_object_set_data (GTK_OBJECT (dsnchooser), "dialog_action_area1",
2357      dialog_action_area1);
2358  gtk_widget_show (dialog_action_area1);
2359  gtk_container_set_border_width (GTK_CONTAINER (dialog_action_area1), 5);
2360
2361  hbuttonbox1 = gtk_hbutton_box_new ();
2362  gtk_widget_ref (hbuttonbox1);
2363  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "hbuttonbox1",
2364      hbuttonbox1, (GtkDestroyNotify) gtk_widget_unref);
2365  gtk_widget_show (hbuttonbox1);
2366  gtk_box_pack_start (GTK_BOX (dialog_action_area1), hbuttonbox1, TRUE, TRUE,
2367      0);
2368  gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox1), GTK_BUTTONBOX_END);
2369  gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox1), 10);
2370
2371  b_ok = gtk_button_new_with_label ("");
2372  b_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_ok)->child), "_Ok");
2373  gtk_widget_add_accelerator (b_ok, "clicked", accel_group,
2374      b_key, GDK_MOD1_MASK, 0);
2375  gtk_widget_ref (b_ok);
2376  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_ok", b_ok,
2377      (GtkDestroyNotify) gtk_widget_unref);
2378  gtk_widget_show (b_ok);
2379  gtk_container_add (GTK_CONTAINER (hbuttonbox1), b_ok);
2380  GTK_WIDGET_SET_FLAGS (b_ok, GTK_CAN_DEFAULT);
2381  gtk_widget_add_accelerator (b_ok, "clicked", accel_group,
2382      'O', GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
2383
2384  b_cancel = gtk_button_new_with_label ("");
2385  b_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (b_cancel)->child),
2386      "_Cancel");
2387  gtk_widget_add_accelerator (b_cancel, "clicked", accel_group,
2388      b_key, GDK_MOD1_MASK, 0);
2389  gtk_widget_ref (b_cancel);
2390  gtk_object_set_data_full (GTK_OBJECT (dsnchooser), "b_cancel", b_cancel,
2391      (GtkDestroyNotify) gtk_widget_unref);
2392  gtk_widget_show (b_cancel);
2393  gtk_container_add (GTK_CONTAINER (hbuttonbox1), b_cancel);
2394  GTK_WIDGET_SET_FLAGS (b_cancel, GTK_CAN_DEFAULT);
2395  gtk_widget_add_accelerator (b_cancel, "clicked", accel_group,
2396      'C', GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
2397
2398  /* Notebook events */
2399  gtk_signal_connect_after (GTK_OBJECT (notebook1), "switch_page",
2400      GTK_SIGNAL_FUNC (dsnchooser_switch_page), choose_t);
2401  /* Ok button events */
2402  gtk_signal_connect (GTK_OBJECT (b_ok), "clicked",
2403      GTK_SIGNAL_FUNC (dsnchooser_ok_clicked), choose_t);
2404  /* Cancel button events */
2405  gtk_signal_connect (GTK_OBJECT (b_cancel), "clicked",
2406      GTK_SIGNAL_FUNC (dsnchooser_cancel_clicked), choose_t);
2407  /* Close window button events */
2408  gtk_signal_connect (GTK_OBJECT (dsnchooser), "delete_event",
2409      GTK_SIGNAL_FUNC (delete_event), choose_t);
2410  gtk_signal_connect (GTK_OBJECT (dsnchooser), "destroy",
2411      GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
2412  /* Add user DSN button events */
2413  gtk_signal_connect (GTK_OBJECT (choose_t->uadd), "clicked",
2414      GTK_SIGNAL_FUNC (userdsn_add_clicked), choose_t);
2415  /* Remove user DSN button events */
2416  gtk_signal_connect (GTK_OBJECT (choose_t->uremove), "clicked",
2417      GTK_SIGNAL_FUNC (userdsn_remove_clicked), choose_t);
2418  /* Test user DSN button events */
2419  gtk_signal_connect (GTK_OBJECT (choose_t->utest), "clicked",
2420      GTK_SIGNAL_FUNC (userdsn_test_clicked), choose_t);
2421  /* Configure user DSN button events */
2422  gtk_signal_connect (GTK_OBJECT (choose_t->uconfigure), "clicked",
2423      GTK_SIGNAL_FUNC (userdsn_configure_clicked), choose_t);
2424  /* Add system DSN button events */
2425  gtk_signal_connect (GTK_OBJECT (choose_t->sadd), "clicked",
2426      GTK_SIGNAL_FUNC (systemdsn_add_clicked), choose_t);
2427  /* Remove system DSN button events */
2428  gtk_signal_connect (GTK_OBJECT (choose_t->sremove), "clicked",
2429      GTK_SIGNAL_FUNC (systemdsn_remove_clicked), choose_t);
2430  /* Test system DSN button events */
2431  gtk_signal_connect (GTK_OBJECT (choose_t->stest), "clicked",
2432      GTK_SIGNAL_FUNC (systemdsn_test_clicked), choose_t);
2433  /* Configure system DSN button events */
2434  gtk_signal_connect (GTK_OBJECT (choose_t->sconfigure), "clicked",
2435      GTK_SIGNAL_FUNC (systemdsn_configure_clicked), choose_t);
2436  /* User DSN list events */
2437  gtk_signal_connect (GTK_OBJECT (clist1), "select_row",
2438      GTK_SIGNAL_FUNC (userdsn_list_select), choose_t);
2439  gtk_signal_connect (GTK_OBJECT (clist1), "unselect_row",
2440      GTK_SIGNAL_FUNC (userdsn_list_unselect), choose_t);
2441  /* System DSN list events */
2442  gtk_signal_connect (GTK_OBJECT (clist2), "select_row",
2443      GTK_SIGNAL_FUNC (systemdsn_list_select), choose_t);
2444  gtk_signal_connect (GTK_OBJECT (clist2), "unselect_row",
2445      GTK_SIGNAL_FUNC (systemdsn_list_unselect), choose_t);
2446
2447  /* Add file DSN button events */
2448  gtk_signal_connect (GTK_OBJECT (choose_t->fadd), "clicked",
2449      GTK_SIGNAL_FUNC (filedsn_add_clicked),
2450      choose_t);
2451  /* Remove file DSN button events */
2452  gtk_signal_connect (GTK_OBJECT (choose_t->fremove), "clicked",
2453      GTK_SIGNAL_FUNC (filedsn_remove_clicked),
2454      choose_t);
2455  /* Test file DSN button events */
2456  gtk_signal_connect (GTK_OBJECT (choose_t->ftest), "clicked",
2457     GTK_SIGNAL_FUNC (filedsn_test_clicked),
2458     choose_t);
2459  /* Configure file DSN button events */
2460  gtk_signal_connect (GTK_OBJECT (choose_t->fconfigure), "clicked",
2461     GTK_SIGNAL_FUNC (filedsn_configure_clicked),
2462     choose_t);
2463  /* Configure file DSN button events */
2464  gtk_signal_connect (GTK_OBJECT (choose_t->fsetdir), "clicked",
2465     GTK_SIGNAL_FUNC (filedsn_setdir_clicked),
2466     choose_t);
2467  /* Directories file DSN list events */
2468  gtk_signal_connect (GTK_OBJECT (clist3), "select_row",
2469     GTK_SIGNAL_FUNC (filedsn_dirlist_select),
2470     choose_t);
2471  /* Files file DSN list events */
2472  gtk_signal_connect (GTK_OBJECT (clist4), "select_row",
2473     GTK_SIGNAL_FUNC (filedsn_filelist_select),
2474     choose_t);
2475  gtk_signal_connect (GTK_OBJECT (clist4), "unselect_row",
2476     GTK_SIGNAL_FUNC (filedsn_filelist_unselect),
2477     choose_t);
2478
2479  gtk_window_add_accel_group (GTK_WINDOW (dsnchooser), accel_group);
2480
2481  SQLSetConfigMode (ODBC_BOTH_DSN);
2482  if (!SQLGetPrivateProfileString("ODBC", "FileDSNPath", "",
2483      choose_t->curr_dir, sizeof(choose_t->curr_dir), "odbcinst.ini"))
2484    strcpy(choose_t->curr_dir, DEFAULT_FILEDSNPATH);
2485
2486  adddsns_to_list (clist1, FALSE);
2487
2488  choose_t->udsnlist = clist1;
2489  choose_t->sdsnlist = clist2;
2490  choose_t->type_dsn = USER_DSN;
2491  choose_t->mainwnd = dsnchooser;
2492
2493  gtk_widget_show_all (dsnchooser);
2494  gtk_main ();
2495}
2496
2497
2498#define CHECK_DRVCONN_DIALBOX(path) \
2499  { \
2500    if ((handle = DLL_OPEN(path)) != NULL) \
2501      { \
2502        if (DLL_PROC(handle, "_iodbcdm_drvconn_dialboxw") != NULL) \
2503          { \
2504            DLL_CLOSE(handle); \
2505            retVal = TRUE; \
2506            goto quit; \
2507          } \
2508        else \
2509          { \
2510            if (DLL_PROC(handle, "_iodbcdm_drvconn_dialbox") != NULL) \
2511              { \
2512                DLL_CLOSE(handle); \
2513                retVal = TRUE; \
2514                goto quit; \
2515              } \
2516          } \
2517        DLL_CLOSE(handle); \
2518      } \
2519  }
2520
2521
2522
2523static BOOL
2524_CheckDriverLoginDlg (
2525    char *drv
2526)
2527{
2528  char drvbuf[4096] = { L'\0'};
2529  HDLL handle;
2530  BOOL retVal = FALSE;
2531
2532
2533  if (!drv)
2534    return FALSE;
2535
2536  SQLSetConfigMode (ODBC_USER_DSN);
2537  if (!access (drv, X_OK))
2538    { CHECK_DRVCONN_DIALBOX (drv); }
2539  if (SQLGetPrivateProfileString (drv, "Driver", "", drvbuf,
2540    sizeof (drvbuf), "odbcinst.ini"))
2541    { CHECK_DRVCONN_DIALBOX (drvbuf); }
2542  if (SQLGetPrivateProfileString (drv, "Setup", "", drvbuf,
2543    sizeof (drvbuf), "odbcinst.ini"))
2544    { CHECK_DRVCONN_DIALBOX (drvbuf); }
2545
2546  SQLSetConfigMode (ODBC_SYSTEM_DSN);
2547  if (!access (drv, X_OK))
2548    { CHECK_DRVCONN_DIALBOX (drv); }
2549  if (SQLGetPrivateProfileString (drv, "Driver", "", drvbuf,
2550    sizeof (drvbuf), "odbcinst.ini"))
2551    { CHECK_DRVCONN_DIALBOX (drvbuf); }
2552  if (SQLGetPrivateProfileString (drv, "Setup", "", drvbuf,
2553    sizeof (drvbuf), "odbcinst.ini"))
2554    { CHECK_DRVCONN_DIALBOX (drvbuf); }
2555
2556quit:
2557  return retVal;
2558}
2559