1/*
2 *  IODBCadm_DriverChooseFDSNController.m
3 *
4 *  $Id$
5 *
6 *  The iODBC driver manager.
7 *
8 *  Copyright (C) 1996-2021 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#import "IODBCadm_DriverChooseFDSNController.h"
76#import "IODBCadm_KeyValController.h"
77#import "utils.h"
78#import "Helpers.h"
79
80
81static char* showKeyVal(NSWindow *mainWin, char* attrs, BOOL *verify_conn);
82
83
84void
85create_fdriverchooser (HWND hwnd, TFDRIVERCHOOSER * choose_t)
86{
87    choose_t->attrs = NULL;
88    choose_t->verify_conn = TRUE;
89    choose_t->driver = NULL;
90    choose_t->dsn = NULL;
91    choose_t->ok = FALSE;
92
93    if (hwnd == NULL)
94        return;
95
96	@autoreleasepool {
97        NSApplication *app = [NSApplication sharedApplication];
98
99        IODBCadm_DriverChooseFDSNController *dlg = [[IODBCadm_DriverChooseFDSNController alloc] init];
100        if (choose_t && choose_t->curr_dir)
101            dlg.fdsn_dir = [NSString stringWithUTF8String:choose_t->curr_dir];
102
103        NSInteger rc = [app runModalForWindow:dlg.window];
104        if (choose_t) {
105            choose_t->attrs = NULL;
106            choose_t->verify_conn = TRUE;
107            choose_t->driver = NULL;
108            choose_t->dsn = NULL;
109            choose_t->ok = FALSE;
110
111            if (rc == 1) {
112                NSArray *item = [dlg.Drv_ArrController selectedObjects];
113                if (item!=nil && item.count>0){
114                    NSDictionary *dict = [item objectAtIndex:0];
115                    choose_t->driver = conv_NSString_to_wchar([dict valueForKey:@"name"]);
116                }
117
118                NSString *fdsn = dlg.fld_FDSN.stringValue;
119                NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"/"];
120                if ([fdsn rangeOfCharacterFromSet:set].location == NSNotFound)
121                    choose_t->dsn = strdup([[NSString stringWithFormat:@"%@/%@", dlg.fdsn_dir, fdsn] UTF8String]);
122                else
123                    choose_t->dsn = strdup(fdsn.UTF8String);
124                choose_t->attrs = dlg.attrs;
125                dlg.attrs = NULL;
126                choose_t->ok = TRUE;
127            }
128        }
129        [dlg.window orderOut:dlg.window];
130        [dlg release];
131
132    }
133
134}
135
136static char* showKeyVal(NSWindow *mainWin, char* attrs, BOOL *verify_conn)
137{
138    char *connstr = NULL;
139	@autoreleasepool {
140
141        IODBCadm_KeyValController *dlg = [[IODBCadm_KeyValController alloc] initWithAttrs:attrs];
142
143        NSInteger rc = [NSApp runModalForWindow:dlg.window];
144        [dlg.window orderOut:dlg.window];
145        if (rc == 1){
146            char *cour;
147            int i = 0, size = 1;
148            char *val,*key;
149
150            /* Malloc it */
151            if ((connstr = (char *) calloc(sizeof(char), 2)))
152            {
153                for (i = 0; i < dlg.Attrs_list.count; i++)
154                {
155                    NSDictionary *row = [dlg.Attrs_list objectAtIndex:i];
156                    key = (char*)conv_NSString_to_char((NSString*)[row valueForKey:@"key"]);
157                    val = (char*)conv_NSString_to_char((NSString*)[row valueForKey:@"val"]);
158
159                    cour = connstr;
160                    connstr = (char*) malloc (size + strlen(key) + strlen(val) + 2);
161                    if (connstr)
162                    {
163                        memcpy (connstr, cour, size);
164                        sprintf (connstr + size - 1, "%s=%s", key, val);
165                        free (cour);
166                        size += strlen(key) + strlen(val) + 2;
167                    }
168                    else
169                        connstr = cour;
170
171                    if (key!=NULL) free(key);
172                    if (val!=NULL) free(val);
173                }
174
175                connstr[size - 1] = '\0';
176            }
177            if (verify_conn)
178                *verify_conn = (dlg.chk_Verify.state == NSOnState);
179        }
180        [dlg release];
181        return connstr;
182    }
183}
184
185
186@interface IODBCadm_DriverChooseFDSNController ()
187
188@end
189
190@implementation IODBCadm_DriverChooseFDSNController
191@synthesize Drv_ArrController = _Drv_ArrController;
192@synthesize Results_ArrController = _Results_ArrController;
193@synthesize btn_Continue = _btn_Continue;
194@synthesize tab_view = _tab_view;
195@synthesize btn_Back = _btn_Back;
196@synthesize fld_FDSN = _fld_FDSN;
197@synthesize Drv_list=_Drv_list;
198@synthesize Results_list=_Results_list;
199@synthesize fdsn_dir=_fdsn_dir;
200@synthesize attrs=_attrs;
201
202
203- (id)init
204{
205    self = [super initWithWindowNibName:@"IODBCadm_DriverChooseFDSNController"];
206    if (self) {
207        self.Drv_list = [NSMutableArray arrayWithCapacity:16];
208        self.Results_list = [NSMutableArray arrayWithCapacity:16];
209        _verify_conn = TRUE;
210        _attrs = calloc(sizeof(char), 2);
211    }
212    return self;
213}
214
215- (void)dealloc
216{
217    [_Drv_list release];
218    [_Results_list release];
219    if (_attrs)
220        free(_attrs);
221	[super dealloc];
222}
223
224- (id)initWithWindow:(NSWindow *)window
225{
226    self = [super initWithWindow:window];
227    if (self) {
228        // Initialization code here.
229    }
230    return self;
231}
232
233- (void)windowDidLoad
234{
235    [super windowDidLoad];
236
237    _dialogCode = 0;
238
239    [[self window] center];  // Center the window.
240    addDrivers_to_list(_Drv_ArrController);
241}
242
243- (void)windowWillClose:(NSNotification*)notification
244{
245    [NSApp stopModalWithCode:_dialogCode];
246}
247
248
249- (void) updateResArray
250{
251    NSString *fdsn = _fld_FDSN.stringValue;
252
253    [_Results_ArrController removeObjects:[_Results_ArrController arrangedObjects]];
254    [_Results_ArrController addObject:@"File Data Source:"];
255
256    NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"/"];
257    if ([fdsn rangeOfCharacterFromSet:set].location == NSNotFound)
258        [_Results_ArrController addObject:[NSString stringWithFormat:@"Filename: %@/%@", _fdsn_dir, fdsn]];
259    else
260        [_Results_ArrController addObject:[NSString stringWithFormat:@"Filename: %@", fdsn]];
261
262    NSArray *item = [_Drv_ArrController selectedObjects];
263    if (item!=nil && item.count>0){
264        NSDictionary *dict = [item objectAtIndex:0];
265        [_Results_ArrController addObject:[NSString stringWithFormat:@"Driver: %@", [dict valueForKey:@"name"]]];
266    }
267
268    [_Results_ArrController addObject:@"Driver-specific Keywords:"];
269    if (_attrs){
270        char *curr;
271        for (curr = _attrs; *curr; curr += (strlen (curr) + 1))
272        {
273            if (!strncasecmp (curr, "PWD=", strlen ("PWD=")))
274            {
275                continue;
276            }
277
278            [_Results_ArrController addObject:conv_char_to_NSString(curr)];
279        }
280    }
281}
282
283/** NSTabViewDelegate **/
284- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem
285{
286    NSString *identifier = [tabViewItem identifier];
287
288    if ([identifier isEqualToString:@"drv"]){
289        [_btn_Back setEnabled:FALSE];
290        [_btn_Continue setTitle:@"Continue"];
291    }
292    else if ([identifier isEqualToString:@"name"]){
293        [_btn_Back setEnabled:TRUE];
294        [_btn_Continue setTitle:@"Continue"];
295    }
296    else if ([identifier isEqualToString:@"res"]){
297        [_btn_Back setEnabled:TRUE];
298        [_btn_Continue setTitle:@"Finish"];
299        [self updateResArray];
300    }
301}
302
303- (BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem
304{
305    NSString *identifier = [tabViewItem identifier];
306    if ([identifier isEqualToString:@"res"]){
307        if (_fld_FDSN.stringValue.length==0){
308            NSRunAlertPanel(@"Enter File DSN Name...", @"", @"OK", nil, nil);
309            return FALSE;
310        }
311    } else if ([identifier isEqualToString:@"name"]){
312        NSArray *item = [_Drv_ArrController selectedObjects];
313        if (item==nil && item.count==0){
314            NSRunAlertPanel(@"Driver wasn't selected!", @"", @"OK", nil, nil);
315            return FALSE;
316        }
317    }
318    return TRUE;
319}
320
321
322
323- (IBAction)call_Cancel:(id)sender {
324    _dialogCode = 0;
325    [self.window close];
326}
327
328- (IBAction)call_Continue:(id)sender {
329    NSString *ident = _tab_view.selectedTabViewItem.identifier;
330    if ([ident isEqualToString:@"res"]) {
331        _dialogCode = 1;
332        [self.window close];
333    } else if ([ident isEqualToString:@"name"]) {
334        if (_fld_FDSN.stringValue.length==0)
335            NSRunAlertPanel(@"Enter File DSN Name...", @"", @"OK", nil, nil);
336        else
337            [_tab_view selectNextTabViewItem:self];
338    } else {
339        [_tab_view selectNextTabViewItem:self];
340    }
341}
342
343
344- (IBAction)call_Back:(id)sender {
345    NSString *ident = _tab_view.selectedTabViewItem.identifier;
346    if (![ident isEqualToString:@"drv"]) {
347        [_tab_view selectPreviousTabViewItem:self];
348    }
349}
350
351- (IBAction)call_Advanced:(id)sender {
352    char *connstr = showKeyVal(self.window, _attrs, &_verify_conn);
353    if (connstr) {
354        if (_attrs)
355            free(_attrs);
356        _attrs = connstr;
357    }
358    [self.window makeKeyAndOrderFront:self.window];
359}
360
361- (IBAction)call_Browse:(id)sender {
362    NSSavePanel *panel = [NSSavePanel savePanel];
363
364    [panel setTitle:@"Save as ..."];
365    [panel setNameFieldStringValue:@"xxx.dsn"];
366    [panel setDirectoryURL:[NSURL fileURLWithPath:_fdsn_dir isDirectory:TRUE]];
367    NSInteger rc = [panel runModal];
368    if (rc==NSFileHandlingPanelOKButton){
369        NSURL *dirURL = [panel directoryURL];
370        [_fld_FDSN setStringValue:[NSString stringWithFormat:@"%@/%@", dirURL.path, panel.nameFieldStringValue]];
371    }
372    [self.window makeKeyAndOrderFront:self.window];
373}
374@end
375