Mercurial > dwindows
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 /* |