Synchronise with trunk

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/branches/themes@24018 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2006-11-02 19:48:37 +00:00
parent de0771f88a
commit ed1128c5cd
18 changed files with 745 additions and 252 deletions

103
ChangeLog
View file

@ -1,13 +1,108 @@
2006-10-26 Richard Frith-Macdonald <rfm@gnu.org>
2006-11-02 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSTheme.m: implement use of tiling for NSButton
* Source/GSTheme.m:
* Source/GSInfoPanel.m:
Merge in changes from theme branch...
Support tiling when drawing button cells.
Make theme panel link visible, as someone suggested that having
it totally hidden was not so good. Perhaps make it more explicit
in future?
2006-11-01 Matt Rice <ratmice@yahoo.com>
* Source/NSTableView.m:
(-editColumn:row:withEvent:select:): Raise when passed an unselected
row.
(-textDidEndEditing:): Handle NSReturnTextMovement.
(_editNextCellAfterRow:inColumn:): New private method.
2006-11-01 Matt Rice <ratmice@yahoo.com>
* Source/NSTableView.m: Add new private methods.
(-mouseDown:): Reorganize and don't track cells until dragging
has been ruled out.
* Source/NSCell.m (trackMouse:inRect:ofView:untilMouseUp:):
Handle events no longer in the queue.
* Source/GSDragView.m: Change NSLog to NSDebugLLog.
2006-10-31 Matt Rice <ratmice@yahoo.com>
* Tools/gopen.m
* Source/NSView.m
* Source/GSPDFPrintOperation.m
* Source/NSHelpManager.m
* Source/GSHelpManagerPanel.m: Add missing includes.
2006-10-31 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSWorkspace.m: add missing include
2006-10-30 Matt Rice <ratmice@yahoo.com>
* Source/NSComboBoxCell.m (validateSelection): Test for invalid row.
2006-10-28 Adam Fedor <fedor@gnu.org>
* Source/NSApplication.m (initialize_gnustep_backend): Use
GSBackend class directly when backend is compiled as a library.
(Partial fix for Bug #16453, see also gnustep-back).
2006-10-27 Matt Rice <ratmice@yahoo.com>
* Source/NSAlert.m: Add GSRunExceptionPanel function
and GSExceptionPanel class.
* Headers/AppKit/NSPanel.h: Declare GSRunExceptionPanel.
* Source/NSApplication.m (_NSAppKitUncaughtExceptionHandler):
Use GSRunExceptionPanel.
2006-10-27 Matt Rice <ratmice@yahoo.com>
* Source/NSTableView.m (-setFrame:,-setFrameSize:): Use
documentVisibleRect. Shrink if table is larger than needed height.
fixes bug #18117.
(-drawBackgroundInClipRect:): Draw the background.
* Source/NSClipView.m (-documentVisibleRect:): Return the clip views
visible rect converted to the document views coordinate system.
2006-10-24 Matt Rice <ratmice@yahoo.com>
* Source/NSApplication.m (NSAppIcon -mouseDown:): Call unhide:
regardless of whether we're hidden or not.
2006-10-22 Matt Rice <ratmice@yahoo.com>
* Source/NSTableView.m (-mouseDown:): Check for empty selection.
when adding to the current selection. Fixes bug #15261.
2006-10-21 Matt Rice <ratmice@yahoo.com>
* Headers/AppKit/NSGraphics.h: Add GSOrderedWindows function.
* Source/NSApplication.m (NSAppIconView -mouseDown:): Use
GSOrderedWindows.
(NSApplication -deactivate): Ditto.
(-hide:): Ditto.
(-unhideWithoutActivation:): Ditto.
(-makeWindowsPerform:inOrder): Ditto.
(-orderedWindows:): Ditto.
(-windowWillClose:): Ditto.
* Source/GSDisplayServer.m: Implement -windowlist.
* Source/NSWindow.m (NSCountWindowList,NSWindowList): Use -windowlist.
(GSOrderedWindows): Initial implementation.
2006-10-21 11:30-EDT Matt Rice <ratmice@yahoo.com>
* Source/NSTableView.m: If the tableview is smaller than
it's clipview, then resize it so that it fits.
Corrects bug#9608 and bug#18073.
Patch committed by: Gregory Casamento <greg_casamento@yahoo.com>
2006-10-19 21:17-EDT Gregory John Casamento <greg_casamento@yahoo.com>
* Source/NSMenuItemCell.m: Correct menu highlighting issue
found by applying changes suggested by Jeff Teunissen. This
change causes the menu to use the correct text color when
highlighted.
highlighted. (minor change)
2006-10-19 Richard Frith-Macdonald <rfm@gnu.org>
@ -25,7 +120,7 @@
* Source/NSFont.m: Apply slightly modified version of patch
from Jeff Teunissen deek@d2dc.net to setNSFont(). Setting
a font should set its size.
a font should set its size. (minor change)
* Source/NSImage.m: Set the alpha on the background when printing.
2006-10-15 11:23-EDT Mark Tracy <tracy454 at concentric dot net>

View file

@ -215,6 +215,7 @@ GSWViewIsFlipped(NSGraphicsContext *ctxt)
@class NSArray;
@class NSWindow;
APPKIT_EXPORT NSArray* GSOrderedWindows(void);
APPKIT_EXPORT NSArray* GSAllWindows(void);
APPKIT_EXPORT NSWindow* GSWindowWithNumber(int num);
#endif

View file

@ -174,6 +174,12 @@ APPKIT_EXPORT void NSBeginInformationalAlertSheet(NSString *title,
void *contextInfo,
NSString *msg, ...);
APPKIT_EXPORT int GSRunExceptionPanel(NSString *title,
NSException *exception,
NSString *defaultButton,
NSString *alternateButton,
NSString *otherButton);
#endif
//

View file

@ -33,6 +33,7 @@
#include <Foundation/NSThread.h>
#include <Foundation/NSGeometry.h>
#include "AppKit/NSApplication.h"
#include "AppKit/NSEvent.h"
#include "AppKit/NSImage.h"
#include "AppKit/NSWindow.h"
@ -664,11 +665,25 @@ GSCurrentServer(void)
return 0;
}
/** Returns the list of windows that the server controls */
/** Backends can override this method to return an array of window numbers
ordered front to back. The front most window being the first object
in the array.
The default implementation returns the visible windows in an
unspecified order.
*/
- (NSArray *) windowlist
{
[self subclassResponsibility: _cmd];
return nil;
NSMutableArray *list = [NSMutableArray arrayWithArray:[NSApp windows]];
int c = [list count];
while (c-- > 0)
{
if (![[list objectAtIndex:c] isVisible])
{
[list removeObjectAtIndex:c];
}
}
return [list valueForKey:@"windowNumber"];
}
/** Returns the depth of the window */

View file

@ -756,7 +756,7 @@ static GSDragView *sharedDragView = nil;
break;
default:
NSLog(@"Internal: dropped NSAppKitDefined (%d) event", sub);
NSDebugLLog(@"NSDragging", @"dropped NSAppKitDefined (%d) event", sub);
break;
}
}

View file

@ -29,6 +29,7 @@
#include "AppKit/NSAttributedString.h"
#include "AppKit/NSTextView.h"
#include "AppKit/NSTextContainer.h"
#include "AppKit/NSTextStorage.h"
#include "AppKit/NSScrollView.h"
#include "AppKit/NSButton.h"
#include "AppKit/NSClipView.h"

View file

@ -35,6 +35,7 @@
#include <Foundation/NSPathUtilities.h>
#include <Foundation/NSTask.h>
#include <Foundation/NSProcessInfo.h>
#include <Foundation/NSData.h>
#include "AppKit/NSView.h"
#include "GNUstepGUI/GSPDFPrintOperation.h"

View file

@ -1468,3 +1468,236 @@ void NSBeginInformationalAlertSheet(NSString *title,
}
@end
@interface GSExceptionPanel : GSAlertPanel
{
NSBrowser *_browser;
NSDictionary *_userInfo;
NSPanel *_userInfoPanel;
}
- (void) setUserInfo:(NSDictionary *)userInfo;
- (NSPanel *)userInfoPanel;
@end
int GSRunExceptionPanel(
NSString *title,
NSException *exception,
NSString *defaultButton,
NSString *alternateButton,
NSString *otherButton)
{
NSString *message;
GSExceptionPanel *panel;
int result;
message = [NSString stringWithFormat:@"%@: %@",
[exception name],
[exception reason]];
if (defaultButton == nil)
{
defaultButton = @"OK";
}
panel = [[GSExceptionPanel alloc] init];
if (title == nil)
{
title = @"Exception";
}
[panel setTitle: title
message: message
def: defaultButton
alt: alternateButton
other: otherButton];
[panel setUserInfo: [exception userInfo]];
result = [panel runModal];
[[panel userInfoPanel] orderOut:nil];
[panel setUserInfo: nil];
RELEASE(panel);
return result;
}
@implementation GSExceptionPanel
- (void) dealloc
{
RELEASE(_userInfo);
RELEASE(_browser);
RELEASE(_userInfoPanel);
[super dealloc];
}
- (id) init
{
if ((self = [super init]))
{
[icoButton setEnabled:YES];
[icoButton setTarget:self];
[icoButton setAction:@selector(_icoAction:)];
}
return self;
}
- (NSPanel *) userInfoPanel
{
return _userInfoPanel;
}
- (void) setUserInfo:(NSDictionary *)userInfo;
{
ASSIGN(_userInfo, userInfo);
[_browser reloadColumn:0];
}
- (void) _icoAction:(id)sender
{
NSRect fr;
if (_userInfoPanel)
{
[_browser reloadColumn:0];
return;
}
fr = NSMakeRect(_frame.origin.x, _frame.origin.y + _frame.size.height + 15,
_frame.size.width, 108);
_userInfoPanel = [[NSPanel alloc] initWithContentRect:fr
styleMask:NSTitledWindowMask
| NSResizableWindowMask
backing:NSBackingStoreBuffered
defer:NO];
[_userInfoPanel setTitle:@"User Info Inspector"];
[_userInfoPanel setWorksWhenModal:YES];
fr = NSMakeRect(8, 8, _frame.size.width - 16, 100);
_browser = [[NSBrowser alloc] initWithFrame:fr];
[_browser setMaxVisibleColumns:2];
[_browser setDelegate:self];
[_browser setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[_browser reloadColumn:0];
[[_userInfoPanel contentView] addSubview:_browser];
[_userInfoPanel makeKeyAndOrderFront:self];
}
- (int) browser:(id)browser
numberOfRowsInColumn:(int)col
{
if (col == 0)
return [[_userInfo allKeys] count];
else
{
id val = [[(NSCell *)[browser selectedCellInColumn:col - 1] representedObject] description];
volatile id foo = nil;
NS_DURING
foo = [val propertyList];
val = foo;
NS_HANDLER
NS_ENDHANDLER
if ([val isKindOfClass:[NSArray class]])
return [val count];
else if ([val isKindOfClass:[NSDictionary class]])
return [[val allKeys] count];
else return val != nil;
}
return 0;
}
- (void) browser:(NSBrowser *)browser willDisplayCell:(NSBrowserCell *)cell atRow:(int)row
column:(int)column
{
if (column == 0)
{
id key = [[_userInfo allKeys] objectAtIndex:row];
id val = [_userInfo objectForKey:key];
[cell setLeaf:NO];
[cell setStringValue:[key description]];
[cell setRepresentedObject: val];
}
else
{
volatile id val = [(NSCell *)[browser selectedCellInColumn:column - 1] representedObject];
BOOL flag;
if (!([val isKindOfClass:[NSArray class]] || [val isKindOfClass:[NSArray class]]))
{
volatile id foo = nil;
val = [val description];
NS_DURING
foo = [val propertyList];
val = foo;
NS_HANDLER
NS_ENDHANDLER
}
flag = (!([val isKindOfClass:[NSArray class]]
|| [val isKindOfClass:[NSDictionary class]]));
[cell setLeaf:flag];
if ([val isKindOfClass:[NSArray class]])
{
volatile id obj = [val objectAtIndex:row];
if (!([obj isKindOfClass:[NSArray class]] || [obj isKindOfClass:[NSArray class]]))
{
volatile id foo;
obj = [[obj description] propertyList];
NS_DURING
foo = [obj propertyList];
obj = foo;
NS_HANDLER
NS_ENDHANDLER
}
if ([obj isKindOfClass:[NSArray class]])
{
[cell setRepresentedObject:obj];
[cell setLeaf:NO];
[cell setStringValue:[NSString stringWithFormat:@"%@ %p", [obj class], obj]];
}
else if ([obj isKindOfClass:[NSDictionary class]])
{
[cell setRepresentedObject:obj];
[cell setLeaf:NO];
[cell setStringValue:[NSString stringWithFormat:@"%@ %p", [obj class], obj]];
}
else
{
[cell setLeaf:YES];
[cell setStringValue:[obj description]];
[cell setRepresentedObject:nil];
}
}
else if ([val isKindOfClass:[NSDictionary class]])
{
id key = [[val allKeys] objectAtIndex:row];
volatile id it = [(NSDictionary *)val objectForKey: key];
volatile id foo;
foo = [it description];
NS_DURING
foo = [it propertyList];
it = foo;
NS_HANDLER
NS_ENDHANDLER
[cell setStringValue:[key description]];
[cell setRepresentedObject:it];
}
else
{
[cell setLeaf:YES];
[cell setStringValue:[val description]];
}
}
}
- (id) browser:(NSBrowser *)browser titleOfColumn:(int)column
{
if (column == 0) return @"userInfo";
id val = [(NSCell *)[browser selectedCellInColumn:column - 1] representedObject];
NSString *title = [NSString stringWithFormat:@"%@ %p", [val class], val];
return title;
}
@end

View file

@ -113,19 +113,17 @@ _NSAppKitUncaughtExceptionHandler (NSException *exception)
[exception raise];
}
retVal = NSRunCriticalAlertPanel
retVal = GSRunExceptionPanel
([NSString stringWithFormat: _(@"Critical Error in %@"),
[[NSProcessInfo processInfo] processName]],
@"%@: %@",
exception,
_(@"Abort"),
nil,
#ifdef DEBUG
_(@"Debug"),
_(@"Debug"));
#else
nil,
nil);
#endif
[exception name],
[exception reason]);
/* The user wants to abort */
if (retVal == NSAlertDefault)
@ -298,11 +296,10 @@ initialize_gnustep_backend(void)
}
#else
/* GSBackend will be in a separate library, so use the runtime
to find the class and avoid an unresolved reference problem */
backend = [[NSBundle gnustepBundle] classNamed: @"GSBackend"];
NSCAssert (backend, _(@"Can't find backend context"));
[backend initializeBackend];
/* GSBackend will be in a separate library linked in with the app.
This would be cleaner with ...classNamed: @"GSBackend", but that
doesn't work in some cases (Mac OS X for instance). */
[GSBackend initializeBackend];
#endif
}
return YES;
@ -504,30 +501,15 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
{
if ([theEvent clickCount] >= 2)
{
/* If the app is not hidden we need to order front any visible and
possibly obscured windows. If we are active we need to order front
the key or main window again, otherwise unhide: will unhide and
activate us. Do this all in a way which will not change the stacking
order.
There are 3 possibilities:
1. app is active and has no obscured windows
2. app is active and has obscured windows
3. app is inactive.
I don't know of any way to tell 1 from 2 and do nothing.
This should ideally set aWin NSWindowBelow the key or main window
but with most windowmanagers. It doesn't seem to place the receiving
window immediately below like it should.
*/
/* if not hidden raise windows which are possibly obscured. */
if ([NSApp isHidden] == NO)
{
int i;
NSArray *windows = RETAIN([NSApp windows]);
for (i = 0; i < [windows count]; i++)
NSArray *windows = RETAIN(GSOrderedWindows());
NSWindow *aWin;
NSEnumerator *iter = [windows reverseObjectEnumerator];
while ((aWin = [iter nextObject]))
{
NSWindow *aWin = [windows objectAtIndex:i];
if ([aWin isVisible] == YES && [aWin isMiniaturized] == NO
&& aWin != [NSApp keyWindow] && aWin != [NSApp mainWindow]
@ -562,7 +544,7 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
RELEASE(windows);
}
[NSApp unhide: self];
[NSApp unhide: self]; // or activate or do nothing.
}
else
{
@ -1167,6 +1149,12 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
[[_inactive objectAtIndex: i] orderFrontRegardless];
}
[_inactive removeAllObjects];
if (_unhide_on_activation)
{
[self unhide: nil];
}
if ([self keyWindow] == nil && _hidden_key != nil
&& [[self windows] indexOfObjectIdenticalTo: _hidden_key] != NSNotFound)
{
@ -1174,11 +1162,6 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
_hidden_key = nil;
}
if (_unhide_on_activation)
{
[self unhide: nil];
}
if ([self keyWindow] != nil)
{
[[self keyWindow] orderFront: self];
@ -1216,13 +1199,14 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
{
if (_app_is_active == YES)
{
NSArray *windows_list = [self windows];
unsigned count = [windows_list count];
unsigned i;
NSArray *windows_list;
NSDictionary *info;
NSWindow *win;
NSEnumerator *iter;
[nc postNotificationName: NSApplicationWillResignActiveNotification
object: self];
_app_is_active = NO;
@ -1235,11 +1219,14 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
// This is not a problem if it is also key, and I'm not sure if it
// is a problem at all. May be annoying in the case of workspace switch.
[[self mainWindow] resignMainWindow];
for (i = 0; i < count; i++)
windows_list = GSOrderedWindows();
iter = [windows_list reverseObjectEnumerator];
while ((win = [iter nextObject]))
{
NSModalSession theSession;
NSWindow *win = [windows_list objectAtIndex: i];
if ([win isVisible] == NO)
{
continue; /* Already invisible */
@ -2205,10 +2192,10 @@ image.</p><p>See Also: -applicationIconImage</p>
{
if (_app_is_hidden == NO)
{
NSArray *windows_list = [self windows];
unsigned count = [windows_list count];
NSArray *windows_list;
NSDictionary *info;
unsigned i;
NSWindow *win;
NSEnumerator *iter;
[nc postNotificationName: NSApplicationWillHideNotification
object: self];
@ -2218,10 +2205,12 @@ image.</p><p>See Also: -applicationIconImage</p>
_hidden_key = [self keyWindow];
[_hidden_key resignKeyWindow];
}
for (i = 0; i < count; i++)
{
NSWindow *win = [windows_list objectAtIndex: i];
windows_list = GSOrderedWindows();
iter = [windows_list reverseObjectEnumerator];
while ((win = [iter nextObject]))
{
if ([win isVisible] == NO)
{
continue; /* Already invisible */
@ -2314,12 +2303,6 @@ image.</p><p>See Also: -applicationIconImage</p>
[[_hidden objectAtIndex: i] orderFrontRegardless];
}
[_hidden removeAllObjects];
if (_hidden_key != nil
&& [[self windows] indexOfObjectIdenticalTo: _hidden_key] != NSNotFound)
{
[_hidden_key makeKeyAndOrderFront: self];
_hidden_key = nil;
}
[[_app_icon_window contentView] setNeedsDisplay: YES];
info = [self _notificationUserInfo];
@ -2393,12 +2376,20 @@ image.</p><p>See Also: -applicationIconImage</p>
*/
- (NSWindow*) makeWindowsPerform: (SEL)aSelector inOrder: (BOOL)flag
{
NSArray *window_list = [self windows];
unsigned i;
NSArray *window_list;
unsigned i, c;
// FIXME flag ignored
i = [window_list count];
while (i-- > 0)
// so i suppose when flag is YES it only runs on visible windows
if (flag)
{
window_list = GSOrderedWindows();
}
else
{
window_list = [self windows];
}
for (i = 0, c = [window_list count]; i < c; i++)
{
NSWindow *window = [window_list objectAtIndex: i];
@ -3251,14 +3242,24 @@ image.</p><p>See Also: -applicationIconImage</p>
}
/**
* OS X scripting method to return windows in front-to-back on-screen order.
* <em>The GNUstep implementation returns all the windows in an arbitrary
* order.</em>
* OS X scripting method to return windows in front-to-back on-screen order
* for scriptable windows.
* <em>The GNUstep implementation returns all the windows excluding NSPanels.
* some backends may return an array in an unspecified order.</em>
*/
- (NSArray *) orderedWindows
{
// FIXME
return [self windows];
NSArray *arr = GSOrderedWindows();
NSMutableArray *ret = [[NSArray alloc] initWithCapacity:[arr count]];
NSEnumerator *iter = [arr objectEnumerator];
id win;
while ((win = [iter nextObject]))
{
if (![win isKindOfClass:[NSPanel class]])
[ret addObject:win];
}
return AUTORELEASE(ret);
}
/*
@ -3478,17 +3479,17 @@ image.</p><p>See Also: -applicationIconImage</p>
- (void) _windowWillClose: (NSNotification*) notification
{
NSWindow *win = [notification object];
NSArray *windows_list = [self windows];
NSArray *windows_list = GSOrderedWindows();
unsigned count = [windows_list count];
unsigned i;
NSMutableArray *list = [NSMutableArray arrayWithCapacity: count];
BOOL wasKey = [win isKeyWindow];
BOOL wasMain = [win isMainWindow];
NSEnumerator *iter = [windows_list objectEnumerator];
NSWindow *tmp;
for (i = 0; i < count; i++)
while ((tmp = [iter nextObject]))
{
NSWindow *tmp = [windows_list objectAtIndex: i];
if ([tmp canBecomeMainWindow] == YES && [tmp isVisible] == YES)
{
[list addObject: tmp];

View file

@ -1548,15 +1548,19 @@ static NSColor *shadowCol;
NSDebugLLog(@"NSCell", @"cell get mouse events\n");
mouseWentUp = NO;
done = NO;
if (theEvent != [NSApp currentEvent])
theEvent = [NSApp currentEvent];
else
theEvent = [theApp nextEventMatchingMask: event_mask
untilDate: nil
inMode: NSEventTrackingRunLoopMode
dequeue: YES];
while (!done)
{
NSEventType eventType;
BOOL pointIsInCell;
theEvent = [theApp nextEventMatchingMask: event_mask
untilDate: nil
inMode: NSEventTrackingRunLoopMode
dequeue: YES];
eventType = [theEvent type];
if (eventType != NSPeriodic || periodCount == 4)
@ -1626,6 +1630,12 @@ static NSColor *shadowCol;
&& (_action_mask & NSPeriodicMask))))
[(NSControl*)controlView sendAction: action to: target];
}
if (!done)
theEvent = [theApp nextEventMatchingMask: event_mask
untilDate: nil
inMode: NSEventTrackingRunLoopMode
dequeue: YES];
}
// Hook called when stop tracking

View file

@ -462,26 +462,17 @@ static inline NSRect integralRect (NSRect rect, NSView *view)
return rect;
}
/**<p>Returns the document visible rectangle. Returns NSZeroRect if the
document view does not exists.</p>
/**<p>Returns the document visible rectangle in the document views coordinate
* system.
<p>See Also: -documentRect [NSView-convertRect:toView:]</p>
*/
- (NSRect) documentVisibleRect
{
NSRect documentBounds;
NSRect clipViewBounds;
NSRect rect;
if (_documentView == nil)
{
return NSZeroRect;
}
documentBounds = [_documentView bounds];
clipViewBounds = [self convertRect: _bounds toView: _documentView];
rect = NSIntersectionRect (documentBounds, clipViewBounds);
return rect;
NSRect visRect;
visRect = [self visibleRect];
visRect = [self convertRect:visRect toView:_documentView];
return visRect;
}
- (void) drawRect: (NSRect)rect

View file

@ -697,21 +697,25 @@ static GSComboWindow *gsWindow = nil;
{
NSText *textObject = nil;
id cv = [_cell controlView];
int index = [_cell indexOfSelectedItem];
if ([cv isKindOfClass: [NSControl class]])
{
textObject = [(NSControl *)cv currentEditor];
}
[_cell setStringValue: [_cell _stringValueAtIndex:
[_cell indexOfSelectedItem]]];
// Will update the editor when needed
if (index != -1)
{
[_cell setStringValue: [_cell _stringValueAtIndex:
[_cell indexOfSelectedItem]]];
// Will update the editor when needed
// FIXME: Because NSCell doesn't behave correctly the line just over has
// no effect, to correct this fact, the code below is needed.
[textObject setString: [_cell _stringValueAtIndex:
[_cell indexOfSelectedItem]]];
// End of the code to remove
// FIXME: Because NSCell doesn't behave correctly the line just over has
// no effect, to correct this fact, the code below is needed.
[textObject setString: [_cell _stringValueAtIndex:
[_cell indexOfSelectedItem]]];
// End of the code to remove
}
if (textObject != nil)
{

View file

@ -36,6 +36,7 @@
#include "AppKit/NSAttributedString.h"
#include "AppKit/NSApplication.h"
#include "AppKit/NSWorkspace.h"
#include "AppKit/NSFileWrapper.h"
#include "AppKit/NSHelpManager.h"
#include "AppKit/NSHelpPanel.h"
#include "AppKit/NSHelpPanel.h"
@ -44,6 +45,7 @@
#include "AppKit/NSGraphics.h"
#include "AppKit/NSScrollView.h"
#include "AppKit/NSTextView.h"
#include "AppKit/NSTextStorage.h"
#include "GNUstepGUI/GSHelpManagerPanel.h"

View file

@ -146,7 +146,10 @@ typedef struct _tableViewFlags
- (void) _unselectAllColumns;
@end
@interface NSTableView (EventLoopHelper)
- (void) _trackCellAtColumn:(int)column row:(int)row withEvent:(NSEvent *)ev;
- (BOOL) _startDragOperationWithEvent:(NSEvent *)theEvent;
@end
/*
* A specific struct and its associated quick sort function
@ -1941,6 +1944,7 @@ static void computeNewSelection
column: (int)column;
- (BOOL) _editPreviousEditableCellBeforeRow: (int)row
column: (int)column;
- (void) _editNextCellAfterRow:(int)row inColumn:(int)column;
- (void) _autosaveTableColumns;
- (void) _autoloadTableColumns;
@end
@ -3210,6 +3214,12 @@ byExtendingSelection: (BOOL)flag
[self scrollRowToVisible: rowIndex];
[self scrollColumnToVisible: columnIndex];
if (rowIndex != _selectedRow)
{
[NSException raise:NSInvalidArgumentException
format:@"Attempted to edit unselected row"];
}
if (rowIndex < 0 || rowIndex >= _numberOfRows
|| columnIndex < 0 || columnIndex >= _numberOfColumns)
{
@ -3341,25 +3351,121 @@ static inline float computePeriod(NSPoint mouseLocationWin,
return 0.01;
}
- (void) _trackCellAtColumn:(int)columnIndex
row:(int)rowIndex
withEvent:(NSEvent *)theEvent
{
NSTableColumn *tb;
NSCell *cell;
NSRect cellFrame;
id originalValue;
if (rowIndex == -1 || columnIndex == -1)
{
return;
}
tb = [_tableColumns objectAtIndex: columnIndex];
/* we should copy the cell here, as we do on editing.
otherwise validation on a cell being edited could
cause the cell we are selecting to get it's objectValue */
cell = [[tb dataCellForRow: rowIndex] copy];
originalValue = RETAIN([self _objectValueForTableColumn:tb
row:rowIndex]);
[cell setObjectValue: originalValue];
cellFrame = [self frameOfCellAtColumn: columnIndex
row: rowIndex];
[cell setHighlighted: YES];
[self setNeedsDisplayInRect: cellFrame];
/* give delegate a chance to i.e set target */
[self _willDisplayCell: cell
forTableColumn: tb
row: rowIndex];
if ([cell trackMouse: theEvent
inRect: cellFrame
ofView: self
untilMouseUp:[[cell class]
prefersTrackingUntilMouseUp]])
{
id newValue = [cell objectValue];
if ([tb isEditable]
&& originalValue != newValue
&& ![originalValue isEqual: newValue])
{
[self _setObjectValue: newValue
forTableColumn: tb
row: rowIndex];
}
}
RELEASE(originalValue);
[cell setHighlighted: NO];
[self setNeedsDisplayInRect: cellFrame];
RELEASE(cell);
}
- (BOOL) _startDragOperationWithEvent:(NSEvent *)theEvent
{
NSPasteboard *pboard;
NSArray *rows;
rows = [self _selectedRowArray];
pboard = [NSPasteboard pasteboardWithName: NSDragPboard];
if ([self _writeRows: rows
toPasteboard: pboard] == YES)
{
NSPoint p = NSZeroPoint;
NSImage *dragImage;
NSSize s;
dragImage = [self dragImageForRows: rows
event: theEvent
dragImageOffset: &p];
/*
* Store image offset in s ... the returned
* value is the position of the center of
* the image, so we adjust to the bottom left
* corner.
*/
s = [dragImage size];
s.width = p.x - s.width/2;
s.height = p.y + s.height/2; // View is flipped
/*
* Find the current mouse location and adjust
* it to determine the location of the bottom
* left corner of the image in this view's
* coordinate system.
*/
p = [self convertPoint: [theEvent locationInWindow] fromView: nil];
p.x += s.width;
p.y += s.height;
[self dragImage: dragImage
at: p
offset: NSMakeSize(0, 0)
event: theEvent
pasteboard: pboard
source: self
slideBack: YES];
return YES;
}
return NO;
}
- (void) mouseDown: (NSEvent *)theEvent
{
NSPoint initialLocation = [theEvent locationInWindow];
NSPoint location;
int clickCount;
// Pathological case -- ignore mouse down
if ((_numberOfRows == 0) || (_numberOfColumns == 0))
{
[super mouseDown: theEvent];
return;
}
clickCount = [theEvent clickCount];
if (clickCount > 2)
{
return;
}
/* Stop editing if any */
if (_textObject != nil)
{
@ -3371,8 +3477,9 @@ static inline float computePeriod(NSPoint mouseLocationWin,
location = [self convertPoint: initialLocation fromView: nil];
_clickedRow = [self rowAtPoint: location];
_clickedColumn = [self columnAtPoint: location];
if (clickCount == 2)
if ([theEvent type] == NSLeftMouseDown
&& [theEvent clickCount] > 1)
{
// Double-click event
@ -3384,13 +3491,19 @@ static inline float computePeriod(NSPoint mouseLocationWin,
if (![self _isCellEditableColumn: _clickedColumn row: _clickedRow ])
{
// Send double-action but don't edit
[self sendAction: _doubleAction to: _target];
[self _trackCellAtColumn:_clickedColumn
row:_clickedRow
withEvent:theEvent];
if (_clickedRow != -1)
[self sendAction: _doubleAction to: _target];
}
else
{
// It is OK to edit column. Go on, do it.
[self editColumn: _clickedColumn row: _clickedRow
withEvent: theEvent select: YES];
[self editColumn: _clickedColumn
row: _clickedRow
withEvent: theEvent
select: YES];
}
}
else
@ -3401,7 +3514,7 @@ static inline float computePeriod(NSPoint mouseLocationWin,
| NSLeftMouseDownMask
| NSLeftMouseDraggedMask
| NSPeriodicMask);
unsigned selectionMode;
unsigned selectionMode = 0;
NSPoint mouseLocationWin;
NSPoint mouseLocationView;
NSDate *distantFuture = [NSDate distantFuture];
@ -3420,8 +3533,8 @@ static inline float computePeriod(NSPoint mouseLocationWin,
int originalRow = _clickedRow;
int oldRow = -1;
int currentRow = -1;
selectionMode = 0;
BOOL getNextEvent = YES;
if (_allowsMultipleSelection == YES)
{
selectionMode |= ALLOWS_MULTIPLE;
@ -3445,7 +3558,7 @@ static inline float computePeriod(NSPoint mouseLocationWin,
if (modifiers & NSControlKeyMask)
{
selectionMode |= CONTROL_DOWN;
if (_allowsMultipleSelection == YES)
if (_allowsMultipleSelection == YES && _selectedRow != -1)
{
originalRow = _selectedRow;
selectionMode |= SHIFT_DOWN;
@ -3464,78 +3577,25 @@ static inline float computePeriod(NSPoint mouseLocationWin,
// let's sort the _selectedRows
oldSelectedRows = [_selectedRows copy];
mouseLocationView = location;
lastEvent = theEvent;
if ([self mouse: mouseLocationView inRect: _bounds])
{
NSTableColumn *tb;
NSCell *cell;
NSRect cellFrame;
id originalValue;
// Prepare the cell
tb = [_tableColumns objectAtIndex: _clickedColumn];
/* we should copy the cell here, as we do on editing.
otherwise validation on a cell being edited could
cause the cell we are selecting to get it's objectValue */
cell = [[tb dataCellForRow: _clickedRow] copy];
originalValue = RETAIN([self _objectValueForTableColumn:tb row:_clickedRow]);
[cell setObjectValue: originalValue];
cellFrame = [self frameOfCellAtColumn: _clickedColumn
row: _clickedRow];
[cell setHighlighted: YES];
[self setNeedsDisplayInRect: cellFrame];
/* give delegate a chance to i.e set target */
[self _willDisplayCell: cell
forTableColumn: tb
row: _clickedRow];
if ([cell trackMouse: lastEvent
inRect: cellFrame
ofView: self
untilMouseUp: [[cell class] prefersTrackingUntilMouseUp]])
{
id newValue = [cell objectValue];
if ([tb isEditable] && originalValue != newValue
&& ![originalValue isEqual: newValue])
{
[self _setObjectValue: newValue
forTableColumn: tb
row: _clickedRow];
}
done = YES;
currentRow = _clickedRow;
computeNewSelection(self,
oldSelectedRows,
_selectedRows,
originalRow,
oldRow,
currentRow,
&_selectedRow,
selectionMode);
}
RELEASE(originalValue);
[cell setHighlighted: NO];
RELEASE(cell);
[self setNeedsDisplayInRect: cellFrame];
lastEvent = [NSApp currentEvent];
}
while (done != YES)
{
/*
Wrap each iteration in an autorelease pool. Otherwise, we end
up allocating huge amounts of objects if the button is held
down for a long time.
Wrap each iteration in an autorelease pool. Otherwise, we end
up allocating huge amounts of objects if the button is held
down for a long time.
*/
CREATE_AUTORELEASE_POOL(arp);
BOOL shouldComputeNewSelection = NO;
mouseLocationWin = [lastEvent locationInWindow];
mouseLocationView = [self convertPoint: mouseLocationWin
fromView: nil];
switch ([lastEvent type])
{
case NSLeftMouseUp:
mouseLocationWin = [lastEvent locationInWindow];
if ((mouseLocationWin.y > minYVisible)
&& (mouseLocationWin.y < maxYVisible))
{
@ -3545,15 +3605,21 @@ static inline float computePeriod(NSPoint mouseLocationWin,
[NSEvent stopPeriodicEvents];
startedPeriodicEvents = NO;
}
mouseLocationView = [self convertPoint: mouseLocationWin
fromView: nil];
mouseLocationView.x = _bounds.origin.x;
oldRow = currentRow;
currentRow = [self rowAtPoint: mouseLocationView];
if (oldRow != currentRow)
{
shouldComputeNewSelection = YES;
}
if (draggingPossible == YES)
{
[self _trackCellAtColumn:_clickedColumn
row:_clickedRow
withEvent:theEvent];
}
}
else
{
@ -3565,10 +3631,6 @@ static inline float computePeriod(NSPoint mouseLocationWin,
case NSLeftMouseDown:
case NSLeftMouseDragged:
mouseLocationWin = [lastEvent locationInWindow];
mouseLocationView = [self convertPoint: mouseLocationWin
fromView: nil];
if (fabs(mouseLocationWin.x - initialLocation.x) > 1
|| fabs(mouseLocationWin.y - initialLocation.y) > 1)
{
@ -3584,12 +3646,10 @@ static inline float computePeriod(NSPoint mouseLocationWin,
}
else if (fabs(mouseLocationWin.x - initialLocation.x) >= 4)
{
NSPasteboard *pboard;
NSArray *rows;
mouseLocationView.x = _bounds.origin.x;
oldRow = currentRow;
currentRow = [self rowAtPoint: mouseLocationView];
if (![_selectedRows containsIndex: currentRow])
{
/* Mouse drag in a row that wasn't selected.
@ -3604,46 +3664,8 @@ static inline float computePeriod(NSPoint mouseLocationWin,
selectionMode);
}
rows = [self _selectedRowArray];
pboard = [NSPasteboard pasteboardWithName: NSDragPboard];
if ([self _writeRows: rows
toPasteboard: pboard] == YES)
if ([self _startDragOperationWithEvent:theEvent])
{
NSPoint p = NSZeroPoint;
NSImage *dragImage;
NSSize s;
dragImage = [self dragImageForRows: rows
event: theEvent
dragImageOffset: &p];
/*
* Store image offset in s ... the returned
* value is the position of the center of
* the image, so we adjust to the bottom left
* corner.
*/
s = [dragImage size];
s.width = p.x - s.width/2;
s.height = p.y + s.height/2; // View is flipped
/*
* Find the current mouse location and adjust
* it to determine the location of the bottom
* left corner of the image in this view's
* coordinate system.
*/
p = [self convertPoint:
[theEvent locationInWindow] fromView: nil];
p.x += s.width;
p.y += s.height;
[self dragImage: dragImage
at: p
offset: NSMakeSize(0, 0)
event: theEvent
pasteboard: pboard
source: self
slideBack: YES];
return;
}
else
@ -3662,8 +3684,6 @@ static inline float computePeriod(NSPoint mouseLocationWin,
startedPeriodicEvents = NO;
}
mouseLocationView = [self convertPoint: mouseLocationWin
fromView: nil];
mouseLocationView.x = _bounds.origin.x;
oldRow = currentRow;
currentRow = [self rowAtPoint: mouseLocationView];
@ -3671,6 +3691,11 @@ static inline float computePeriod(NSPoint mouseLocationWin,
{
shouldComputeNewSelection = YES;
}
[self _trackCellAtColumn:_clickedColumn
row:_clickedRow
withEvent:theEvent];
getNextEvent = (lastEvent == [NSApp currentEvent]);
}
else
{
@ -3731,6 +3756,15 @@ static inline float computePeriod(NSPoint mouseLocationWin,
if (shouldComputeNewSelection == YES)
{
if (originalRow == -1)
{
originalRow = currentRow;
}
if (currentRow == -1)
{
currentRow = _numberOfRows - 1;
}
computeNewSelection(self,
oldSelectedRows,
_selectedRows,
@ -3741,12 +3775,25 @@ static inline float computePeriod(NSPoint mouseLocationWin,
selectionMode);
[self displayIfNeeded];
}
if (done == NO)
{
lastEvent = [NSApp nextEventMatchingMask: eventMask
/* in certain cases we are working with events that have already
* occured and been dequeued by NSCell classes, in these cases
* we set getNextEvent to NO, and get the current event.
*/
if (getNextEvent == YES)
{
lastEvent = [NSApp nextEventMatchingMask: eventMask
untilDate: distantFuture
inMode: NSEventTrackingRunLoopMode
dequeue: YES];
}
else
{
lastEvent = [NSApp currentEvent];
getNextEvent = YES;
}
}
DESTROY(arp);
}
@ -3769,7 +3816,8 @@ static inline float computePeriod(NSPoint mouseLocationWin,
TODO: should we ask the data source/column for the cell for this
row/column and check whether it has its own action/target?
*/
[self sendAction: _action to: _target];
if (_clickedRow != -1)
[self sendAction: _action to: _target];
}
return;
}
@ -4002,7 +4050,52 @@ static inline float computePeriod(NSPoint mouseLocationWin,
- (void) setFrame: (NSRect)frameRect
{
[super setFrame: frameRect];
NSRect tmpRect = frameRect;
if ([_super_view respondsToSelector:@selector(documentVisibleRect)])
{
float rowsHeight = ((_numberOfRows * _rowHeight) + 1);
NSRect docRect = [(NSClipView *)_super_view documentVisibleRect];
if (rowsHeight < docRect.size.height)
{
tmpRect.size.height = docRect.size.height;
}
else
{
tmpRect.size.height = rowsHeight;
}
// TODO width?
}
[super setFrame: tmpRect];
}
- (void) setFrameSize: (NSSize)frameSize
{
NSSize tmpSize = frameSize;
if ([_super_view respondsToSelector:@selector(documentVisibleRect)])
{
float rowsHeight = ((_numberOfRows * _rowHeight) + 1);
NSRect docRect = [(NSClipView *)_super_view documentVisibleRect];
if (rowsHeight < docRect.size.height)
{
tmpSize.height = docRect.size.height;
}
else
{
tmpSize.height = rowsHeight;
}
// TODO width?
}
[super setFrameSize: tmpSize];
}
- (void) viewWillMoveToSuperview:(NSView *)newSuper
{
[super viewWillMoveToSuperview:newSuper];
/* need to potentially enlarge to fill the documentRect of the clip view */
[self setFrame:_frame];
}
- (void) sizeToFit
@ -4639,11 +4732,8 @@ static inline float computePeriod(NSPoint mouseLocationWin,
- (void) drawBackgroundInClipRect: (NSRect)clipRect
{
// FIXME
/*
[_backgroundColor set];
NSRectFill (clipRect);
*/
}
- (void) drawRect: (NSRect)aRect
@ -4867,6 +4957,7 @@ static inline float computePeriod(NSPoint mouseLocationWin,
switch ([(NSNumber *)textMovement intValue])
{
case NSReturnTextMovement:
[self _editNextCellAfterRow:row inColumn:column];
// Send action ?
break;
case NSTabTextMovement:
@ -5466,6 +5557,23 @@ static inline float computePeriod(NSPoint mouseLocationWin,
}
}
- (void) _editNextCellAfterRow:(int)row inColumn:(int)column
{
if (++row >= _numberOfColumns)
row = 0;
if ([self _shouldSelectRow:row])
{
[self selectRowIndexes:[NSIndexSet indexSetWithIndex:row]
byExtendingSelection:NO];
if ([self _isCellEditableColumn:column row:row])
{
[self editColumn:column row:row withEvent:nil select:YES];
}
}
}
-(BOOL) _editNextEditableCellAfterRow: (int)row
column: (int)column
{
@ -5697,6 +5805,7 @@ static inline float computePeriod(NSPoint mouseLocationWin,
}
_superview_width = visible_width;
}
[self setFrame:_frame];
}
@ -5802,8 +5911,15 @@ static inline float computePeriod(NSPoint mouseLocationWin,
[self displayIfNeeded];
[[NSColor darkGrayColor] set];
if (currentDropOperation == NSTableViewDropAbove)
if (currentDropRow > _numberOfRows)
{
newRect = [self bounds];
NSFrameRectWithWidth(newRect, 2.0);
oldDraggingRect = newRect;
currentDropRow = _numberOfRows;
}
else if (currentDropOperation == NSTableViewDropAbove)
{
if (currentDropRow == 0)
{

View file

@ -52,6 +52,7 @@
#include "AppKit/NSAffineTransform.h"
#include "AppKit/NSApplication.h"
#include "AppKit/NSCursor.h"
#include "AppKit/NSDocumentController.h"
#include "AppKit/NSDocument.h"
#include "AppKit/NSClipView.h"

View file

@ -4613,23 +4613,37 @@ BOOL GSViewAcceptsDrag(NSView *v, id<NSDraggingInfo> dragInfo)
void NSCountWindows(int *count)
{
*count = (int)NSCountMapTable(windowmaps);
*count = (int)[[GSCurrentServer() windowlist] count];
}
void NSWindowList(int size, int list[])
{
NSMapEnumerator me = NSEnumerateMapTable(windowmaps);
void *key;
id win;
int i = 0;
while (i < size && NSNextMapEnumeratorPair(&me, &key, (void*)&win))
NSArray *windowList = [GSCurrentServer() windowlist];
unsigned i, c;
for (i = 0, c = [windowList count]; i < size && i < c; i++)
{
list[i++] = (intptr_t)key;
list[i] = [[windowList objectAtIndex:i] intValue];
}
/* FIXME - the list produced should be in window stacking order */
}
NSArray *GSOrderedWindows(void)
{
NSArray *window_list = [GSCurrentServer() windowlist];
NSMutableArray *ret = [NSMutableArray array];
int i, c;
for (i = 0, c = [window_list count]; i < c; i++)
{
int windowNumber = [[window_list objectAtIndex:i] intValue];
NSWindow *win = GSWindowWithNumber(windowNumber);
[ret addObject:win];
}
return ret;
}
NSArray* GSAllWindows(void)
{
if (windowmaps)

View file

@ -42,6 +42,7 @@
#endif
#include <Foundation/NSBundle.h>
#include <Foundation/NSData.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSHost.h>
#include <Foundation/NSLock.h>

View file

@ -21,6 +21,7 @@
*/
#include <Foundation/NSArray.h>
#include <Foundation/NSData.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSString.h>
#include <Foundation/NSProcessInfo.h>