The R Project SVN R

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
24681 iacus 1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
25632 iacus 3
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
4
 *  Copyright (C) 1997--2003  Robert Gentleman, Ross Ihaka
5
 *			      and the R Development Core Team
24681 iacus 6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  (at your option) any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program; if not, write to the Free Software
25632 iacus 19
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
24681 iacus 21
 
24749 iacus 22
#ifndef __AQUA_DATA_BROWSER__
23
#define __AQUA_DATA_BROWSER__
24681 iacus 24
 
25
 
26
#ifdef HAVE_CONFIG_H
27
#include <config.h>
28
#endif
29
#include <Defn.h>
30
 
24749 iacus 31
#ifdef HAVE_AQUA
26035 iacus 32
#define __DEBUGGING__
24681 iacus 33
 
34
# include <Carbon/Carbon.h>
35
# include "DataBrowser.h"
36
 
37
#include <limits.h>
38
 
39
#include <R.h>
40
#include <R_ext/Boolean.h>
41
#include <R_ext/Rdynload.h>
42
#include <Rdefines.h>
43
#include <Rinternals.h>
44
 
45
#ifndef kDataBrowserListViewAppendColumn
46
#define kDataBrowserListViewAppendColumn ULONG_MAX
47
#endif
25522 iacus 48
#include "Raqua.h"
24681 iacus 49
 
25522 iacus 50
extern RAquaPrefs CurrentPrefs;
51
 
24681 iacus 52
static void ConfigureDataBrowser(ControlRef);
53
static void CreateDataBrowser(WindowRef, ControlRef*);
54
static ControlRef GetDataBrowserFromWindow(WindowRef window);
55
static void InstallDataBrowserCallbacks(ControlRef);
56
 
57
static pascal OSStatus MyGetSetItemData(ControlRef browser, 
58
    DataBrowserItemID itemID, DataBrowserPropertyID property, 
59
    DataBrowserItemDataRef itemData, Boolean changeValue);
60
 
61
static pascal void MyItemNotification(
62
	ControlRef browser, 
63
	DataBrowserItemID itemID, 
64
	DataBrowserItemNotification message);
65
pascal OSStatus BrowserEventHandler(EventHandlerCallRef, EventRef, void*);
66
 
67
static pascal Boolean MyItemComparison(
68
	ControlRef browser, DataBrowserItemID itemOneID, 
69
	DataBrowserItemID itemTwoID, DataBrowserPropertyID sortProperty);
70
 
71
 
72
void OpenDataBrowser(void);
73
void CloseDataBrowser(void);
74
void FreeBrowserStuff(void);
75
 
76
Boolean isBrowserOpen = false;
77
WindowRef BrowserWindow = NULL;
78
ControlRef WSpaceBrowser = NULL;
79
Rboolean isEventHandlerOn = FALSE;
80
 
81
#define MaxItems  2500
82
 
83
/*
84
  How works the workspace browser? Suppose you have 4 objects
85
  in the workspace. The should be prepeared as follows:
86
 
87
  w vector
88
  x list of 3 objects
89
  y list of 2 object (d,e)
90
  z vector
91
 
92
  number of 
93
  total items  1  <-  w
94
             3+1  <-  x
95
             1+2  <-  y
96
            1  <-  z
97
            ---------
98
               9  Totale
99
 
100
object	ID			subitems	IsRoot	IsContainer
101
w		1			0			*
102
x		2			3			*		*
103
y		3			2			*		*
104
z		4			0			*
105
 
106
from x 
107
 
108
a		5			0
109
b		6			0
110
c		7			0
111
 
112
from y
113
d		8			0					
114
e		9			0
115
 
116
 
117
*/
118
 
27143 ripley 119
UInt32		NumOfRoots = 0;
120
DataBrowserItemID	*RootItems = NULL; 
26123 iacus 121
int		**SubItemsID;
24681 iacus 122
int		CurrentID = 0;
123
void	InitContainers(void);
124
void	SetSubItems(int i);
125
 
126
Rect WSBounds = { 400, 400, 600, 800 };
127
 
128
/*
129
  id : integer, id number in the browser
130
  isroot : boolean, this id is a root item
131
  iscont : boolean, is container?
132
  numofit : integer, number of items
133
  parid   : parent id number
134
  name   : char, name of objects
135
  type   : type, class or mode
136
  objsize: can be dim, length or number of levels 
137
*/
138
 
139
/* The following are local copies of the above */
140
 
141
int *IDNum;              /* id          */
142
Rboolean *IsRoot;        /* isroot      */
143
Rboolean *IsContainer;   /* iscontainer */
27143 ripley 144
UInt32 *NumberOfItems;      /* numofit     */
24681 iacus 145
int *ParentID;           /* parid       */
146
char **Names;            /* name        */
147
char **Types;            /* type        */
148
char **Sizes;            /* objsize     */
149
int NumOfID = 0;         /* length of the vectors    */
150
                                /* We do not check for this */ 
151
 
24749 iacus 152
SEXP Raqua_do_wsbrowser(SEXP call, SEXP op, SEXP args, SEXP env);
24681 iacus 153
void EmptyDataBrowser(void);
154
 
24749 iacus 155
SEXP Raqua_do_wsbrowser(SEXP call, SEXP op, SEXP args, SEXP env)
24681 iacus 156
{
157
  int i;
158
   SEXP id, isroot, iscont, numofit, parid;
159
  SEXP name, type, objsize;
160
  char *vm;
161
 
162
  if(isBrowserOpen){
163
    EmptyDataBrowser();
164
   }
165
 
166
  FreeBrowserStuff();
167
 
168
  checkArity(op, args);
169
 
170
  vm = vmaxget();
171
  id = CAR(args); args = CDR(args);
172
  isroot = CAR(args); args = CDR(args);
173
  iscont = CAR(args); args = CDR(args);
174
  numofit = CAR(args); args = CDR(args);
175
  parid = CAR(args); args = CDR(args);
176
  name = CAR(args); args = CDR(args);
177
  type = CAR(args); args = CDR(args);
178
  objsize = CAR(args); 
179
 
180
  if(!isInteger(id)) {
181
   CloseDataBrowser();
182
   errorcall(call,"`id' must be integer");
183
   }
184
 
185
  NumOfID = LENGTH(id);
186
  if(NumOfID > MaxItems)
187
   NumOfID = MaxItems;
188
 
189
 
190
  if(!isString(name)){
191
    CloseDataBrowser();
192
	errorcall(call, "invalid objects' name");
193
  }
194
 
195
  if(!isString(type)){
196
    CloseDataBrowser();
197
    errorcall(call, "invalid objects' type");
198
   }
199
 
200
  if(!isString(objsize)){
201
    CloseDataBrowser();
202
	errorcall(call, "invalid objects' size");
203
  } 
204
  if(!isLogical(isroot)){
205
   CloseDataBrowser();
206
   errorcall(call, "invalid `isroot' definition");
207
  }
208
 
209
  if(!isLogical(iscont)){
210
    CloseDataBrowser();
211
	errorcall(call, "invalid `iscont' definition");
212
  } 
213
 
214
  if(!isInteger(numofit)){
215
   CloseDataBrowser(); 
216
   errorcall(call,"`numofit' must be integer");
217
  }
218
 
219
  if(!isInteger(parid)){
220
   CloseDataBrowser(); 
221
   errorcall(call,"`parid' must be integer");
222
  }
223
 
224
 
225
  Names = (char**)malloc(NumOfID * sizeof(char*));
226
  Sizes = (char**)malloc(NumOfID * sizeof(char*));
227
  Types = (char**)malloc(NumOfID * sizeof(char*));
228
 
229
  IDNum = (int*)malloc(NumOfID * sizeof(int));
230
  IsRoot = (Rboolean*)malloc(NumOfID * sizeof(Rboolean));
27143 ripley 231
  IsContainer = (Rboolean *)malloc(NumOfID * sizeof(Rboolean));
232
  NumberOfItems = (UInt32 *)malloc(NumOfID * sizeof(UInt32));
24681 iacus 233
  ParentID = (int*)malloc(NumOfID * sizeof(int));
234
 
235
  for(i=0; i<NumOfID; i++){
236
 
237
   if (!isNull(STRING_ELT(name, i)))
238
	    Names[i] = CHAR(STRING_ELT(name, i));
239
	else
240
	    Names[i] = CHAR(R_BlankString);
241
 
242
   if (!isNull(STRING_ELT(type, i)))
243
	    Types[i] = CHAR(STRING_ELT(type, i));
244
	else
245
	    Types[i] = CHAR(R_BlankString);
246
 
247
   if (!isNull(STRING_ELT(objsize, i)))
248
	    Sizes[i] = CHAR(STRING_ELT(objsize, i));
249
	else
250
	    Sizes[i] = CHAR(R_BlankString);  
251
 
27143 ripley 252
    IDNum[i] = INTEGER(id)[i];
24681 iacus 253
    NumberOfItems[i] = INTEGER(numofit)[i];
27143 ripley 254
    if(INTEGER(parid)[i] == -1)
255
     ParentID[i] = kDataBrowserNoItem;
256
    else 
25522 iacus 257
    ParentID[i] = INTEGER(parid)[i]; 
24681 iacus 258
    IsRoot[i] = LOGICAL(isroot)[i];
259
    IsContainer[i] = LOGICAL(iscont)[i];
27143 ripley 260
 
24681 iacus 261
  }
262
 
263
  OpenDataBrowser();
264
 
265
  vmaxset(vm);
266
  return R_NilValue;
267
}
268
 
269
 
270
 
271
void InitContainers(void){
272
 
273
	int i, j, k=0, l;
274
	NumOfRoots = 0;
275
 
276
	for(i=0;i<NumOfID; i++)
277
	 if(IsRoot[i])
278
	  NumOfRoots++;
279
	if(RootItems) free(RootItems);
280
 
27143 ripley 281
	RootItems = malloc(sizeof(DataBrowserItemID)*NumOfRoots);
26123 iacus 282
	SubItemsID = malloc(NumOfID * sizeof(int*));
24681 iacus 283
 
284
	for(i = 0; i < NumOfID; i++){
285
     if(IsRoot[i]) { RootItems[k] = IDNum[i]; k++;}     
286
     if(IsContainer[i]){
287
      l = 0;
26123 iacus 288
      SubItemsID[i] = malloc(sizeof(int)*NumberOfItems[i]);
24681 iacus 289
      for(j=0; j<NumOfID; j++){
290
        if(ParentID[j] == IDNum[i]){
291
          SubItemsID[i][l] = IDNum[j];
292
          l++;
293
         }
294
       }
27143 ripley 295
     } else {   /* if(IsContainer[i]) */
296
      SubItemsID[i] = malloc(sizeof(int));
297
      SubItemsID[i][0] = 0;
298
     }
24681 iacus 299
	} /* for */
300
 
301
}
302
 
303
 
304
 
305
 
306
void OpenDataBrowser(void)
307
{
308
	OSStatus err = noErr;
309
	int i;
25696 iacus 310
        Rect bounds; 
24681 iacus 311
    EventTypeSpec windowEvents[] = {
312
		{ kEventClassCommand,	kEventCommandProcess }, 
313
		{ kEventClassCommand,	kEventCommandUpdateStatus }, 
314
		{ kEventClassWindow,	kEventWindowClose }, 
315
		{ kEventClassWindow,	kEventWindowGetIdealSize },
316
		{ kEventClassWindow,	kEventWindowBoundsChanged }, 
317
		{ kEventClassWindow,	kEventWindowGetClickActivation }
318
			};
319
 
320
 
321
 
322
 
323
    InitContainers();
324
 
325
 
326
    if(BrowserWindow == NULL) 
327
    CreateNewWindow(kDocumentWindowClass,  kWindowStandardHandlerAttribute |
328
            kWindowStandardDocumentAttributes, &WSBounds, &BrowserWindow);
329
 
330
    if(BrowserWindow == NULL)
331
     return;
332
 
333
 
334
    if(!isEventHandlerOn){
335
     InstallWindowEventHandler(BrowserWindow, 
336
    		NewEventHandlerUPP(BrowserEventHandler), 
337
    		sizeof(windowEvents)/sizeof(EventTypeSpec), windowEvents, NULL, NULL);
338
     isEventHandlerOn = TRUE;
339
     SetWindowTitleWithCFString(BrowserWindow, CFSTR("R Workspace Browser"));
340
    }
341
 
342
 
343
 
344
    /* Create the DataBrowser */
345
    if(WSpaceBrowser==NULL){
346
     CreateDataBrowser(BrowserWindow, &WSpaceBrowser);
25696 iacus 347
     InstallDataBrowserCallbacks(WSpaceBrowser);
348
 
24681 iacus 349
    /* Configure the DataBrowser */
350
	if(!isBrowserOpen)
351
	 ConfigureDataBrowser(WSpaceBrowser);
27143 ripley 352
    err = SetDataBrowserTarget(WSpaceBrowser, 0);
25696 iacus 353
 
354
    AddDataBrowserItems(WSpaceBrowser, kDataBrowserNoItem, 
27143 ripley 355
				NumOfRoots, RootItems, kDataBrowserItemNoProperty);
24681 iacus 356
    /* Set the keyboard focus */
357
	SetKeyboardFocus(BrowserWindow, WSpaceBrowser, kControlDataBrowserPart);
358
 
359
	/* Store DB as a window property */
360
    SetWindowProperty(BrowserWindow,
361
        kMyCreator, kMyDataBrowser,
362
        sizeof(WSpaceBrowser), &WSpaceBrowser);
363
 
25696 iacus 364
 
24681 iacus 365
    }
366
 
367
	if(WSpaceBrowser == NULL){              
368
	 CloseDataBrowser();	 
369
	 return;
370
	}
371
 
25696 iacus 372
 
373
    ShowWindow(BrowserWindow);
24681 iacus 374
 
25696 iacus 375
    GetPortBounds(GetWindowPort(BrowserWindow), &bounds);
376
    SizeControl(WSpaceBrowser, bounds.right - bounds.left, bounds.bottom - bounds.top);
24681 iacus 377
 
378
 
379
    isBrowserOpen = true;
380
}
381
 
382
void FreeBrowserStuff(void)
383
{    
384
    if(SubItemsID) { free(SubItemsID); SubItemsID = NULL; }
385
 
386
    NumOfID = 0;
387
 
388
    if(RootItems)
389
     { free(RootItems); RootItems = NULL; }
390
 
391
    if(Names)   { free(Names); Names = NULL; }
392
    if(Sizes)   { free(Sizes); Sizes = NULL; }
393
    if(Types)   { free(Types); Types = NULL; }
394
    if(IDNum)   { free(IDNum); IDNum = NULL; }
395
    if(IsRoot)  { free(IsRoot); IsRoot = NULL; }
396
    if(IsContainer)  { free(IsContainer); IsContainer = NULL; }
397
    if(NumberOfItems) { free(NumberOfItems); NumberOfItems = NULL; }
398
    if(ParentID) { free(ParentID); ParentID = NULL; }
399
 
400
}
401
 
402
 
403
 
404
void EmptyDataBrowser(void)
405
{
406
  RemoveDataBrowserItems (WSpaceBrowser, kDataBrowserNoItem, 0, 
407
          NULL, kDataBrowserItemNoProperty);
408
} 
409
 
410
void CloseDataBrowser(void)
411
{
412
 
413
    if(BrowserWindow){
414
     if( GetWindowBounds(BrowserWindow,kWindowStructureRgn,&WSBounds) != noErr)
415
      SetRect(&WSBounds, 400, 400, 600, 800);
416
    }
417
    else 
418
     SetRect(&WSBounds, 400, 400, 600, 800);
419
 
420
 
421
    DisposeWindow(BrowserWindow);
422
    BrowserWindow = NULL;
423
 
424
	isEventHandlerOn = FALSE;
425
 
426
    FreeBrowserStuff();
427
 
428
    isBrowserOpen = false;
429
    WSpaceBrowser = NULL;
430
} 
431
 
432
static void CreateDataBrowser(WindowRef window, ControlRef *browser)
433
{
434
    Rect bounds;
435
    Boolean frameAndFocus = false;
436
 
437
    /* Create a DataBrowser */
438
    GetWindowBounds(window, kWindowContentRgn, &bounds);
439
 
440
    bounds.top = bounds.left = 0;
441
    bounds.right = bounds.right - bounds.left;
442
    bounds.bottom = bounds.bottom - bounds.top;
443
 
444
    CreateDataBrowserControl(window, 
445
    	&bounds, kDataBrowserListView, browser);
446
 
447
    /* Turn off DB's focus frame */
448
	SetControlData(
449
		*browser, kControlNoPart, 
450
		kControlDataBrowserIncludesFrameAndFocusTag,
451
		sizeof(frameAndFocus), &frameAndFocus);
452
}
453
 
454
static void ConfigureDataBrowser(ControlRef browser)
455
{
456
	Rect insetRect;
457
	DataBrowserViewStyle viewStyle;
25487 iacus 458
        SInt16                            fontID;
459
        Str255	fontname;
460
 
24681 iacus 461
	GetDataBrowserViewStyle(browser, &viewStyle);
462
 
463
	GetDataBrowserScrollBarInset(browser, &insetRect);
464
 
465
	insetRect.right = 16 - 1;
466
	SetDataBrowserScrollBarInset(browser, &insetRect);
467
 
468
	switch (viewStyle)
469
	{
470
		case kDataBrowserListView:
471
		{	DataBrowserListViewColumnDesc columnDesc;
472
 
473
			columnDesc.headerBtnDesc.titleOffset = 0;
474
 
475
			columnDesc.headerBtnDesc.version = 
476
				kDataBrowserListViewLatestHeaderDesc;
477
 
478
			columnDesc.headerBtnDesc.btnFontStyle.flags	= 
479
				kControlUseFontMask | kControlUseJustMask;
480
 
481
			columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlNoContent;
25487 iacus 482
 
483
 
24681 iacus 484
			/* Add the Object column */
485
 
486
			columnDesc.propertyDesc.propertyID = kObjectColumn;
487
			columnDesc.propertyDesc.propertyType = kDataBrowserTextType;
488
			columnDesc.propertyDesc.propertyFlags = kDataBrowserPropertyIsMutable | 
25704 tlumley 489
			  kDataBrowserListViewDefaultColumnFlags;
24681 iacus 490
 
25522 iacus 491
 
24681 iacus 492
			columnDesc.headerBtnDesc.minimumWidth = 30;
493
			columnDesc.headerBtnDesc.maximumWidth = 200;
494
 
495
			columnDesc.headerBtnDesc.btnFontStyle.just = teFlushLeft;
25487 iacus 496
 
497
                        CopyCStringToPascal(CurrentPrefs.ConsoleFontName, fontname);
498
                        GetFNum(fontname,&fontID);
499
 
500
			columnDesc.headerBtnDesc.btnFontStyle.font = fontID;
501
			columnDesc.headerBtnDesc.btnFontStyle.size = CurrentPrefs.ConsoleFontSize;
24681 iacus 502
			columnDesc.headerBtnDesc.btnFontStyle.style = normal;
25487 iacus 503
			columnDesc.headerBtnDesc.btnFontStyle.backColor = CurrentPrefs.BGOutputColor;
24681 iacus 504
 
505
			columnDesc.headerBtnDesc.titleString = CFStringCreateWithCString(
506
				CFAllocatorGetDefault(), "Object", kCFStringEncodingMacRoman);
507
 
508
			AddDataBrowserListViewColumn(browser, 
509
				&columnDesc, kDataBrowserListViewAppendColumn),
510
 
511
			/* Add the Type column */
512
 
513
			columnDesc.propertyDesc.propertyID = kTypeColumn;
514
 
515
			columnDesc.headerBtnDesc.btnFontStyle.just = teFlushLeft;
516
 
517
			columnDesc.propertyDesc.propertyFlags = kDataBrowserPropertyIsMutable | 
518
													kDataBrowserListViewDefaultColumnFlags;
519
 
520
			columnDesc.headerBtnDesc.titleString = CFStringCreateWithCString(
521
				CFAllocatorGetDefault(), "Type", kCFStringEncodingMacRoman);
522
 
523
			AddDataBrowserListViewColumn(browser, 
524
				&columnDesc, kDataBrowserListViewAppendColumn);
525
 
526
			/* Add the Properties column */
527
 
528
			columnDesc.propertyDesc.propertyID = kSizeColumn;
529
			columnDesc.propertyDesc.propertyType = kDataBrowserTextType;
530
			columnDesc.propertyDesc.propertyFlags = kDataBrowserPropertyIsMutable | 
531
													kDataBrowserListViewDefaultColumnFlags;
532
 
533
 
534
			columnDesc.headerBtnDesc.minimumWidth = 30;
535
			columnDesc.headerBtnDesc.maximumWidth = 200;
536
			columnDesc.headerBtnDesc.btnFontStyle.just = teFlushLeft;
537
 
538
			columnDesc.headerBtnDesc.titleString =CFStringCreateWithCString(
539
				CFAllocatorGetDefault(), "Property", kCFStringEncodingMacRoman);
540
 
541
			AddDataBrowserListViewColumn(browser, 
542
				&columnDesc, kDataBrowserListViewAppendColumn);
543
 
544
			SetDataBrowserListViewDisclosureColumn(browser, kObjectColumn, false);
545
 
546
		}	break;
547
	}
548
}
549
 
550
 
551
static ControlRef GetDataBrowserFromWindow(WindowRef window)
552
{
553
	ControlRef browser = NULL;
554
 
555
	if (window != NULL)
556
		GetWindowProperty(window, kMyCreator, 
557
		kMyDataBrowser, sizeof(browser), NULL, &browser);
558
 
559
	return browser;
560
}
561
 
562
 
563
void InstallDataBrowserCallbacks(ControlRef browser)
564
{
565
    DataBrowserCallbacks myCallbacks;
566
 
567
 
568
    myCallbacks.version = kDataBrowserLatestCallbacks;
569
    InitDataBrowserCallbacks(&myCallbacks);
570
 
571
    myCallbacks.u.v1.itemDataCallback = 
572
        NewDataBrowserItemDataUPP(MyGetSetItemData);
573
 
574
	myCallbacks.u.v1.itemCompareCallback = 
575
		NewDataBrowserItemCompareUPP(MyItemComparison);
576
 
577
    myCallbacks.u.v1.itemNotificationCallback = 
578
        NewDataBrowserItemNotificationUPP(MyItemNotification);
579
 
580
 
581
    SetDataBrowserCallbacks(browser, &myCallbacks);
582
}
583
 
584
 
585
 
586
static pascal Boolean MyItemComparison(
587
	ControlRef browser, DataBrowserItemID itemOneID, 
588
	DataBrowserItemID itemTwoID, DataBrowserPropertyID sortProperty)
589
{
590
	SInt16 compareResult = 0;
591
 
592
	#define Compare(i1,i2,p) MyItemComparison(browser,i1,i2,p)
593
 
594
	switch (sortProperty)
595
	{
596
		case kObjectColumn:
597
		{	Str255 s1, s2;
598
			compareResult = strcmp(Names[itemOneID-1],Names[itemTwoID-1]);
599
			if (compareResult < 0) return true;
600
			else if (compareResult > 0) return false;
601
			else return Compare(itemOneID, itemTwoID, kDontKnow);
602
		}	break;
603
 
604
		default:
605
		{	return itemOneID < itemTwoID;
606
		}	break;
607
	}
608
}
609
 
610
 
611
 
612
static pascal OSStatus MyGetSetItemData(ControlRef browser, 
613
    DataBrowserItemID itemID, DataBrowserPropertyID property, 
614
    DataBrowserItemDataRef itemData, Boolean changeValue)
615
{
616
#pragma unused (browser)
617
	Str255 pascalString;
618
	OSStatus err = noErr;
619
 
620
	if (!changeValue) 
621
	 switch (property)
622
	{
623
 
624
		case kObjectColumn:
625
		{
626
			CFStringRef text;
27143 ripley 627
                        CopyCStringToPascal(Names[itemID-1],pascalString);
24681 iacus 628
			text = CFStringCreateWithPascalString(
629
				CFAllocatorGetDefault(), pascalString, kCFStringEncodingMacRoman);
630
			err = SetDataBrowserItemDataText(itemData, text); 
631
		CFRelease(text);
632
		}	
633
		break;
634
 
635
		case kTypeColumn:
636
		{	CFStringRef text;
637
			CopyCStringToPascal(Types[itemID-1],pascalString);
638
			 text = CFStringCreateWithPascalString(
639
				CFAllocatorGetDefault(), pascalString, kCFStringEncodingMacRoman);
640
			err = SetDataBrowserItemDataText(itemData, text); 
641
			CFRelease(text);
642
		}	
643
		break;
644
 
645
 
646
		case kSizeColumn:
647
		{
648
			CFStringRef text=NULL;
649
				CopyCStringToPascal(Sizes[itemID-1],pascalString);
650
			text = CFStringCreateWithPascalString(
651
				CFAllocatorGetDefault(), pascalString, kCFStringEncodingMacRoman);
652
			err = SetDataBrowserItemDataText(itemData, text); 
653
			CFRelease(text);
654
		}	
655
		break;
656
 
657
 
658
 
659
		case kDataBrowserItemIsEditableProperty:
660
		{	err = SetDataBrowserItemDataBooleanValue(itemData, false);
661
		}	break;
662
 
663
		case kDataBrowserItemIsContainerProperty:
664
		{	err = SetDataBrowserItemDataBooleanValue(itemData, IsContainer[itemID-1]);
665
		}	break;
666
 
667
		case kDataBrowserItemParentContainerProperty:
668
		{	err = SetDataBrowserItemDataItemID(itemData, ParentID[itemID-1]);
669
		}	break;
670
 
671
		default:
672
		{	err = errDataBrowserPropertyNotSupported;
673
		}	break;
674
	}
675
	else err = errDataBrowserPropertyNotSupported;
676
 
677
	return err;
678
}
679
 
680
 
681
 static pascal void MyItemNotification(
682
	ControlRef browser, 
683
	DataBrowserItemID itemID, 
684
	DataBrowserItemNotification message)
685
{
686
	UInt32 i;
687
	UInt32 numSelectedItems;
688
	UInt16 j;
689
 
690
	switch (message)
691
	{
692
		case kDataBrowserItemSelected:
693
		{	Handle handle = NewHandle(0);
694
			GetDataBrowserItems(browser, 
695
				kDataBrowserNoItem, true, kDataBrowserItemIsSelected, handle);
696
		    numSelectedItems = GetHandleSize(handle)/sizeof(DataBrowserItemID);
697
		}	break;
698
 
699
		case kDataBrowserContainerOpened:
700
		{	
27143 ripley 701
                AddDataBrowserItems(browser, itemID, NumberOfItems[itemID-1], (DataBrowserItemID *)SubItemsID[itemID-1], kObjectColumn);
24681 iacus 702
			{	
703
				Boolean variableHeightRows;
704
				GetDataBrowserTableViewGeometry(
705
					browser, NULL, &variableHeightRows);
706
 
707
				if (variableHeightRows)
708
					for ( j = 0; j < NumberOfItems[itemID-1]; j++)
709
						SetDataBrowserTableViewItemRowHeight(
710
							browser, SubItemsID[itemID-1][j], 20 + (SubItemsID[itemID-1][j] - 1) % 10 * 3);
711
			}
712
		}	
713
 
714
		break;
715
	}
716
}
717
 
718
pascal OSStatus BrowserEventHandler(
719
	EventHandlerCallRef a, EventRef inEvent, void*b)
720
{
721
    OSStatus result = noErr;
722
 
723
	switch (GetEventClass(inEvent))
724
	{
725
    	default:
726
    	{	result = eventNotHandledErr;
727
    	}	break;
728
 
729
 
730
 
731
	    case kEventClassWindow:
732
		{
733
		    WindowRef window = NULL;
734
			GetEventParameter(inEvent, 
735
		        kEventParamDirectObject, typeWindowRef, 
736
		        NULL, sizeof(window), NULL, &window);
737
 
738
		    switch (GetEventKind(inEvent))
739
		 	{
740
		    	default:
741
		    	{	result = eventNotHandledErr;
742
		    	}	break;
743
 
744
 
745
				 case kEventWindowClose:
746
		     	{
747
                  	CloseDataBrowser();
748
			 	}	break;
749
 
750
		    	case kEventWindowBoundsChanged:
751
		    	{	ControlRef browser = GetDataBrowserFromWindow(window);
752
		    		Rect bounds; GetPortBounds(GetWindowPort(window), &bounds);
753
		        	SizeControl(browser, bounds.right - bounds.left, bounds.bottom - bounds.top);
754
		    	}	break;
755
 
756
 
757
 
758
			}
759
		}	break;
760
	}
761
 
762
    return result;
763
}
764
 
24749 iacus 765
#endif  /* HAVE_AQUA */
766
 
767
#endif /* __AQUA_DATA_BROWSER__ */