comparison mac/dw.m @ 1065:25e0317335fc

Switched from using NSPointerArray to NSMutableArray on Mac to avoid the duplicate string crashes that have been plaguing the tree control.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sun, 12 Jun 2011 15:06:30 +0000
parents b673b25bbd77
children 6ca1132a240e
comparison
equal deleted inserted replaced
1064:b673b25bbd77 1065:25e0317335fc
337 337
338 /* Fill in both items for the tree */ 338 /* Fill in both items for the tree */
339 if([object isKindOfClass:[NSOutlineView class]]) 339 if([object isKindOfClass:[NSOutlineView class]])
340 { 340 {
341 id item = event; 341 id item = event;
342 NSString *nstr = [item pointerAtIndex:1]; 342 NSString *nstr = [item objectAtIndex:1];
343 text = (char *)[nstr UTF8String]; 343 text = (char *)[nstr UTF8String];
344 user = [item pointerAtIndex:2]; 344 NSValue *value = [item objectAtIndex:2];
345 if(value && [value isKindOfClass:[NSValue class]])
346 {
347 user = [value pointerValue];
348 }
345 } 349 }
346 350
347 dw_pointer_query_pos(&x, &y); 351 dw_pointer_query_pos(&x, &y);
348 352
349 return containercontextfunc(handler->window, text, (int)x, (int)y, handler->data, user); 353 return containercontextfunc(handler->window, text, (int)x, (int)y, handler->data, user);
366 id item = nil; 370 id item = nil;
367 371
368 if([object isKindOfClass:[NSOutlineView class]]) 372 if([object isKindOfClass:[NSOutlineView class]])
369 { 373 {
370 item = (id)event; 374 item = (id)event;
371 NSString *nstr = [item pointerAtIndex:1]; 375 NSString *nstr = [item objectAtIndex:1];
372 376
373 if(nstr) 377 if(nstr)
374 { 378 {
375 text = strdup([nstr UTF8String]); 379 text = strdup([nstr UTF8String]);
376 } 380 }
377 else 381 else
378 { 382 {
379 text = NULL; 383 text = NULL;
380 } 384 }
381 user = [item pointerAtIndex:2]; 385
386 NSValue *value = [item objectAtIndex:2];
387 if(value && [value isKindOfClass:[NSValue class]])
388 {
389 user = [value pointerValue];
390 }
382 int result = treeselectfunc(handler->window, item, text, handler->data, user); 391 int result = treeselectfunc(handler->window, item, text, handler->data, user);
383 if(text) 392 if(text)
384 { 393 {
385 free(text); 394 free(text);
386 } 395 }
1604 } 1613 }
1605 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; } 1614 -(void)dealloc { UserData *root = userdata; _remove_userdata(&root, NULL, TRUE); [super dealloc]; }
1606 @end 1615 @end
1607 1616
1608 /* Dive into the tree showing all nodes */ 1617 /* Dive into the tree showing all nodes */
1609 void _free_tree_recurse(NSMutableArray *node, NSPointerArray *item) 1618 void _free_tree_recurse(NSMutableArray *node, NSMutableArray *item)
1610 { 1619 {
1611 if(node) 1620 if(node && ([node isMemberOfClass:[NSMutableArray class]]))
1612 { 1621 {
1613 int count = (int)[node count]; 1622 int count = (int)[node count];
1614 int z; 1623 int z;
1615 1624
1616 for(z=0;z<count;z++) 1625 for(z=0;z<count;z++)
1617 { 1626 {
1618 NSPointerArray *pnt = [node objectAtIndex:z]; 1627 NSMutableArray *pnt = [node objectAtIndex:z];
1619 NSMutableArray *children = (NSMutableArray *)[pnt pointerAtIndex:3]; 1628 NSMutableArray *children = nil;
1629
1630 if(pnt && [pnt isMemberOfClass:[NSMutableArray class]])
1631 {
1632 children = (NSMutableArray *)[pnt objectAtIndex:3];
1633 }
1620 1634
1621 if(item == pnt) 1635 if(item == pnt)
1622 { 1636 {
1623 _free_tree_recurse(children, NULL); 1637 _free_tree_recurse(children, NULL);
1624 [node removeObjectAtIndex:z]; 1638 [node removeObjectAtIndex:z];
1625 count = (int)[node count]; 1639 count = (int)[node count];
1626 z--; 1640 z--;
1627 } 1641 }
1628 else if(item == NULL) 1642 else if(item == NULL)
1629 { 1643 {
1630 NSString *oldstr = [pnt pointerAtIndex:1]; 1644 NSString *oldstr = [pnt objectAtIndex:1];
1631 [oldstr release]; 1645 [oldstr release];
1632 _free_tree_recurse(children, item); 1646 _free_tree_recurse(children, item);
1633 } 1647 }
1634 else 1648 else
1635 _free_tree_recurse(children, item); 1649 _free_tree_recurse(children, item);
1660 -(BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item; 1674 -(BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item;
1661 -(int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item; 1675 -(int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item;
1662 -(id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item; 1676 -(id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item;
1663 -(void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item; 1677 -(void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item;
1664 -(BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item; 1678 -(BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item;
1665 -(void)addTree:(NSPointerArray *)item and:(NSPointerArray *)parent after:(NSPointerArray *)after; 1679 -(void)addTree:(NSMutableArray *)item and:(NSMutableArray *)parent after:(NSMutableArray *)after;
1666 -(void *)userdata; 1680 -(void *)userdata;
1667 -(void)setUserdata:(void *)input; 1681 -(void)setUserdata:(void *)input;
1668 -(void)treeSelectionChanged:(id)sender; 1682 -(void)treeSelectionChanged:(id)sender;
1669 -(void)treeItemExpanded:(NSNotification *)notification; 1683 -(void)treeItemExpanded:(NSNotification *)notification;
1670 -(NSScrollView *)scrollview; 1684 -(NSScrollView *)scrollview;
1671 -(void)setScrollview:(NSScrollView *)input; 1685 -(void)setScrollview:(NSScrollView *)input;
1672 -(void)deleteNode:(NSPointerArray *)item; 1686 -(void)deleteNode:(NSMutableArray *)item;
1673 -(void)setForegroundColor:(NSColor *)input; 1687 -(void)setForegroundColor:(NSColor *)input;
1674 -(void)clear; 1688 -(void)clear;
1675 @end 1689 @end
1676 1690
1677 @implementation DWTree 1691 @implementation DWTree
1694 } 1708 }
1695 -(id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item 1709 -(id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item
1696 { 1710 {
1697 if(item) 1711 if(item)
1698 { 1712 {
1699 NSMutableArray *array = [item pointerAtIndex:3]; 1713 NSMutableArray *array = [item objectAtIndex:3];
1700 return array ? [array objectAtIndex:index] : nil; 1714 return ([array isKindOfClass:[NSNull class]]) ? nil : [array objectAtIndex:index];
1701 } 1715 }
1702 else 1716 else
1703 { 1717 {
1704 return [data objectAtIndex:index]; 1718 return [data objectAtIndex:index];
1705 } 1719 }
1710 } 1724 }
1711 -(int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item 1725 -(int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
1712 { 1726 {
1713 if(item) 1727 if(item)
1714 { 1728 {
1715 if([item isKindOfClass:[NSPointerArray class]]) 1729 if([item isKindOfClass:[NSMutableArray class]])
1716 { 1730 {
1717 NSMutableArray *array = [item pointerAtIndex:3]; 1731 NSMutableArray *array = [item objectAtIndex:3];
1718 return array ? (int)[array count] : 0; 1732 return ([array isKindOfClass:[NSNull class]]) ? 0 : (int)[array count];
1719 } 1733 }
1720 else 1734 else
1721 { 1735 {
1722 return 0; 1736 return 0;
1723 } 1737 }
1729 } 1743 }
1730 -(id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item 1744 -(id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
1731 { 1745 {
1732 if(item) 1746 if(item)
1733 { 1747 {
1734 if([item isKindOfClass:[NSPointerArray class]]) 1748 if([item isKindOfClass:[NSMutableArray class]])
1735 { 1749 {
1736 NSPointerArray *this = (NSPointerArray *)item; 1750 NSMutableArray *this = (NSMutableArray *)item;
1737 return [this pointerAtIndex:1]; 1751 return [this objectAtIndex:1];
1738 } 1752 }
1739 else 1753 else
1740 { 1754 {
1741 return nil; 1755 return nil;
1742 } 1756 }
1745 } 1759 }
1746 -(void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item 1760 -(void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
1747 { 1761 {
1748 if([cell isMemberOfClass:[NSBrowserCell class]]) 1762 if([cell isMemberOfClass:[NSBrowserCell class]])
1749 { 1763 {
1750 NSPointerArray *this = (NSPointerArray *)item; 1764 NSMutableArray *this = (NSMutableArray *)item;
1751 NSImage *img = [this pointerAtIndex:0]; 1765 NSImage *img = [this objectAtIndex:0];
1752 [(NSBrowserCell*)cell setImage:img]; 1766 [(NSBrowserCell*)cell setImage:img];
1753 } 1767 }
1754 } 1768 }
1755 -(BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item { return NO; } 1769 -(BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item { return NO; }
1756 -(void)addTree:(NSPointerArray *)item and:(NSPointerArray *)parent after:(NSPointerArray *)after 1770 -(void)addTree:(NSMutableArray *)item and:(NSMutableArray *)parent after:(NSMutableArray *)after
1757 { 1771 {
1758 NSMutableArray *children = data; 1772 NSMutableArray *children = data;
1759 if(parent) 1773 if(parent)
1760 { 1774 {
1761 children = [parent pointerAtIndex:3]; 1775 children = [parent objectAtIndex:3];
1762 if(!children) 1776 if([children isKindOfClass:[NSNull class]])
1763 { 1777 {
1764 children = [[[NSMutableArray alloc] init] retain]; 1778 children = [[[NSMutableArray alloc] init] retain];
1765 [parent replacePointerAtIndex:3 withPointer:children]; 1779 [parent replaceObjectAtIndex:3 withObject:children];
1766 } 1780 }
1767 } 1781 }
1768 else 1782 else
1769 { 1783 {
1770 if(!data) 1784 if(!data)
1812 _event_handler(self, (NSEvent *)item, 10); 1826 _event_handler(self, (NSEvent *)item, 10);
1813 return nil; 1827 return nil;
1814 } 1828 }
1815 -(NSScrollView *)scrollview { return scrollview; } 1829 -(NSScrollView *)scrollview { return scrollview; }
1816 -(void)setScrollview:(NSScrollView *)input { scrollview = input; } 1830 -(void)setScrollview:(NSScrollView *)input { scrollview = input; }
1817 -(void)deleteNode:(NSPointerArray *)item { _free_tree_recurse(data, item); } 1831 -(void)deleteNode:(NSMutableArray *)item { _free_tree_recurse(data, item); }
1818 -(void)setForegroundColor:(NSColor *)input 1832 -(void)setForegroundColor:(NSColor *)input
1819 { 1833 {
1820 NSTextFieldCell *cell = [treecol dataCell]; 1834 NSTextFieldCell *cell = [treecol dataCell];
1821 fgcolor = input; 1835 fgcolor = input;
1822 [fgcolor retain]; 1836 [fgcolor retain];
5011 { 5025 {
5012 int _locked_by_me = FALSE; 5026 int _locked_by_me = FALSE;
5013 DW_MUTEX_LOCK; 5027 DW_MUTEX_LOCK;
5014 DWTree *tree = handle; 5028 DWTree *tree = handle;
5015 NSString *nstr = [[NSString stringWithUTF8String:title] retain]; 5029 NSString *nstr = [[NSString stringWithUTF8String:title] retain];
5016 NSPointerArray *treenode = [NSPointerArray pointerArrayWithWeakObjects]; 5030 NSMutableArray *treenode = [[[NSMutableArray alloc] init] retain];
5017 [treenode addPointer:icon]; 5031 [treenode addObject:icon];
5018 [treenode addPointer:nstr]; 5032 [treenode addObject:nstr];
5019 [treenode addPointer:itemdata]; 5033 [treenode addObject:[NSValue valueWithPointer:itemdata]];
5020 [treenode addPointer:NULL]; 5034 [treenode addObject:[NSNull null]];
5021 [tree addTree:treenode and:parent after:item]; 5035 [tree addTree:treenode and:parent after:item];
5022 if(parent) 5036 if(parent)
5023 [tree reloadItem:parent reloadChildren:YES]; 5037 [tree reloadItem:parent reloadChildren:YES];
5024 else 5038 else
5025 [tree reloadData]; 5039 [tree reloadData];
5049 */ 5063 */
5050 char * API dw_tree_get_title(HWND handle, HTREEITEM item) 5064 char * API dw_tree_get_title(HWND handle, HTREEITEM item)
5051 { 5065 {
5052 int _locked_by_me = FALSE; 5066 int _locked_by_me = FALSE;
5053 DW_MUTEX_LOCK; 5067 DW_MUTEX_LOCK;
5054 NSPointerArray *array = (NSPointerArray *)item; 5068 NSMutableArray *array = (NSMutableArray *)item;
5055 NSString *nstr = (NSString *)[array pointerAtIndex:1]; 5069 NSString *nstr = (NSString *)[array objectAtIndex:1];
5056 DW_MUTEX_UNLOCK; 5070 DW_MUTEX_UNLOCK;
5057 return strdup([nstr UTF8String]); 5071 return strdup([nstr UTF8String]);
5058 } 5072 }
5059 5073
5060 /* 5074 /*
5086 void API dw_tree_item_change(HWND handle, HTREEITEM item, char *title, HICN icon) 5100 void API dw_tree_item_change(HWND handle, HTREEITEM item, char *title, HICN icon)
5087 { 5101 {
5088 int _locked_by_me = FALSE; 5102 int _locked_by_me = FALSE;
5089 DW_MUTEX_LOCK; 5103 DW_MUTEX_LOCK;
5090 DWTree *tree = handle; 5104 DWTree *tree = handle;
5091 NSPointerArray *array = (NSPointerArray *)item; 5105 NSMutableArray *array = (NSMutableArray *)item;
5092 if(title) 5106 if(title)
5093 { 5107 {
5094 NSString *oldstr = [array pointerAtIndex:1]; 5108 NSString *oldstr = [array objectAtIndex:1];
5095 NSString *nstr = [[NSString stringWithUTF8String:title] retain]; 5109 NSString *nstr = [[NSString stringWithUTF8String:title] retain];
5096 [array replacePointerAtIndex:1 withPointer:nstr]; 5110 [array replaceObjectAtIndex:1 withObject:nstr];
5097 [oldstr release]; 5111 [oldstr release];
5098 } 5112 }
5099 if(icon) 5113 if(icon)
5100 { 5114 {
5101 [array replacePointerAtIndex:0 withPointer:icon]; 5115 [array replaceObjectAtIndex:0 withObject:icon];
5102 } 5116 }
5103 [tree reloadData]; 5117 [tree reloadData];
5104 DW_MUTEX_UNLOCK; 5118 DW_MUTEX_UNLOCK;
5105 } 5119 }
5106 5120
5113 */ 5127 */
5114 void API dw_tree_item_set_data(HWND handle, HTREEITEM item, void *itemdata) 5128 void API dw_tree_item_set_data(HWND handle, HTREEITEM item, void *itemdata)
5115 { 5129 {
5116 int _locked_by_me = FALSE; 5130 int _locked_by_me = FALSE;
5117 DW_MUTEX_LOCK; 5131 DW_MUTEX_LOCK;
5118 NSPointerArray *array = (NSPointerArray *)item; 5132 NSMutableArray *array = (NSMutableArray *)item;
5119 [array replacePointerAtIndex:2 withPointer:itemdata]; 5133 [array replaceObjectAtIndex:2 withObject:[NSValue valueWithPointer:itemdata]];
5120 DW_MUTEX_UNLOCK; 5134 DW_MUTEX_UNLOCK;
5121 } 5135 }
5122 5136
5123 /* 5137 /*
5124 * Gets the item data of a tree item. 5138 * Gets the item data of a tree item.
5127 * item: Handle of the item to be modified. 5141 * item: Handle of the item to be modified.
5128 */ 5142 */
5129 void * API dw_tree_item_get_data(HWND handle, HTREEITEM item) 5143 void * API dw_tree_item_get_data(HWND handle, HTREEITEM item)
5130 { 5144 {
5131 int _locked_by_me = FALSE; 5145 int _locked_by_me = FALSE;
5146 void *result = NULL;
5132 DW_MUTEX_LOCK; 5147 DW_MUTEX_LOCK;
5133 NSPointerArray *array = (NSPointerArray *)item; 5148 NSMutableArray *array = (NSMutableArray *)item;
5134 void *result = [array pointerAtIndex:2]; 5149 NSValue *value = [array objectAtIndex:2];
5150 if(value && [value isMemberOfClass:[NSValue class]])
5151 {
5152 result = [value pointerValue];
5153 }
5135 DW_MUTEX_UNLOCK; 5154 DW_MUTEX_UNLOCK;
5136 return result; 5155 return result;
5137 } 5156 }
5138 5157
5139 /* 5158 /*