Fix drag and drop of file objects - invoke cleanUpAfterDragOperation on lastDragView on NSWindow and add cleanup code to cleanUpAfterDragOperation in NSTextView

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/branches/gnustep_testplant_branch@35896 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Marcian Lytwyn 2012-12-15 04:50:05 +00:00
parent 09efaeba41
commit 43a41c50fc
2 changed files with 147 additions and 114 deletions

View file

@ -513,8 +513,7 @@ this happens when layout has been invalidated, and when we are resized.
[self sizeToFit];
/* TODO: we don't have to redisplay the entire view */
[self setNeedsDisplay: YES];
[self updateInsertionPointStateAndRestartTimer:
[self shouldDrawInsertionPoint]];
[self updateInsertionPointStateAndRestartTimer: [self shouldDrawInsertionPoint]];
[self _updateInputMethodState];
/* In case any sections of text with custom cursors were moved */
[[self window] invalidateCursorRectsForView: self];
@ -4111,6 +4110,30 @@ Figure out how the additional layout stuff is supposed to work.
return nil;
}
- (void) _stopInsertionTimer
{
if (_insertionPointTimer)
{
[_insertionPointTimer invalidate];
DESTROY(_insertionPointTimer);
}
}
- (void) _startInsertionTimer
{
if (_insertionPointTimer)
{
NSWarnMLog(@"Starting insertion timer with existing one running");
[self _stopInsertionTimer];
}
_insertionPointTimer = [NSTimer scheduledTimerWithTimeInterval: 0.5
target: self
selector: @selector(_blink:)
userInfo: nil
repeats: YES];
RETAIN(_insertionPointTimer);
}
- (void) updateInsertionPointStateAndRestartTimer: (BOOL)restartFlag
{
NSRect new;
@ -4121,6 +4144,7 @@ Figure out how the additional layout stuff is supposed to work.
return;
}
// If we are in the middle of a dragging operation...
if (_dragTargetLocation != NSNotFound)
{
_tf.drag_target_hijacks_insertion_point = YES;
@ -4168,21 +4192,25 @@ Figure out how the additional layout stuff is supposed to work.
method or during the previous call to this method) */
if (_tf.drag_target_hijacks_insertion_point)
{
// Erase previous insertion point line...
_drawInsertionPointNow = NO;
[self setNeedsDisplayInRect: _insertionPointRect
avoidAdditionalLayout: YES];
[self setNeedsDisplayInRect: _insertionPointRect avoidAdditionalLayout: YES];
// Save new insertion point rectangle...
_insertionPointRect = new;
if (_dragTargetLocation != NSNotFound)
{
_insertionPointRect = new;
// Draw insertion point line in new location...
_drawInsertionPointNow = YES;
[self setNeedsDisplayInRect: _insertionPointRect
avoidAdditionalLayout: YES];
[self setNeedsDisplayInRect: _insertionPointRect avoidAdditionalLayout: YES];
}
else
{
// Drag either completed or cancelled...
_tf.drag_target_hijacks_insertion_point = NO;
}
}
/* Otherwise, draw insertion point only if there is a need to do so */
else if ([self shouldDrawInsertionPoint] || _drawInsertionPointNow)
@ -4192,22 +4220,19 @@ Figure out how the additional layout stuff is supposed to work.
/* Start blinking timer if not yet started */
if (_insertionPointTimer == nil && [self shouldDrawInsertionPoint])
{
// NSLog(@"Start timer");
// Save new insertion point rectangle before starting the insertion timer...
_insertionPointRect = new;
_insertionPointTimer = [NSTimer scheduledTimerWithTimeInterval: 0.5
target: self
selector: @selector(_blink:)
userInfo: nil
repeats: YES];
RETAIN (_insertionPointTimer);
[self _startInsertionTimer];
}
else if (_insertionPointTimer != nil)
{
// Erase previous insertion point line...
if (!NSEqualRects(new, _insertionPointRect))
{
_drawInsertionPointNow = NO;
[self setNeedsDisplayInRect: _insertionPointRect
avoidAdditionalLayout: YES];
[self setNeedsDisplayInRect: _insertionPointRect avoidAdditionalLayout: YES];
// Save new insertion point rectangle...
_insertionPointRect = new;
}
}
@ -4218,22 +4243,20 @@ Figure out how the additional layout stuff is supposed to work.
* possible.
*/
_drawInsertionPointNow = YES;
[self setNeedsDisplayInRect: _insertionPointRect
avoidAdditionalLayout: YES];
[self setNeedsDisplayInRect: _insertionPointRect avoidAdditionalLayout: YES];
}
else if ([self shouldDrawInsertionPoint] && (_insertionPointTimer != nil))
{
// restartFlag is set to NO when control resigns first responder
// status or window resings key window status. So we invalidate
// timer to avoid extra method calls
// NSLog(@"Stop timer");
[_insertionPointTimer invalidate];
DESTROY (_insertionPointTimer);
[self _stopInsertionTimer];
// Erase previous insertion point line...
_drawInsertionPointNow = NO;
[self setNeedsDisplayInRect: _insertionPointRect
avoidAdditionalLayout: YES];
[self setNeedsDisplayInRect: _insertionPointRect avoidAdditionalLayout: YES];
// Save new insertion point rectangle...
_insertionPointRect = new;
}
@ -5351,7 +5374,10 @@ other than copy/paste or dragging. */
- (void) cleanUpAfterDragOperation
{
// release drag information
// Cleanup information after dragging operation completes...
_dragTargetLocation = NSNotFound;
[self updateInsertionPointStateAndRestartTimer: NO];
[self displayIfNeeded];
}
- (unsigned int) dragOperationForDraggingInfo: (id <NSDraggingInfo>)dragInfo
@ -6034,8 +6060,7 @@ or add guards
_drawInsertionPointNow = YES;
}
[self setNeedsDisplayInRect: _insertionPointRect
avoidAdditionalLayout: YES];
[self setNeedsDisplayInRect: _insertionPointRect avoidAdditionalLayout: YES];
/* Because we are called by a timer which is independent of any
event processing in the gui runloop, we need to manually update
the window. */

View file

@ -4301,8 +4301,8 @@ resetCursorRectsForView(NSView *theView)
case GSAppKitDraggingDrop:
NSDebugLLog(@"NSDragging", @"GSAppKitDraggingDrop");
dragInfo = [GSServerForWindow(self) dragInfo];
if (_lastDragView && _f.accepts_drag
&& _lastDragOperationMask != NSDragOperationNone)
if (_lastDragView && _f.accepts_drag &&
_lastDragOperationMask != NSDragOperationNone)
{
action = YES;
GSPerformDragSelector(_lastDragView,
@ -4318,6 +4318,14 @@ resetCursorRectsForView(NSView *theView)
GSPerformVoidDragSelector(_lastDragView,
@selector(concludeDragOperation:), dragInfo);
}
// Check for specific cleanup after drag methods...
if ([_lastDragView respondsToSelector: @selector(cleanUpAfterDragOperation)])
{
GSPerformVoidDragSelector(_lastDragView,
@selector(cleanUpAfterDragOperation),
dragInfo)
}
}
_lastDragOperationMask = NSDragOperationNone;
DESTROY(_lastDragView);