mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-22 19:01:15 +00:00
Stable 0.16.0
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/branches/stable@27390 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
commit
a0ed4f9ca6
108 changed files with 9452 additions and 5918 deletions
14
ANNOUNCE
14
ANNOUNCE
|
@ -1,7 +1,7 @@
|
|||
1 ANNOUNCE
|
||||
**********
|
||||
|
||||
This is version 0.14.0 of the GNUstep GUI library (`gnustep-gui').
|
||||
This is version 0.16.0 of the GNUstep GUI library (`gnustep-gui').
|
||||
|
||||
1.1 What is the GNUstep GUI Library?
|
||||
====================================
|
||||
|
@ -27,21 +27,21 @@ systems.
|
|||
GNUstep Base Library, the TIFF Graphics library, and a back-end
|
||||
component like the GNUstep 'Back' Backend.
|
||||
|
||||
1.2 Noteworthy changes in version `0.14.0'
|
||||
1.2 Noteworthy changes in version `0.16.0'
|
||||
==========================================
|
||||
|
||||
* New class NSGlyphGenerator for glyph generation
|
||||
* Nib loading refractored and improved.
|
||||
|
||||
* NSSplitView implemented setAutosaveName:
|
||||
* Added support for autosaving in NSDocuments
|
||||
|
||||
* NSOpenGLView added some Mac OS X 10.3 methods
|
||||
* NSWindowController made a subclass of NSResponder
|
||||
|
||||
* Manu bug fixes.
|
||||
* NSTokenField and netokenFiledCell classes added.
|
||||
|
||||
1.3 Where can you get it? How can you compile it?
|
||||
==================================================
|
||||
|
||||
The gstep-gui-0.14.0.tar.gz distribution file has been placed at
|
||||
The gstep-gui-0.16.0.tar.gz distribution file has been placed at
|
||||
`ftp://ftp.gnustep.org/pub/gnustep/core'.
|
||||
|
||||
Read the INSTALL file or the GNUstep-HOWTO for installation
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
GNUSTEP_INSTALLATION_DOMAIN = SYSTEM
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES = ../gui.make
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
|
|
|
@ -22,9 +22,7 @@
|
|||
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
# Install into the system root by default
|
||||
GNUSTEP_INSTALLATION_DOMAIN = SYSTEM
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../gui.make
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
|
|
|
@ -23,9 +23,7 @@
|
|||
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
# Install into the system root by default
|
||||
GNUSTEP_INSTALLATION_DOMAIN = SYSTEM
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
include ../../config.make
|
||||
|
||||
|
|
|
@ -23,9 +23,7 @@
|
|||
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
# Install into the system root by default
|
||||
GNUSTEP_INSTALLATION_DOMAIN = SYSTEM
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
include ../../config.make
|
||||
|
||||
|
|
|
@ -19,6 +19,57 @@
|
|||
changes and other information that might help developers and users
|
||||
migrate to using a newer version of the library.
|
||||
</p>
|
||||
<section>
|
||||
<heading>Version 0.16.0</heading>
|
||||
<p>This is an stable release. A lot of improvements and bug
|
||||
fixes went into this release. Thanks to Wolfgang Lux for fixing plenty
|
||||
of bugs. Note that gnustep-core is now installed in the LOCAL domain
|
||||
by default instead of the SYSTEM domain. You may want to remove old
|
||||
installations in the SYSTEM domain to avoid any incompatibility problems.
|
||||
Or you can force installation in SYSTEM using make
|
||||
GNUSTEP_INSTALLATION_DOMAIN=SYSTEM install.
|
||||
</p>
|
||||
<deflist>
|
||||
<term>Nib Loading</term>
|
||||
<desc>
|
||||
Several methods were added and Nib loading in general was refactored
|
||||
and improved.
|
||||
</desc>
|
||||
<term>NSDocument</term>
|
||||
<desc>
|
||||
Document autosaving was implemented.
|
||||
</desc>
|
||||
<term>NSSavePanel</term>
|
||||
<desc>
|
||||
Several methods were added to implement support for document types
|
||||
with multiple allowed file extensions.
|
||||
</desc>
|
||||
<term>NSWindow</term>
|
||||
<desc>
|
||||
Definitions and skeleton implementation of attachedSheet.
|
||||
</desc>
|
||||
<term>NSTextView</term>
|
||||
<desc>
|
||||
Renamed and changed types of attributes related to drag and drop.
|
||||
</desc>
|
||||
<term>NSLayoutManager</term>
|
||||
<desc>
|
||||
New methods added to handle temporary attributes.
|
||||
</desc>
|
||||
<term>NSWindowContrller</term>
|
||||
<desc>
|
||||
NSWindowController was made a subclass of NSResponder.
|
||||
</desc>
|
||||
<term>NSCell</term>
|
||||
<desc>
|
||||
Rearranged somewhat to use GSTheme implemetations.
|
||||
</desc>
|
||||
<term>NSTokenField, NSTokenFieldCell</term>
|
||||
<desc>
|
||||
Ned classes added.
|
||||
</desc>
|
||||
</deflist>
|
||||
</section>
|
||||
<section>
|
||||
<heading>Version 0.14.0</heading>
|
||||
<p>This is an stable release.
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
PACKAGE_NAME = gnustep-gui
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
DOCUMENT_NAME = AppKit
|
||||
|
|
|
@ -9,6 +9,17 @@
|
|||
The currently released version of the library is @samp{@value{GNUSTEP-GUI-VERSION}}.
|
||||
@end ifclear
|
||||
|
||||
@section Noteworthy changes in version @samp{0.16.0}
|
||||
|
||||
@itemize @bullet
|
||||
@item Nib loading refractored and improved.
|
||||
@item Added support for autosaving in NSDocuments
|
||||
@item NSWindowController made a subclass of NSResponder
|
||||
@item NSTokenField and netokenFiledCell classes added.
|
||||
@end itemize
|
||||
|
||||
@ifclear ANNOUNCE-ONLY
|
||||
|
||||
@section Noteworthy changes in version @samp{0.14.0}
|
||||
|
||||
@itemize @bullet
|
||||
|
@ -18,8 +29,6 @@ The currently released version of the library is @samp{@value{GNUSTEP-GUI-VERSIO
|
|||
@item Manu bug fixes.
|
||||
@end itemize
|
||||
|
||||
@ifclear ANNOUNCE-ONLY
|
||||
|
||||
@section Noteworthy changes in version @samp{0.13.2}
|
||||
|
||||
@itemize @bullet
|
||||
|
|
|
@ -31,9 +31,8 @@ ifeq ($(GNUSTEP_MAKEFILES),)
|
|||
$(error You need to set GNUSTEP_MAKEFILES before compiling!)
|
||||
endif
|
||||
|
||||
# Install into the system root by default
|
||||
GNUSTEP_INSTALLATION_DOMAIN = SYSTEM
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
export PACKAGE_NAME
|
||||
RPM_DISABLE_RELOCATABLE=YES
|
||||
PACKAGE_NEEDS_CONFIGURE = YES
|
||||
|
||||
|
@ -44,8 +43,6 @@ SVN_BASE_URL = svn+ssh://svn.gna.org/svn/gnustep/libs
|
|||
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=gui.make
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
|
||||
include ./Version
|
||||
|
||||
# Don't build docs by default
|
||||
|
|
|
@ -50,9 +50,14 @@
|
|||
@protocol OSXNibTemplate
|
||||
- (void) setClassName: (NSString *)className;
|
||||
- (NSString *)className;
|
||||
- (void) setRealObject: (id)o;
|
||||
- (id) realObject;
|
||||
@end
|
||||
|
||||
@protocol GSNibLoading
|
||||
- (id) nibInstantiate;
|
||||
@end
|
||||
|
||||
typedef struct _GSWindowTemplateFlags
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
|
@ -110,7 +115,7 @@ typedef struct _GSWindowTemplateFlags
|
|||
* when it's unarchived and second, it holds certain attributes (but doesn't set them
|
||||
* on the window, when the window is being edited in the application builder.
|
||||
*/
|
||||
@interface NSWindowTemplate : NSObject <OSXNibTemplate, NSCoding>
|
||||
@interface NSWindowTemplate : NSObject <OSXNibTemplate, NSCoding, GSNibLoading>
|
||||
{
|
||||
NSBackingStoreType _backingStoreType;
|
||||
NSSize _maxSize;
|
||||
|
@ -152,7 +157,6 @@ typedef struct _GSWindowTemplateFlags
|
|||
- (NSRect)windowRect;
|
||||
- (void) setScreenRect: (NSRect)rect;
|
||||
- (NSRect) screenRect;
|
||||
- (id) realObject;
|
||||
- (void) setView: (id)view;
|
||||
- (id) view;
|
||||
- (Class) baseWindowClass;
|
||||
|
@ -163,6 +167,8 @@ typedef struct _GSWindowTemplateFlags
|
|||
NSString *_className;
|
||||
id _realObject;
|
||||
}
|
||||
- (id) initWithObject: (id)o
|
||||
className: (NSString *)name;
|
||||
@end
|
||||
|
||||
@interface NSTextTemplate : NSViewTemplate
|
||||
|
@ -189,10 +195,9 @@ typedef struct _GSWindowTemplateFlags
|
|||
}
|
||||
- (void) setClassName: (NSString *)name;
|
||||
- (NSString *)className;
|
||||
- (id)nibInstantiate;
|
||||
@end
|
||||
|
||||
@interface NSCustomObject : NSObject <NSCoding>
|
||||
@interface NSCustomObject : NSObject <NSCoding, GSNibLoading>
|
||||
{
|
||||
NSString *_className;
|
||||
NSString *_extension;
|
||||
|
@ -202,11 +207,9 @@ typedef struct _GSWindowTemplateFlags
|
|||
- (NSString *)className;
|
||||
- (void) setExtension: (NSString *)ext;
|
||||
- (NSString *)extension;
|
||||
- (void) setObject: (id)obj;
|
||||
- (id)object;
|
||||
@end
|
||||
|
||||
@interface NSCustomView : NSView
|
||||
@interface NSCustomView : NSView <GSNibLoading>
|
||||
{
|
||||
NSString *_className;
|
||||
NSString *_extension;
|
||||
|
@ -217,7 +220,7 @@ typedef struct _GSWindowTemplateFlags
|
|||
- (NSString *)className;
|
||||
- (void) setExtension: (NSString *)view;
|
||||
- (NSString *)extension;
|
||||
- (id)nibInstantiate;
|
||||
- (id)nibInstantiateWithCoder: (NSCoder *)coder;
|
||||
@end
|
||||
|
||||
@interface NSCustomResource : NSObject <NSCoding>
|
||||
|
@ -229,7 +232,6 @@ typedef struct _GSWindowTemplateFlags
|
|||
- (NSString *)className;
|
||||
- (void) setResourceName: (NSString *)view;
|
||||
- (NSString *)resourceName;
|
||||
- (id)nibInstantiate;
|
||||
@end
|
||||
|
||||
@interface NSClassSwapper : NSObject <NSCoding>
|
||||
|
@ -270,7 +272,6 @@ typedef struct _GSWindowTemplateFlags
|
|||
NSMutableSet *_topLevelObjects;
|
||||
}
|
||||
- (id) instantiateObject: (id)obj;
|
||||
- (void) nibInstantiateWithOwner: (id)owner;
|
||||
- (void) nibInstantiateWithOwner: (id)owner topLevelObjects: (NSMutableArray *)toplevel;
|
||||
- (id) objectForName: (NSString *)name;
|
||||
- (NSString *) nameForObject: (id)name;
|
|
@ -138,6 +138,8 @@
|
|||
#include "AppKit/NSCell.h"
|
||||
// For gradient types
|
||||
#include "AppKit/NSButtonCell.h"
|
||||
// For image frame style
|
||||
#include "AppKit/NSImageCell.h"
|
||||
|
||||
#if OS_API_VERSION(GS_API_NONE,GS_API_NONE)
|
||||
@class NSArray;
|
||||
|
@ -405,6 +407,30 @@ APPKIT_EXPORT NSString *GSThemeDidDeactivateNotification;
|
|||
*/
|
||||
- (void) drawWindowBackground: (NSRect)frame view: (NSView*)view;
|
||||
|
||||
/**
|
||||
* Draw a border of the specified border type.
|
||||
*/
|
||||
- (void) drawBorderType: (NSBorderType)aType
|
||||
frame: (NSRect)frame
|
||||
view: (NSView*)view;
|
||||
|
||||
/**
|
||||
* Determine the size for the specified border type .
|
||||
*/
|
||||
- (NSSize) sizeForBorderType: (NSBorderType)aType;
|
||||
|
||||
/**
|
||||
* Draw a border of the specified frame style.
|
||||
*/
|
||||
- (void) drawBorderForImageFrameStyle: (NSImageFrameStyle)frameStyle
|
||||
frame: (NSRect)frame
|
||||
view: (NSView*)view;
|
||||
|
||||
/**
|
||||
* Determine the size for the specified frame style.
|
||||
*/
|
||||
- (NSSize) sizeForImageFrameStyle: (NSImageFrameStyle)frameStyle;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
|
@ -502,5 +528,14 @@ withRepeatedImage: (NSImage*)image
|
|||
flipped: (BOOL)flipped;
|
||||
@end
|
||||
|
||||
//
|
||||
// Function which should be somewhere else
|
||||
//
|
||||
static inline NSSize
|
||||
_sizeForBorderType (NSBorderType aType)
|
||||
{
|
||||
return [[GSTheme theme] sizeForBorderType: aType];
|
||||
}
|
||||
|
||||
#endif /* OS_API_VERSION */
|
||||
#endif /* _GNUstep_H_GSTheme */
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
/* Define to 1 if you have the `ungif' library (-lungif). */
|
||||
#undef HAVE_LIBUNGIF
|
||||
|
||||
/* Define to 1 if you have the `icns' library (-licns). */
|
||||
#undef HAVE_LIBICNS
|
||||
|
||||
/* Define to 1 if you have the `z' library (-lz). */
|
||||
#undef HAVE_LIBZ
|
||||
|
||||
|
|
|
@ -66,6 +66,8 @@ enum {
|
|||
id _delegate;
|
||||
NSAlertStyle _style;
|
||||
BOOL _shows_help;
|
||||
id _modalDelegate;
|
||||
SEL _didEndSelector;
|
||||
int _result;
|
||||
}
|
||||
|
||||
|
|
|
@ -608,7 +608,7 @@ APPKIT_EXPORT NSString *NSEventTrackingRunLoopMode;
|
|||
* method). <em>Not sent yet under GNUstep.</em>
|
||||
*/
|
||||
- (BOOL) applicationShouldHandleReopen: (NSApplication*)theApplication
|
||||
hasVisibleWindows: (BOOL)flag;
|
||||
hasVisibleWindows: (BOOL)flag;
|
||||
|
||||
/**
|
||||
* Called on OS X when the resolution or other characteristics of the display
|
||||
|
|
|
@ -493,11 +493,5 @@ enum {
|
|||
inView: (NSView*)controlView;
|
||||
@end
|
||||
|
||||
//
|
||||
// Function which should be somewhere else
|
||||
//
|
||||
inline NSSize
|
||||
_sizeForBorderType (NSBorderType aType);
|
||||
|
||||
#endif // _GNUstep_H_NSCell
|
||||
|
||||
|
|
|
@ -108,7 +108,9 @@ typedef enum _NSSaveOperationType {
|
|||
struct __docFlags {
|
||||
unsigned int in_close:1;
|
||||
unsigned int has_undo_manager:1;
|
||||
unsigned int RESERVED:30;
|
||||
unsigned int permanently_modified:1;
|
||||
unsigned int autosave_permanently_modified:1;
|
||||
unsigned int RESERVED:28;
|
||||
} _doc_flags;
|
||||
void *_reserved1;
|
||||
}
|
||||
|
|
|
@ -142,7 +142,6 @@ NSDrawBezel(const NSRect aRect, const NSRect clipRect)
|
|||
NSDrawGrayBezel(aRect, clipRect);
|
||||
}
|
||||
|
||||
|
||||
/** Draws a rectangle along the inside of aRect. The rectangle will be
|
||||
black, dotted (using 1 point dashes), and will have a line width
|
||||
of 1 point. */
|
||||
|
@ -244,4 +243,15 @@ APPKIT_EXPORT int NSGetWindowServerMemory(int context, int *virtualMemory,
|
|||
|
||||
#endif
|
||||
|
||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_1, GS_API_LATEST)
|
||||
typedef enum _NSFocusRingPlacement
|
||||
{
|
||||
NSFocusRingOnly=0,
|
||||
NSFocusRingBelow,
|
||||
NSFocusRingAbove
|
||||
} NSFocusRingPlacement;
|
||||
|
||||
void NSSetFocusRingStyle(NSFocusRingPlacement placement);
|
||||
#endif
|
||||
|
||||
#endif /* __NSGraphics_h__ */
|
||||
|
|
|
@ -183,6 +183,15 @@ GNUstep extension.
|
|||
|
||||
@end
|
||||
|
||||
|
||||
@interface NSLayoutManager (temporaryattributes)
|
||||
- (void) addTemporaryAttributes: (NSDictionary *)attrs forCharacterRange: (NSRange)range;
|
||||
- (void) addTemporaryAttribute: (NSString *)attr value: (id)value forCharacterRange: (NSRange)range;
|
||||
- (void) setTemporaryAttributes:forCharacterRange: (NSRange)range;
|
||||
- (void) removeTemporaryAttribute: (NSString *)attr forCharacterRange: (NSRange)range;
|
||||
- (id) temporaryAttribute: (NSString *)attr atCharacterIndex: (unsigned int)index effectiveRange: (NSRange)range;
|
||||
- (id) temporaryAttribute: (NSString *)attr atCharacterIndex: (unsigned int)index longestEffectiveRange: (NSRange*)longestRange inRange: (NSRange)range;
|
||||
- (NSDictionary *) temporaryAttributesAtCharacterIndex: (unsigned int)index effectiveRange: (NSRange)range;
|
||||
- (NSDictionary *) temporaryAttributesAtCharacterIndex: (unsigned int) longestEffectiveRange: (NSRange*)longestRange inRange: (NSRange)range;
|
||||
@end
|
||||
#endif
|
||||
|
||||
|
|
|
@ -68,6 +68,9 @@
|
|||
- (void)selectItem:(id <NSMenuItem>)anObject;
|
||||
- (void)selectItemAtIndex:(int)index;
|
||||
- (void)selectItemWithTitle:(NSString *)title;
|
||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)
|
||||
- (BOOL) selectItemWithTag: (NSInteger)tag;
|
||||
#endif
|
||||
- (int)numberOfItems;
|
||||
- (NSArray *)itemArray;
|
||||
- (id <NSMenuItem>)itemAtIndex:(int)index;
|
||||
|
|
|
@ -70,7 +70,7 @@ enum {
|
|||
NSSize _originalMinSize;
|
||||
NSSize _originalSize;
|
||||
|
||||
NSString *_requiredFileType;
|
||||
NSArray *_allowedFileTypes;
|
||||
NSString *_directory;
|
||||
NSString *_fullFileName;
|
||||
|
||||
|
|
|
@ -57,9 +57,6 @@ typedef enum _NSTextFieldBezelStyle
|
|||
|
||||
// Think of the following ones as of two BOOL ivars
|
||||
#define _textfieldcell_draws_background _cell.subclass_bool_one
|
||||
// The following is different from _draws_background
|
||||
// if we are using a semi-transparent color.
|
||||
#define _textfieldcell_is_opaque _cell.subclass_bool_two
|
||||
#define _textfieldcell_placeholder_is_attributed_string _cell.subclass_bool_three
|
||||
id _placeholder;
|
||||
}
|
||||
|
@ -90,4 +87,13 @@ typedef enum _NSTextFieldBezelStyle
|
|||
|
||||
@end
|
||||
|
||||
//
|
||||
// Methods that are private GNUstep extensions
|
||||
//
|
||||
@interface NSTextFieldCell (PrivateMethods)
|
||||
|
||||
- (void) _drawBackgroundWithFrame: (NSRect)cellFrame
|
||||
inView: (NSView*)controlView;
|
||||
@end
|
||||
|
||||
#endif // _GNUstep_H_NSTextFieldCell
|
||||
|
|
|
@ -144,8 +144,8 @@ therefore be stored in the NSLayoutManager to avoid problems.
|
|||
/* YES if delegate responds to
|
||||
`textView:willChangeSelectionFromCharacterRange:toCharacterRange:' */
|
||||
unsigned delegate_responds_to_will_change_sel:1;
|
||||
/* YES if a DnD operation is in progress with this as the target view */
|
||||
unsigned isDragTarget:1;
|
||||
/* YES if a DnD operation controls the insertion point in this text view */
|
||||
unsigned drag_target_hijacks_insertion_point:1;
|
||||
|
||||
unsigned uses_find_panel:1;
|
||||
unsigned accepts_glyph_info:1;
|
||||
|
@ -226,10 +226,15 @@ therefore be stored in the NSLayoutManager to avoid problems.
|
|||
*/
|
||||
int _currentInsertionPointMovementDirection;
|
||||
|
||||
/* Ivar to store the original range so it can be restored after a DnD
|
||||
* operation is cancelled (the mouse moves back out of the view).
|
||||
/* Ivar to store the location where text is going to be inserted during
|
||||
* a DnD operation.
|
||||
* Note: This used to be a range attribute with a different meaning; the
|
||||
* _dragTargetUnused attribute is present just to preserve the size of
|
||||
* NSTextView instances.
|
||||
* FIXME: Drop this attribute on the next major release.
|
||||
*/
|
||||
NSRange _dragTargetSelectionRange;
|
||||
unsigned int _dragTargetLocation;
|
||||
unsigned int _dragTargetUnused;
|
||||
/*
|
||||
TODO:
|
||||
Still need to figure out what "proper behavior" is when moving between two
|
||||
|
|
53
Headers/AppKit/NSTokenField.h
Normal file
53
Headers/AppKit/NSTokenField.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
NSTokenField.h
|
||||
|
||||
Token field control class for text entry
|
||||
|
||||
Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
|
||||
Author: Gregory Casamento <greg.casamento@gmail.com>
|
||||
Date: 2008
|
||||
|
||||
This file is part of the GNUstep GUI Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; see the file COPYING.LIB.
|
||||
If not, see <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _GNUstep_H_NSTokenField
|
||||
#define _GNUstep_H_NSTokenField
|
||||
|
||||
#import <GNUstepBase/GSVersionMacros.h>
|
||||
#include <AppKit/NSTextField.h>
|
||||
#include <AppKit/NSTokenFieldCell.h>
|
||||
|
||||
@interface NSTokenField : NSTextField
|
||||
// Style...
|
||||
- (NSTokenStyle)tokenStyle;
|
||||
- (void)setTokenStyle:(NSTokenStyle)style;
|
||||
|
||||
// Completion delay...
|
||||
+ (NSTimeInterval)defaultCompletionDelay;
|
||||
- (NSTimeInterval)completionDelay;
|
||||
- (void)setCompletionDelay:(NSTimeInterval)delay;
|
||||
|
||||
// Character set...
|
||||
+ (NSCharacterSet *)defaultTokenizingCharacterSet;
|
||||
- (void)setTokenizingCharacterSet:(NSCharacterSet *)characterSet;
|
||||
- (NSCharacterSet *)tokenizingCharacterSet;
|
||||
@end;
|
||||
|
||||
#endif // _GNUstep_H_NSTokenField
|
66
Headers/AppKit/NSTokenFieldCell.h
Normal file
66
Headers/AppKit/NSTokenFieldCell.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
NSTokenFieldCell.h
|
||||
|
||||
Cell class for the token field entry control
|
||||
|
||||
Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
|
||||
Author: Gregory Casamento <greg.casamento@gmail.com>
|
||||
Date: 2008
|
||||
|
||||
This file is part of the GNUstep GUI Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; see the file COPYING.LIB.
|
||||
If not, see <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _GNUstep_H_NSTokenFieldCell
|
||||
#define _GNUstep_H_NSTokenFieldCell
|
||||
#import <GNUstepBase/GSVersionMacros.h>
|
||||
|
||||
#include <AppKit/NSTextFieldCell.h>
|
||||
|
||||
typedef enum _NSTokenStyle
|
||||
{
|
||||
NSDefaultTokenStyle = 0,
|
||||
NSPlainTextTokenStyle,
|
||||
NSRoundedTokenStyle
|
||||
} NSTokenStyle;
|
||||
|
||||
|
||||
@interface NSTokenFieldCell : NSTextFieldCell <NSCoding>
|
||||
{
|
||||
NSTokenStyle tokenStyle;
|
||||
NSTimeInterval completionDelay;
|
||||
NSCharacterSet *tokenizingCharacterSet;
|
||||
}
|
||||
|
||||
// Style...
|
||||
- (NSTokenStyle)tokenStyle;
|
||||
- (void)setTokenStyle:(NSTokenStyle)style;
|
||||
|
||||
// Completion delay...
|
||||
+ (NSTimeInterval)defaultCompletionDelay;
|
||||
- (NSTimeInterval)completionDelay;
|
||||
- (void)setCompletionDelay:(NSTimeInterval)delay;
|
||||
|
||||
// Character set...
|
||||
+ (NSCharacterSet *)defaultTokenizingCharacterSet;
|
||||
- (void)setTokenizingCharacterSet:(NSCharacterSet *)characterSet;
|
||||
- (NSCharacterSet *)tokenizingCharacterSet;
|
||||
@end
|
||||
|
||||
#endif // _GNUstep_H_NSTokenFieldCell
|
|
@ -803,6 +803,9 @@ APPKIT_EXPORT NSSize NSTokenSize;
|
|||
willPositionSheet: (NSWindow *)sheet
|
||||
usingRect: (NSRect)rect;
|
||||
#endif
|
||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_1, GS_API_LATEST)
|
||||
- (NSWindow *) attachedSheet;
|
||||
#endif
|
||||
- (NSSize) windowWillResize: (NSWindow*)sender
|
||||
toSize: (NSSize)frameSize;
|
||||
- (id) windowWillReturnFieldEditor: (NSWindow*)sender
|
||||
|
|
|
@ -27,15 +27,15 @@
|
|||
#ifndef _GNUstep_H_NSWindowController
|
||||
#define _GNUstep_H_NSWindowController
|
||||
|
||||
#include <Foundation/NSObject.h>
|
||||
#include <AppKit/NSNibDeclarations.h>
|
||||
#include <AppKit/NSResponder.h>
|
||||
|
||||
@class NSString;
|
||||
@class NSArray;
|
||||
@class NSWindow;
|
||||
@class NSDocument;
|
||||
|
||||
@interface NSWindowController : NSObject <NSCoding>
|
||||
@interface NSWindowController : NSResponder <NSCoding>
|
||||
{
|
||||
@private
|
||||
NSWindow *_window;
|
||||
|
|
|
@ -23,8 +23,7 @@
|
|||
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
GNUSTEP_INSTALLATION_DOMAIN = SYSTEM
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../gui.make
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
|
@ -117,6 +116,7 @@ common_LeftTabStop.tiff \
|
|||
common_DecimalTabStop.tiff \
|
||||
common_Diamond.tiff \
|
||||
common_Printer.tiff \
|
||||
common_ToolbarCustomizeToolbarItem.tiff \
|
||||
common_ToolbarClippedItemsMark.tiff \
|
||||
common_ToolbarSeparatorItem.tiff \
|
||||
common_ToolbarShowColorsItem.tiff \
|
||||
|
|
BIN
Images/common_ToolbarCustomizeToolbarItem.tiff
Normal file
BIN
Images/common_ToolbarCustomizeToolbarItem.tiff
Normal file
Binary file not shown.
|
@ -23,8 +23,7 @@
|
|||
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
GNUSTEP_INSTALLATION_DOMAIN = SYSTEM
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../gui.make
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
|
|
99
NEWS
99
NEWS
|
@ -1,9 +1,20 @@
|
|||
1 NEWS
|
||||
******
|
||||
|
||||
The currently released version of the library is `0.14.0'.
|
||||
The currently released version of the library is `0.16.0'.
|
||||
|
||||
1.1 Noteworthy changes in version `0.14.0'
|
||||
1.1 Noteworthy changes in version `0.16.0'
|
||||
==========================================
|
||||
|
||||
* Nib loading refractored and improved.
|
||||
|
||||
* Added support for autosaving in NSDocuments
|
||||
|
||||
* NSWindowController made a subclass of NSResponder
|
||||
|
||||
* NSTokenField and netokenFiledCell classes added.
|
||||
|
||||
1.2 Noteworthy changes in version `0.14.0'
|
||||
==========================================
|
||||
|
||||
* New class NSGlyphGenerator for glyph generation
|
||||
|
@ -14,7 +25,7 @@ The currently released version of the library is `0.14.0'.
|
|||
|
||||
* Manu bug fixes.
|
||||
|
||||
1.2 Noteworthy changes in version `0.13.2'
|
||||
1.3 Noteworthy changes in version `0.13.2'
|
||||
==========================================
|
||||
|
||||
* Printing works a little better now.
|
||||
|
@ -30,7 +41,7 @@ The currently released version of the library is `0.14.0'.
|
|||
|
||||
* NSDrawer was implemented.
|
||||
|
||||
1.3 Noteworthy changes in version `0.13.1'
|
||||
1.4 Noteworthy changes in version `0.13.1'
|
||||
==========================================
|
||||
|
||||
* NSMenu - Added more MacOS X methods and an ivar.
|
||||
|
@ -44,7 +55,7 @@ The currently released version of the library is `0.14.0'.
|
|||
|
||||
* Changed the NSCursor hot point to 0,0 for MacOS X compatibility.
|
||||
|
||||
1.4 Noteworthy changes in version `0.13.0'
|
||||
1.5 Noteworthy changes in version `0.13.0'
|
||||
==========================================
|
||||
|
||||
This is an unstable release. There may be backward compatibility issues
|
||||
|
@ -81,7 +92,7 @@ with previous releases of the gui library.
|
|||
|
||||
* Base library version 1.15.1 is required for this release
|
||||
|
||||
1.5 Noteworthy changes in version `0.12.0'
|
||||
1.6 Noteworthy changes in version `0.12.0'
|
||||
==========================================
|
||||
|
||||
It has been a long time since the last release and many things have been
|
||||
|
@ -106,7 +117,7 @@ added and changed, including new classes, new ivars, and new methods.
|
|||
* NSSpellServer and NSAffineTransform was moved to GNUstep base for
|
||||
Mac OS X compatibility.
|
||||
|
||||
1.6 Noteworthy changes in version `0.11.0'
|
||||
1.7 Noteworthy changes in version `0.11.0'
|
||||
==========================================
|
||||
|
||||
* Added support for keyed encoding in all gui classes.
|
||||
|
@ -117,26 +128,26 @@ added and changed, including new classes, new ivars, and new methods.
|
|||
* Implemented glue code in GSNibCompatibility for classes such as
|
||||
NSIBObjectData, NSClassSwapper, etc. to facilitate nib loading.
|
||||
|
||||
1.7 Noteworthy changes in version `0.10.3'
|
||||
1.8 Noteworthy changes in version `0.10.3'
|
||||
==========================================
|
||||
|
||||
* Horizontal menus now work
|
||||
|
||||
* Better support for tracking active applications.
|
||||
|
||||
1.8 Noteworthy changes in version `0.10.2'
|
||||
1.9 Noteworthy changes in version `0.10.2'
|
||||
==========================================
|
||||
|
||||
Mostly bug fixes.
|
||||
|
||||
1.9 Noteworthy changes in version `0.10.1'
|
||||
==========================================
|
||||
1.10 Noteworthy changes in version `0.10.1'
|
||||
===========================================
|
||||
|
||||
GNUstep now uses v19 of portaudio for the sound daemon. Version v19
|
||||
hasn't been officially released, but it is still used in several
|
||||
distributions (SuSE, etc) as v18 is very old.
|
||||
|
||||
1.10 Noteworthy changes in version `0.10.0'
|
||||
1.11 Noteworthy changes in version `0.10.0'
|
||||
===========================================
|
||||
|
||||
This release is binary incompatible with previous releases. The
|
||||
|
@ -148,7 +159,7 @@ new version.
|
|||
|
||||
* Keyed encoding is supported in many classes.
|
||||
|
||||
1.11 Noteworthy changes in version `0.9.5'
|
||||
1.12 Noteworthy changes in version `0.9.5'
|
||||
==========================================
|
||||
|
||||
* Beginnings of CUPS interface were added.
|
||||
|
@ -161,7 +172,7 @@ new version.
|
|||
|
||||
* You can find the GUI library's version using the Info.plist
|
||||
|
||||
1.12 Noteworthy changes in version `0.9.4'
|
||||
1.13 Noteworthy changes in version `0.9.4'
|
||||
==========================================
|
||||
|
||||
* The printing classes have been completely reorganized to
|
||||
|
@ -176,7 +187,7 @@ new version.
|
|||
|
||||
* Some improvement of NSDataLink classes.
|
||||
|
||||
1.13 Noteworthy changes in version `0.9.3'
|
||||
1.14 Noteworthy changes in version `0.9.3'
|
||||
==========================================
|
||||
|
||||
* Spell checker reimplemented using libaspell
|
||||
|
@ -188,7 +199,7 @@ new version.
|
|||
* Binary incompatibilites from ivar additions in NSView and
|
||||
subclasses.
|
||||
|
||||
1.14 Noteworthy changes in version `0.9.2'
|
||||
1.15 Noteworthy changes in version `0.9.2'
|
||||
==========================================
|
||||
|
||||
* Working NSToolbar implementation
|
||||
|
@ -207,7 +218,7 @@ new version.
|
|||
|
||||
* Much improved loading of gorm files
|
||||
|
||||
1.15 Noteworthy changes in version `0.9.1'
|
||||
1.16 Noteworthy changes in version `0.9.1'
|
||||
==========================================
|
||||
|
||||
* NSWindow - DnD works on whole window and events are propogated up
|
||||
|
@ -215,14 +226,14 @@ new version.
|
|||
|
||||
* Absolute paths and DnD works in OpenPanels.
|
||||
|
||||
1.16 Noteworthy changes in version `0.9.0'
|
||||
1.17 Noteworthy changes in version `0.9.0'
|
||||
==========================================
|
||||
|
||||
Improvements in various classes, include NSPopUpButton,
|
||||
NSBitmapImageRep, NSMenu, NSToolbar. Added support for thumbnail images
|
||||
in NSWorkspace.
|
||||
|
||||
1.17 Noteworthy changes in version `0.8.9'
|
||||
1.18 Noteworthy changes in version `0.8.9'
|
||||
==========================================
|
||||
|
||||
Note that many headers have moved to new locations (both in the package
|
||||
|
@ -231,14 +242,14 @@ applications may not compile because they cannot find the right header.
|
|||
|
||||
* New Language Setup documentation.
|
||||
|
||||
1.18 Noteworthy changes in version `0.8.8'
|
||||
1.19 Noteworthy changes in version `0.8.8'
|
||||
==========================================
|
||||
|
||||
* Updated LanguageSetup documentation
|
||||
|
||||
* Improved RTF reader (unicode support, etc).
|
||||
|
||||
1.19 Noteworthy changes in version `0.8.7'
|
||||
1.20 Noteworthy changes in version `0.8.7'
|
||||
==========================================
|
||||
|
||||
* NSBezierPath glyph methods implemented (depends on backend).
|
||||
|
@ -248,7 +259,7 @@ applications may not compile because they cannot find the right header.
|
|||
* Added default to load user-defined bundles (GSAppKitUserBundles
|
||||
default).
|
||||
|
||||
1.20 Noteworthy changes in version `0.8.6'
|
||||
1.21 Noteworthy changes in version `0.8.6'
|
||||
==========================================
|
||||
|
||||
Updated to install in new locations based on changes in gnustep-make
|
||||
|
@ -260,12 +271,12 @@ Updated to install in new locations based on changes in gnustep-make
|
|||
|
||||
* Lots of menu improvements.
|
||||
|
||||
1.21 Noteworthy changes in version `0.8.5'
|
||||
1.22 Noteworthy changes in version `0.8.5'
|
||||
==========================================
|
||||
|
||||
Bug fixes. NSStringDrawing now uses text system implementation.
|
||||
|
||||
1.22 Noteworthy changes in version `0.8.4'
|
||||
1.23 Noteworthy changes in version `0.8.4'
|
||||
==========================================
|
||||
|
||||
This release features a brand new text and layout system thanks to
|
||||
|
@ -279,7 +290,7 @@ Alexander Malmberg. Other improvements include:
|
|||
|
||||
* NSToolbar partially implemented.
|
||||
|
||||
1.23 Noteworthy changes in version `0.8.3'
|
||||
1.24 Noteworthy changes in version `0.8.3'
|
||||
==========================================
|
||||
|
||||
* Additions for Gorm support.
|
||||
|
@ -296,7 +307,7 @@ Alexander Malmberg. Other improvements include:
|
|||
|
||||
* Key view handling rewritten.
|
||||
|
||||
1.24 Noteworthy changes in version `0.8.2'
|
||||
1.25 Noteworthy changes in version `0.8.2'
|
||||
==========================================
|
||||
|
||||
* Handle fonts that aren't found better.
|
||||
|
@ -313,7 +324,7 @@ Alexander Malmberg. Other improvements include:
|
|||
|
||||
* Fix firstResponder status in text fields.
|
||||
|
||||
1.25 Noteworthy changes in version `0.8.1'
|
||||
1.26 Noteworthy changes in version `0.8.1'
|
||||
==========================================
|
||||
|
||||
* Handle scaled curves correctly.
|
||||
|
@ -326,10 +337,10 @@ Alexander Malmberg. Other improvements include:
|
|||
|
||||
* Spell checker starts correctly now.
|
||||
|
||||
1.26 Noteworthy changes in version `0.8.0'
|
||||
1.27 Noteworthy changes in version `0.8.0'
|
||||
==========================================
|
||||
|
||||
1.27 Noteworthy changes in version `0.7.9'
|
||||
1.28 Noteworthy changes in version `0.7.9'
|
||||
==========================================
|
||||
|
||||
* NSTableView, NSOutlineView improvements.
|
||||
|
@ -338,14 +349,14 @@ Alexander Malmberg. Other improvements include:
|
|||
|
||||
* Skeleton implementation of NSToolBar
|
||||
|
||||
1.28 Noteworthy changes in version `0.7.8'
|
||||
1.29 Noteworthy changes in version `0.7.8'
|
||||
==========================================
|
||||
|
||||
* Wheel color picker, standard color picker (bundles) added.
|
||||
|
||||
* System colors now use named colors. Easier configuration
|
||||
|
||||
1.29 Noteworthy changes in version `0.7.7'
|
||||
1.30 Noteworthy changes in version `0.7.7'
|
||||
==========================================
|
||||
|
||||
The graphics/window interface was completely revamped. Window functions
|
||||
|
@ -369,7 +380,7 @@ computers, although it is in a very alpha state.
|
|||
|
||||
* NSOutlineView much improved.
|
||||
|
||||
1.30 Noteworthy changes in version `0.7.6'
|
||||
1.31 Noteworthy changes in version `0.7.6'
|
||||
==========================================
|
||||
|
||||
* NSOutlineView implemented.
|
||||
|
@ -382,7 +393,7 @@ computers, although it is in a very alpha state.
|
|||
|
||||
* Memory panel available from Info Panel.
|
||||
|
||||
1.31 Noteworthy changes in version `0.7.5'
|
||||
1.32 Noteworthy changes in version `0.7.5'
|
||||
==========================================
|
||||
|
||||
* Drag and drop and image sliding much improved.
|
||||
|
@ -413,7 +424,7 @@ computers, although it is in a very alpha state.
|
|||
|
||||
* Gmodel code compiled as a separate bundle.
|
||||
|
||||
1.32 Noteworthy changes in version `0.7.0'
|
||||
1.33 Noteworthy changes in version `0.7.0'
|
||||
==========================================
|
||||
|
||||
* Much improvement in NSBrowser, NSMatrix, NSPopUpButton, combo
|
||||
|
@ -429,7 +440,7 @@ computers, although it is in a very alpha state.
|
|||
|
||||
* NSColorWell works.
|
||||
|
||||
1.33 Noteworthy changes in version `0.6.7'
|
||||
1.34 Noteworthy changes in version `0.6.7'
|
||||
==========================================
|
||||
|
||||
* App Icons can support documents dropped using DnD.
|
||||
|
@ -456,7 +467,7 @@ computers, although it is in a very alpha state.
|
|||
|
||||
* Support middle mouse button.
|
||||
|
||||
1.34 Noteworthy changes in version `0.6.6'
|
||||
1.35 Noteworthy changes in version `0.6.6'
|
||||
==========================================
|
||||
|
||||
* Window hints for motif and generic window managers.
|
||||
|
@ -493,7 +504,7 @@ however, that the xdps backend is still considered experimental and you
|
|||
may have to deal with many problems in order to get it working. We
|
||||
recommend sticking with the xgps backend (the default) for now.
|
||||
|
||||
1.35 Noteworthy changes in version `0.6.5'
|
||||
1.36 Noteworthy changes in version `0.6.5'
|
||||
==========================================
|
||||
|
||||
Many of the basic GUI classes have been vastly improved or rewritten,
|
||||
|
@ -527,7 +538,7 @@ thanks to Nicola Pero <n.pero@mi.flashnet.it> and many others.
|
|||
been written, thanks to Richard Frith-Macdonald
|
||||
<richard@brainstorm.co.uk>
|
||||
|
||||
1.36 Noteworthy changes in version `0.6.0'
|
||||
1.37 Noteworthy changes in version `0.6.0'
|
||||
==========================================
|
||||
|
||||
A Huge amount of progress, although a lot still needs to be done. It's
|
||||
|
@ -558,7 +569,7 @@ apps and libraries have been ported with little changes.
|
|||
|
||||
* Several fixes that at least double the speed of the gui.
|
||||
|
||||
1.37 Noteworthy changes in version `0.5.5'
|
||||
1.38 Noteworthy changes in version `0.5.5'
|
||||
==========================================
|
||||
|
||||
Too extensive to list.
|
||||
|
@ -567,7 +578,7 @@ Too extensive to list.
|
|||
cleanup of coordinate conversion code, etc.
|
||||
|
||||
|
||||
1.38 Noteworthy changes in version `0.5.0'
|
||||
1.39 Noteworthy changes in version `0.5.0'
|
||||
==========================================
|
||||
|
||||
* NSBrowser and NSBrowserCell have been implemented. There is one
|
||||
|
@ -617,7 +628,7 @@ Too extensive to list.
|
|||
* Several cleanups and as usual, many bug fixes.
|
||||
|
||||
|
||||
1.39 Noteworthy changes in version `0.3.0'
|
||||
1.40 Noteworthy changes in version `0.3.0'
|
||||
==========================================
|
||||
|
||||
* Completely reworked the menu class. The NSMenu class is now
|
||||
|
@ -649,7 +660,7 @@ Too extensive to list.
|
|||
implement the NSCopying protocol and many others.
|
||||
|
||||
|
||||
1.40 Noteworthy changes in version `0.2.0'
|
||||
1.41 Noteworthy changes in version `0.2.0'
|
||||
==========================================
|
||||
|
||||
* Additional NSImage and NSImageRep class work. Incorporated common
|
||||
|
@ -684,7 +695,7 @@ Too extensive to list.
|
|||
* Many bug fixes and minor enhancements.
|
||||
|
||||
|
||||
1.41 Noteworthy changes in version `0.1.1'
|
||||
1.42 Noteworthy changes in version `0.1.1'
|
||||
==========================================
|
||||
|
||||
* Almost complete implementation of the PXKMenu and PXKMenuCell
|
||||
|
@ -708,7 +719,7 @@ Too extensive to list.
|
|||
manipulating tiff files and images.
|
||||
|
||||
|
||||
1.42 Noteworthy changes in version `0.1.0'
|
||||
1.43 Noteworthy changes in version `0.1.0'
|
||||
==========================================
|
||||
|
||||
* Integration of the GNUstep X/DPS GUI Backend. This has finally
|
||||
|
|
|
@ -24,8 +24,7 @@
|
|||
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
GNUSTEP_INSTALLATION_DOMAIN = SYSTEM
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../gui.make
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
|
|
|
@ -23,8 +23,7 @@
|
|||
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
GNUSTEP_INSTALLATION_DOMAIN = SYSTEM
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../gui.make
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
|
@ -32,7 +31,7 @@ include ../Version
|
|||
|
||||
RES_INSTALL_DIR = $(GNUSTEP_LIBRARY)/PostScript
|
||||
PPD_INSTALL_DIR = $(GNUSTEP_LIBRARY)/PostScript/PPD
|
||||
|
||||
|
||||
RESOURCE_DIRS = English.lproj
|
||||
|
||||
RESOURCE_FILES = GSProlog.ps
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../gui.make
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../../gui.make
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../../gui.make
|
||||
GNUSTEP_INSTALLATION_DOMAIN = SYSTEM
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
include ../../config.make
|
||||
|
|
|
@ -23,8 +23,7 @@
|
|||
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
GNUSTEP_INSTALLATION_DOMAIN = SYSTEM
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../gui.make
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
|
|
|
@ -815,6 +815,12 @@ NSFrameLinkRect(NSRect aRect, BOOL isDestination)
|
|||
NSFrameRectWithWidth(aRect, NSLinkFrameThickness());
|
||||
}
|
||||
|
||||
void NSSetFocusRingStyle(NSFocusRingPlacement placement)
|
||||
{
|
||||
// FIXME: NIMP
|
||||
NSLog(@"*** NSSetFocusRingStyle not implemented ***");
|
||||
}
|
||||
|
||||
void
|
||||
NSConvertGlobalToWindowNumber(int globalNum, unsigned int *winNum)
|
||||
{
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
GNUSTEP_INSTALLATION_DOMAIN = SYSTEM
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../gui.make
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
|
||||
|
@ -55,6 +54,7 @@ NSAttributedString.m \
|
|||
NSBezierPath.m \
|
||||
NSBitmapImageRep.m \
|
||||
NSBitmapImageRep+GIF.m \
|
||||
NSBitmapImageRep+ICNS.m \
|
||||
NSBitmapImageRep+JPEG.m \
|
||||
NSBitmapImageRep+PNG.m \
|
||||
NSBitmapImageRep+PNM.m \
|
||||
|
@ -175,6 +175,8 @@ NSTextTable.m \
|
|||
NSTextTableBlock.m \
|
||||
NSToolbar.m \
|
||||
NSToolbarItem.m \
|
||||
NSTokenField.m \
|
||||
NSTokenFieldCell.m \
|
||||
NSUserDefaultsController.m \
|
||||
NSView.m \
|
||||
NSWindow+Toolbar.m \
|
||||
|
@ -208,8 +210,8 @@ NSTextView_actions.m \
|
|||
GSLayoutManager.m \
|
||||
GSTypesetter.m \
|
||||
GSHorizontalTypesetter.m \
|
||||
GSNibTemplates.m \
|
||||
GSNibCompatibility.m \
|
||||
GSGormLoading.m \
|
||||
GSNibLoading.m \
|
||||
GSTitleView.m \
|
||||
GSToolTips.m \
|
||||
GSToolbar.m \
|
||||
|
@ -365,6 +367,8 @@ NSTextTable.h \
|
|||
NSTextView.h \
|
||||
NSToolbar.h \
|
||||
NSToolbarItem.h \
|
||||
NSTokenField.h \
|
||||
NSTokenFieldCell.h \
|
||||
NSUserDefaultsController.h \
|
||||
NSView.h \
|
||||
NSWindow.h \
|
||||
|
@ -399,7 +403,7 @@ GSServicesManager.h \
|
|||
GSTextConverter.h \
|
||||
GSTrackingRect.h \
|
||||
GSHelpManagerPanel.h \
|
||||
GSNibTemplates.h \
|
||||
GSGormLoading.h \
|
||||
GSNibContainer.h \
|
||||
GSDisplayServer.h \
|
||||
GSFusedSilica.h \
|
||||
|
@ -415,7 +419,7 @@ GSTypesetter.h \
|
|||
GSHorizontalTypesetter.h \
|
||||
GSToolbar.h \
|
||||
GSToolbarView.h \
|
||||
GSNibCompatibility.h \
|
||||
GSNibLoading.h \
|
||||
GSDragView.h \
|
||||
GSTitleView.h \
|
||||
GSPrinting.h \
|
||||
|
|
|
@ -36,16 +36,8 @@
|
|||
# Flags dealing with compiling and linking
|
||||
#
|
||||
|
||||
# This GNUSTEP_TOOLS_NO_DESTDIR is used to somehow locate the gui
|
||||
# Tools when we are not using gnustep-base (currently, that's mostly a
|
||||
# hypothetical case!). It should be the same as GNUSTEP_TOOLS, except
|
||||
# that DESTDIR is not included. It's not used if we are using
|
||||
# gnustep-base.
|
||||
GNUSTEP_TOOLS_NO_DESTDIR = $(GNUSTEP_$(GNUSTEP_INSTALLATION_DOMAIN)_TOOLS)
|
||||
|
||||
# Additional flags to pass to the preprocessor
|
||||
ADDITIONAL_CPPFLAGS = \
|
||||
-DGNUSTEP_TOOLS_NO_DESTDIR=\"$(GNUSTEP_TOOLS_NO_DESTDIR)\" \
|
||||
-DGNUSTEP_TARGET_DIR=\"$(GNUSTEP_TARGET_DIR)\" \
|
||||
-DGNUSTEP_TARGET_CPU=\"$(GNUSTEP_TARGET_CPU)\" \
|
||||
-DGNUSTEP_TARGET_OS=\"$(GNUSTEP_TARGET_OS)\" \
|
||||
|
|
|
@ -834,6 +834,22 @@ static GSDragView *sharedDragView = nil;
|
|||
{
|
||||
[self _updateAndMoveImageToCorrectPosition];
|
||||
}
|
||||
else if (destWindow)
|
||||
{
|
||||
[self _sendLocalEvent: GSAppKitDraggingUpdate
|
||||
action: dragMask & operationMask
|
||||
position: newPosition
|
||||
timestamp: [theEvent timestamp]
|
||||
toWindow: destWindow];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self sendExternalEvent: GSAppKitDraggingUpdate
|
||||
action: dragMask & operationMask
|
||||
position: newPosition
|
||||
timestamp: [theEvent timestamp]
|
||||
toWindow: targetWindowRef];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NSLog(@"Internal: dropped event (%d) during dragging", [theEvent type]);
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "GNUstepGUI/GSModelLoaderFactory.h"
|
||||
#include "GNUstepGUI/GSNibTemplates.h"
|
||||
#include "GNUstepGUI/GSGormLoading.h"
|
||||
|
||||
@interface GSGormLoader : GSModelLoader
|
||||
@end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/** <title>GSNibTemplates</title>
|
||||
/** <title>GSGormLoading</title>
|
||||
|
||||
<abstract>Contains all of the private classes used in .gorm files.</abstract>
|
||||
|
||||
|
@ -53,7 +53,7 @@
|
|||
#include <AppKit/NSApplication.h>
|
||||
#include <AppKit/NSScreen.h>
|
||||
#include <GNUstepBase/GSObjCRuntime.h>
|
||||
#include <GNUstepGUI/GSNibTemplates.h>
|
||||
#include <GNUstepGUI/GSGormLoading.h>
|
||||
|
||||
static const int currentVersion = 1; // GSNibItem version number...
|
||||
|
||||
|
@ -557,14 +557,20 @@ static NSString *GSInternalNibItemAddedNotification = @"_GSInternalNibItemAddedN
|
|||
format: @"Unable to find class '%@', it is not linked into the application.", theClass];
|
||||
}
|
||||
|
||||
obj = [cls allocWithZone: [self zone]];
|
||||
if (theFrame.size.height > 0 && theFrame.size.width > 0)
|
||||
{
|
||||
obj = [obj initWithFrame: theFrame];
|
||||
obj = [[cls allocWithZone: [self zone]] initWithFrame: theFrame];
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = [obj init];
|
||||
if(GSObjCIsKindOf(cls, [NSApplication class]))
|
||||
{
|
||||
obj = [cls sharedApplication];
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = [[cls allocWithZone: [self zone]] init];
|
||||
}
|
||||
}
|
||||
|
||||
if ([obj respondsToSelector: @selector(setAutoresizingMask:)])
|
||||
|
@ -963,15 +969,6 @@ static NSString *GSInternalNibItemAddedNotification = @"_GSInternalNibItemAddedN
|
|||
id obj = [super initWithCoder: coder];
|
||||
if (obj != nil)
|
||||
{
|
||||
if ([self shouldSwapClass])
|
||||
{
|
||||
if (GSGetMethod([obj class],@selector(initWithFrame:), YES, NO) != NULL
|
||||
&& ![_className isEqualToString: NSStringFromClass(_superClass)])
|
||||
{
|
||||
NSRect theFrame = [obj frame];
|
||||
obj = [obj initWithFrame: theFrame];
|
||||
}
|
||||
}
|
||||
RELEASE(self);
|
||||
}
|
||||
return obj;
|
||||
|
@ -993,15 +990,6 @@ static NSString *GSInternalNibItemAddedNotification = @"_GSInternalNibItemAddedN
|
|||
id obj = [super initWithCoder: coder];
|
||||
if (obj != nil)
|
||||
{
|
||||
if ([self shouldSwapClass])
|
||||
{
|
||||
if (GSGetMethod([obj class],@selector(initWithFrame:), YES, NO) != NULL
|
||||
&& ![_className isEqualToString: NSStringFromClass(_superClass)])
|
||||
{
|
||||
NSRect theFrame = [obj frame];
|
||||
obj = [obj initWithFrame: theFrame];
|
||||
}
|
||||
}
|
||||
RELEASE(self);
|
||||
}
|
||||
return obj;
|
||||
|
@ -1023,17 +1011,6 @@ static NSString *GSInternalNibItemAddedNotification = @"_GSInternalNibItemAddedN
|
|||
id obj = [super initWithCoder: coder];
|
||||
if (obj != nil)
|
||||
{
|
||||
if ([self shouldSwapClass])
|
||||
{
|
||||
if (GSGetMethod([obj class],@selector(initWithFrame:textContainer:), YES, NO) != NULL
|
||||
&& ![_className isEqualToString: NSStringFromClass(_superClass)])
|
||||
{
|
||||
NSRect theFrame = [obj frame];
|
||||
id textContainer = [obj textContainer];
|
||||
obj = [obj initWithFrame: theFrame
|
||||
textContainer: textContainer];
|
||||
}
|
||||
}
|
||||
RELEASE(self);
|
||||
}
|
||||
return obj;
|
||||
|
@ -1055,15 +1032,6 @@ static NSString *GSInternalNibItemAddedNotification = @"_GSInternalNibItemAddedN
|
|||
id obj = [super initWithCoder: coder];
|
||||
if (obj != nil)
|
||||
{
|
||||
if ([self shouldSwapClass])
|
||||
{
|
||||
if (GSGetMethod([obj class],@selector(initWithTitle:), YES, NO) != NULL
|
||||
&& ![_className isEqualToString: NSStringFromClass(_superClass)])
|
||||
{
|
||||
NSString *theTitle = [obj title];
|
||||
obj = [obj initWithTitle: theTitle];
|
||||
}
|
||||
}
|
||||
RELEASE(self);
|
||||
}
|
||||
return obj;
|
||||
|
@ -1086,16 +1054,6 @@ static NSString *GSInternalNibItemAddedNotification = @"_GSInternalNibItemAddedN
|
|||
id obj = [super initWithCoder: coder];
|
||||
if (obj != nil)
|
||||
{
|
||||
/*
|
||||
if ([self shouldSwapClass])
|
||||
{
|
||||
if (GSGetMethod([obj class],@selector(initWithFrame:), YES, NO) != NULL)
|
||||
{
|
||||
NSRect theFrame = [obj frame];
|
||||
obj = [obj initWithFrame: theFrame];
|
||||
}
|
||||
}
|
||||
*/
|
||||
RELEASE(self);
|
||||
}
|
||||
return obj;
|
||||
|
@ -1116,14 +1074,6 @@ static NSString *GSInternalNibItemAddedNotification = @"_GSInternalNibItemAddedN
|
|||
id obj = [super initWithCoder: coder];
|
||||
if (obj != nil)
|
||||
{
|
||||
if ([self shouldSwapClass])
|
||||
{
|
||||
if (GSGetMethod([obj class],@selector(init), YES, NO) != NULL
|
||||
&& ![_className isEqualToString: NSStringFromClass(_superClass)])
|
||||
{
|
||||
obj = [self init];
|
||||
}
|
||||
}
|
||||
RELEASE(self);
|
||||
}
|
||||
return obj;
|
|
@ -214,13 +214,17 @@ new_label (NSString *value)
|
|||
if (nil_or_not_of_class (name, [NSString class]))
|
||||
{
|
||||
name = value_from_info_plist_for_key (@"ApplicationName");
|
||||
|
||||
if (nil_or_not_of_class (name, [NSString class]))
|
||||
{
|
||||
name = value_from_info_plist_for_key (@"NSHumanReadableShortName");
|
||||
|
||||
if (nil_or_not_of_class (name, [NSString class]))
|
||||
name = [[NSProcessInfo processInfo] processName];
|
||||
{
|
||||
name = value_from_info_plist_for_key (@"CFBundleName");
|
||||
if (nil_or_not_of_class (name, [NSString class]))
|
||||
{
|
||||
name = [[NSProcessInfo processInfo] processName];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Application Description */
|
||||
|
@ -265,7 +269,14 @@ new_label (NSString *value)
|
|||
release = value_from_info_plist_for_key (@"NSAppVersion");
|
||||
|
||||
if (nil_or_not_of_class (release, [NSString class]))
|
||||
release = @"Unknown";
|
||||
{
|
||||
release = value_from_info_plist_for_key (@"CFBundleVersion");
|
||||
|
||||
if (nil_or_not_of_class (release, [NSString class]))
|
||||
{
|
||||
release = @"Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -302,17 +313,19 @@ new_label (NSString *value)
|
|||
if (nil_or_not_of_class (authors, [NSArray class]))
|
||||
{
|
||||
authors = value_from_info_plist_for_key (@"Authors");
|
||||
|
||||
if (nil_or_not_of_class (authors, [NSArray class]))
|
||||
authors = [NSArray arrayWithObject: @"Unknown"];
|
||||
|
||||
// if (nil_or_not_of_class (authors, [NSArray class]))
|
||||
// authors = [NSArray arrayWithObject: @"Unknown"];
|
||||
}
|
||||
/* URL */
|
||||
if (dictionary)
|
||||
url = [dictionary objectForKey: @"URL"];
|
||||
url = [dictionary objectForKey: @"URL"];
|
||||
|
||||
if ([url isKindOfClass: [NSString class]] == NO)
|
||||
url = nil;
|
||||
/* NB: URL can be nil */
|
||||
if (nil_or_not_of_class (url, [NSString class]))
|
||||
{
|
||||
url = value_from_info_plist_for_key (@"URL");
|
||||
}
|
||||
// URL can be nil
|
||||
|
||||
/* Copyright */
|
||||
if (dictionary)
|
||||
|
@ -376,7 +389,11 @@ new_label (NSString *value)
|
|||
[versionLabel setFont: smallFont];
|
||||
[versionLabel sizeToFit];
|
||||
|
||||
if ([authors count] == 1)
|
||||
if ([authors count] == 0)
|
||||
{
|
||||
authorTitleLabel = new_label (@"");
|
||||
}
|
||||
else if ([authors count] == 1)
|
||||
{
|
||||
authorTitleLabel = new_label (@"Author: ");
|
||||
}
|
||||
|
|
|
@ -778,7 +778,7 @@ Fills in all glyph holes up to last. only looking at levels below level
|
|||
if (!r->glyphs)
|
||||
{
|
||||
// range, but no glyphs, may be an empty glyph run
|
||||
*rindex = i;
|
||||
*rindex = 0; // FIXME ... is this right?
|
||||
*rpos = pos;
|
||||
*rcpos = cpos;
|
||||
return r;
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "GNUstepGUI/GSModelLoaderFactory.h"
|
||||
#include "GNUstepGUI/GSNibCompatibility.h"
|
||||
#include "GNUstepGUI/GSNibLoading.h"
|
||||
|
||||
@interface GSNibLoader : GSModelLoader
|
||||
@end
|
||||
|
|
File diff suppressed because it is too large
Load diff
204
Source/GSTheme.m
204
Source/GSTheme.m
|
@ -654,8 +654,7 @@ static NSNull *null = nil;
|
|||
unsigned count;
|
||||
|
||||
imageTypes = [NSImage imageFileTypes];
|
||||
for (count = 0, image = nil; image == nil && count < [imageTypes count];
|
||||
count++)
|
||||
for (count = 0; count < [imageTypes count]; count++)
|
||||
{
|
||||
NSString *ext = [imageTypes objectAtIndex: count];
|
||||
|
||||
|
@ -860,6 +859,86 @@ static NSNull *null = nil;
|
|||
NSRectFill (frame);
|
||||
}
|
||||
|
||||
- (void) drawBorderType: (NSBorderType)aType
|
||||
frame: (NSRect)frame
|
||||
view: (NSView*)view
|
||||
{
|
||||
switch (aType)
|
||||
{
|
||||
case NSLineBorder:
|
||||
[[NSColor controlDarkShadowColor] set];
|
||||
NSFrameRect(frame);
|
||||
break;
|
||||
case NSGrooveBorder:
|
||||
[self drawGroove: frame withClip: NSZeroRect];
|
||||
break;
|
||||
case NSBezelBorder:
|
||||
[self drawWhiteBezel: frame withClip: NSZeroRect];
|
||||
break;
|
||||
case NSNoBorder:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSSize) sizeForBorderType: (NSBorderType)aType
|
||||
{
|
||||
// Returns the size of a border
|
||||
switch (aType)
|
||||
{
|
||||
case NSLineBorder:
|
||||
return NSMakeSize(1, 1);
|
||||
case NSGrooveBorder:
|
||||
case NSBezelBorder:
|
||||
return NSMakeSize(2, 2);
|
||||
case NSNoBorder:
|
||||
default:
|
||||
return NSZeroSize;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) drawBorderForImageFrameStyle: (NSImageFrameStyle)frameStyle
|
||||
frame: (NSRect)frame
|
||||
view: (NSView*)view
|
||||
{
|
||||
switch (frameStyle)
|
||||
{
|
||||
case NSImageFrameNone:
|
||||
// do nothing
|
||||
break;
|
||||
case NSImageFramePhoto:
|
||||
[self drawFramePhoto: frame withClip: NSZeroRect];
|
||||
break;
|
||||
case NSImageFrameGrayBezel:
|
||||
[self drawGrayBezel: frame withClip: NSZeroRect];
|
||||
break;
|
||||
case NSImageFrameGroove:
|
||||
[self drawGroove: frame withClip: NSZeroRect];
|
||||
break;
|
||||
case NSImageFrameButton:
|
||||
[self drawButton: frame withClip: NSZeroRect];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSSize) sizeForImageFrameStyle: (NSImageFrameStyle)frameStyle
|
||||
{
|
||||
// Get border size
|
||||
switch (frameStyle)
|
||||
{
|
||||
case NSImageFrameNone:
|
||||
default:
|
||||
return NSZeroSize;
|
||||
case NSImageFramePhoto:
|
||||
// FIXME
|
||||
return NSMakeSize(2, 2);
|
||||
case NSImageFrameGrayBezel:
|
||||
case NSImageFrameGroove:
|
||||
case NSImageFrameButton:
|
||||
return NSMakeSize(2, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -968,9 +1047,10 @@ static NSNull *null = nil;
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
- (NSRect) drawGradientBorder: (NSGradientType)gradientType
|
||||
inRect: (NSRect)border
|
||||
withClip: (NSRect)clip
|
||||
inRect: (NSRect)border
|
||||
withClip: (NSRect)clip
|
||||
{
|
||||
NSRectEdge up_sides[] = {NSMaxXEdge, NSMinYEdge,
|
||||
NSMinXEdge, NSMaxYEdge};
|
||||
|
@ -1017,6 +1097,122 @@ static NSNull *null = nil;
|
|||
return rect;
|
||||
}
|
||||
|
||||
#else
|
||||
// FIXME: I think this method is wrong.
|
||||
- (NSRect) drawGradientBorder: (NSGradientType)gradientType
|
||||
inRect: (NSRect)cellFrame
|
||||
withClip: (NSRect)clip
|
||||
{
|
||||
float start_white = 0.0;
|
||||
float end_white = 0.0;
|
||||
float white = 0.0;
|
||||
float white_step = 0.0;
|
||||
float h, s, v, a;
|
||||
NSPoint p1, p2;
|
||||
NSColor *gray = nil;
|
||||
NSColor *darkGray = nil;
|
||||
NSColor *lightGray = nil;
|
||||
|
||||
lightGray = [NSColor colorWithDeviceRed: NSLightGray
|
||||
green: NSLightGray
|
||||
blue: NSLightGray
|
||||
alpha:1.0];
|
||||
gray = [NSColor colorWithDeviceRed: NSGray
|
||||
green: NSGray
|
||||
blue: NSGray
|
||||
alpha:1.0];
|
||||
darkGray = [NSColor colorWithDeviceRed: NSDarkGray
|
||||
green: NSDarkGray
|
||||
blue: NSDarkGray
|
||||
alpha:1.0];
|
||||
|
||||
switch (gradientType)
|
||||
{
|
||||
case NSGradientNone:
|
||||
return NSZeroRect;
|
||||
break;
|
||||
|
||||
case NSGradientConcaveWeak:
|
||||
[gray getHue: &h saturation: &s brightness: &v alpha: &a];
|
||||
start_white = [lightGray brightnessComponent];
|
||||
end_white = [gray brightnessComponent];
|
||||
break;
|
||||
|
||||
case NSGradientConvexWeak:
|
||||
[darkGray getHue: &h saturation: &s brightness: &v alpha: &a];
|
||||
start_white = [gray brightnessComponent];
|
||||
end_white = [lightGray brightnessComponent];
|
||||
break;
|
||||
|
||||
case NSGradientConcaveStrong:
|
||||
[lightGray getHue: &h saturation: &s brightness: &v alpha: &a];
|
||||
start_white = [lightGray brightnessComponent];
|
||||
end_white = [darkGray brightnessComponent];
|
||||
break;
|
||||
|
||||
case NSGradientConvexStrong:
|
||||
[darkGray getHue: &h saturation: &s brightness: &v alpha: &a];
|
||||
start_white = [darkGray brightnessComponent];
|
||||
end_white = [lightGray brightnessComponent];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
white = start_white;
|
||||
white_step = fabs(start_white - end_white)
|
||||
/ (cellFrame.size.width + cellFrame.size.height);
|
||||
|
||||
// Start from top left
|
||||
p1 = NSMakePoint(cellFrame.origin.x,
|
||||
cellFrame.size.height + cellFrame.origin.y);
|
||||
p2 = NSMakePoint(cellFrame.origin.x,
|
||||
cellFrame.size.height + cellFrame.origin.y);
|
||||
|
||||
// Move by Y
|
||||
while (p1.y > cellFrame.origin.y)
|
||||
{
|
||||
[[NSColor
|
||||
colorWithDeviceHue: h saturation: s brightness: white alpha: 1.0] set];
|
||||
[NSBezierPath strokeLineFromPoint: p1 toPoint: p2];
|
||||
|
||||
if (start_white > end_white)
|
||||
white -= white_step;
|
||||
else
|
||||
white += white_step;
|
||||
|
||||
p1.y -= 1.0;
|
||||
if (p2.x < (cellFrame.size.width + cellFrame.origin.x))
|
||||
p2.x += 1.0;
|
||||
else
|
||||
p2.y -= 1.0;
|
||||
}
|
||||
|
||||
// Move by X
|
||||
while (p1.x < (cellFrame.size.width + cellFrame.origin.x))
|
||||
{
|
||||
[[NSColor
|
||||
colorWithDeviceHue: h saturation: s brightness: white alpha: 1.0] set];
|
||||
[NSBezierPath strokeLineFromPoint: p1 toPoint: p2];
|
||||
|
||||
if (start_white > end_white)
|
||||
white -= white_step;
|
||||
else
|
||||
white += white_step;
|
||||
|
||||
p1.x += 1.0;
|
||||
if (p2.x >= (cellFrame.size.width + cellFrame.origin.x))
|
||||
p2.y -= 1.0;
|
||||
else
|
||||
p2.x += 1.0;
|
||||
}
|
||||
|
||||
return NSZeroRect;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
- (NSRect) drawGrayBezel: (NSRect)border withClip: (NSRect)clip
|
||||
{
|
||||
NSRectEdge up_sides[] = {NSMaxXEdge, NSMinYEdge, NSMinXEdge, NSMaxYEdge,
|
||||
|
|
|
@ -32,16 +32,16 @@
|
|||
|
||||
@class NSWindow;
|
||||
|
||||
// These are implemented as class methods on GSWindowDecorationView
|
||||
@protocol GSWindowDecorator
|
||||
- (id) newWindowDecorationViewWithFrame: (NSRect)frame
|
||||
window: (NSWindow *)window;
|
||||
|
||||
- (NSRect) contentRectForFrameRect: (NSRect)aRect
|
||||
styleMask: (unsigned int)aStyle;
|
||||
styleMask: (unsigned int)aStyle;
|
||||
- (NSRect) frameRectForContentRect: (NSRect)aRect
|
||||
styleMask: (unsigned int)aStyle;
|
||||
- (float) minFrameWidthWithTitle: (NSString *)aTitle
|
||||
styleMask: (unsigned int)aStyle;
|
||||
styleMask: (unsigned int)aStyle;
|
||||
@end
|
||||
|
||||
|
||||
|
@ -64,6 +64,11 @@ this, either directly, or indirectly (by using the backend).
|
|||
|
||||
- (id) initWithFrame: (NSRect)frame window: (NSWindow *)w;
|
||||
|
||||
- (NSRect) contentRectForFrameRect: (NSRect)aRect
|
||||
styleMask: (unsigned int)aStyle;
|
||||
- (NSRect) frameRectForContentRect: (NSRect)aRect
|
||||
styleMask: (unsigned int)aStyle;
|
||||
|
||||
- (void) setBackgroundColor: (NSColor *)color;
|
||||
- (void) setContentView: (NSView *)contentView;
|
||||
- (void) setDocumentEdited: (BOOL)flag;
|
||||
|
@ -79,6 +84,13 @@ windowNumber will be 0.
|
|||
@end
|
||||
|
||||
|
||||
/* Manage window decorations by using the backend functions. This only works
|
||||
* on backends that can handle window decorations.
|
||||
*/
|
||||
@interface GSBackendWindowDecorationView : GSWindowDecorationView
|
||||
@end
|
||||
|
||||
|
||||
/*
|
||||
Standard OPENSTEP-ish window decorations.
|
||||
*/
|
||||
|
|
|
@ -33,20 +33,6 @@
|
|||
#include "GNUstepGUI/GSDisplayServer.h"
|
||||
#include "GNUstepGUI/GSTheme.h"
|
||||
|
||||
|
||||
struct NSWindow_struct
|
||||
{
|
||||
@defs(NSWindow)
|
||||
};
|
||||
|
||||
|
||||
/* Manage window decorations by using the backend functions. This only works
|
||||
* on backends that can handle window decorations.
|
||||
*/
|
||||
@interface GSBackendWindowDecorationView : GSWindowDecorationView
|
||||
@end
|
||||
|
||||
|
||||
@implementation GSWindowDecorationView
|
||||
|
||||
+ (id<GSWindowDecorator>) windowDecorator
|
||||
|
@ -118,13 +104,29 @@ struct NSWindow_struct
|
|||
self = [super initWithFrame: frame];
|
||||
if (self != nil)
|
||||
{
|
||||
contentRect = [isa contentRectForFrameRect: frame
|
||||
styleMask: [w styleMask]];
|
||||
window = w;
|
||||
contentRect = [self contentRectForFrameRect: frame
|
||||
styleMask: [w styleMask]];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSRect) contentRectForFrameRect: (NSRect)aRect
|
||||
styleMask: (unsigned int)aStyle
|
||||
{
|
||||
// TODO: Handle toolbar and others
|
||||
return [isa contentRectForFrameRect: aRect
|
||||
styleMask: aStyle];
|
||||
}
|
||||
|
||||
- (NSRect) frameRectForContentRect: (NSRect)aRect
|
||||
styleMask: (unsigned int)aStyle
|
||||
{
|
||||
// TODO: Handle toolbar and others
|
||||
return [isa frameRectForContentRect: aRect
|
||||
styleMask: aStyle];
|
||||
}
|
||||
|
||||
#if 0
|
||||
- (void) removeSubview: (NSView*)aView
|
||||
{
|
||||
|
@ -179,8 +181,8 @@ struct NSWindow_struct
|
|||
_autoresizes_subviews = NO;
|
||||
[super setFrame: frameRect];
|
||||
|
||||
contentRect = [isa contentRectForFrameRect: frameRect
|
||||
styleMask: [window styleMask]];
|
||||
contentRect = [self contentRectForFrameRect: frameRect
|
||||
styleMask: [window styleMask]];
|
||||
|
||||
// Safety Check.
|
||||
[cv setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
|
||||
|
|
|
@ -318,8 +318,14 @@ static Class controlClass;
|
|||
if ([aCoder allowsKeyedCoding])
|
||||
{
|
||||
[aCoder encodeInt: [self tag] forKey: @"NSTag"];
|
||||
[aCoder encodeObject: [self target] forKey: @"NSTarget"];
|
||||
[aCoder encodeObject: NSStringFromSelector([self action]) forKey: @"NSAction"];
|
||||
if([self target] != nil)
|
||||
{
|
||||
[aCoder encodeObject: [self target] forKey: @"NSTarget"];
|
||||
}
|
||||
if([self action] != NULL)
|
||||
{
|
||||
[aCoder encodeObject: NSStringFromSelector([self action]) forKey: @"NSAction"];
|
||||
}
|
||||
[aCoder encodeObject: _control_view forKey: @"NSControlView"];
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1642,15 +1642,30 @@ void NSBeginInformationalAlertSheet(NSString *title,
|
|||
}
|
||||
else
|
||||
{
|
||||
_modalDelegate = delegate;
|
||||
_didEndSelector = didEndSelector;
|
||||
[NSApp beginSheet: _window
|
||||
modalForWindow: window
|
||||
modalDelegate: delegate
|
||||
didEndSelector: didEndSelector
|
||||
modalDelegate: self
|
||||
didEndSelector: @selector(_alertDidEnd:returnCode:contextInfo:)
|
||||
contextInfo: contextInfo];
|
||||
DESTROY(_window);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _alertDidEnd: (NSWindow *)sheet
|
||||
returnCode: (int)returnCode
|
||||
contextInfo: (void *)contextInfo
|
||||
{
|
||||
if ([_modalDelegate respondsToSelector: _didEndSelector])
|
||||
{
|
||||
void (*didEnd)(id, SEL, id, int, void *);
|
||||
didEnd = (void (*)(id, SEL, id, int, void *))[_modalDelegate
|
||||
methodForSelector: _didEndSelector];
|
||||
didEnd(_modalDelegate, _didEndSelector, self, returnCode, contextInfo);
|
||||
}
|
||||
}
|
||||
|
||||
- (id) window
|
||||
{
|
||||
return _window;
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
#include "GSGuiPrivate.h"
|
||||
#include "GNUstepGUI/GSInfoPanel.h"
|
||||
#include "GNUstepGUI/GSVersion.h"
|
||||
#include "NSDocumentFrameworkPrivate.h"
|
||||
|
||||
/* The -gui thread. See the comment in initialize_gnustep_backend. */
|
||||
NSThread *GSAppKitThread;
|
||||
|
@ -903,8 +904,7 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
|
|||
* Nib file if <code>NSMainNibFile</code> is set in the application
|
||||
* property list, posts an
|
||||
* <code>NSApplicationWillFinishLaunchingNotification</code>, and takes care
|
||||
* of a few other startup tasks, then posts
|
||||
* <code>NSApplicationDidFinishLaunchingNotification</code>.
|
||||
* of a few other startup tasks.
|
||||
* If you override this method, be sure to call <em>super</em>.</p>
|
||||
*
|
||||
* <p>The -run method calls this the first time it is called, before starting
|
||||
|
@ -922,6 +922,7 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
|
|||
unsigned count;
|
||||
unsigned i;
|
||||
BOOL hadDuplicates = NO;
|
||||
BOOL didAutoreopen = NO;
|
||||
NSImage *image = nil;
|
||||
|
||||
appIconFile = [infoDict objectForKey: @"NSIcon"];
|
||||
|
@ -929,6 +930,14 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
|
|||
{
|
||||
image = [NSImage imageNamed: appIconFile];
|
||||
}
|
||||
|
||||
// Try to look up the icns file.
|
||||
appIconFile = [infoDict objectForKey: @"CFBundleIconFile"];
|
||||
if (appIconFile && ![appIconFile isEqual: @""])
|
||||
{
|
||||
image = [NSImage imageNamed: appIconFile];
|
||||
}
|
||||
|
||||
if (image == nil)
|
||||
{
|
||||
image = [NSImage imageNamed: @"GNUstep"];
|
||||
|
@ -1046,9 +1055,16 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
|
|||
|
||||
[self activateIgnoringOtherApps: YES];
|
||||
|
||||
/* Instantiate the NSDocumentController if we are a doc-based app */
|
||||
/*
|
||||
* Instantiate the NSDocumentController if we are a doc-based app
|
||||
* and eventually reopen all autosaved documents
|
||||
*/
|
||||
if ([NSDocumentController isDocumentBasedApplication])
|
||||
[NSDocumentController sharedDocumentController];
|
||||
{
|
||||
didAutoreopen =
|
||||
[[NSDocumentController sharedDocumentController]
|
||||
_reopenAutosavedDocuments];
|
||||
}
|
||||
|
||||
/*
|
||||
* Now check to see if we were launched with arguments asking to
|
||||
|
@ -1068,7 +1084,7 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
|
|||
[_listener application: self printFile: filePath];
|
||||
[self terminate: self];
|
||||
}
|
||||
else if (![defs boolForKey: @"autolaunch"]
|
||||
else if (!didAutoreopen && ![defs boolForKey: @"autolaunch"]
|
||||
&& [_delegate respondsToSelector:
|
||||
@selector(applicationShouldOpenUntitledFile:)]
|
||||
&& ([_delegate applicationShouldOpenUntitledFile: self])
|
||||
|
@ -1077,7 +1093,16 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
|
|||
{
|
||||
[_delegate applicationOpenUntitledFile: self];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Posts <code>NSApplicationDidFinishLaunchingNotification</code>.
|
||||
*
|
||||
* <p>The -run method calls this the first time it is called, before starting
|
||||
* the event loop for the first time and after calling finishLaunching.</p>
|
||||
*/
|
||||
- (void) _didFinishLaunching
|
||||
{
|
||||
/* finish the launching post notification that launching has finished */
|
||||
[nc postNotificationName: NSApplicationDidFinishLaunchingNotification
|
||||
object: self];
|
||||
|
@ -1085,14 +1110,14 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
|
|||
NS_DURING
|
||||
{
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter]
|
||||
postNotificationName: NSWorkspaceDidLaunchApplicationNotification
|
||||
object: [NSWorkspace sharedWorkspace]
|
||||
userInfo: [self _notificationUserInfo]];
|
||||
postNotificationName: NSWorkspaceDidLaunchApplicationNotification
|
||||
object: [NSWorkspace sharedWorkspace]
|
||||
userInfo: [self _notificationUserInfo]];
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSLog (_(@"Problem during launch app notification: %@"),
|
||||
[localException reason]);
|
||||
[localException reason]);
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
|
@ -1364,6 +1389,7 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
|
|||
IF_NO_GC(_runLoopPool = [arpClass new]);
|
||||
|
||||
[self finishLaunching];
|
||||
[self _didFinishLaunching];
|
||||
|
||||
[_listener updateServicesMenu];
|
||||
[_main_menu update];
|
||||
|
@ -1753,8 +1779,10 @@ See -runModalForWindow:
|
|||
{
|
||||
if (_session == 0)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"stopModalWithCode: when not in a modal session"];
|
||||
// According to the spec, there is no exception which is thrown if we are not
|
||||
// currently in a modal session. While it is not good practice to call this
|
||||
// when we're not, we shouldn't throw an exception.
|
||||
return;
|
||||
}
|
||||
else if (returnCode == NSRunContinuesResponse)
|
||||
{
|
||||
|
@ -1853,8 +1881,8 @@ See -runModalForWindow:
|
|||
case NSKeyDown:
|
||||
{
|
||||
NSDebugLLog(@"NSEvent", @"send key down event\n");
|
||||
if ([[self mainMenu] performKeyEquivalent: theEvent] == NO
|
||||
&& [[self keyWindow] performKeyEquivalent: theEvent] == NO)
|
||||
if ([[self keyWindow] performKeyEquivalent: theEvent] == NO
|
||||
&& [[self mainMenu] performKeyEquivalent: theEvent] == NO)
|
||||
{
|
||||
[[theEvent window] sendEvent: theEvent];
|
||||
}
|
||||
|
@ -2167,6 +2195,8 @@ image.</p><p>See Also: -applicationIconImage</p>
|
|||
RETAIN(old_app_icon);
|
||||
[_app_icon setName: nil];
|
||||
[anImage setName: @"NSApplicationIcon"];
|
||||
[anImage setScalesWhenResized: YES];
|
||||
[anImage setSize: NSMakeSize(48,48)];
|
||||
ASSIGN(_app_icon, anImage);
|
||||
|
||||
[_main_menu _organizeMenu]; // Let horizontal menu change icon
|
||||
|
@ -3196,8 +3226,8 @@ struct _DelegateWrapper
|
|||
* it returns <code>NSTerminateNow</code> will termination be
|
||||
* carried out.<br />
|
||||
* The old version of -applicationShouldTerminate: returned a BOOL, and this
|
||||
* behavior is handled for backward compatibility with YES being
|
||||
* equivalent to <code>NSTerminateNow</code> and NO being
|
||||
* should still work as YES is
|
||||
* equivalent to <code>NSTerminateNow</code> and NO is
|
||||
* equivalent to <code>NSTerminateCancel</code>.
|
||||
*/
|
||||
- (void) terminate: (id)sender
|
||||
|
@ -3210,11 +3240,12 @@ struct _DelegateWrapper
|
|||
* so if we are linked in to an application which used that
|
||||
* API, the delegate might return a BOOL rather than an
|
||||
* NSTerminateNow. That's fine as both NSTerminateNow
|
||||
* and BOOL are integers, and NSTerminateNow is defined as YES
|
||||
* and NSTerminateCancel as NO.
|
||||
* and BOOL are integral types (though potentially of different sizes),
|
||||
* and NSTerminateNow is defined as YES and NSTerminateCancel as NO.
|
||||
* So all we need to do is mask the low byte of the return value in
|
||||
* case there is uninitialised random data in the higher bytes.
|
||||
*/
|
||||
termination = (NSApplicationTerminateReply)
|
||||
[_delegate applicationShouldTerminate: self];
|
||||
termination = ([_delegate applicationShouldTerminate: self] & 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3668,9 +3699,10 @@ struct _DelegateWrapper
|
|||
if (wasMain && count == 0)
|
||||
{
|
||||
if ([_delegate respondsToSelector:
|
||||
@selector(applicationShouldTerminateAfterLastWindowClosed:)])
|
||||
@selector(applicationShouldTerminateAfterLastWindowClosed:)])
|
||||
{
|
||||
if ([_delegate applicationShouldTerminateAfterLastWindowClosed: self])
|
||||
if ([_delegate
|
||||
applicationShouldTerminateAfterLastWindowClosed: self])
|
||||
{
|
||||
[self terminate: self];
|
||||
}
|
||||
|
|
|
@ -62,6 +62,10 @@ static Class stringClass = nil;
|
|||
static NSCharacterSet *wordBreakCSet = nil;
|
||||
/* A character set containing characters that are legal within words. */
|
||||
static NSCharacterSet *wordCSet = nil;
|
||||
/* Character sets containing characters that are white space and
|
||||
not white space */
|
||||
static NSCharacterSet *whiteCSet = nil;
|
||||
static NSCharacterSet *nonWhiteCSet = nil;
|
||||
/* A String containing the attachment character */
|
||||
static NSString *attachmentString = nil;
|
||||
|
||||
|
@ -94,6 +98,10 @@ static void cache_init_real(void)
|
|||
|
||||
/* Initializes wordCSet */
|
||||
wordCSet = [[wordBreakCSet invertedSet] copy];
|
||||
|
||||
/* Initializes white space and non-white space character sets */
|
||||
whiteCSet = [[NSCharacterSet whitespaceCharacterSet] copy];
|
||||
nonWhiteCSet = [[whiteCSet invertedSet] copy];
|
||||
|
||||
/* Initializes attachmentString */
|
||||
attachmentString = [stringClass stringWithCharacters: &ch length: 1];
|
||||
|
@ -403,6 +411,7 @@ static Class converter_class(NSString *format, BOOL producer)
|
|||
NSRange scanRange;
|
||||
NSRange startRange;
|
||||
NSRange endRange;
|
||||
NSCharacterSet *breakCSet;
|
||||
|
||||
cache_init ();
|
||||
|
||||
|
@ -413,10 +422,15 @@ static Class converter_class(NSString *format, BOOL producer)
|
|||
}
|
||||
|
||||
/*
|
||||
* If the location lies between words, a double click selects only
|
||||
* the character actually clicked on.
|
||||
* Double clicking on a white space character selects all surrounding
|
||||
* white space. Otherwise, if the location lies between words, a double
|
||||
* click selects only the character actually clicked on.
|
||||
*/
|
||||
if ([wordBreakCSet characterIsMember: [str characterAtIndex: location]])
|
||||
if ([whiteCSet characterIsMember: [str characterAtIndex: location]])
|
||||
{
|
||||
breakCSet = nonWhiteCSet;
|
||||
}
|
||||
else if ([wordBreakCSet characterIsMember: [str characterAtIndex: location]])
|
||||
{
|
||||
if (location == 0 || location == length - 1
|
||||
|| [str characterAtIndex: location] != '\''
|
||||
|
@ -425,13 +439,21 @@ static Class converter_class(NSString *format, BOOL producer)
|
|||
{
|
||||
return NSMakeRange(location, 1);
|
||||
}
|
||||
breakCSet = wordBreakCSet;
|
||||
}
|
||||
else
|
||||
{
|
||||
breakCSet = wordBreakCSet;
|
||||
}
|
||||
|
||||
scanRange = NSMakeRange (0, location);
|
||||
startRange = [str rangeOfCharacterFromSet: wordBreakCSet
|
||||
startRange = [str rangeOfCharacterFromSet: breakCSet
|
||||
options: NSBackwardsSearch|NSLiteralSearch
|
||||
range: scanRange];
|
||||
|
||||
/*
|
||||
* Don't treat single quotes embedded within a word as break characters.
|
||||
* Note: The loop condition is always false when breakCSet==nonWhiteSetCSet.
|
||||
*/
|
||||
while (startRange.length > 0
|
||||
&& startRange.location > 0 && startRange.location < length - 1
|
||||
&& [str characterAtIndex: startRange.location] == '\''
|
||||
|
@ -447,9 +469,13 @@ static Class converter_class(NSString *format, BOOL producer)
|
|||
}
|
||||
|
||||
scanRange = NSMakeRange (location, length - location);
|
||||
endRange = [str rangeOfCharacterFromSet: wordBreakCSet
|
||||
endRange = [str rangeOfCharacterFromSet: breakCSet
|
||||
options: NSLiteralSearch
|
||||
range: scanRange];
|
||||
/*
|
||||
* Don't treat single quotes embedded within a word as break characters.
|
||||
* Note: The loop condition is always false when breakCSet==nonWhiteSetCSet.
|
||||
*/
|
||||
while (endRange.length > 0
|
||||
&& endRange.location > 0 && endRange.location < length - 1
|
||||
&& [str characterAtIndex: endRange.location] == '\''
|
||||
|
|
|
@ -1418,6 +1418,9 @@ static int winding_curve(double_point from, double_point to, double_point c1,
|
|||
total = 0;
|
||||
count = [self elementCount];
|
||||
|
||||
if (count == 0)
|
||||
return 0;
|
||||
|
||||
/* 'Unroll' the first element to avoid compiler warnings. It has to be
|
||||
a MoveTo, anyway. */
|
||||
type = [self elementAtIndex: 0 associatedPoints: pts];
|
||||
|
|
41
Source/NSBitmapImageRep+ICNS.h
Normal file
41
Source/NSBitmapImageRep+ICNS.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
NSBitmapImageRep+ICNS.m
|
||||
|
||||
Methods for loading .icns images.
|
||||
|
||||
Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Gregory Casamento
|
||||
Date: 2008-08-12
|
||||
|
||||
This file is part of the GNUstep GUI Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; see the file COPYING.LIB.
|
||||
If not, see <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _NSBitmapImageRep_ICNS_H_include
|
||||
#define _NSBitmapImageRep_ICNS_H_include
|
||||
|
||||
#include "AppKit/NSBitmapImageRep.h"
|
||||
|
||||
@interface NSBitmapImageRep (ICNS)
|
||||
+ (BOOL) _bitmapIsICNS: (NSData *)imageData;
|
||||
- (id) _initBitmapFromICNS: (NSData *)imageData;
|
||||
// - (NSData *) _ICNSRepresentationWithProperties: (NSDictionary *) properties;
|
||||
@end
|
||||
|
||||
#endif
|
599
Source/NSBitmapImageRep+ICNS.m
Normal file
599
Source/NSBitmapImageRep+ICNS.m
Normal file
|
@ -0,0 +1,599 @@
|
|||
/*
|
||||
NSBitmapImageRep+ICNS.m
|
||||
|
||||
Methods for loading .icns images.
|
||||
|
||||
Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Gregory Casamento
|
||||
Date: 2008-08-12
|
||||
|
||||
Author: Fred Kiefer <fredkiefer@gmx.de>
|
||||
Date: September 2008
|
||||
|
||||
This file is part of the GNUstep GUI Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; see the file COPYING.LIB.
|
||||
If not, see <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "NSBitmapImageRep+ICNS.h"
|
||||
#include <Foundation/NSByteOrder.h>
|
||||
#include <Foundation/NSData.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSValue.h>
|
||||
#include "AppKit/NSGraphics.h"
|
||||
|
||||
#define ICNS_HEADER "icns"
|
||||
|
||||
#if HAVE_LIBICNS
|
||||
|
||||
#include <icns.h>
|
||||
|
||||
#else /* !HAVE_LIBICNS */
|
||||
/*
|
||||
The following code is a drop in replacement for libicns. It may be used
|
||||
when the library is not available or unsuited due to its licence (Currently
|
||||
GPL 2). This code was mostly build based on the documentation found at
|
||||
http://icns.sourceforge.net/apidocs.html. It also includes icns decoding
|
||||
ideas based on code in mySTEP.
|
||||
Only limited formats are implemented and some errors still exist.
|
||||
*/
|
||||
|
||||
typedef unsigned char icns_byte_t;
|
||||
typedef unsigned long icns_size_t;
|
||||
typedef struct _icns_type_t {
|
||||
char c[4];
|
||||
} icns_type_t;
|
||||
|
||||
typedef struct _icns_element_t {
|
||||
icns_type_t elementType;
|
||||
icns_size_t elementSize;
|
||||
} icns_element_t;
|
||||
|
||||
typedef struct _icns_icon_info_t {
|
||||
unsigned int iconHeight;
|
||||
unsigned int iconWidth;
|
||||
unsigned int iconDepth;
|
||||
unsigned int iconChannels;
|
||||
} icns_icon_info_t;
|
||||
|
||||
typedef struct _icns_image_t {
|
||||
unsigned int imageWidth;
|
||||
unsigned int imageHeight;
|
||||
unsigned int imageChannels;
|
||||
unsigned int imagePixelDepth;
|
||||
unsigned int imageDataSize;
|
||||
icns_byte_t *imageData;
|
||||
} icns_image_t;
|
||||
|
||||
typedef struct _icns_family_t {
|
||||
icns_type_t resourceType;
|
||||
icns_size_t resourceSize;
|
||||
icns_element_t elements[1];
|
||||
} icns_family_t;
|
||||
|
||||
#define ICNS_HEADER_SIZE 8
|
||||
|
||||
/*
|
||||
// ics# 0x69637323
|
||||
static icns_type_t ICNS_16x16_1BIT_DATA = {{'i', 'c', 's', '#'}};
|
||||
|
||||
// ich# 0x69636823
|
||||
static icns_type_t ICNS_48x48_1BIT_DATA = {{'i', 'c', 'h', '#'}};
|
||||
*/
|
||||
|
||||
// is32 0x69733332
|
||||
static icns_type_t ICNS_16x16_32BIT_DATA = {{'i', 's', '3', '2'}};
|
||||
|
||||
// il32 0x696c3332
|
||||
static icns_type_t ICNS_32x32_32BIT_DATA = {{'i', 'l', '3', '2'}};
|
||||
|
||||
// ih32 0x69683332
|
||||
static icns_type_t ICNS_48x48_32BIT_DATA = {{'i', 'h', '3', '2'}};
|
||||
|
||||
// it32 0x69743332
|
||||
static icns_type_t ICNS_128X128_32BIT_DATA = {{'i', 't', '3', '2'}};
|
||||
|
||||
// s8mk 0x73386d6b
|
||||
static icns_type_t ICNS_16x16_8BIT_MASK = {{'s', '8', 'm', 'k'}};
|
||||
|
||||
// l8mk 0x6c386d6b
|
||||
static icns_type_t ICNS_32x32_8BIT_MASK = {{'l', '8', 'm', 'k'}};
|
||||
|
||||
// h8mk 0x68386d6b
|
||||
static icns_type_t ICNS_48x48_8BIT_MASK = {{'h', '8', 'm', 'k'}};
|
||||
|
||||
// t8mk 0x74386d6b
|
||||
static icns_type_t ICNS_128X128_8BIT_MASK = {{'t', '8', 'm', 'k'}};
|
||||
|
||||
static icns_type_t ICNS_FAMILY_TYPE = {{'i','c','n','s'}};
|
||||
|
||||
static icns_type_t ICNS_NULL_TYPE = {{0 , 0 , 0 , 0 }};
|
||||
|
||||
#define ICNS_STATUS_OK 0
|
||||
|
||||
static int icns_types_equal(icns_type_t type1, icns_type_t type2)
|
||||
{
|
||||
return (strncmp((char*)&type1.c, (char*)&type2.c, 4) == 0);
|
||||
}
|
||||
|
||||
static icns_type_t icns_get_mask_type_for_icon_type(icns_type_t type)
|
||||
{
|
||||
if (icns_types_equal(type, ICNS_16x16_32BIT_DATA))
|
||||
{
|
||||
return ICNS_16x16_8BIT_MASK;
|
||||
}
|
||||
else if (icns_types_equal(type, ICNS_32x32_32BIT_DATA))
|
||||
{
|
||||
return ICNS_32x32_8BIT_MASK;
|
||||
}
|
||||
else if (icns_types_equal(type, ICNS_48x48_32BIT_DATA))
|
||||
{
|
||||
return ICNS_48x48_8BIT_MASK;
|
||||
}
|
||||
else if (icns_types_equal(type, ICNS_128X128_32BIT_DATA))
|
||||
{
|
||||
return ICNS_128X128_8BIT_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ICNS_NULL_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
static icns_icon_info_t icns_get_image_info_for_type(icns_type_t type)
|
||||
{
|
||||
icns_icon_info_t info;
|
||||
|
||||
if (icns_types_equal(type, ICNS_16x16_32BIT_DATA))
|
||||
{
|
||||
info.iconHeight = 16;
|
||||
info.iconWidth = 16;
|
||||
info.iconDepth = 8;
|
||||
info.iconChannels = 4;
|
||||
}
|
||||
else if (icns_types_equal(type, ICNS_32x32_32BIT_DATA))
|
||||
{
|
||||
info.iconHeight = 32;
|
||||
info.iconWidth = 32;
|
||||
info.iconDepth = 8;
|
||||
info.iconChannels = 4;
|
||||
}
|
||||
else if (icns_types_equal(type, ICNS_48x48_32BIT_DATA))
|
||||
{
|
||||
info.iconHeight = 48;
|
||||
info.iconWidth = 48;
|
||||
info.iconDepth = 8;
|
||||
info.iconChannels = 4;
|
||||
}
|
||||
else if (icns_types_equal(type, ICNS_128X128_32BIT_DATA))
|
||||
{
|
||||
info.iconHeight = 128;
|
||||
info.iconWidth = 128;
|
||||
info.iconDepth = 8;
|
||||
info.iconChannels = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.iconHeight = 0;
|
||||
info.iconWidth = 0;
|
||||
info.iconDepth = 0;
|
||||
info.iconChannels = 0;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static int icns_get_element_from_family(icns_family_t *iconFamily,
|
||||
icns_type_t iconType,
|
||||
icns_element_t **iconElement)
|
||||
{
|
||||
icns_byte_t *bytes = (icns_byte_t *)iconFamily->elements;
|
||||
unsigned long size = iconFamily->resourceSize;
|
||||
icns_element_t *element;
|
||||
icns_byte_t *data;
|
||||
|
||||
data = bytes;
|
||||
element = (icns_element_t *)data;
|
||||
while ((bytes + size > data) && element->elementSize)
|
||||
{
|
||||
if (icns_types_equal(element->elementType, iconType))
|
||||
{
|
||||
*iconElement = element;
|
||||
return ICNS_STATUS_OK;
|
||||
}
|
||||
data += element->elementSize;
|
||||
element = (icns_element_t *)data;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int icns_import_family_data(int size, icns_byte_t *bytes,
|
||||
icns_family_t **iconFamily)
|
||||
{
|
||||
icns_element_t *element = NULL;
|
||||
icns_family_t *family;
|
||||
unsigned long el_size;
|
||||
icns_byte_t *data;
|
||||
icns_byte_t *end;
|
||||
|
||||
data = bytes;
|
||||
family = (icns_family_t *)data;
|
||||
while ((bytes + size > data) && family->resourceSize)
|
||||
{
|
||||
if (icns_types_equal(family->resourceType, ICNS_FAMILY_TYPE))
|
||||
{
|
||||
element = (icns_element_t *)family;
|
||||
break;
|
||||
}
|
||||
el_size = NSSwapBigIntToHost(family->resourceSize);
|
||||
data += el_size;
|
||||
family = (icns_family_t *)data;
|
||||
}
|
||||
if (element == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
el_size = NSSwapBigIntToHost(element->elementSize);
|
||||
family = malloc(el_size);
|
||||
if (!family)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
strncpy((char*)&family->resourceType.c, (char*)&element->elementType.c, 4);
|
||||
family->resourceSize = el_size;
|
||||
memcpy((char*)(family->elements),
|
||||
(char*)element + ICNS_HEADER_SIZE,
|
||||
el_size - ICNS_HEADER_SIZE);
|
||||
|
||||
data = (icns_byte_t *)family->elements;
|
||||
end = data + el_size - ICNS_HEADER_SIZE;
|
||||
element = family->elements;
|
||||
while ((data < end) && element->elementSize)
|
||||
{
|
||||
el_size = NSSwapBigIntToHost(element->elementSize);
|
||||
element->elementSize = el_size;
|
||||
data += el_size;
|
||||
element = (icns_element_t *)data;
|
||||
}
|
||||
|
||||
*iconFamily = family;
|
||||
|
||||
return ICNS_STATUS_OK;
|
||||
}
|
||||
|
||||
static int icns_init_image(unsigned int iconWidth,
|
||||
unsigned int iconHeight,
|
||||
unsigned int iconChannels,
|
||||
unsigned int iconPixelDepth,
|
||||
icns_image_t *imageOut)
|
||||
{
|
||||
imageOut->imageWidth = iconWidth;
|
||||
imageOut->imageHeight = iconHeight;
|
||||
imageOut->imageChannels = iconChannels;
|
||||
imageOut->imagePixelDepth = iconPixelDepth;
|
||||
imageOut->imageDataSize = (iconHeight * iconWidth
|
||||
* iconPixelDepth * iconChannels) / 8;
|
||||
imageOut->imageData = malloc(imageOut->imageDataSize);
|
||||
if (!imageOut->imageData)
|
||||
return 1;
|
||||
else
|
||||
return ICNS_STATUS_OK;
|
||||
}
|
||||
|
||||
static int icns_init_image_for_type(icns_type_t iconType,
|
||||
icns_image_t *imageOut)
|
||||
{
|
||||
icns_icon_info_t info;
|
||||
|
||||
info = icns_get_image_info_for_type(iconType);
|
||||
return icns_init_image(info.iconWidth, info.iconHeight, info.iconChannels,
|
||||
info.iconDepth, imageOut);
|
||||
}
|
||||
|
||||
static int icns_free_image(icns_image_t *imageIn)
|
||||
{
|
||||
free(imageIn->imageData);
|
||||
imageIn->imageData = NULL;
|
||||
return ICNS_STATUS_OK;
|
||||
}
|
||||
|
||||
static int icns_get_image32_with_mask_from_family(icns_family_t *iconFamily,
|
||||
icns_type_t type,
|
||||
icns_image_t *iconImage)
|
||||
{
|
||||
icns_element_t *element;
|
||||
unsigned int samplesPerPixel = 4;
|
||||
icns_byte_t *b;
|
||||
icns_byte_t *end;
|
||||
int j;
|
||||
int res;
|
||||
icns_type_t mask_type;
|
||||
unsigned int imageDataSize;
|
||||
|
||||
if (icns_types_equal(type, ICNS_NULL_TYPE))
|
||||
return 1;
|
||||
|
||||
res = icns_get_element_from_family(iconFamily, type, &element);
|
||||
if (res != ICNS_STATUS_OK)
|
||||
return res;
|
||||
|
||||
res = icns_init_image_for_type(type, iconImage);
|
||||
if (res != ICNS_STATUS_OK)
|
||||
return res;
|
||||
|
||||
b = (icns_byte_t *)element + ICNS_HEADER_SIZE;
|
||||
end = b + element->elementSize - ICNS_HEADER_SIZE;
|
||||
// Safety check
|
||||
if (end > (icns_byte_t *)iconFamily->elements + iconFamily->resourceSize)
|
||||
{
|
||||
icns_free_image(iconImage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
imageDataSize = iconImage->imageDataSize;
|
||||
if ((element->elementSize - ICNS_HEADER_SIZE) <
|
||||
3 * iconImage->imageHeight * iconImage->imageWidth)
|
||||
{
|
||||
unsigned int plane;
|
||||
|
||||
// Run length encoded planar data
|
||||
for (plane = 0; plane < 3; plane++)
|
||||
{
|
||||
unsigned int offset;
|
||||
|
||||
offset = 0;
|
||||
while ((offset < iconImage->imageHeight * iconImage->imageWidth)
|
||||
&& (b < end))
|
||||
{
|
||||
icns_byte_t bv = *b++;
|
||||
int runLen;
|
||||
unsigned int index = samplesPerPixel * offset + plane;
|
||||
|
||||
if (bv & 0x80)
|
||||
{
|
||||
// Compressed run
|
||||
icns_byte_t val = *b++;
|
||||
|
||||
runLen = bv - 125;
|
||||
for (j = 0; (j < runLen) && (index < imageDataSize); j++)
|
||||
{
|
||||
iconImage->imageData[index] = val;
|
||||
index += samplesPerPixel;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Uncompressed run
|
||||
int j;
|
||||
|
||||
runLen = bv + 1;
|
||||
for (j = 0; (j < runLen) && (index < imageDataSize); j++)
|
||||
{
|
||||
iconImage->imageData[index] = *b++;
|
||||
index += samplesPerPixel;
|
||||
}
|
||||
}
|
||||
|
||||
offset += runLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < iconImage->imageHeight * iconImage->imageWidth; j++)
|
||||
{
|
||||
iconImage->imageData[samplesPerPixel * j + 0] = *b++;
|
||||
iconImage->imageData[samplesPerPixel * j + 1] = *b++;
|
||||
iconImage->imageData[samplesPerPixel * j + 2] = *b++;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in the mask
|
||||
mask_type = icns_get_mask_type_for_icon_type(type);
|
||||
res = icns_get_element_from_family(iconFamily, mask_type, &element);
|
||||
if (res == ICNS_STATUS_OK)
|
||||
{
|
||||
b = (icns_byte_t *)element + ICNS_HEADER_SIZE;
|
||||
end = b + element->elementSize - ICNS_HEADER_SIZE;
|
||||
// Safety check
|
||||
if (end > (icns_byte_t *)iconFamily->elements + iconFamily->resourceSize)
|
||||
{
|
||||
icns_free_image(iconImage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (j = 0; j < iconImage->imageHeight * iconImage->imageWidth; j++)
|
||||
{
|
||||
iconImage->imageData[samplesPerPixel * j + 3] = *b++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < iconImage->imageHeight * iconImage->imageWidth; j++)
|
||||
{
|
||||
iconImage->imageData[samplesPerPixel * j + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
return ICNS_STATUS_OK;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_LIBICNS */
|
||||
|
||||
// Define the pixel
|
||||
typedef struct pixel_t
|
||||
{
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
} pixel_t;
|
||||
|
||||
@implementation NSBitmapImageRep (ICNS)
|
||||
|
||||
+ (BOOL) _bitmapIsICNS: (NSData *)imageData
|
||||
{
|
||||
char header[5];
|
||||
|
||||
/*
|
||||
* If the data is 0, return immediately.
|
||||
*/
|
||||
if ([imageData length] < 8)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the beginning of the data for
|
||||
* the string "icns".
|
||||
*/
|
||||
[imageData getBytes: header length: 4];
|
||||
if(strncmp(header, ICNS_HEADER, 4) == 0)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (id) _initBitmapFromICNS: (NSData *)imageData
|
||||
{
|
||||
int error = 0;
|
||||
int size = [imageData length];
|
||||
icns_byte_t *bytes = (icns_byte_t *)[imageData bytes];
|
||||
icns_family_t *iconFamily = NULL;
|
||||
unsigned long dataOffset = 0;
|
||||
icns_byte_t *data = NULL;
|
||||
icns_type_t typeStr = ICNS_NULL_TYPE;
|
||||
unsigned int iconWidth = 0, iconHeight = 0;
|
||||
icns_image_t iconImage;
|
||||
int sPP = 4;
|
||||
unsigned char *rgbBuffer = NULL; /* image converted to rgb */
|
||||
unsigned int rgbBufferPos = 0;
|
||||
unsigned int rgbBufferSize = 0;
|
||||
int i = 0, j = 0;
|
||||
int imageChannels = 0;
|
||||
|
||||
error = icns_import_family_data(size, bytes, &iconFamily);
|
||||
if(error != ICNS_STATUS_OK)
|
||||
{
|
||||
NSLog(@"Error reading ICNS data.");
|
||||
RELEASE(self);
|
||||
return nil;
|
||||
}
|
||||
|
||||
// skip the header...
|
||||
dataOffset = sizeof(icns_type_t) + sizeof(icns_size_t);
|
||||
data = (icns_byte_t *)iconFamily;
|
||||
|
||||
// read each icon...
|
||||
while (((dataOffset + 8) < iconFamily->resourceSize))
|
||||
{
|
||||
icns_element_t element;
|
||||
|
||||
memcpy(&element, (data + dataOffset), 8);
|
||||
|
||||
//
|
||||
// Temporarily limit to 48 until we can find a way to
|
||||
// utilize the other representations in the icns file.
|
||||
//
|
||||
if (icns_types_equal(element.elementType, ICNS_48x48_32BIT_DATA)
|
||||
|| (icns_types_equal(typeStr, ICNS_NULL_TYPE)
|
||||
&& (icns_types_equal(element.elementType, ICNS_32x32_32BIT_DATA)
|
||||
|| icns_types_equal(element.elementType, ICNS_128X128_32BIT_DATA))))
|
||||
{
|
||||
memcpy(&typeStr, &(element.elementType), 4);
|
||||
}
|
||||
|
||||
// next...
|
||||
dataOffset += element.elementSize;
|
||||
}
|
||||
|
||||
// extract the image...
|
||||
memset(&iconImage, 0, sizeof(icns_image_t));
|
||||
error = icns_get_image32_with_mask_from_family(iconFamily,
|
||||
typeStr,
|
||||
&iconImage);
|
||||
if (error)
|
||||
{
|
||||
NSLog(@"Error while extracting image from ICNS data.");
|
||||
RELEASE(self);
|
||||
free(iconFamily);
|
||||
return nil;
|
||||
}
|
||||
|
||||
iconWidth = iconImage.imageWidth;
|
||||
iconHeight = iconImage.imageHeight;
|
||||
|
||||
// allocate the buffer...
|
||||
rgbBufferSize = iconHeight * (iconWidth * sizeof(unsigned char) * sPP);
|
||||
rgbBuffer = NSZoneMalloc([self zone], rgbBufferSize);
|
||||
if (rgbBuffer == NULL)
|
||||
{
|
||||
NSLog(@"Couldn't allocate memory for image data from ICNS.");
|
||||
RELEASE(self);
|
||||
icns_free_image(&iconImage);
|
||||
free(iconFamily);
|
||||
return nil;
|
||||
}
|
||||
|
||||
imageChannels = iconImage.imageChannels;
|
||||
rgbBufferPos = 0;
|
||||
for (i = 0; i < iconHeight; i++)
|
||||
{
|
||||
for (j = 0; j < iconWidth; j++)
|
||||
{
|
||||
pixel_t *src_rgb_pixel;
|
||||
|
||||
src_rgb_pixel = (pixel_t *)&(iconImage.imageData[i*iconWidth*imageChannels+j*imageChannels]);
|
||||
|
||||
rgbBuffer[rgbBufferPos++] = src_rgb_pixel->r;
|
||||
rgbBuffer[rgbBufferPos++] = src_rgb_pixel->g;
|
||||
rgbBuffer[rgbBufferPos++] = src_rgb_pixel->b;
|
||||
rgbBuffer[rgbBufferPos++] = src_rgb_pixel->a;
|
||||
}
|
||||
}
|
||||
|
||||
icns_free_image(&iconImage);
|
||||
free(iconFamily);
|
||||
|
||||
/* initialize self */
|
||||
[self initWithBitmapDataPlanes: &rgbBuffer
|
||||
pixelsWide: iconWidth
|
||||
pixelsHigh: iconHeight
|
||||
bitsPerSample: 8
|
||||
samplesPerPixel: sPP
|
||||
hasAlpha: YES
|
||||
isPlanar: NO
|
||||
colorSpaceName: NSCalibratedRGBColorSpace
|
||||
// FIXME: Not sure whether this format is pre-multiplied
|
||||
bitmapFormat: NSAlphaNonpremultipliedBitmapFormat
|
||||
bytesPerRow: iconWidth * sPP
|
||||
bitsPerPixel: 8 * sPP];
|
||||
|
||||
_imageData = [[NSData alloc] initWithBytesNoCopy: rgbBuffer
|
||||
length: rgbBufferSize];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
|
@ -37,6 +37,7 @@
|
|||
#include "NSBitmapImageRep+JPEG.h"
|
||||
#include "NSBitmapImageRep+PNG.h"
|
||||
#include "NSBitmapImageRep+PNM.h"
|
||||
#include "NSBitmapImageRep+ICNS.h"
|
||||
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSAutoreleasePool.h>
|
||||
|
@ -116,6 +117,9 @@
|
|||
if ([self _bitmapIsGIF: data])
|
||||
return YES;
|
||||
|
||||
if ([self _bitmapIsICNS: data])
|
||||
return YES;
|
||||
|
||||
image = NSTiffOpenDataRead ((char *)[data bytes], [data length]);
|
||||
|
||||
if (image != NULL)
|
||||
|
@ -149,6 +153,7 @@
|
|||
#if HAVE_LIBPNG
|
||||
@"png",
|
||||
#endif
|
||||
@"icns",
|
||||
nil];
|
||||
}
|
||||
|
||||
|
@ -256,6 +261,19 @@
|
|||
return a;
|
||||
}
|
||||
|
||||
if ([self _bitmapIsICNS: imageData])
|
||||
{
|
||||
NSBitmapImageRep *rep;
|
||||
NSArray *a;
|
||||
|
||||
rep=[[self alloc] _initBitmapFromICNS: imageData];
|
||||
if (!rep)
|
||||
return [NSArray array];
|
||||
a = [NSArray arrayWithObject: rep];
|
||||
DESTROY(rep);
|
||||
return a;
|
||||
}
|
||||
|
||||
image = NSTiffOpenDataRead((char *)[imageData bytes], [imageData length]);
|
||||
if (image == NULL)
|
||||
{
|
||||
|
@ -307,6 +325,9 @@
|
|||
return [self _initBitmapFromGIF: imageData
|
||||
errorMessage: NULL];
|
||||
|
||||
if ([isa _bitmapIsICNS: imageData])
|
||||
return [self _initBitmapFromICNS: imageData];
|
||||
|
||||
|
||||
image = NSTiffOpenDataRead((char *)[imageData bytes], [imageData length]);
|
||||
if (image == NULL)
|
||||
|
@ -2126,7 +2147,11 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
|
|||
bytesPerRow: rowBytes
|
||||
bitsPerPixel: pixelBits];
|
||||
|
||||
if ([_colorSpace isEqualToString: colorSpaceName])
|
||||
if ([_colorSpace isEqualToString: colorSpaceName] ||
|
||||
([_colorSpace isEqualToString: NSDeviceRGBColorSpace] &&
|
||||
[colorSpaceName isEqualToString: NSCalibratedRGBColorSpace]) ||
|
||||
([colorSpaceName isEqualToString: NSDeviceRGBColorSpace] &&
|
||||
[_colorSpace isEqualToString: NSCalibratedRGBColorSpace]))
|
||||
{
|
||||
SEL getPSel = @selector(getPixel:atX:y:);
|
||||
SEL setPSel = @selector(setPixel:atX:y:);
|
||||
|
@ -2137,7 +2162,8 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
|
|||
float _scale;
|
||||
float scale;
|
||||
|
||||
NSDebugLLog(@"NSImage", @"Converting %@ bitmap data", colorSpaceName);
|
||||
NSDebugLLog(@"NSImage", @"Converting %@ bitmap data", _colorSpace);
|
||||
|
||||
if (_bitsPerSample != bps)
|
||||
{
|
||||
_scale = (float)((1 << _bitsPerSample) - 1);
|
||||
|
@ -2393,7 +2419,8 @@ _set_bit_value(unsigned char *base, long msb_off, int bit_width,
|
|||
IMP setC = [new methodForSelector: setCSel];
|
||||
int i, j;
|
||||
|
||||
NSDebugLLog(@"NSImage", @"Slow converting %@ bitmap data", colorSpaceName);
|
||||
NSDebugLLog(@"NSImage", @"Slow converting %@ bitmap data to %@",
|
||||
_colorSpace, colorSpaceName);
|
||||
for (j = 0; j < _pixelsHigh; j++)
|
||||
{
|
||||
CREATE_AUTORELEASE_POOL(pool);
|
||||
|
|
|
@ -212,6 +212,7 @@ static NSTextFieldCell *titleCell;
|
|||
inView: (NSView*)controlView
|
||||
{
|
||||
[[GSTheme theme] drawGrayBezel: cellFrame withClip: NSZeroRect];
|
||||
[self _drawBackgroundWithFrame: cellFrame inView: controlView];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -1304,6 +1305,7 @@ static NSTextFieldCell *titleCell;
|
|||
{
|
||||
float cw;
|
||||
|
||||
cw = columnWidth;
|
||||
// Take the border into account
|
||||
if (_separatesColumns)
|
||||
cw -= 2 * (_sizeForBorderType(NSBezelBorder)).width;
|
||||
|
@ -1453,9 +1455,10 @@ static NSTextFieldCell *titleCell;
|
|||
if (!_isTitled || !NSBR_COLUMN_IS_VISIBLE(column))
|
||||
return;
|
||||
|
||||
[titleCell setControlView: self];
|
||||
// [titleCell setControlView: self];
|
||||
[titleCell setStringValue: title];
|
||||
[titleCell drawWithFrame: aRect inView: self];
|
||||
[titleCell setControlView: nil];
|
||||
}
|
||||
|
||||
/** <p>Returns the height of column titles. The Nextish look returns 21.</p>
|
||||
|
@ -3226,4 +3229,9 @@ static NSTextFieldCell *titleCell;
|
|||
}
|
||||
}
|
||||
|
||||
- (void) setNeedsDisplayInRect: (NSRect)invalidRect
|
||||
{
|
||||
[super setNeedsDisplayInRect: invalidRect];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -174,13 +174,6 @@
|
|||
[self label]];
|
||||
return desc;
|
||||
}
|
||||
|
||||
- (void) instantiateWithInstantiator: (id<GSInstantiator>)instantiator
|
||||
{
|
||||
_src = [instantiator instantiateObject: _src];
|
||||
_dst = [instantiator instantiateObject: _dst];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSNibControlConnector
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
#include "AppKit/NSSound.h"
|
||||
#include "AppKit/NSWindow.h"
|
||||
#include "GNUstepGUI/GSTheme.h"
|
||||
#include "GNUstepGUI/GSNibCompatibility.h"
|
||||
#include "GNUstepGUI/GSNibLoading.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
@ -433,18 +433,12 @@ typedef struct _GSButtonCellFlags
|
|||
|
||||
- (void) setImage: (NSImage *)anImage
|
||||
{
|
||||
if (anImage)
|
||||
{
|
||||
NSAssert ([anImage isKindOfClass: [NSImage class]],
|
||||
NSInvalidArgumentException);
|
||||
}
|
||||
|
||||
if (_cell.image_position == NSNoImage)
|
||||
{
|
||||
[self setImagePosition: NSImageOnly];
|
||||
}
|
||||
|
||||
ASSIGN (_cell_image, anImage);
|
||||
[super setImage: anImage];
|
||||
}
|
||||
|
||||
/**<p>Sets the NSButtonCell's alternate image to <var>anImage</var>.</p>
|
||||
|
@ -929,6 +923,14 @@ typedef struct _GSButtonCellFlags
|
|||
- (void) _drawBorderAndBackgroundWithFrame: (NSRect)cellFrame
|
||||
inView: (NSView*)controlView
|
||||
{
|
||||
// Draw gradient
|
||||
if (!_cell.is_highlighted)
|
||||
{
|
||||
[[GSTheme theme] drawGradientBorder: _gradient_type
|
||||
inRect: cellFrame
|
||||
withClip: NSZeroRect];
|
||||
}
|
||||
|
||||
// The inside check could also be done via a track rect, but then this would
|
||||
// only work with specially prepared controls. Therefore we dont use
|
||||
// _mouse_inside here.
|
||||
|
@ -941,105 +943,6 @@ typedef struct _GSButtonCellFlags
|
|||
}
|
||||
}
|
||||
|
||||
- (void) drawGradientWithFrame: (NSRect)cellFrame inView: (NSView *)controlView
|
||||
{
|
||||
float start_white = 0.0;
|
||||
float end_white = 0.0;
|
||||
float white = 0.0;
|
||||
float white_step = 0.0;
|
||||
float h, s, v, a;
|
||||
NSColor *lightGray = nil;
|
||||
NSColor *gray = nil;
|
||||
NSColor *darkGray = nil;
|
||||
NSPoint p1, p2;
|
||||
|
||||
lightGray = [NSColor colorWithDeviceRed:0.83 green:0.83 blue:0.83 alpha:1.0];
|
||||
gray = [NSColor colorWithDeviceRed:0.50 green:0.50 blue:0.50 alpha:1.0];
|
||||
darkGray = [NSColor colorWithDeviceRed:0.32 green:0.32 blue:0.32 alpha:1.0];
|
||||
|
||||
switch (_gradient_type)
|
||||
{
|
||||
case NSGradientNone:
|
||||
return;
|
||||
break;
|
||||
|
||||
case NSGradientConcaveWeak:
|
||||
[gray getHue: &h saturation: &s brightness: &v alpha: &a];
|
||||
start_white = [lightGray brightnessComponent];
|
||||
end_white = [gray brightnessComponent];
|
||||
break;
|
||||
|
||||
case NSGradientConvexWeak:
|
||||
[darkGray getHue: &h saturation: &s brightness: &v alpha: &a];
|
||||
start_white = [gray brightnessComponent];
|
||||
end_white = [lightGray brightnessComponent];
|
||||
break;
|
||||
|
||||
case NSGradientConcaveStrong:
|
||||
[lightGray getHue: &h saturation: &s brightness: &v alpha: &a];
|
||||
start_white = [lightGray brightnessComponent];
|
||||
end_white = [darkGray brightnessComponent];
|
||||
break;
|
||||
|
||||
case NSGradientConvexStrong:
|
||||
[darkGray getHue: &h saturation: &s brightness: &v alpha: &a];
|
||||
start_white = [darkGray brightnessComponent];
|
||||
end_white = [lightGray brightnessComponent];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
white = start_white;
|
||||
white_step = fabs(start_white - end_white)
|
||||
/ (cellFrame.size.width + cellFrame.size.height);
|
||||
|
||||
// Start from top left
|
||||
p1 = NSMakePoint(cellFrame.origin.x,
|
||||
cellFrame.size.height + cellFrame.origin.y);
|
||||
p2 = NSMakePoint(cellFrame.origin.x,
|
||||
cellFrame.size.height + cellFrame.origin.y);
|
||||
|
||||
// Move by Y
|
||||
while (p1.y > cellFrame.origin.y)
|
||||
{
|
||||
[[NSColor
|
||||
colorWithDeviceHue: h saturation: s brightness: white alpha: 1.0] set];
|
||||
[NSBezierPath strokeLineFromPoint: p1 toPoint: p2];
|
||||
|
||||
if (start_white > end_white)
|
||||
white -= white_step;
|
||||
else
|
||||
white += white_step;
|
||||
|
||||
p1.y -= 1.0;
|
||||
if (p2.x < (cellFrame.size.width + cellFrame.origin.x))
|
||||
p2.x += 1.0;
|
||||
else
|
||||
p2.y -= 1.0;
|
||||
}
|
||||
|
||||
// Move by X
|
||||
while (p1.x < (cellFrame.size.width + cellFrame.origin.x))
|
||||
{
|
||||
[[NSColor
|
||||
colorWithDeviceHue: h saturation: s brightness: white alpha: 1.0] set];
|
||||
[NSBezierPath strokeLineFromPoint: p1 toPoint: p2];
|
||||
|
||||
if (start_white > end_white)
|
||||
white -= white_step;
|
||||
else
|
||||
white += white_step;
|
||||
|
||||
p1.x += 1.0;
|
||||
if (p2.x >= (cellFrame.size.width + cellFrame.origin.x))
|
||||
p2.y -= 1.0;
|
||||
else
|
||||
p2.x += 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView*)controlView
|
||||
{
|
||||
unsigned mask;
|
||||
|
@ -1275,13 +1178,6 @@ typedef struct _GSButtonCellFlags
|
|||
break;
|
||||
}
|
||||
|
||||
// Draw gradient
|
||||
if (!_cell.is_highlighted && _gradient_type != NSGradientNone)
|
||||
{
|
||||
// FIXME: I think this method is wrong.
|
||||
[self drawGradientWithFrame: cellFrame inView: controlView];
|
||||
}
|
||||
|
||||
// Draw image
|
||||
if (imageToDisplay != nil)
|
||||
{
|
||||
|
|
|
@ -32,11 +32,16 @@
|
|||
using the rect information.
|
||||
*/
|
||||
|
||||
// for fabs()
|
||||
#include <math.h>
|
||||
|
||||
#include "config.h"
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
|
||||
#include "AppKit/NSAffineTransform.h"
|
||||
#include "AppKit/NSBitmapImageRep.h"
|
||||
#include "AppKit/NSCachedImageRep.h"
|
||||
#include "AppKit/NSView.h"
|
||||
#include "AppKit/NSWindow.h"
|
||||
|
@ -166,8 +171,40 @@
|
|||
|
||||
- (BOOL) draw
|
||||
{
|
||||
PScomposite(NSMinX(_rect), NSMinY(_rect), NSWidth(_rect), NSHeight(_rect),
|
||||
[_window gState], 0, 0, NSCompositeSourceOver);
|
||||
/*
|
||||
FIXME: Horrible hack to get drawing on a scaled or rotated
|
||||
context correct. We need another interface with the backend
|
||||
to do it properly.
|
||||
*/
|
||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||
NSAffineTransform *transform;
|
||||
NSAffineTransformStruct ts;
|
||||
|
||||
// Is there anything to draw?
|
||||
if (NSIsEmptyRect(_rect))
|
||||
return YES;
|
||||
|
||||
transform = [ctxt GSCurrentCTM];
|
||||
ts = [transform transformStruct];
|
||||
|
||||
if (fabs(ts.m11 - 1.0) < 0.01 && fabs(ts.m12) < 0.01
|
||||
&& fabs(ts.m21) < 0.01 && fabs(ts.m22 - 1.0) < 0.01)
|
||||
{
|
||||
PScomposite(NSMinX(_rect), NSMinY(_rect), NSWidth(_rect), NSHeight(_rect),
|
||||
[_window gState], 0, 0, NSCompositeSourceOver);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSView *view = [_window contentView];
|
||||
NSBitmapImageRep *rep;
|
||||
|
||||
[view lockFocus];
|
||||
rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect: _rect];
|
||||
[view unlockFocus];
|
||||
|
||||
[rep draw];
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,6 @@ static Class imageClass;
|
|||
|
||||
static NSColor *txtCol;
|
||||
static NSColor *dtxtCol;
|
||||
static NSColor *shadowCol;
|
||||
|
||||
@interface NSCell (PrivateColor)
|
||||
+ (void) _systemColorsChanged: (NSNotification*)n;
|
||||
|
@ -83,7 +82,6 @@ static NSColor *shadowCol;
|
|||
{
|
||||
ASSIGN (txtCol, [colorClass controlTextColor]);
|
||||
ASSIGN (dtxtCol, [colorClass disabledControlTextColor]);
|
||||
ASSIGN (shadowCol, [colorClass controlDarkShadowColor]);
|
||||
}
|
||||
@end
|
||||
|
||||
|
@ -1763,14 +1761,17 @@ static NSColor *shadowCol;
|
|||
- (NSSize) cellSize
|
||||
{
|
||||
NSSize borderSize, s;
|
||||
|
||||
NSBorderType aType;
|
||||
|
||||
// Get border size
|
||||
if (_cell.is_bordered)
|
||||
borderSize = _sizeForBorderType (NSLineBorder);
|
||||
aType = NSLineBorder;
|
||||
else if (_cell.is_bezeled)
|
||||
borderSize = _sizeForBorderType (NSBezelBorder);
|
||||
aType = NSBezelBorder;
|
||||
else
|
||||
borderSize = NSZeroSize;
|
||||
aType = NSNoBorder;
|
||||
|
||||
borderSize = [[GSTheme theme] sizeForBorderType: aType];
|
||||
|
||||
// Add spacing between border and inside
|
||||
if (_cell.is_bordered || _cell.is_bezeled)
|
||||
|
@ -1841,15 +1842,17 @@ static NSColor *shadowCol;
|
|||
- (NSRect) drawingRectForBounds: (NSRect)theRect
|
||||
{
|
||||
NSSize borderSize;
|
||||
NSBorderType aType;
|
||||
|
||||
// Get border size
|
||||
if (_cell.is_bordered)
|
||||
borderSize = _sizeForBorderType (NSLineBorder);
|
||||
aType = NSLineBorder;
|
||||
else if (_cell.is_bezeled)
|
||||
borderSize = _sizeForBorderType (NSBezelBorder);
|
||||
aType = NSBezelBorder;
|
||||
else
|
||||
borderSize = NSZeroSize;
|
||||
|
||||
aType = NSNoBorder;
|
||||
|
||||
borderSize = [[GSTheme theme] sizeForBorderType: aType];
|
||||
return NSInsetRect(theRect, borderSize.width, borderSize.height);
|
||||
}
|
||||
|
||||
|
@ -2814,15 +2817,17 @@ static NSColor *shadowCol;
|
|||
- (void) _drawBorderAndBackgroundWithFrame: (NSRect)cellFrame
|
||||
inView: (NSView*)controlView
|
||||
{
|
||||
NSBorderType aType;
|
||||
|
||||
// Get border size
|
||||
if (_cell.is_bordered)
|
||||
{
|
||||
[shadowCol set];
|
||||
NSFrameRect(cellFrame);
|
||||
}
|
||||
aType = NSLineBorder;
|
||||
else if (_cell.is_bezeled)
|
||||
{
|
||||
[[GSTheme theme] drawWhiteBezel: cellFrame withClip: NSZeroRect];
|
||||
}
|
||||
aType = NSBezelBorder;
|
||||
else
|
||||
aType = NSNoBorder;
|
||||
|
||||
[[GSTheme theme] drawBorderType: aType frame: cellFrame view: controlView];
|
||||
}
|
||||
|
||||
// Private helper method
|
||||
|
@ -2855,23 +2860,3 @@ static NSColor *shadowCol;
|
|||
}
|
||||
|
||||
@end
|
||||
|
||||
/*
|
||||
* Global function which should go somewhere else
|
||||
*/
|
||||
inline NSSize
|
||||
_sizeForBorderType (NSBorderType aType)
|
||||
{
|
||||
// Returns the size of a border
|
||||
switch (aType)
|
||||
{
|
||||
case NSLineBorder:
|
||||
return NSMakeSize(1, 1);
|
||||
case NSGrooveBorder:
|
||||
case NSBezelBorder:
|
||||
return NSMakeSize(2, 2);
|
||||
case NSNoBorder:
|
||||
default:
|
||||
return NSZeroSize;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include <Foundation/NSNotification.h>
|
||||
#include <Foundation/NSException.h>
|
||||
|
||||
#include "AppKit/NSClipView.h"
|
||||
#include "AppKit/NSCursor.h"
|
||||
|
@ -38,6 +39,8 @@
|
|||
#include "AppKit/NSWindow.h"
|
||||
#include "AppKit/PSOperators.h"
|
||||
|
||||
#include <GNUstepGUI/GSNibLoading.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
DEFINE_RINT_IF_MISSING
|
||||
|
@ -789,6 +792,9 @@ static inline NSRect integralRect (NSRect rect, NSView *view)
|
|||
if ([[self subviews] count] > 0)
|
||||
{
|
||||
id document = [aDecoder decodeObjectForKey: @"NSDocView"];
|
||||
|
||||
NSAssert([document class] != [NSCustomView class],
|
||||
NSInvalidArgumentException);
|
||||
NSRect rect = [document frame];
|
||||
rect.origin = NSZeroPoint;
|
||||
[document setFrame: rect];
|
||||
|
|
|
@ -971,7 +971,11 @@ static NSNotificationCenter *nc;
|
|||
|
||||
- (id) initWithCoder: (NSCoder*)aDecoder
|
||||
{
|
||||
[super initWithCoder: aDecoder];
|
||||
self = [super initWithCoder: aDecoder];
|
||||
if (self == nil)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ([aDecoder allowsKeyedCoding])
|
||||
{
|
||||
|
@ -981,6 +985,15 @@ static NSNotificationCenter *nc;
|
|||
{
|
||||
[self setCell: cell];
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is needed for subclasses without cells, like NSColorWeel
|
||||
// as we store some properties only on the cell.
|
||||
NSCell *cell = [[[self class] cellClass] new];
|
||||
|
||||
[self setCell: cell];
|
||||
RELEASE(cell);
|
||||
}
|
||||
if ([aDecoder containsValueForKey: @"NSEnabled"])
|
||||
{
|
||||
[self setEnabled: [aDecoder decodeBoolForKey: @"NSEnabled"]];
|
||||
|
|
|
@ -140,13 +140,17 @@ withContentsOfURL: (NSURL *)url
|
|||
self = [self initWithType: type error: error];
|
||||
if (self != nil)
|
||||
{
|
||||
[self setFileType: type];
|
||||
if (forUrl)
|
||||
[self setFileURL: forUrl];
|
||||
if ([self readFromURL: url
|
||||
ofType: type
|
||||
error: error])
|
||||
{
|
||||
if (forUrl != nil)
|
||||
if (![url isEqual:forUrl])
|
||||
{
|
||||
[self setFileURL: forUrl];
|
||||
[self setAutosavedContentsFileURL: url];
|
||||
[self updateChangeCount: NSChangeReadOtherContents];
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -311,6 +315,7 @@ withContentsOfURL: (NSURL *)url
|
|||
if ([windowController document] != self)
|
||||
{
|
||||
[windowController setDocument: self];
|
||||
[windowController setDocumentEdited: [self isDocumentEdited]];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,6 +323,7 @@ withContentsOfURL: (NSURL *)url
|
|||
{
|
||||
if ([_window_controllers containsObject: windowController])
|
||||
{
|
||||
[windowController setDocumentEdited: NO];
|
||||
[windowController setDocument: nil];
|
||||
[_window_controllers removeObject: windowController];
|
||||
}
|
||||
|
@ -388,7 +394,7 @@ withContentsOfURL: (NSURL *)url
|
|||
|
||||
- (BOOL) isDocumentEdited
|
||||
{
|
||||
return _change_count != 0;
|
||||
return _change_count != 0 || _doc_flags.permanently_modified;
|
||||
}
|
||||
|
||||
- (void)updateChangeCount: (NSDocumentChangeType)change
|
||||
|
@ -398,17 +404,22 @@ withContentsOfURL: (NSURL *)url
|
|||
|
||||
switch (change)
|
||||
{
|
||||
case NSChangeDone: _change_count++;
|
||||
case NSChangeDone: _change_count++;
|
||||
_autosave_change_count++;
|
||||
break;
|
||||
case NSChangeUndone: _change_count--;
|
||||
_autosave_change_count--;
|
||||
break;
|
||||
case NSChangeReadOtherContents:
|
||||
_doc_flags.permanently_modified = 1;
|
||||
break;
|
||||
case NSChangeCleared: _change_count = 0;
|
||||
_autosave_change_count = 0;
|
||||
_doc_flags.permanently_modified = 0;
|
||||
_doc_flags.autosave_permanently_modified = 0;
|
||||
break;
|
||||
case NSChangeAutosaved: _autosave_change_count = 0;
|
||||
_doc_flags.autosave_permanently_modified = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -766,47 +777,38 @@ withContentsOfURL: (NSURL *)url
|
|||
|
||||
if (fileName && isNativeType)
|
||||
{
|
||||
NSArray *extensions = [[NSDocumentController sharedDocumentController]
|
||||
fileExtensionsFromType: fileType];
|
||||
|
||||
if ([extensions count] > 0)
|
||||
if ([fileManager fileExistsAtPath: fileName])
|
||||
{
|
||||
NSString *extension = [extensions objectAtIndex: 0];
|
||||
NSString *newFileName = [[fileName stringByDeletingPathExtension]
|
||||
stringByAppendingPathExtension: extension];
|
||||
backupFilename = [self _backupFileNameFor: fileName];
|
||||
|
||||
if ([fileManager fileExistsAtPath: newFileName])
|
||||
if (![self _writeBackupForFile: fileName
|
||||
toFile: backupFilename])
|
||||
{
|
||||
backupFilename = [self _backupFileNameFor: newFileName];
|
||||
|
||||
if (![self _writeBackupForFile: newFileName
|
||||
toFile: backupFilename])
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
if ([self writeToFile: fileName
|
||||
ofType: fileType
|
||||
originalFile: backupFilename
|
||||
saveOperation: saveOp])
|
||||
if ([self writeToFile: fileName
|
||||
ofType: fileType
|
||||
originalFile: backupFilename
|
||||
saveOperation: saveOp])
|
||||
{
|
||||
// FIXME: Should set the file attributes
|
||||
|
||||
if (saveOp != NSSaveToOperation)
|
||||
{
|
||||
// FIXME: Should set the file attributes
|
||||
|
||||
if (saveOp != NSSaveToOperation)
|
||||
{
|
||||
[self setFileName: newFileName];
|
||||
[self setFileType: fileType];
|
||||
[self updateChangeCount: NSChangeCleared];
|
||||
}
|
||||
|
||||
if (backupFilename && ![self keepBackupFile])
|
||||
{
|
||||
[fileManager removeFileAtPath: backupFilename handler: nil];
|
||||
}
|
||||
|
||||
return YES;
|
||||
[self _removeAutosavedContentsFile];
|
||||
[self setFileName: fileName];
|
||||
[self setFileType: fileType];
|
||||
[self updateChangeCount: NSChangeCleared];
|
||||
}
|
||||
|
||||
if (backupFilename && ![self keepBackupFile])
|
||||
{
|
||||
[fileManager removeFileAtPath: backupFilename handler: nil];
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -848,14 +850,14 @@ withContentsOfURL: (NSURL *)url
|
|||
{
|
||||
if ([url isFileURL])
|
||||
{
|
||||
NSString *newFileName;
|
||||
NSString *fileName;
|
||||
|
||||
newFileName = [url path];
|
||||
if ([fileManager fileExistsAtPath: newFileName])
|
||||
fileName = [url path];
|
||||
if ([fileManager fileExistsAtPath: fileName])
|
||||
{
|
||||
backupFilename = [self _backupFileNameFor: newFileName];
|
||||
backupFilename = [self _backupFileNameFor: fileName];
|
||||
|
||||
if (![self _writeBackupForFile: newFileName
|
||||
if (![self _writeBackupForFile: fileName
|
||||
toFile: backupFilename])
|
||||
{
|
||||
// FIXME: Set error.
|
||||
|
@ -882,8 +884,14 @@ withContentsOfURL: (NSURL *)url
|
|||
error: error];
|
||||
// FIXME: Should set the file attributes
|
||||
|
||||
if (saveOp != NSSaveToOperation)
|
||||
if (saveOp == NSAutosaveOperation)
|
||||
{
|
||||
[self setAutosavedContentsFileURL: url];
|
||||
[self updateChangeCount: NSChangeAutosaved];
|
||||
}
|
||||
else if (saveOp != NSSaveToOperation)
|
||||
{
|
||||
[self _removeAutosavedContentsFile];
|
||||
[self setFileURL: url];
|
||||
[self setFileType: type];
|
||||
[self updateChangeCount: NSChangeCleared];
|
||||
|
@ -956,10 +964,7 @@ originalContentsURL: (NSURL *)orig
|
|||
ASSIGN(_save_type, [controller _nameForHumanReadableType:
|
||||
[sender titleOfSelectedItem]]);
|
||||
extensions = [controller fileExtensionsFromType: _save_type];
|
||||
if ([extensions count] > 0)
|
||||
{
|
||||
[(NSSavePanel *)[sender window] setRequiredFileType: [extensions objectAtIndex:0]];
|
||||
}
|
||||
[(NSSavePanel *)[sender window] setAllowedFileTypes: extensions];
|
||||
}
|
||||
|
||||
- (int)runModalSavePanel: (NSSavePanel *)savePanel
|
||||
|
@ -1083,10 +1088,7 @@ originalContentsURL: (NSURL *)orig
|
|||
{
|
||||
NSArray *extensions = [[NSDocumentController sharedDocumentController]
|
||||
fileExtensionsFromType: [self fileType]];
|
||||
if ([extensions count] > 0)
|
||||
{
|
||||
[savePanel setRequiredFileType:[extensions objectAtIndex:0]];
|
||||
}
|
||||
[savePanel setAllowedFileTypes: extensions];
|
||||
}
|
||||
|
||||
switch (saveOperation)
|
||||
|
@ -1319,46 +1321,6 @@ originalContentsURL: (NSURL *)orig
|
|||
{
|
||||
result = ([self fileName] != nil && [self isDocumentEdited]);
|
||||
}
|
||||
else if (sel_eq(action, @selector(undo:)))
|
||||
{
|
||||
if (_undo_manager == nil)
|
||||
{
|
||||
result = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([_undo_manager canUndo])
|
||||
{
|
||||
[anItem setTitle: [_undo_manager undoMenuItemTitle]];
|
||||
result = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
[anItem setTitle: [_undo_manager undoMenuTitleForUndoActionName: @""]];
|
||||
result = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sel_eq(action, @selector(redo:)))
|
||||
{
|
||||
if (_undo_manager == nil)
|
||||
{
|
||||
result = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([_undo_manager canRedo])
|
||||
{
|
||||
[anItem setTitle: [_undo_manager redoMenuItemTitle]];
|
||||
result = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
[anItem setTitle: [_undo_manager redoMenuTitleForUndoActionName: @""]];
|
||||
result = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1536,6 +1498,8 @@ originalContentsURL: (NSURL *)orig
|
|||
error: &error])
|
||||
{
|
||||
[self updateChangeCount: NSChangeCleared];
|
||||
[[self undoManager] removeAllActions];
|
||||
[self _removeAutosavedContentsFile];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1565,6 +1529,7 @@ originalContentsURL: (NSURL *)orig
|
|||
while (count-- > 0)
|
||||
[array[count] close];
|
||||
}
|
||||
[self _removeAutosavedContentsFile];
|
||||
[[NSDocumentController sharedDocumentController] removeDocument: self];
|
||||
}
|
||||
}
|
||||
|
@ -1671,14 +1636,40 @@ originalContentsURL: (NSURL *)orig
|
|||
- (void)setAutosavedContentsFileURL: (NSURL *)url
|
||||
{
|
||||
ASSIGN(_autosaved_file_url, url);
|
||||
[[NSDocumentController sharedDocumentController]
|
||||
_recordAutosavedDocument: self];
|
||||
}
|
||||
|
||||
- (void)autosaveDocumentWithDelegate: (id)delegate
|
||||
didAutosaveSelector: (SEL)didAutosaveSelector
|
||||
contextInfo: (void *)context
|
||||
{
|
||||
[self saveToURL: [self autosavedContentsFileURL]
|
||||
ofType: [self autosavingFileType]
|
||||
NSURL *url = [self autosavedContentsFileURL];
|
||||
NSString *type = [self autosavingFileType];
|
||||
NSArray *exts =
|
||||
[[NSDocumentController sharedDocumentController]
|
||||
fileExtensionsFromType: type];
|
||||
NSString *ext = [exts count] ? (NSString *)[exts objectAtIndex: 0] : @"";
|
||||
|
||||
if (url == nil)
|
||||
{
|
||||
static NSString *processName = nil;
|
||||
NSString *path;
|
||||
|
||||
if (!processName)
|
||||
processName = [[[NSProcessInfo processInfo] processName] copy];
|
||||
|
||||
path = [[NSDocumentController sharedDocumentController]
|
||||
_autosaveDirectory: YES];
|
||||
path = [path stringByAppendingPathComponent:
|
||||
[NSString stringWithFormat: @"%@-%d",
|
||||
processName, _document_index]];
|
||||
path = [path stringByAppendingPathExtension: ext];
|
||||
url = [NSURL fileURLWithPath: path];
|
||||
}
|
||||
|
||||
[self saveToURL: url
|
||||
ofType: type
|
||||
forSaveOperation: NSAutosaveOperation
|
||||
delegate: delegate
|
||||
didSaveSelector: didAutosaveSelector
|
||||
|
@ -1692,7 +1683,7 @@ originalContentsURL: (NSURL *)orig
|
|||
|
||||
- (BOOL)hasUnautosavedChanges
|
||||
{
|
||||
return _autosave_change_count != 0;
|
||||
return _autosave_change_count != 0 || _doc_flags.autosave_permanently_modified;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -1728,8 +1719,30 @@ originalContentsURL: (NSURL *)orig
|
|||
}
|
||||
}
|
||||
|
||||
- (void)_removeAutosavedContentsFile
|
||||
{
|
||||
NSURL *url = [self autosavedContentsFileURL];
|
||||
|
||||
if (url)
|
||||
{
|
||||
NSString *path = [[url path] retain];
|
||||
|
||||
[self setAutosavedContentsFileURL: nil];
|
||||
[[NSFileManager defaultManager] removeFileAtPath: path handler: nil];
|
||||
[path release];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _changeWasDone: (NSNotification *)notification
|
||||
{
|
||||
/* Prevent a document from appearing unmodified after saving the
|
||||
* document, undoing a number of changes, and then making an equal
|
||||
* number of changes. Ditto for autosaved changes.
|
||||
*/
|
||||
if (_change_count < 0)
|
||||
_doc_flags.permanently_modified = 1;
|
||||
if (_autosave_change_count < 0)
|
||||
_doc_flags.autosave_permanently_modified = 1;
|
||||
[self updateChangeCount: NSChangeDone];
|
||||
}
|
||||
|
||||
|
@ -1740,17 +1753,12 @@ originalContentsURL: (NSURL *)orig
|
|||
|
||||
- (void) _changeWasRedone: (NSNotification *)notification
|
||||
{
|
||||
/* FIXME
|
||||
* Mac OS X 10.5 uses a new constant NSChangeRedone here, but
|
||||
* old applications are not prepared to handle this constant
|
||||
* and expect NSChangeDone instead.
|
||||
*/
|
||||
[self updateChangeCount: NSChangeDone];
|
||||
}
|
||||
|
||||
- (void) undo: (id)sender
|
||||
{
|
||||
[[self undoManager] undo];
|
||||
}
|
||||
|
||||
- (void) redo: (id)sender
|
||||
{
|
||||
[[self undoManager] redo];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -32,9 +32,11 @@
|
|||
#include <Foundation/NSFileManager.h>
|
||||
#include <Foundation/NSNotification.h>
|
||||
#include <Foundation/NSPathUtilities.h>
|
||||
#include <Foundation/NSProcessInfo.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSURL.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/NSTimer.h>
|
||||
|
||||
#include "AppKit/NSDocumentController.h"
|
||||
#include "AppKit/NSOpenPanel.h"
|
||||
|
@ -54,8 +56,12 @@ static NSString *NSDOSExtensionsKey = @"NSDOSExtensions";
|
|||
//static NSString *NSMIMETypesKey = @"NSMIMETypes";
|
||||
static NSString *NSDocumentClassKey = @"NSDocumentClass";
|
||||
|
||||
static NSString *CFBundleDocumentTypes = @"CFBundleDocumentTypes";
|
||||
static NSString *CFBundleTypeExtensions = @"CFBundleTypeExtensions";
|
||||
static NSString *CFBundleTypeName = @"CFBundleTypeName";
|
||||
static NSString *CFBundleTypeRole = @"CFBundleTypeRole";
|
||||
|
||||
static NSString *NSRecentDocuments = @"NSRecentDocuments";
|
||||
static NSString *NSDefaultOpenDirectory = @"NSDefaultOpenDirectory";
|
||||
|
||||
static NSDocumentController *sharedController = nil;
|
||||
|
||||
|
@ -73,6 +79,10 @@ static NSDictionary *TypeInfoForName (NSArray *types, NSString *typeName)
|
|||
{
|
||||
return dict;
|
||||
}
|
||||
else if ([[dict objectForKey: CFBundleTypeName] isEqualToString: typeName])
|
||||
{
|
||||
return dict;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
|
@ -89,6 +99,10 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
{
|
||||
return dict;
|
||||
}
|
||||
else if ([[dict objectForKey: CFBundleTypeName] isEqualToString: typeName])
|
||||
{
|
||||
return dict;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
|
@ -156,8 +170,9 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
*/
|
||||
+ (BOOL) isDocumentBasedApplication
|
||||
{
|
||||
return ([[[NSBundle mainBundle] infoDictionary] objectForKey: NSTypesKey])
|
||||
? YES : NO;
|
||||
return ([[[NSBundle mainBundle] infoDictionary] objectForKey: NSTypesKey] ||
|
||||
[[[NSBundle mainBundle] infoDictionary] objectForKey: CFBundleDocumentTypes])
|
||||
? YES : NO;
|
||||
}
|
||||
|
||||
/** </init>Initializes the document controller class. The first
|
||||
|
@ -169,6 +184,12 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
NSDictionary *customDict = [[NSBundle mainBundle] infoDictionary];
|
||||
|
||||
ASSIGN (_types, [customDict objectForKey: NSTypesKey]);
|
||||
|
||||
if(_types == nil)
|
||||
{
|
||||
ASSIGN(_types, [customDict objectForKey: CFBundleDocumentTypes]);
|
||||
}
|
||||
|
||||
_documents = [[NSMutableArray alloc] init];
|
||||
|
||||
/* Get list of recent documents */
|
||||
|
@ -259,7 +280,24 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
|
||||
- (void) setAutosavingDelay: (NSTimeInterval)autosavingDelay
|
||||
{
|
||||
static NSTimer *autosavingTimer;
|
||||
|
||||
if (autosavingTimer)
|
||||
{
|
||||
[autosavingTimer invalidate];
|
||||
DESTROY (autosavingTimer);
|
||||
}
|
||||
_autosavingDelay = autosavingDelay;
|
||||
if (autosavingDelay > 0)
|
||||
{
|
||||
autosavingTimer =
|
||||
[NSTimer scheduledTimerWithTimeInterval: autosavingDelay
|
||||
target: self
|
||||
selector: @selector(_autosaveDocuments:)
|
||||
userInfo: nil
|
||||
repeats: YES];
|
||||
RETAIN (autosavingTimer);
|
||||
}
|
||||
}
|
||||
|
||||
- (id) makeUntitledDocumentOfType: (NSString *)type
|
||||
|
@ -344,12 +382,19 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
|
||||
- (NSString*) defaultType
|
||||
{
|
||||
NSString *defaultName = nil;
|
||||
if ([_types count] == 0)
|
||||
{
|
||||
return nil; // raise exception?
|
||||
}
|
||||
|
||||
return [(NSDictionary*)[_types objectAtIndex: 0] objectForKey: NSNameKey];
|
||||
defaultName = [(NSDictionary*)[_types objectAtIndex: 0] objectForKey: NSNameKey];
|
||||
if(defaultName == nil)
|
||||
{
|
||||
defaultName = [(NSDictionary*)[_types objectAtIndex: 0] objectForKey: CFBundleTypeName];
|
||||
}
|
||||
|
||||
return defaultName;
|
||||
}
|
||||
|
||||
- (void) addDocument: (NSDocument *)document
|
||||
|
@ -546,7 +591,32 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
withContentsOfURL: (NSURL *)contents
|
||||
error: (NSError **)err
|
||||
{
|
||||
// FIXME
|
||||
if ([contents isFileURL])
|
||||
{
|
||||
NSString *type =
|
||||
[self typeFromFileExtension: [[contents path] pathExtension]];
|
||||
id document =
|
||||
[self makeDocumentForURL: url
|
||||
withContentsOfURL: contents
|
||||
ofType: type
|
||||
error: err];
|
||||
if (document)
|
||||
{
|
||||
[self addDocument:document];
|
||||
if ([self shouldCreateUI])
|
||||
{
|
||||
[document makeWindowControllers];
|
||||
[document showWindows];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: set error
|
||||
*err = nil;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
@ -577,6 +647,7 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
NSDictionary *typeInfo = [_types objectAtIndex: i];
|
||||
[array addObjectsFromArray: [typeInfo objectForKey: NSUnixExtensionsKey]];
|
||||
[array addObjectsFromArray: [typeInfo objectForKey: NSDOSExtensionsKey]];
|
||||
[array addObjectsFromArray: [typeInfo objectForKey: CFBundleTypeExtensions]];
|
||||
}
|
||||
|
||||
return array;
|
||||
|
@ -700,10 +771,6 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
NSString *cancelString = (cancellable)? ((NSString *)_(@"Cancel")) : ((NSString *)nil);
|
||||
int result;
|
||||
|
||||
/* Probably as good a place as any to do this */
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
setObject: [self currentDirectory] forKey: NSDefaultOpenDirectory];
|
||||
|
||||
if (![self hasEditedDocuments])
|
||||
{
|
||||
return YES;
|
||||
|
@ -822,13 +889,19 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
{
|
||||
NSFileManager *manager = [NSFileManager defaultManager];
|
||||
NSDocument *document = [self currentDocument];
|
||||
NSString *directory;
|
||||
NSString *directory = nil;
|
||||
BOOL isDir = NO;
|
||||
|
||||
if (document)
|
||||
directory = [[document fileName] stringByDeletingLastPathComponent];
|
||||
else
|
||||
directory = [[NSOpenPanel openPanel] directory];
|
||||
{
|
||||
directory = [[document fileName] stringByDeletingLastPathComponent];
|
||||
}
|
||||
if (directory == nil || [directory isEqual: @""]
|
||||
|| [manager fileExistsAtPath: directory isDirectory: &isDir] == NO
|
||||
|| isDir == NO)
|
||||
{
|
||||
directory = [[NSOpenPanel openPanel] directory];
|
||||
}
|
||||
if (directory == nil || [directory isEqual: @""]
|
||||
|| [manager fileExistsAtPath: directory isDirectory: &isDir] == NO
|
||||
|| isDir == NO)
|
||||
|
@ -943,9 +1016,16 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
if ([[typeInfo objectForKey:NSUnixExtensionsKey]
|
||||
containsObject: fileExtension] ||
|
||||
[[typeInfo objectForKey:NSDOSExtensionsKey]
|
||||
containsObject: fileExtension] ||
|
||||
[[typeInfo objectForKey:CFBundleTypeExtensions]
|
||||
containsObject: fileExtension])
|
||||
{
|
||||
return [typeInfo objectForKey: NSNameKey];
|
||||
NSString *type = [typeInfo objectForKey: NSNameKey];
|
||||
if(type == nil)
|
||||
{
|
||||
type = [typeInfo objectForKey: CFBundleTypeName];
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -966,10 +1046,14 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
NSDictionary *typeInfo = TYPE_INFO(type);
|
||||
NSArray *unixExtensions = [typeInfo objectForKey: NSUnixExtensionsKey];
|
||||
NSArray *dosExtensions = [typeInfo objectForKey: NSDOSExtensionsKey];
|
||||
|
||||
NSArray *cfFileExtensions = [typeInfo objectForKey: CFBundleTypeExtensions];
|
||||
|
||||
if (!dosExtensions && !unixExtensions) return cfFileExtensions;
|
||||
if (!dosExtensions) return unixExtensions;
|
||||
if (!unixExtensions) return dosExtensions;
|
||||
return [unixExtensions arrayByAddingObjectsFromArray: dosExtensions];
|
||||
|
||||
return [[unixExtensions arrayByAddingObjectsFromArray: dosExtensions]
|
||||
arrayByAddingObjectsFromArray: cfFileExtensions];
|
||||
}
|
||||
|
||||
- (Class) documentClassForType: (NSString *)type
|
||||
|
@ -1081,12 +1165,23 @@ static NSString *NSViewerRole = @"Viewer";
|
|||
NSString *className = [typeInfo objectForKey: NSDocumentClassKey];
|
||||
NSString *role = [typeInfo objectForKey: NSRoleKey];
|
||||
|
||||
// if the standard one isn't filled... check the CF key.
|
||||
if(role == nil)
|
||||
{
|
||||
role = [typeInfo objectForKey: CFBundleTypeRole];
|
||||
}
|
||||
|
||||
if ([docClassName isEqualToString: className]
|
||||
&& (role == nil
|
||||
|| [role isEqual: NSEditorRole]
|
||||
|| [role isEqual: NSViewerRole]))
|
||||
{
|
||||
[types addObject: [typeInfo objectForKey: NSNameKey]];
|
||||
NSString *name = [typeInfo objectForKey: NSNameKey];
|
||||
if(name == nil)
|
||||
{
|
||||
name = [typeInfo objectForKey: CFBundleTypeName];
|
||||
}
|
||||
[types addObject: name];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1108,7 +1203,12 @@ static NSString *NSViewerRole = @"Viewer";
|
|||
if ([docClassName isEqualToString: className] &&
|
||||
(role == nil || [role isEqual: NSEditorRole]))
|
||||
{
|
||||
[types addObject: [typeInfo objectForKey: NSNameKey]];
|
||||
NSString *name = [typeInfo objectForKey: NSNameKey];
|
||||
if(name == nil)
|
||||
{
|
||||
name = [typeInfo objectForKey: CFBundleTypeName];
|
||||
}
|
||||
[types addObject: name];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1144,5 +1244,152 @@ static NSString *NSViewerRole = @"Viewer";
|
|||
return [self _displayNamesForTypes:
|
||||
[self _editorTypesForClass: documentClass]];
|
||||
}
|
||||
|
||||
static NSMapTable *autosavedDocuments;
|
||||
static NSString *processName;
|
||||
|
||||
- (NSString *) _autosaveDirectory: (BOOL)create
|
||||
{
|
||||
NSArray *paths =
|
||||
NSSearchPathForDirectoriesInDomains (NSLibraryDirectory,
|
||||
NSUserDomainMask,
|
||||
YES);
|
||||
NSString *path = [paths objectAtIndex:0];
|
||||
path = [path stringByAppendingPathComponent: @"Autosave"];
|
||||
|
||||
if (create)
|
||||
{
|
||||
BOOL isDir;
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
|
||||
if ([fm fileExistsAtPath: path isDirectory: &isDir] == NO)
|
||||
{
|
||||
if (![fm createDirectoryAtPath: path attributes: nil])
|
||||
return nil;
|
||||
}
|
||||
else if (isDir == NO)
|
||||
{
|
||||
if (![fm removeFileAtPath: path handler: nil] ||
|
||||
![fm createDirectoryAtPath: path attributes: nil])
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
- (void) _autosaveDocuments: (NSTimer *)timer
|
||||
{
|
||||
id document;
|
||||
int i, n = [_documents count];
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
document = [_documents objectAtIndex: i];
|
||||
if ([document autosavingFileType] && [document hasUnautosavedChanges])
|
||||
{
|
||||
[document autosaveDocumentWithDelegate: nil
|
||||
didAutosaveSelector: NULL
|
||||
contextInfo: NULL];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) _reopenAutosavedDocuments
|
||||
{
|
||||
BOOL didOpen = NO;
|
||||
|
||||
if (!autosavedDocuments)
|
||||
{
|
||||
NSArray *autosaved;
|
||||
NSString *path;
|
||||
|
||||
autosavedDocuments =
|
||||
NSCreateMapTable (NSObjectMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks,
|
||||
1);
|
||||
if (!processName)
|
||||
processName = [[[NSProcessInfo processInfo] processName] copy];
|
||||
|
||||
path = [self _autosaveDirectory: NO];
|
||||
path = [path stringByAppendingPathComponent: processName];
|
||||
path = [path stringByAppendingPathExtension: @"plist"];
|
||||
autosaved = [NSArray arrayWithContentsOfFile: path];
|
||||
if (autosaved)
|
||||
{
|
||||
int i, n = [autosaved count];
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
NSDictionary *dict = [autosaved objectAtIndex: i];
|
||||
NSString *location = [dict objectForKey: @"Location"];
|
||||
NSString *autosavedLoc = [dict objectForKey: @"AutosavedLocation"];
|
||||
NSURL *url = location ? [NSURL URLWithString: location] : nil;
|
||||
NSURL *autosavedURL =
|
||||
autosavedLoc ? [NSURL URLWithString: autosavedLoc] : nil;
|
||||
|
||||
if (autosavedURL && [fm fileExistsAtPath: [autosavedURL path]])
|
||||
{
|
||||
NSError *err;
|
||||
if ([self reopenDocumentForURL: url
|
||||
withContentsOfURL: autosavedURL
|
||||
error: &err])
|
||||
didOpen = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return didOpen;
|
||||
}
|
||||
|
||||
- (void) _recordAutosavedDocument: (NSDocument *)document
|
||||
{
|
||||
BOOL changed = NO;
|
||||
NSURL *url = [document autosavedContentsFileURL];
|
||||
|
||||
if (!autosavedDocuments)
|
||||
autosavedDocuments =
|
||||
NSCreateMapTable (NSObjectMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks,
|
||||
1);
|
||||
if (!processName)
|
||||
processName = [[[NSProcessInfo processInfo] processName] copy];
|
||||
|
||||
if (url)
|
||||
{
|
||||
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
||||
if ([document fileURL])
|
||||
[dict setObject: [document fileURL] forKey: @"Location"];
|
||||
[dict setObject: url forKey: @"AutosavedLocation"];
|
||||
NSMapInsert (autosavedDocuments, document, dict);
|
||||
[dict release];
|
||||
changed = YES;
|
||||
}
|
||||
else if (NSMapGet (autosavedDocuments, document))
|
||||
{
|
||||
NSMapRemove (autosavedDocuments, document);
|
||||
changed = YES;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
NSString *path = [self _autosaveDirectory: YES];
|
||||
NSArray *autosaved = NSAllMapTableValues (autosavedDocuments);
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
|
||||
path = [path stringByAppendingPathComponent: processName];
|
||||
path = [path stringByAppendingPathExtension: @"plist"];
|
||||
if ([autosaved count] == 0)
|
||||
{
|
||||
[fm removeFileAtPath: path handler: nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
[autosaved writeToFile: path atomically:YES];
|
||||
}
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
#include <AppKit/NSDocumentController.h>
|
||||
|
||||
@class NSTimer;
|
||||
|
||||
@interface NSDocumentController (Private)
|
||||
- (NSArray *)_editorAndViewerTypesForClass:(Class)documentClass;
|
||||
- (NSArray *)_editorTypesForClass:(Class)fp12;
|
||||
|
@ -39,6 +41,10 @@
|
|||
- (NSString *)_nameForHumanReadableType: (NSString *)type;
|
||||
- (NSArray *)_displayNamesForTypes: (NSArray *)types;
|
||||
- (NSArray *)_displayNamesForClass: (Class)documentClass;
|
||||
- (NSString *)_autosaveDirectory: (BOOL)create;
|
||||
- (void)_autosaveDocuments: (NSTimer *)timer;
|
||||
- (BOOL)_reopenAutosavedDocuments;
|
||||
- (void)_recordAutosavedDocument: (NSDocument *)document;
|
||||
@end
|
||||
|
||||
|
||||
|
@ -47,6 +53,7 @@
|
|||
@interface NSDocument (Private)
|
||||
- (void)_removeWindowController:(NSWindowController *)controller;
|
||||
- (NSWindow *)_transferWindowOwnership;
|
||||
- (void)_removeAutosavedContentsFile;
|
||||
@end
|
||||
|
||||
|
||||
|
|
1259
Source/NSImage.m
1259
Source/NSImage.m
File diff suppressed because it is too large
Load diff
|
@ -52,9 +52,7 @@
|
|||
//
|
||||
- (id) init
|
||||
{
|
||||
[self initImageCell: nil];
|
||||
|
||||
return self;
|
||||
return [self initImageCell: nil];
|
||||
}
|
||||
|
||||
- (void) setImage:(NSImage *)anImage
|
||||
|
@ -120,35 +118,13 @@
|
|||
//
|
||||
// Displaying
|
||||
//
|
||||
- (void) drawWithFrame: (NSRect)cellFrame inView: (NSView *)controlView
|
||||
- (void) _drawBorderAndBackgroundWithFrame: (NSRect)cellFrame
|
||||
inView: (NSView *)controlView
|
||||
{
|
||||
NSDebugLLog(@"NSImageCell", @"NSImageCell -drawWithFrame");
|
||||
|
||||
// do nothing if cell's frame rect is zero
|
||||
if (NSIsEmptyRect (cellFrame))
|
||||
return;
|
||||
|
||||
// draw the border if needed
|
||||
switch (_frameStyle)
|
||||
{
|
||||
case NSImageFrameNone:
|
||||
// do nothing
|
||||
break;
|
||||
case NSImageFramePhoto:
|
||||
[[GSTheme theme] drawFramePhoto: cellFrame withClip: NSZeroRect];
|
||||
break;
|
||||
case NSImageFrameGrayBezel:
|
||||
[[GSTheme theme] drawGrayBezel: cellFrame withClip: NSZeroRect];
|
||||
break;
|
||||
case NSImageFrameGroove:
|
||||
[[GSTheme theme] drawGroove: cellFrame withClip: NSZeroRect];
|
||||
break;
|
||||
case NSImageFrameButton:
|
||||
[[GSTheme theme] drawButton: cellFrame withClip: NSZeroRect];
|
||||
break;
|
||||
}
|
||||
|
||||
[self drawInteriorWithFrame: cellFrame inView: controlView];
|
||||
NSDebugLLog(@"NSImageCell", @"NSImageCell -_drawBorderAndBackgroundWithFrame");
|
||||
[[GSTheme theme] drawBorderForImageFrameStyle: _frameStyle
|
||||
frame: cellFrame
|
||||
view: controlView];
|
||||
}
|
||||
|
||||
static inline float
|
||||
|
@ -219,7 +195,7 @@ scaleProportionally(NSSize imageSize, NSRect canvasRect)
|
|||
{
|
||||
NSPoint position;
|
||||
BOOL is_flipped = [controlView isFlipped];
|
||||
NSSize imageSize, realImageSize;
|
||||
NSSize imageSize, realImageSize;
|
||||
|
||||
NSDebugLLog(@"NSImageCell", @"NSImageCell drawInteriorWithFrame called");
|
||||
|
||||
|
@ -234,65 +210,65 @@ scaleProportionally(NSSize imageSize, NSRect canvasRect)
|
|||
switch (_imageScaling)
|
||||
{
|
||||
case NSScaleProportionally:
|
||||
{
|
||||
NSDebugLLog(@"NSImageCell", @"NSScaleProportionally");
|
||||
imageSize = scaleProportionally (realImageSize, cellFrame);
|
||||
break;
|
||||
}
|
||||
{
|
||||
NSDebugLLog(@"NSImageCell", @"NSScaleProportionally");
|
||||
imageSize = scaleProportionally (realImageSize, cellFrame);
|
||||
break;
|
||||
}
|
||||
case NSScaleToFit:
|
||||
{
|
||||
NSDebugLLog(@"NSImageCell", @"NSScaleToFit");
|
||||
imageSize = cellFrame.size;
|
||||
break;
|
||||
}
|
||||
{
|
||||
NSDebugLLog(@"NSImageCell", @"NSScaleToFit");
|
||||
imageSize = cellFrame.size;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case NSScaleNone:
|
||||
{
|
||||
NSDebugLLog(@"NSImageCell", @"NSScaleNone");
|
||||
imageSize = realImageSize;
|
||||
break;
|
||||
}
|
||||
{
|
||||
NSDebugLLog(@"NSImageCell", @"NSScaleNone");
|
||||
imageSize = realImageSize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (_imageAlignment)
|
||||
{
|
||||
default:
|
||||
case NSImageAlignLeft:
|
||||
position.x = xLeftInRect(imageSize, cellFrame);
|
||||
position.y = yCenterInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
position.x = xLeftInRect(imageSize, cellFrame);
|
||||
position.y = yCenterInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
case NSImageAlignRight:
|
||||
position.x = xRightInRect(imageSize, cellFrame);
|
||||
position.y = yCenterInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
position.x = xRightInRect(imageSize, cellFrame);
|
||||
position.y = yCenterInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
case NSImageAlignCenter:
|
||||
position.x = xCenterInRect(imageSize, cellFrame);
|
||||
position.y = yCenterInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
position.x = xCenterInRect(imageSize, cellFrame);
|
||||
position.y = yCenterInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
case NSImageAlignTop:
|
||||
position.x = xCenterInRect(imageSize, cellFrame);
|
||||
position.y = yTopInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
position.x = xCenterInRect(imageSize, cellFrame);
|
||||
position.y = yTopInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
case NSImageAlignBottom:
|
||||
position.x = xCenterInRect(imageSize, cellFrame);
|
||||
position.y = yBottomInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
position.x = xCenterInRect(imageSize, cellFrame);
|
||||
position.y = yBottomInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
case NSImageAlignTopLeft:
|
||||
position.x = xLeftInRect(imageSize, cellFrame);
|
||||
position.y = yTopInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
position.x = xLeftInRect(imageSize, cellFrame);
|
||||
position.y = yTopInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
case NSImageAlignTopRight:
|
||||
position.x = xRightInRect(imageSize, cellFrame);
|
||||
position.y = yTopInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
position.x = xRightInRect(imageSize, cellFrame);
|
||||
position.y = yTopInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
case NSImageAlignBottomLeft:
|
||||
position.x = xLeftInRect(imageSize, cellFrame);
|
||||
position.y = yBottomInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
position.x = xLeftInRect(imageSize, cellFrame);
|
||||
position.y = yBottomInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
case NSImageAlignBottomRight:
|
||||
position.x = xRightInRect(imageSize, cellFrame);
|
||||
position.y = yBottomInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
position.x = xRightInRect(imageSize, cellFrame);
|
||||
position.y = yBottomInRect(imageSize, cellFrame, is_flipped);
|
||||
break;
|
||||
}
|
||||
|
||||
// account for flipped views
|
||||
|
@ -304,11 +280,11 @@ scaleProportionally(NSSize imageSize, NSRect canvasRect)
|
|||
|
||||
// draw!
|
||||
[_cell_image drawInRect: NSMakeRect(position.x, position.y,
|
||||
imageSize.width, imageSize.height)
|
||||
fromRect: NSMakeRect(0, 0, realImageSize.width,
|
||||
realImageSize.height)
|
||||
operation: NSCompositeSourceOver
|
||||
fraction: 1.0];
|
||||
imageSize.width, imageSize.height)
|
||||
fromRect: NSMakeRect(0, 0, realImageSize.width,
|
||||
realImageSize.height)
|
||||
operation: NSCompositeSourceOver
|
||||
fraction: 1.0];
|
||||
}
|
||||
|
||||
- (NSSize) cellSize
|
||||
|
@ -316,22 +292,7 @@ scaleProportionally(NSSize imageSize, NSRect canvasRect)
|
|||
NSSize borderSize, s;
|
||||
|
||||
// Get border size
|
||||
switch (_frameStyle)
|
||||
{
|
||||
case NSImageFrameNone:
|
||||
default:
|
||||
borderSize = NSZeroSize;
|
||||
break;
|
||||
case NSImageFramePhoto:
|
||||
// FIXME
|
||||
borderSize = _sizeForBorderType (NSNoBorder);
|
||||
break;
|
||||
case NSImageFrameGrayBezel:
|
||||
case NSImageFrameGroove:
|
||||
case NSImageFrameButton:
|
||||
borderSize = _sizeForBorderType (NSBezelBorder);
|
||||
break;
|
||||
}
|
||||
borderSize = [[GSTheme theme] sizeForImageFrameStyle: _frameStyle];
|
||||
|
||||
// Get Content Size
|
||||
s = _original_image_size;
|
||||
|
@ -348,23 +309,7 @@ scaleProportionally(NSSize imageSize, NSRect canvasRect)
|
|||
NSSize borderSize;
|
||||
|
||||
// Get border size
|
||||
switch (_frameStyle)
|
||||
{
|
||||
case NSImageFrameNone:
|
||||
default:
|
||||
borderSize = NSZeroSize;
|
||||
break;
|
||||
case NSImageFramePhoto:
|
||||
// what does this one look like? TODO (in sync with the rest of the code)
|
||||
borderSize = _sizeForBorderType (NSNoBorder);
|
||||
break;
|
||||
case NSImageFrameGrayBezel:
|
||||
case NSImageFrameGroove:
|
||||
case NSImageFrameButton:
|
||||
borderSize = _sizeForBorderType (NSBezelBorder);
|
||||
break;
|
||||
}
|
||||
|
||||
borderSize = [[GSTheme theme] sizeForImageFrameStyle: _frameStyle];
|
||||
return NSInsetRect (theRect, borderSize.width, borderSize.height);
|
||||
}
|
||||
|
||||
|
|
|
@ -2291,3 +2291,48 @@ no_soft_invalidation:
|
|||
|
||||
@end
|
||||
|
||||
@implementation NSLayoutManager (temporaryattributes)
|
||||
- (void) addTemporaryAttributes: (NSDictionary *)attrs forCharacterRange: (NSRange)range
|
||||
{
|
||||
// to be implemented
|
||||
}
|
||||
|
||||
- (void) addTemporaryAttribute: (NSString *)attr value: (id)value forCharacterRange: (NSRange)range
|
||||
{
|
||||
// to be implemented
|
||||
}
|
||||
|
||||
- (void) setTemporaryAttributes:forCharacterRange: (NSRange)range
|
||||
{
|
||||
// to be implemented
|
||||
}
|
||||
|
||||
- (void) removeTemporaryAttribute: (NSString *)attr forCharacterRange: (NSRange)range
|
||||
{
|
||||
// to be implemented
|
||||
}
|
||||
|
||||
- (id) temporaryAttribute: (NSString *)attr atCharacterIndex: (unsigned int)index effectiveRange: (NSRange)range
|
||||
{
|
||||
// to be implemented
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id) temporaryAttribute: (NSString *)attr atCharacterIndex: (unsigned int)index longestEffectiveRange: (NSRange*)longestRange inRange: (NSRange)range
|
||||
{
|
||||
// to be implemented
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSDictionary *) temporaryAttributesAtCharacterIndex: (unsigned int)index effectiveRange: (NSRange)range
|
||||
{
|
||||
// to be implemented
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSDictionary *) temporaryAttributesAtCharacterIndex: (unsigned int) longestEffectiveRange: (NSRange*)longestRange inRange: (NSRange)range
|
||||
{
|
||||
// to be implemented
|
||||
return nil;
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -291,8 +291,8 @@ static BOOL menuBarVisible = YES;
|
|||
[[appMenu menuRepresentation] update];
|
||||
|
||||
RELEASE(itemsToMove);
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
[appItem setImage: nil];
|
||||
if (appMenu != nil)
|
||||
|
@ -316,7 +316,7 @@ static BOOL menuBarVisible = YES;
|
|||
}
|
||||
[self removeItem: appItem];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < [_items count]; i++)
|
||||
|
@ -1384,7 +1384,7 @@ static BOOL menuBarVisible = YES;
|
|||
[encoder encodeObject: _items forKey: @"NSMenuItems"];
|
||||
|
||||
// if there is no supermenu, make it the main menu.
|
||||
if ([self supermenu] == nil)
|
||||
if ([self supermenu] == nil && ![self _ownedByPopUp])
|
||||
{
|
||||
[encoder encodeObject: @"_NSMainMenu" forKey: @"NSName"];
|
||||
}
|
||||
|
|
|
@ -185,10 +185,19 @@ static NSImage *arrowImage = nil; /* Cache arrow image. */
|
|||
unsigned int m = [_menuItem keyEquivalentModifierMask];
|
||||
NSString *ucKey = [key uppercaseString];
|
||||
BOOL shift;
|
||||
|
||||
unichar uchar;
|
||||
|
||||
if ((key == nil) || [key isEqualToString: @""])
|
||||
return key;
|
||||
|
||||
uchar = [key characterAtIndex: 0];
|
||||
if (uchar >= 0xF700)
|
||||
{
|
||||
// FIXME: At the moment we are not able to handle function keys
|
||||
// as key equivalent
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ([key isEqualToString: @"\\r"])
|
||||
key = @"RET";
|
||||
else if ([key isEqualToString: @"\\e"])
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
#include <Foundation/NSException.h>
|
||||
|
||||
#include "GNUstepGUI/GSModelLoaderFactory.h"
|
||||
#include "GNUstepGUI/GSNibTemplates.h"
|
||||
#include "GNUstepGUI/GSGormLoading.h"
|
||||
#include "GNUstepGUI/IMLoading.h"
|
||||
|
||||
@implementation NSNib
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#import <GNUstepGUI/GSNibCompatibility.h>
|
||||
#import <GNUstepGUI/GSNibLoading.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
@implementation NSNibAXAttributeConnector
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#import <GNUstepGUI/GSNibCompatibility.h>
|
||||
#import <GNUstepGUI/GSNibLoading.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
@implementation NSNibAXRelationshipConnector
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#import <GNUstepGUI/GSNibCompatibility.h>
|
||||
#import <GNUstepGUI/GSNibLoading.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <AppKit/NSKeyValueBinding.h>
|
||||
|
|
|
@ -73,10 +73,13 @@ static NSOpenPanel *_gs_gui_open_panel = nil;
|
|||
// Pacify the compiler
|
||||
@interface NSSavePanel (GSPrivateMethods)
|
||||
- (void) _resetDefaults;
|
||||
- (void) _updateDefaultDirectory;
|
||||
- (void) _reloadBrowser;
|
||||
- (void) _selectCellName: (NSString *)title;
|
||||
- (void) _selectTextInColumn: (int)column;
|
||||
- (void) _setupForDirectory: (NSString *)path file: (NSString *)filename;
|
||||
- (BOOL) _shouldShowExtension: (NSString *)extension isDir: (BOOL *)isDir;
|
||||
- (void) _setupForTypes: (NSArray *)fileTypes; /* I'm cheating here... */
|
||||
- (BOOL) _shouldShowExtension: (NSString *)extension;
|
||||
- (NSComparisonResult) _compareFilename: (NSString *)n1 with: (NSString *)n2;
|
||||
@end
|
||||
|
||||
|
@ -92,29 +95,12 @@ static NSOpenPanel *_gs_gui_open_panel = nil;
|
|||
}
|
||||
|
||||
- (BOOL) _shouldShowExtension: (NSString *)extension
|
||||
isDir: (BOOL *)isDir;
|
||||
{
|
||||
BOOL found = YES;
|
||||
if (_canChooseFiles == NO ||
|
||||
(_fileTypes != nil && [_fileTypes containsObject: extension] == NO))
|
||||
return NO;
|
||||
|
||||
if (_fileTypes != nil)
|
||||
{
|
||||
if ([_fileTypes containsObject: extension] == YES)
|
||||
{
|
||||
if ([self treatsFilePackagesAsDirectories] == NO)
|
||||
{
|
||||
*isDir = NO;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
found = NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (*isDir == YES || (found == YES && _canChooseFiles == YES))
|
||||
return YES;
|
||||
|
||||
return NO;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) _selectTextInColumn: (int)column
|
||||
|
@ -235,6 +221,16 @@ static NSOpenPanel *_gs_gui_open_panel = nil;
|
|||
[super _setupForDirectory: path file: filename];
|
||||
}
|
||||
|
||||
- (void) _setupForTypes: (NSArray *)fileTypes
|
||||
{
|
||||
if (_fileTypes != fileTypes)
|
||||
{
|
||||
BOOL reload = ![_fileTypes isEqual: fileTypes];
|
||||
ASSIGN (_fileTypes, fileTypes);
|
||||
if (reload)
|
||||
[self _reloadBrowser];
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
/**
|
||||
|
@ -347,7 +343,11 @@ static NSOpenPanel *_gs_gui_open_panel = nil;
|
|||
*/
|
||||
- (void) setCanChooseFiles: (BOOL)flag
|
||||
{
|
||||
_canChooseFiles = flag;
|
||||
if (flag != _canChooseFiles)
|
||||
{
|
||||
_canChooseFiles = flag;
|
||||
[self _reloadBrowser];
|
||||
}
|
||||
}
|
||||
|
||||
/**<p>Returns YES if the user is allowed to choose files. The
|
||||
|
@ -459,8 +459,7 @@ static NSOpenPanel *_gs_gui_open_panel = nil;
|
|||
file: (NSString *)name
|
||||
types: (NSArray *)fileTypes
|
||||
{
|
||||
ASSIGN (_fileTypes, fileTypes);
|
||||
|
||||
[self _setupForTypes: fileTypes];
|
||||
return [self runModalForDirectory: path
|
||||
file: name];
|
||||
}
|
||||
|
@ -470,8 +469,7 @@ static NSOpenPanel *_gs_gui_open_panel = nil;
|
|||
types: (NSArray *)fileTypes
|
||||
relativeToWindow: (NSWindow*)window
|
||||
{
|
||||
ASSIGN (_fileTypes, fileTypes);
|
||||
|
||||
[self _setupForTypes: fileTypes];
|
||||
return [self runModalForDirectory: path
|
||||
file: name
|
||||
relativeToWindow: window];
|
||||
|
@ -485,8 +483,7 @@ static NSOpenPanel *_gs_gui_open_panel = nil;
|
|||
didEndSelector: (SEL)didEndSelector
|
||||
contextInfo: (void *)contextInfo
|
||||
{
|
||||
ASSIGN (_fileTypes, fileTypes);
|
||||
|
||||
[self _setupForTypes: fileTypes];
|
||||
[self beginSheetForDirectory: path
|
||||
file: name
|
||||
modalForWindow: docWindow
|
||||
|
@ -579,6 +576,7 @@ static NSOpenPanel *_gs_gui_open_panel = nil;
|
|||
}
|
||||
}
|
||||
|
||||
[self _updateDefaultDirectory];
|
||||
[NSApp stopModalWithCode: NSOKButton];
|
||||
[_okButton setEnabled: NO];
|
||||
[self close];
|
||||
|
|
|
@ -1711,12 +1711,19 @@ static NSImage *unexpandable = nil;
|
|||
- (void) _loadDictionaryStartingWith: (id) startitem
|
||||
atLevel: (int) level
|
||||
{
|
||||
int num = [_dataSource outlineView: self
|
||||
numberOfChildrenOfItem: startitem];
|
||||
int num = 0;
|
||||
int i = 0;
|
||||
id sitem = (startitem == nil) ? (id)[NSNull null] : (id)startitem;
|
||||
NSMutableArray *anarray = nil;
|
||||
|
||||
// Check to see if item is expandable before getting the number of
|
||||
// items.
|
||||
if([_dataSource outlineView: self isItemExpandable: startitem])
|
||||
{
|
||||
num = [_dataSource outlineView: self
|
||||
numberOfChildrenOfItem: startitem];
|
||||
}
|
||||
|
||||
if (num > 0)
|
||||
{
|
||||
anarray = [NSMutableArray array];
|
||||
|
|
|
@ -532,6 +532,7 @@
|
|||
#include <Foundation/NSConnection.h>
|
||||
#include <Foundation/NSDistantObject.h>
|
||||
#include <Foundation/NSDistributedNotificationCenter.h>
|
||||
#include <Foundation/NSFileManager.h>
|
||||
#include <Foundation/NSMapTable.h>
|
||||
#include <Foundation/NSNotification.h>
|
||||
#include <Foundation/NSException.h>
|
||||
|
@ -547,6 +548,7 @@
|
|||
#include <Foundation/NSRunLoop.h>
|
||||
#include <Foundation/NSSet.h>
|
||||
#include <Foundation/NSTask.h>
|
||||
#include <GNUstepBase/NSTask+GS.h>
|
||||
#include <Foundation/NSTimer.h>
|
||||
|
||||
#include "GNUstepGUI/GSServicesManager.h"
|
||||
|
@ -957,6 +959,7 @@ static NSString *namePrefix = @"NSTypedFilenamesPboardType:";
|
|||
NSConnection *connection;
|
||||
|
||||
connection = [(NSDistantObject*)provider connectionForProxy];
|
||||
[connection enableMultipleThreads];
|
||||
seconds = [finishBy timeIntervalSinceNow];
|
||||
[connection setRequestTimeout: seconds];
|
||||
[connection setReplyTimeout: seconds];
|
||||
|
@ -1962,6 +1965,7 @@ static NSMapTable *mimeMap = NULL;
|
|||
NSConnection *conn = [(id)the_server connectionForProxy];
|
||||
Protocol *p = @protocol(GSPasteboardSvr);
|
||||
|
||||
[conn enableMultipleThreads];
|
||||
[(id)the_server setProtocolForProxy: p];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
|
@ -1976,14 +1980,7 @@ static NSMapTable *mimeMap = NULL;
|
|||
|
||||
if (cmd == nil && recursion ==NO)
|
||||
{
|
||||
#ifdef GNUSTEP_BASE_LIBRARY
|
||||
cmd = RETAIN([[NSSearchPathForDirectoriesInDomains(
|
||||
GSToolsDirectory, NSSystemDomainMask, YES) objectAtIndex: 0]
|
||||
stringByAppendingPathComponent: @"gpbs"]);
|
||||
#else
|
||||
path = RETAIN([@GNUSTEP_TOOLS_NO_DESTDIR
|
||||
stringByAppendingPathComponent: @"gpbs"]);
|
||||
#endif
|
||||
cmd = [NSTask launchPathForTool: @"gpbs"];
|
||||
}
|
||||
if (recursion == YES || cmd == nil)
|
||||
{
|
||||
|
|
|
@ -284,6 +284,22 @@ this to return nil to indicate that we have no context menu.
|
|||
[self synchronizeTitleAndSelectedItem];
|
||||
}
|
||||
|
||||
- (BOOL) selectItemWithTag: (NSInteger)tag
|
||||
{
|
||||
int index = [self indexOfItemWithTag: tag];
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
[self selectItemAtIndex: index];
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** <p>Returns the number of items in the item list</p>
|
||||
<p>See Also: [NSPopUpButtonCell-numberOfItems]</p>
|
||||
*/
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "AppKit/NSPopUpButton.h"
|
||||
#include "AppKit/NSPopUpButtonCell.h"
|
||||
#include "AppKit/NSWindow.h"
|
||||
#include "GNUstepGUI/GSTheme.h"
|
||||
|
||||
/* The image to use in a specific popupbutton depends on type and
|
||||
* preferred edge; that is, _pbc_image[0] if it is a
|
||||
|
@ -1057,6 +1058,11 @@ static NSImage *_pbc_image[5];
|
|||
{
|
||||
[aCoder encodeObject: _menu forKey: @"NSMenu"];
|
||||
}
|
||||
|
||||
if (_menuItem != nil)
|
||||
{
|
||||
[aCoder encodeObject: _menuItem forKey: @"NSMenuItem"];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "AppKit/NSGraphics.h"
|
||||
#include "AppKit/NSWindow.h"
|
||||
#include "GNUstepGUI/GSTheme.h"
|
||||
#include "GNUstepGUI/GSNibCompatibility.h"
|
||||
#include "GNUstepGUI/GSNibLoading.h"
|
||||
|
||||
@implementation NSProgressIndicator
|
||||
|
||||
|
|
|
@ -108,7 +108,9 @@ setPath(NSBrowser *browser, NSString *path)
|
|||
- (id) _initWithoutGModel;
|
||||
- (void) _getOriginalSize;
|
||||
- (void) _setDefaultDirectory;
|
||||
- (void) _updateDefaultDirectory;
|
||||
- (void) _resetDefaults;
|
||||
- (void) _reloadBrowser;
|
||||
// Methods invoked by buttons
|
||||
- (void) _setHomeDirectory;
|
||||
- (void) _mountMedia;
|
||||
|
@ -116,7 +118,7 @@ setPath(NSBrowser *browser, NSString *path)
|
|||
- (void) _selectTextInColumn: (int)column;
|
||||
- (void) _selectCellName: (NSString *)title;
|
||||
- (void) _setupForDirectory: (NSString *)path file: (NSString *)name;
|
||||
- (BOOL) _shouldShowExtension: (NSString *)extension isDir: (BOOL *)isDir;
|
||||
- (BOOL) _shouldShowExtension: (NSString *)extension;
|
||||
- (void) _windowResized: (NSNotification*)n;
|
||||
- (NSComparisonResult) _compareFilename: (NSString *)n1 with: (NSString *)n2;
|
||||
@end /* NSSavePanel (PrivateMethods) */
|
||||
|
@ -149,9 +151,7 @@ setPath(NSBrowser *browser, NSString *path)
|
|||
NSString *file = [[names lastObject] stringByStandardizingPath];
|
||||
BOOL isDir;
|
||||
|
||||
if (file &&
|
||||
[_fm fileExistsAtPath: file isDirectory: &isDir] &&
|
||||
isDir)
|
||||
if (file && [_fm fileExistsAtPath: file isDirectory: &isDir] && isDir)
|
||||
{
|
||||
[self setDirectory: file];
|
||||
}
|
||||
|
@ -386,20 +386,24 @@ setPath(NSBrowser *browser, NSString *path)
|
|||
{
|
||||
NSString *path;
|
||||
|
||||
if (_directory == nil)
|
||||
path = [[NSUserDefaults standardUserDefaults]
|
||||
objectForKey: @"NSDefaultOpenDirectory"];
|
||||
if (path == nil)
|
||||
{
|
||||
path = [[NSUserDefaults standardUserDefaults]
|
||||
objectForKey: @"NSDefaultOpenDirectory"];
|
||||
if (path == nil)
|
||||
{
|
||||
// FIXME: Should we use this or the home directory?
|
||||
ASSIGN(_directory, [_fm currentDirectoryPath]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSIGN(_directory, path);
|
||||
}
|
||||
// FIXME: Should we use this or the home directory?
|
||||
ASSIGN(_directory, [_fm currentDirectoryPath]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSIGN(_directory, path);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _updateDefaultDirectory
|
||||
{
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
setObject: _directory
|
||||
forKey: @"NSDefaultOpenDirectory"];
|
||||
}
|
||||
|
||||
- (void) _resetDefaults
|
||||
|
@ -407,12 +411,19 @@ setPath(NSBrowser *browser, NSString *path)
|
|||
[self _setDefaultDirectory];
|
||||
[self setPrompt: @"Name:"];
|
||||
[self setTitle: @"Save"];
|
||||
[self setRequiredFileType: @""];
|
||||
[self setAllowedFileTypes: nil];
|
||||
[self setTreatsFilePackagesAsDirectories: NO];
|
||||
[self setDelegate: nil];
|
||||
[self setAccessoryView: nil];
|
||||
}
|
||||
|
||||
- (void) _reloadBrowser
|
||||
{
|
||||
NSString *path = [_browser path];
|
||||
[_browser loadColumnZero];
|
||||
setPath(_browser, path);
|
||||
}
|
||||
|
||||
//
|
||||
// Methods invoked by button press
|
||||
//
|
||||
|
@ -552,7 +563,10 @@ selectCellWithString: (NSString*)title
|
|||
{
|
||||
if (path == nil)
|
||||
{
|
||||
[self _setDefaultDirectory];
|
||||
if (_directory == nil)
|
||||
{
|
||||
[self _setDefaultDirectory];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -576,24 +590,11 @@ selectCellWithString: (NSString*)title
|
|||
}
|
||||
|
||||
- (BOOL) _shouldShowExtension: (NSString *)extension
|
||||
isDir: (BOOL *)isDir;
|
||||
{
|
||||
if (*isDir == NO)
|
||||
{
|
||||
if (_requiredFileType != nil && [_requiredFileType length] != 0
|
||||
&& [extension isEqualToString: _requiredFileType] == NO)
|
||||
return NO;
|
||||
}
|
||||
else if ([extension length] == 0)
|
||||
{
|
||||
/* Automatic YES */
|
||||
}
|
||||
else if (_treatsFilePackagesAsDirectories == NO)
|
||||
{
|
||||
if (_requiredFileType == nil || [_requiredFileType length] == 0
|
||||
|| [extension isEqualToString: _requiredFileType] == YES)
|
||||
*isDir = NO;
|
||||
}
|
||||
if (_allowedFileTypes != nil
|
||||
&& [_allowedFileTypes indexOfObject: extension] == NSNotFound
|
||||
&& [_allowedFileTypes indexOfObject: @""] == NSNotFound)
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
@ -679,7 +680,7 @@ selectCellWithString: (NSString*)title
|
|||
[[NSNotificationCenter defaultCenter] removeObserver: self];
|
||||
TEST_RELEASE (_fullFileName);
|
||||
TEST_RELEASE (_directory);
|
||||
TEST_RELEASE (_requiredFileType);
|
||||
TEST_RELEASE (_allowedFileTypes);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
@ -695,7 +696,7 @@ selectCellWithString: (NSString*)title
|
|||
* All these are set automatically
|
||||
_directory = nil;
|
||||
_fullFileName = nil;
|
||||
_requiredFileType = nil;
|
||||
_allowedFileTypes = nil;
|
||||
_delegate = nil;
|
||||
|
||||
_treatsFilePackagesAsDirectories = NO;
|
||||
|
@ -920,24 +921,81 @@ selectCellWithString: (NSString*)title
|
|||
is used for another file type within the application. If
|
||||
you do not invoke it, or set it to empty string or nil, no
|
||||
extension will be appended, indicated by an empty string
|
||||
returned from -requiredFileType .</p><p>See Also: -requiredFileType</p>
|
||||
returned from -requiredFileType.</p><p>This method is equivalent
|
||||
to calling -setAllowedFileTypes: with an array containing only
|
||||
fileType.</p><p>See Also: -requiredFileType</p>
|
||||
*/
|
||||
- (void) setRequiredFileType: (NSString*)fileType
|
||||
{
|
||||
ASSIGN(_requiredFileType, fileType);
|
||||
NSArray *fileTypes;
|
||||
|
||||
if ([fileType length] == 0)
|
||||
fileTypes = nil;
|
||||
else
|
||||
fileTypes = [NSArray arrayWithObject: fileType];
|
||||
[self setAllowedFileTypes: fileTypes];
|
||||
}
|
||||
|
||||
/**<p>Returns the required file type. The default, indicated by empty string,
|
||||
* is no required file type.</p><p>See Also: -setRequiredFileType:</p>
|
||||
/**<p>Returns the required file type. The default, indicated by an empty
|
||||
* string, is no required file type.</p><p>This method is equivalent to
|
||||
* calling -allowedFileTypes and returning the first element of the list
|
||||
* of allowed types, or the empty string if there are none.</p>
|
||||
* <p>See Also: -setRequiredFileType:</p>
|
||||
*/
|
||||
- (NSString*) requiredFileType
|
||||
{
|
||||
return _requiredFileType;
|
||||
if ([_allowedFileTypes count] > 0)
|
||||
return [_allowedFileTypes objectAtIndex: 0];
|
||||
else
|
||||
return @"";
|
||||
}
|
||||
|
||||
/**<p> Specifies the allowed types, i.e., file name extensions to
|
||||
be appended to any selected files that don't already have one
|
||||
of those extensions. The elements of the array should be strings
|
||||
that do not include the period that begins the extension. Invoke
|
||||
this method each time the Save panel is used for another file type
|
||||
within the application. If you do not invoke it, or set it to an
|
||||
empty array or nil, no extension will be appended, indicated by nil
|
||||
returned from -allowedFileTypes.</p><p>See Also: -allowedFileTypes</p>
|
||||
*/
|
||||
- (void) setAllowedFileTypes: (NSArray *)types
|
||||
{
|
||||
// FIXME
|
||||
if (types != _allowedFileTypes)
|
||||
{
|
||||
BOOL hasAllowedExtension = NO;
|
||||
NSString *filename, *extension;
|
||||
|
||||
filename = [[_form cellAtIndex: 0] stringValue];
|
||||
extension = [filename pathExtension];
|
||||
if ([extension length] && [_allowedFileTypes count] &&
|
||||
[_allowedFileTypes indexOfObject: extension] != NSNotFound)
|
||||
hasAllowedExtension = YES;
|
||||
|
||||
if ([types count] == 0)
|
||||
DESTROY(_allowedFileTypes);
|
||||
else
|
||||
ASSIGN(_allowedFileTypes, types);
|
||||
[self _reloadBrowser];
|
||||
|
||||
if (hasAllowedExtension && [types count] &&
|
||||
[types indexOfObject: extension] == NSNotFound &&
|
||||
[types indexOfObject: @""] == NSNotFound)
|
||||
{
|
||||
extension = [types objectAtIndex: 0];
|
||||
filename = [filename stringByDeletingPathExtension];
|
||||
filename = [filename stringByAppendingPathExtension: extension];
|
||||
[[_form cellAtIndex: 0] setStringValue: filename];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**<p>Returns an array of the allowed file types. The default, indicated by
|
||||
* nil, is any file type is allowed.</p><p>See Also: -setAllowedFileTypes:</p>
|
||||
*/
|
||||
- (NSArray *) allowedFileTypes
|
||||
{
|
||||
return _allowedFileTypes;
|
||||
}
|
||||
|
||||
- (void) setAllowsOtherFileTypes: (BOOL)flag
|
||||
|
@ -945,12 +1003,6 @@ selectCellWithString: (NSString*)title
|
|||
_allowsOtherFileTypes = flag;
|
||||
}
|
||||
|
||||
- (NSArray *) allowedFileTypes
|
||||
{
|
||||
// FIXME
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL) allowsOtherFileTypes
|
||||
{
|
||||
return _allowsOtherFileTypes;
|
||||
|
@ -972,7 +1024,11 @@ selectCellWithString: (NSString*)title
|
|||
*/
|
||||
- (void) setTreatsFilePackagesAsDirectories: (BOOL)flag
|
||||
{
|
||||
_treatsFilePackagesAsDirectories = flag;
|
||||
if (flag != _treatsFilePackagesAsDirectories)
|
||||
{
|
||||
_treatsFilePackagesAsDirectories = flag;
|
||||
[self _reloadBrowser];
|
||||
}
|
||||
}
|
||||
|
||||
/**<p> Validates and possibly reloads the browser columns that are visible
|
||||
|
@ -1068,17 +1124,27 @@ selectCellWithString: (NSString*)title
|
|||
*/
|
||||
- (NSString*) filename
|
||||
{
|
||||
NSString *fileType;
|
||||
|
||||
if (_fullFileName == nil)
|
||||
return @"";
|
||||
|
||||
if (_requiredFileType == nil || [_requiredFileType isEqual: @""] == YES)
|
||||
if (_allowedFileTypes == nil ||
|
||||
[_allowedFileTypes indexOfObject: @""] != NSNotFound)
|
||||
return _fullFileName;
|
||||
|
||||
// add filetype extension only if the filename does not include it already
|
||||
if ([[_fullFileName pathExtension] isEqual: _requiredFileType] == YES)
|
||||
return _fullFileName;
|
||||
/* add filetype extension only if the filename does not include an
|
||||
allowed one already */
|
||||
fileType = [_fullFileName pathExtension];
|
||||
if ([_allowedFileTypes indexOfObject: fileType] != NSNotFound)
|
||||
{
|
||||
return _fullFileName;
|
||||
}
|
||||
else
|
||||
return [_fullFileName stringByAppendingPathExtension: _requiredFileType];
|
||||
{
|
||||
fileType = [_allowedFileTypes objectAtIndex: 0];
|
||||
return [_fullFileName stringByAppendingPathExtension: fileType];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSURL *) URL
|
||||
|
@ -1093,6 +1159,7 @@ selectCellWithString: (NSString*)title
|
|||
- (void) cancel: (id)sender
|
||||
{
|
||||
ASSIGN(_directory, pathToColumn(_browser, [_browser lastColumn]));
|
||||
[self _updateDefaultDirectory];
|
||||
[NSApp stopModalWithCode: NSCancelButton];
|
||||
[_okButton setEnabled: NO];
|
||||
[self close];
|
||||
|
@ -1202,6 +1269,7 @@ selectCellWithString: (NSString*)title
|
|||
if (![_delegate panel: self isValidFilename: [self filename]])
|
||||
return;
|
||||
|
||||
[self _updateDefaultDirectory];
|
||||
[NSApp stopModalWithCode: NSOKButton];
|
||||
[_okButton setEnabled: NO];
|
||||
[self close];
|
||||
|
@ -1397,6 +1465,7 @@ selectCellWithString: (NSString*)title
|
|||
// NSSavePanel browser delegate methods
|
||||
//
|
||||
@interface NSSavePanel (GSBrowserDelegate)
|
||||
- (void) browserDidScroll: (NSBrowser *)sender;
|
||||
- (void) browser: (NSBrowser*)sender
|
||||
createRowsForColumn: (int)column
|
||||
inMatrix: (NSMatrix*)matrix;
|
||||
|
@ -1429,6 +1498,11 @@ static int compareFilenames (id elem1, id elem2, void *context)
|
|||
|
||||
|
||||
@implementation NSSavePanel (GSBrowserDelegate)
|
||||
- (void) browserDidScroll: (NSBrowser *)sender
|
||||
{
|
||||
[self validateVisibleColumns];
|
||||
}
|
||||
|
||||
- (void) browser: (NSBrowser*)sender
|
||||
createRowsForColumn: (int)column
|
||||
inMatrix: (NSMatrix*)matrix
|
||||
|
@ -1443,11 +1517,12 @@ createRowsForColumn: (int)column
|
|||
unsigned base_frac = 1;
|
||||
BOOL display_progress = NO;
|
||||
NSString *progressString = nil;
|
||||
NSWorkspace *ws;
|
||||
/* We create lot of objects in this method, so we use a pool */
|
||||
NSAutoreleasePool *pool;
|
||||
|
||||
pool = [NSAutoreleasePool new];
|
||||
|
||||
ws = [NSWorkspace sharedWorkspace];
|
||||
path = pathToColumn(_browser, column);
|
||||
#if defined(__MINGW32__)
|
||||
if (column == 0)
|
||||
|
@ -1455,7 +1530,7 @@ createRowsForColumn: (int)column
|
|||
NSMutableArray *m;
|
||||
unsigned i;
|
||||
|
||||
files = [[NSWorkspace sharedWorkspace] mountedLocalVolumePaths];
|
||||
files = [ws mountedLocalVolumePaths];
|
||||
m = [files mutableCopy];
|
||||
i = [m count];
|
||||
while (i-- > 0)
|
||||
|
@ -1588,16 +1663,19 @@ createRowsForColumn: (int)column
|
|||
pathAndFile = [path stringByAppendingPathComponent: file];
|
||||
exists = [_fm fileExistsAtPath: pathAndFile
|
||||
isDirectory: &isDir];
|
||||
|
||||
if (isDir && !_treatsFilePackagesAsDirectories
|
||||
&& [ws isFilePackageAtPath: pathAndFile])
|
||||
{
|
||||
isDir = NO;
|
||||
}
|
||||
if (_delegateHasShowFilenameFilter)
|
||||
{
|
||||
exists = [_delegate panel: self
|
||||
shouldShowFilename: pathAndFile];
|
||||
exists = [_delegate panel: self shouldShowFilename: pathAndFile];
|
||||
}
|
||||
|
||||
if (exists)
|
||||
if (exists && !isDir)
|
||||
{
|
||||
exists = [self _shouldShowExtension: extension isDir: &isDir];
|
||||
exists = [self _shouldShowExtension: extension];
|
||||
}
|
||||
|
||||
if (exists)
|
||||
|
@ -1639,6 +1717,10 @@ createRowsForColumn: (int)column
|
|||
- (BOOL) browser: (NSBrowser*)sender
|
||||
isColumnValid: (int)column
|
||||
{
|
||||
/*
|
||||
* FIXME This code doesn't handle the case where the delegate now wants
|
||||
* to show additional files, which were not displayed before.
|
||||
*/
|
||||
NSArray *cells = [[sender matrixInColumn: column] cells];
|
||||
unsigned count = [cells count], i;
|
||||
NSString *path = pathToColumn(sender, column);
|
||||
|
|
|
@ -84,6 +84,15 @@
|
|||
format: @"NSSecureTextField only uses NSSecureTextFieldCells."];
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (NSCoder *)coder
|
||||
{
|
||||
if((self = [super initWithCoder: coder]) != nil)
|
||||
{
|
||||
[self setEchosBullets: YES];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithFrame:(NSRect)frameRect
|
||||
{
|
||||
self = [super initWithFrame: frameRect];
|
||||
|
@ -208,7 +217,7 @@
|
|||
self = [super initWithCoder: decoder];
|
||||
if ([decoder allowsKeyedCoding])
|
||||
{
|
||||
// do nothing for now...
|
||||
_echosBullets = [decoder decodeBoolForKey: @"GSEchoBullets"];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -218,12 +227,18 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void) encodeWithCoder: (NSCoder *)aCoder
|
||||
- (void) encodeWithCoder: (NSCoder *)coder
|
||||
{
|
||||
[super encodeWithCoder: aCoder];
|
||||
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &_echosBullets];
|
||||
[super encodeWithCoder: coder];
|
||||
if([coder allowsKeyedCoding])
|
||||
{
|
||||
[coder encodeBool: _echosBullets forKey: @"GSEchoBullets"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[coder encodeValueOfObjCType: @encode(BOOL) at: &_echosBullets];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GSSimpleSecureLayoutManager
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <GNUstepBase/NSTask+GS.h>
|
||||
#include "AppKit/NSPasteboard.h"
|
||||
#include "AppKit/NSSound.h"
|
||||
|
||||
|
@ -173,21 +174,14 @@ static id<GSSoundSvr> the_server = nil;
|
|||
|
||||
if (cmd == nil && recursion == NO)
|
||||
{
|
||||
#ifdef GNUSTEP_BASE_LIBRARY
|
||||
cmd = RETAIN([[NSSearchPathForDirectoriesInDomains(
|
||||
GSToolsDirectory, NSSystemDomainMask, YES)
|
||||
objectAtIndex: 0]
|
||||
stringByAppendingPathComponent: @"gnustep_sndd"]);
|
||||
#else
|
||||
cmd = RETAIN([@GNUSTEP_TOOLS_NO_DESTDIR
|
||||
stringByAppendingPathComponent: @"gnustep_sndd"]);
|
||||
#endif
|
||||
cmd = [NSTask launchPathForTool: @"gnustep_sndd"];
|
||||
}
|
||||
|
||||
if (recursion == YES || cmd == nil)
|
||||
{
|
||||
NSLog(@"Unable to contact sound server - "
|
||||
@"please ensure that gnustep_sndd is running for %@.", description);
|
||||
@"please ensure that gnustep_sndd is running for %@.",
|
||||
description);
|
||||
return nil;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -71,6 +71,8 @@
|
|||
{
|
||||
[[GSTheme theme] drawDarkButton: cellFrame withClip: cellFrame];
|
||||
}
|
||||
|
||||
[self _drawBackgroundWithFrame: cellFrame inView: controlView];
|
||||
}
|
||||
|
||||
- (void) setHighlighted: (BOOL)flag
|
||||
|
|
|
@ -5102,9 +5102,24 @@ static BOOL selectContiguousRegion(NSTableView *self,
|
|||
row = [_selectedRows indexGreaterThanOrEqualToIndex: startingRow];
|
||||
while ((row != NSNotFound) && (row <= endingRow))
|
||||
{
|
||||
NSColor *selectionColor = nil;
|
||||
|
||||
// Switch to the alternate color of the backgroundColor is white.
|
||||
if([_backgroundColor isEqual: [NSColor whiteColor]])
|
||||
{
|
||||
selectionColor = [NSColor colorWithCalibratedRed: 0.86
|
||||
green: 0.92
|
||||
blue: 0.99
|
||||
alpha: 1.0];
|
||||
}
|
||||
else
|
||||
{
|
||||
selectionColor = [NSColor whiteColor];
|
||||
}
|
||||
|
||||
//NSHighlightRect(NSIntersectionRect([self rectOfRow: row],
|
||||
// clipRect));
|
||||
[[NSColor whiteColor] set];
|
||||
// clipRect));
|
||||
[selectionColor set];
|
||||
NSRectFill(NSIntersectionRect([self rectOfRow: row], clipRect));
|
||||
row = [_selectedRows indexGreaterThanIndex: row];
|
||||
}
|
||||
|
|
|
@ -40,45 +40,13 @@
|
|||
#include "AppKit/NSTextFieldCell.h"
|
||||
#include "AppKit/NSText.h"
|
||||
|
||||
static NSColor *bgCol;
|
||||
static NSColor *txtCol;
|
||||
|
||||
@interface NSTextFieldCell (PrivateColor)
|
||||
+ (void) _systemColorsChanged: (NSNotification*)n;
|
||||
// Minor optimization -- cache isOpaque.
|
||||
- (BOOL) _isOpaque;
|
||||
@end
|
||||
|
||||
@implementation NSTextFieldCell (PrivateColor)
|
||||
+ (void) _systemColorsChanged: (NSNotification*)n
|
||||
{
|
||||
ASSIGN(bgCol, [NSColor textBackgroundColor]);
|
||||
ASSIGN(txtCol, [NSColor textColor]);
|
||||
}
|
||||
|
||||
- (BOOL) _isOpaque
|
||||
{
|
||||
if (_textfieldcell_draws_background == NO
|
||||
|| _background_color == nil
|
||||
|| [_background_color alphaComponent] < 1.0)
|
||||
return NO;
|
||||
else
|
||||
return YES;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSTextFieldCell
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSTextFieldCell class])
|
||||
{
|
||||
[self setVersion: 2];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(_systemColorsChanged:)
|
||||
name: NSSystemColorsDidChangeNotification
|
||||
object: nil];
|
||||
[self _systemColorsChanged: nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,10 +59,9 @@ static NSColor *txtCol;
|
|||
if (self == nil)
|
||||
return self;
|
||||
|
||||
ASSIGN(_text_color, txtCol);
|
||||
ASSIGN(_background_color, bgCol);
|
||||
ASSIGN(_text_color, [NSColor textColor]);
|
||||
ASSIGN(_background_color, [NSColor textBackgroundColor]);
|
||||
// _textfieldcell_draws_background = NO;
|
||||
// _textfieldcell_is_opaque = NO;
|
||||
_action_mask = NSKeyUpMask | NSKeyDownMask;
|
||||
return self;
|
||||
}
|
||||
|
@ -124,7 +91,6 @@ static NSColor *txtCol;
|
|||
- (void) setBackgroundColor: (NSColor *)aColor
|
||||
{
|
||||
ASSIGN (_background_color, aColor);
|
||||
_textfieldcell_is_opaque = [self _isOpaque];
|
||||
if (_control_view)
|
||||
if ([_control_view isKindOfClass: [NSControl class]])
|
||||
[(NSControl *)_control_view updateCell: self];
|
||||
|
@ -145,7 +111,6 @@ static NSColor *txtCol;
|
|||
- (void) setDrawsBackground: (BOOL)flag
|
||||
{
|
||||
_textfieldcell_draws_background = flag;
|
||||
_textfieldcell_is_opaque = [self _isOpaque];
|
||||
if (_control_view)
|
||||
if ([_control_view isKindOfClass: [NSControl class]])
|
||||
[(NSControl *)_control_view updateCell: self];
|
||||
|
@ -180,7 +145,7 @@ static NSColor *txtCol;
|
|||
|
||||
- (void) setBezelStyle: (NSTextFieldBezelStyle)style
|
||||
{
|
||||
_bezelStyle = style;
|
||||
_bezelStyle = style;
|
||||
}
|
||||
|
||||
- (NSTextFieldBezelStyle) bezelStyle
|
||||
|
@ -233,7 +198,8 @@ static NSColor *txtCol;
|
|||
return textObject;
|
||||
}
|
||||
|
||||
- (void) drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView*)controlView
|
||||
- (void) _drawBackgroundWithFrame: (NSRect)cellFrame
|
||||
inView: (NSView*)controlView
|
||||
{
|
||||
if (_textfieldcell_draws_background)
|
||||
{
|
||||
|
@ -246,9 +212,15 @@ static NSColor *txtCol;
|
|||
[[NSColor controlBackgroundColor] set];
|
||||
}
|
||||
NSRectFill([self drawingRectForBounds: cellFrame]);
|
||||
}
|
||||
|
||||
[super drawInteriorWithFrame: cellFrame inView: controlView];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _drawBorderAndBackgroundWithFrame: (NSRect)cellFrame
|
||||
inView: (NSView*)controlView
|
||||
{
|
||||
// FIXME: Should use the bezel style if set.
|
||||
[super _drawBorderAndBackgroundWithFrame: cellFrame inView: controlView];
|
||||
[self _drawBackgroundWithFrame: cellFrame inView: controlView];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -297,7 +269,12 @@ static NSColor *txtCol;
|
|||
|
||||
- (BOOL) isOpaque
|
||||
{
|
||||
return _textfieldcell_is_opaque;
|
||||
if (_textfieldcell_draws_background == NO
|
||||
|| _background_color == nil
|
||||
|| [_background_color alphaComponent] < 1.0)
|
||||
return NO;
|
||||
else
|
||||
return YES;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -306,6 +283,7 @@ static NSColor *txtCol;
|
|||
- (void) encodeWithCoder: (NSCoder*)aCoder
|
||||
{
|
||||
BOOL tmp;
|
||||
|
||||
[super encodeWithCoder: aCoder];
|
||||
|
||||
if ([aCoder allowsKeyedCoding])
|
||||
|
@ -313,6 +291,10 @@ static NSColor *txtCol;
|
|||
[aCoder encodeObject: [self backgroundColor] forKey: @"NSBackgroundColor"];
|
||||
[aCoder encodeObject: [self textColor] forKey: @"NSTextColor"];
|
||||
[aCoder encodeBool: [self drawsBackground] forKey: @"NSDrawsBackground"];
|
||||
if ([self isBezeled])
|
||||
{
|
||||
[aCoder encodeInt: [self bezelStyle] forKey: @"NSTextBezelStyle"];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -326,19 +308,30 @@ static NSColor *txtCol;
|
|||
- (id) initWithCoder: (NSCoder*)aDecoder
|
||||
{
|
||||
self = [super initWithCoder: aDecoder];
|
||||
if (self == nil)
|
||||
return self;
|
||||
|
||||
if ([aDecoder allowsKeyedCoding])
|
||||
{
|
||||
id textColor = RETAIN([aDecoder decodeObjectForKey: @"NSTextColor"]);
|
||||
id backColor = RETAIN([aDecoder decodeObjectForKey: @"NSBackgroundColor"]);
|
||||
|
||||
[self setBackgroundColor: backColor];
|
||||
[self setTextColor: textColor];
|
||||
if ([aDecoder containsValueForKey: @"NSBackgroundColor"])
|
||||
{
|
||||
[self setBackgroundColor: [aDecoder decodeObjectForKey:
|
||||
@"NSBackgroundColor"]];
|
||||
}
|
||||
if ([aDecoder containsValueForKey: @"NSTextColor"])
|
||||
{
|
||||
[self setTextColor: [aDecoder decodeObjectForKey: @"NSTextColor"]];
|
||||
}
|
||||
if ([aDecoder containsValueForKey: @"NSDrawsBackground"])
|
||||
{
|
||||
[self setDrawsBackground: [aDecoder decodeBoolForKey:
|
||||
@"NSDrawsBackground"]];
|
||||
}
|
||||
if ([aDecoder containsValueForKey: @"NSTextBezelStyle"])
|
||||
{
|
||||
[self setBezelStyle: [aDecoder decodeIntForKey:
|
||||
@"NSTextBezelStyle"]];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -364,7 +357,6 @@ static NSColor *txtCol;
|
|||
[aDecoder decodeValueOfObjCType: @encode(id) at: &_text_color];
|
||||
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &tmp];
|
||||
_textfieldcell_draws_background = tmp;
|
||||
_textfieldcell_is_opaque = [self _isOpaque];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
|
|
@ -128,6 +128,14 @@ Interface for a bunch of internal methods that need to be cleaned up.
|
|||
- (void) pasteSelection;
|
||||
@end
|
||||
|
||||
|
||||
@interface NSTextStorage(NSTextViewUndoSupport)
|
||||
- (NSTextView *)_bestTextViewForUndo;
|
||||
- (void)_undoReplaceCharactersInRange: (NSRange)undoRange
|
||||
withAttributedString: (NSAttributedString *)undoString
|
||||
selectedRange: (NSRange)selectedRange;
|
||||
@end
|
||||
|
||||
// This class is a helper for keyed unarchiving only
|
||||
@interface NSTextViewSharedData : NSObject
|
||||
{
|
||||
|
@ -661,6 +669,8 @@ If a text view is added to an empty text network, it keeps its attributes.
|
|||
_tf.accepts_glyph_info = NO;
|
||||
_tf.allows_document_background_color_change = YES;
|
||||
|
||||
_dragTargetLocation = NSNotFound;
|
||||
|
||||
_markedRange = NSMakeRange(NSNotFound, 0);
|
||||
[container setTextView: self];
|
||||
[self invalidateTextContainerOrigin];
|
||||
|
@ -849,21 +859,6 @@ that makes decoding and encoding compatible with the old code.
|
|||
{
|
||||
[aDecoder decodeIntForKey: @"NSTVFlags"];
|
||||
}
|
||||
|
||||
// register for services and subscribe to notifications.
|
||||
[self _recacheDelegateResponses];
|
||||
[self invalidateTextContainerOrigin];
|
||||
|
||||
if (!did_register_for_services)
|
||||
[isa registerForServices];
|
||||
|
||||
[self updateDragTypeRegistration];
|
||||
|
||||
[self setPostsFrameChangedNotifications: YES];
|
||||
[notificationCenter addObserver: self
|
||||
selector: @selector(_updateState:)
|
||||
name: NSViewFrameDidChangeNotification
|
||||
object: self];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -927,23 +922,25 @@ that makes decoding and encoding compatible with the old code.
|
|||
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
|
||||
[aTextContainer setHeightTracksTextView: flag];
|
||||
}
|
||||
|
||||
[self _recacheDelegateResponses];
|
||||
[self invalidateTextContainerOrigin];
|
||||
|
||||
// register for services...
|
||||
if (!did_register_for_services)
|
||||
[isa registerForServices];
|
||||
|
||||
[self updateDragTypeRegistration];
|
||||
|
||||
[self setPostsFrameChangedNotifications: YES];
|
||||
[notificationCenter addObserver: self
|
||||
selector: @selector(_updateState:)
|
||||
name: NSViewFrameDidChangeNotification
|
||||
object: self];
|
||||
}
|
||||
|
||||
_dragTargetLocation = NSNotFound;
|
||||
|
||||
[self _recacheDelegateResponses];
|
||||
[self invalidateTextContainerOrigin];
|
||||
|
||||
// register for services...
|
||||
if (!did_register_for_services)
|
||||
[isa registerForServices];
|
||||
|
||||
[self updateDragTypeRegistration];
|
||||
|
||||
[self setPostsFrameChangedNotifications: YES];
|
||||
[notificationCenter addObserver: self
|
||||
selector: @selector(_updateState:)
|
||||
name: NSViewFrameDidChangeNotification
|
||||
object: self];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -1862,8 +1859,10 @@ or add guards
|
|||
index = [_layoutManager glyphIndexForPoint: point
|
||||
inTextContainer: _textContainer
|
||||
fractionOfDistanceThroughGlyph: &fraction];
|
||||
// FIXME The layoutManager should never return -1.
|
||||
// Assume that the text is empty if this happens.
|
||||
if (index == (unsigned int)-1)
|
||||
return (unsigned int)-1;
|
||||
return 0;
|
||||
|
||||
index = [_layoutManager characterIndexForGlyphAtIndex: index];
|
||||
if (respectFraction && fraction > 0.5 && index < [_textStorage length] &&
|
||||
|
@ -2499,8 +2498,10 @@ TextDidEndEditing notification _without_ asking the delegate
|
|||
undoRange = affectedCharRange;
|
||||
}
|
||||
undoString = [self attributedSubstringFromRange: affectedCharRange];
|
||||
[[undo prepareWithInvocationTarget: self] replaceCharactersInRange: undoRange
|
||||
withAttributedString: undoString];
|
||||
[[undo prepareWithInvocationTarget: [self textStorage]]
|
||||
_undoReplaceCharactersInRange: undoRange
|
||||
withAttributedString: undoString
|
||||
selectedRange: [self selectedRange]];
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -3474,12 +3475,12 @@ Figure out how the additional layout stuff is supposed to work.
|
|||
{
|
||||
if (!_layoutManager)
|
||||
return NO;
|
||||
if (_dragTargetLocation != NSNotFound)
|
||||
return YES;
|
||||
if (_layoutManager->_selected_range.length != 0)
|
||||
return NO;
|
||||
if (_tf.is_editable == NO)
|
||||
return NO;
|
||||
if (_tf.isDragTarget == YES)
|
||||
return YES;
|
||||
if ([_window isKeyWindow] == YES && [_window firstResponder] == self)
|
||||
return YES;
|
||||
return NO;
|
||||
|
@ -3585,7 +3586,26 @@ Figure out how the additional layout stuff is supposed to work.
|
|||
return;
|
||||
}
|
||||
|
||||
if (_layoutManager->_selected_range.length > 0 ||
|
||||
if (_dragTargetLocation != NSNotFound)
|
||||
{
|
||||
_tf.drag_target_hijacks_insertion_point = YES;
|
||||
|
||||
new = [_layoutManager
|
||||
insertionPointRectForCharacterIndex: _dragTargetLocation
|
||||
inTextContainer: _textContainer];
|
||||
|
||||
new.origin.x += _textContainerOrigin.x;
|
||||
new.origin.y += _textContainerOrigin.y;
|
||||
|
||||
/* If the insertion would extend outside the view (e.g. because it's
|
||||
just to the right of a character on the far right edge of the view,
|
||||
a common case for right-aligned text), we force it back in. */
|
||||
if (NSMaxX(new) > NSMaxX(_bounds))
|
||||
{
|
||||
new.origin.x = NSMaxX(_bounds) - new.size.width;
|
||||
}
|
||||
}
|
||||
else if (_layoutManager->_selected_range.length > 0 ||
|
||||
_layoutManager->_selected_range.location == NSNotFound ||
|
||||
!restartFlag)
|
||||
{
|
||||
|
@ -3609,63 +3629,81 @@ Figure out how the additional layout stuff is supposed to work.
|
|||
}
|
||||
}
|
||||
|
||||
// Don't draw insertion point if there's no need
|
||||
if (![self shouldDrawInsertionPoint] && !_drawInsertionPointNow)
|
||||
/* Handle hijacked insertion point (either set above when entering this
|
||||
method or during the previous call to this method) */
|
||||
if (_tf.drag_target_hijacks_insertion_point)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (restartFlag)
|
||||
{
|
||||
/* Start blinking timer if not yet started */
|
||||
if (_insertionPointTimer == nil && [self shouldDrawInsertionPoint])
|
||||
{
|
||||
// NSLog(@"Start timer");
|
||||
_insertionPointRect = new;
|
||||
_insertionPointTimer = [NSTimer scheduledTimerWithTimeInterval: 0.5
|
||||
target: self
|
||||
selector: @selector(_blink:)
|
||||
userInfo: nil
|
||||
repeats: YES];
|
||||
RETAIN (_insertionPointTimer);
|
||||
}
|
||||
else if (_insertionPointTimer != nil)
|
||||
{
|
||||
if (!NSEqualRects(new, _insertionPointRect))
|
||||
{
|
||||
_drawInsertionPointNow = NO;
|
||||
[self setNeedsDisplayInRect: _insertionPointRect
|
||||
avoidAdditionalLayout: YES];
|
||||
_insertionPointRect = new;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ok - blinking has just been turned on. Make sure we start
|
||||
* the on/off/on/off blinking from the 'on', because in that way
|
||||
* the user can see where the insertion point is as soon as
|
||||
* possible.
|
||||
*/
|
||||
_drawInsertionPointNow = 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);
|
||||
|
||||
_drawInsertionPointNow = NO;
|
||||
[self setNeedsDisplayInRect: _insertionPointRect
|
||||
avoidAdditionalLayout: YES];
|
||||
|
||||
_insertionPointRect = new;
|
||||
|
||||
if (_dragTargetLocation != NSNotFound)
|
||||
{
|
||||
_insertionPointRect = new;
|
||||
_drawInsertionPointNow = YES;
|
||||
[self setNeedsDisplayInRect: _insertionPointRect
|
||||
avoidAdditionalLayout: YES];
|
||||
}
|
||||
else
|
||||
_tf.drag_target_hijacks_insertion_point = NO;
|
||||
}
|
||||
|
||||
[self _updateInputMethodWithInsertionPoint: _insertionPointRect.origin];
|
||||
/* Otherwise, draw insertion point only if there is a need to do so */
|
||||
else if ([self shouldDrawInsertionPoint] || _drawInsertionPointNow)
|
||||
{
|
||||
if (restartFlag)
|
||||
{
|
||||
/* Start blinking timer if not yet started */
|
||||
if (_insertionPointTimer == nil && [self shouldDrawInsertionPoint])
|
||||
{
|
||||
// NSLog(@"Start timer");
|
||||
_insertionPointRect = new;
|
||||
_insertionPointTimer = [NSTimer scheduledTimerWithTimeInterval: 0.5
|
||||
target: self
|
||||
selector: @selector(_blink:)
|
||||
userInfo: nil
|
||||
repeats: YES];
|
||||
RETAIN (_insertionPointTimer);
|
||||
}
|
||||
else if (_insertionPointTimer != nil)
|
||||
{
|
||||
if (!NSEqualRects(new, _insertionPointRect))
|
||||
{
|
||||
_drawInsertionPointNow = NO;
|
||||
[self setNeedsDisplayInRect: _insertionPointRect
|
||||
avoidAdditionalLayout: YES];
|
||||
_insertionPointRect = new;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ok - blinking has just been turned on. Make sure we start
|
||||
* the on/off/on/off blinking from the 'on', because in that way
|
||||
* the user can see where the insertion point is as soon as
|
||||
* possible.
|
||||
*/
|
||||
_drawInsertionPointNow = 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);
|
||||
|
||||
_drawInsertionPointNow = NO;
|
||||
[self setNeedsDisplayInRect: _insertionPointRect
|
||||
avoidAdditionalLayout: YES];
|
||||
|
||||
_insertionPointRect = new;
|
||||
}
|
||||
|
||||
[self _updateInputMethodWithInsertionPoint: _insertionPointRect.origin];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -4098,7 +4136,20 @@ right.)
|
|||
|
||||
if ([type isEqualToString: NSStringPboardType])
|
||||
{
|
||||
[self insertText: [pboard stringForType: NSStringPboardType]];
|
||||
if (changeRange.location != NSNotFound)
|
||||
{
|
||||
NSString *s = [pboard stringForType: NSStringPboardType];
|
||||
|
||||
if ([self shouldChangeTextInRange: changeRange
|
||||
replacementString: s])
|
||||
{
|
||||
[self replaceCharactersInRange: changeRange
|
||||
withString: s];
|
||||
[self didChangeText];
|
||||
changeRange.length = [s length];
|
||||
[self setSelectedRange: changeRange];
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
@ -4125,6 +4176,8 @@ right.)
|
|||
[self replaceCharactersInRange: changeRange
|
||||
withAttributedString: as];
|
||||
[self didChangeText];
|
||||
changeRange.length = [as length];
|
||||
[self setSelectedRange: changeRange];
|
||||
}
|
||||
|
||||
DESTROY(as);
|
||||
|
@ -4151,6 +4204,8 @@ right.)
|
|||
[self replaceCharactersInRange: changeRange
|
||||
withAttributedString: as];
|
||||
[self didChangeText];
|
||||
changeRange.length = [as length];
|
||||
[self setSelectedRange: changeRange];
|
||||
}
|
||||
|
||||
DESTROY(as);
|
||||
|
@ -4177,6 +4232,8 @@ right.)
|
|||
[self replaceCharactersInRange: changeRange
|
||||
withAttributedString: as];
|
||||
[self didChangeText];
|
||||
changeRange.length = [as length];
|
||||
[self setSelectedRange: changeRange];
|
||||
}
|
||||
RELEASE(attachment);
|
||||
RELEASE(image);
|
||||
|
@ -4199,6 +4256,8 @@ right.)
|
|||
[self replaceCharactersInRange: changeRange
|
||||
withAttributedString: as];
|
||||
[self didChangeText];
|
||||
changeRange.length = [as length];
|
||||
[self setSelectedRange: changeRange];
|
||||
}
|
||||
RELEASE(attachment);
|
||||
return YES;
|
||||
|
@ -4435,7 +4494,7 @@ other than copy/paste or dragging. */
|
|||
change, and those calls are made on all connected text views.
|
||||
*/
|
||||
|
||||
if (_tf.is_editable && _tf.is_rich_text)
|
||||
if (_tf.is_editable)
|
||||
[self registerForDraggedTypes: [self acceptableDragTypes]];
|
||||
else
|
||||
[self unregisterDraggedTypes];
|
||||
|
@ -4445,7 +4504,35 @@ other than copy/paste or dragging. */
|
|||
|
||||
/**** Drag and drop handling ****/
|
||||
|
||||
/*
|
||||
* TODO: Dragging should use a transient insertion point distinct from the
|
||||
* text view's current selection. This allows subclasses of NSTextView to
|
||||
* determine the origin of the dragged selection during a drag operation and
|
||||
* provides better visual feedback for users, since the origin of the dragged
|
||||
* selection remains visible. Note that -rangeForUserTextChange will have to
|
||||
* be changed to take this transient insertion point into account.
|
||||
*/
|
||||
|
||||
// dragging of text, colors and files
|
||||
- (unsigned int)draggingSourceOperationMaskForLocal:(BOOL)isLocal
|
||||
{
|
||||
return (NSDragOperationGeneric | NSDragOperationCopy);
|
||||
}
|
||||
|
||||
- (void)_draggingHijackInsertionPoint: (unsigned int)dragIndex
|
||||
{
|
||||
_dragTargetLocation = dragIndex;
|
||||
[self updateInsertionPointStateAndRestartTimer: NO];
|
||||
[self displayIfNeeded];
|
||||
}
|
||||
|
||||
- (void)_draggingReleaseInsertionPoint
|
||||
{
|
||||
_dragTargetLocation = NSNotFound;
|
||||
[self updateInsertionPointStateAndRestartTimer: NO];
|
||||
[self displayIfNeeded];
|
||||
}
|
||||
|
||||
- (NSDragOperation) draggingEntered: (id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSPasteboard *pboard = [sender draggingPasteboard];
|
||||
|
@ -4459,26 +4546,23 @@ other than copy/paste or dragging. */
|
|||
{
|
||||
NSPoint dragPoint;
|
||||
unsigned dragIndex;
|
||||
NSRange dragRange;
|
||||
NSRange range;
|
||||
|
||||
if (_tf.isDragTarget == NO)
|
||||
{
|
||||
_tf.isDragTarget = YES;
|
||||
_dragTargetSelectionRange = [self selectedRange];
|
||||
}
|
||||
|
||||
dragPoint = [sender draggingLocation];
|
||||
dragPoint = [self convertPoint: dragPoint fromView: nil];
|
||||
dragIndex = [self _characterIndexForPoint: dragPoint
|
||||
respectFraction: YES];
|
||||
dragRange = NSMakeRange (dragIndex, 0);
|
||||
|
||||
range = [self selectionRangeForProposedRange: dragRange
|
||||
granularity: NSSelectByCharacter];
|
||||
[self setSelectedRange: range];
|
||||
[self displayIfNeeded];
|
||||
if ([sender draggingSource] != self ||
|
||||
!NSLocationInRange(dragIndex, [self selectedRange]))
|
||||
[self _draggingHijackInsertionPoint: dragIndex];
|
||||
else
|
||||
{
|
||||
[self _draggingReleaseInsertionPoint];
|
||||
flags = NSDragOperationNone;
|
||||
}
|
||||
}
|
||||
else if (_dragTargetLocation != NSNotFound)
|
||||
[self _draggingReleaseInsertionPoint];
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
@ -4495,41 +4579,68 @@ other than copy/paste or dragging. */
|
|||
{
|
||||
NSPoint dragPoint;
|
||||
unsigned dragIndex;
|
||||
NSRange dragRange;
|
||||
NSRange range;
|
||||
|
||||
if (_tf.isDragTarget == NO)
|
||||
{
|
||||
_tf.isDragTarget = YES;
|
||||
_dragTargetSelectionRange = [self selectedRange];
|
||||
}
|
||||
NSRect vRect;
|
||||
|
||||
dragPoint = [sender draggingLocation];
|
||||
dragPoint = [self convertPoint: dragPoint fromView: nil];
|
||||
dragIndex = [self _characterIndexForPoint: dragPoint
|
||||
respectFraction: YES];
|
||||
dragRange = NSMakeRange (dragIndex, 0);
|
||||
|
||||
range = [self selectionRangeForProposedRange: dragRange
|
||||
granularity: NSSelectByCharacter];
|
||||
[self setSelectedRange: range];
|
||||
[self displayIfNeeded];
|
||||
/* Note: Keep DRAGGING_SCROLL_BORDER in sync with a similar value used
|
||||
* in -draggingUpdated: of NSOutlineView and NSTableView.
|
||||
* FIXME: Is the value of DRAGGING_SCROLL_DIST reasonable?
|
||||
*/
|
||||
#define DRAGGING_SCROLL_BORDER 3
|
||||
#define DRAGGING_SCROLL_DIST 10
|
||||
vRect = [self visibleRect];
|
||||
if (dragPoint.x <= NSMinX(vRect) + DRAGGING_SCROLL_BORDER)
|
||||
{
|
||||
vRect.origin.x -= DRAGGING_SCROLL_DIST;
|
||||
if (NSMinX(vRect) < NSMinX(_bounds))
|
||||
vRect.origin.x = NSMinX(_bounds);
|
||||
}
|
||||
else if (dragPoint.x >= NSMaxX(vRect) - DRAGGING_SCROLL_BORDER)
|
||||
{
|
||||
vRect.origin.x += DRAGGING_SCROLL_DIST;
|
||||
if (NSMaxX(vRect) > NSMaxX(_bounds))
|
||||
vRect.origin.x = NSMaxX(_bounds) - NSWidth(vRect);
|
||||
}
|
||||
|
||||
if (dragPoint.y <= NSMinY(vRect) + DRAGGING_SCROLL_BORDER)
|
||||
{
|
||||
vRect.origin.y -= DRAGGING_SCROLL_DIST;
|
||||
if (NSMinY(vRect) < NSMinY(_bounds))
|
||||
vRect.origin.y = NSMinY(_bounds);
|
||||
}
|
||||
else if (dragPoint.y >= NSMaxY(vRect) - DRAGGING_SCROLL_BORDER)
|
||||
{
|
||||
vRect.origin.y += DRAGGING_SCROLL_DIST;
|
||||
if (NSMaxY(vRect) > NSMaxY(_bounds))
|
||||
vRect.origin.y = NSMaxY(_bounds) - NSHeight(vRect);
|
||||
}
|
||||
[self scrollPoint: vRect.origin];
|
||||
#undef DRAGGING_SCROLL_BORDER
|
||||
#undef DRAGGING_SCROLL_DIST
|
||||
|
||||
if ([sender draggingSource] != self ||
|
||||
!NSLocationInRange(dragIndex, [self selectedRange]))
|
||||
[self _draggingHijackInsertionPoint: dragIndex];
|
||||
else
|
||||
{
|
||||
[self _draggingReleaseInsertionPoint];
|
||||
flags = NSDragOperationNone;
|
||||
}
|
||||
}
|
||||
else if (_dragTargetLocation != NSNotFound)
|
||||
[self _draggingReleaseInsertionPoint];
|
||||
return flags;
|
||||
}
|
||||
|
||||
- (void) draggingExited: (id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSPasteboard *pboard = [sender draggingPasteboard];
|
||||
NSArray *types = [self readablePasteboardTypes];
|
||||
NSString *type = [self preferredPasteboardTypeFromArray: [pboard types]
|
||||
restrictedToTypesFromArray: types];
|
||||
if (_tf.isDragTarget == YES
|
||||
&& ![type isEqual:NSColorPboardType])
|
||||
if (_dragTargetLocation != NSNotFound)
|
||||
{
|
||||
_tf.isDragTarget = NO;
|
||||
[self setSelectedRange: _dragTargetSelectionRange];
|
||||
[self displayIfNeeded];
|
||||
[self _draggingReleaseInsertionPoint];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4540,13 +4651,25 @@ other than copy/paste or dragging. */
|
|||
|
||||
- (BOOL) performDragOperation: (id <NSDraggingInfo>)sender
|
||||
{
|
||||
_tf.isDragTarget = NO;
|
||||
NSRange sourceRange = [self selectedRange];
|
||||
NSRange changeRange = NSMakeRange(_dragTargetLocation, 0);
|
||||
[self _draggingReleaseInsertionPoint];
|
||||
[self setSelectedRange: changeRange];
|
||||
|
||||
if ([sender draggingSource] == self &&
|
||||
([sender draggingSourceOperationMask] & NSDragOperationGeneric))
|
||||
{
|
||||
if (![self shouldChangeTextInRange: sourceRange replacementString: @""])
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
[self replaceCharactersInRange: sourceRange withString: @""];
|
||||
}
|
||||
return [self readSelectionFromPasteboard: [sender draggingPasteboard]];
|
||||
}
|
||||
|
||||
- (void) concludeDragOperation: (id <NSDraggingInfo>)sender
|
||||
{
|
||||
_tf.isDragTarget = NO;
|
||||
}
|
||||
|
||||
- (void) cleanUpAfterDragOperation
|
||||
|
@ -4567,6 +4690,7 @@ other than copy/paste or dragging. */
|
|||
if (origin)
|
||||
*origin = NSMakePoint(0, 0);
|
||||
|
||||
// FIXME
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
@ -4602,6 +4726,7 @@ other than copy/paste or dragging. */
|
|||
|
||||
- (void) mouseDown: (NSEvent *)theEvent
|
||||
{
|
||||
BOOL canDrag = NO;
|
||||
NSSelectionAffinity affinity = [self selectionAffinity];
|
||||
NSSelectionGranularity granularity = NSSelectByCharacter;
|
||||
NSRange chosenRange, proposedRange;
|
||||
|
@ -4624,11 +4749,6 @@ other than copy/paste or dragging. */
|
|||
startIndex = [self _characterIndexForPoint: startPoint
|
||||
respectFraction: [theEvent clickCount] == 1];
|
||||
|
||||
if (startIndex == (unsigned int)-1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ([theEvent modifierFlags] & NSShiftKeyMask)
|
||||
{
|
||||
/* Shift-click is for extending an existing selection using
|
||||
|
@ -4666,6 +4786,9 @@ other than copy/paste or dragging. */
|
|||
break;
|
||||
}
|
||||
|
||||
/* A single click into the selected range can start a drag operation */
|
||||
canDrag = granularity == NSSelectByCharacter
|
||||
&& NSLocationInRange(startIndex, _layoutManager->_selected_range);
|
||||
proposedRange = NSMakeRange (startIndex, 0);
|
||||
|
||||
/* We manage clicks on attachments and links only on the first
|
||||
|
@ -4757,10 +4880,27 @@ other than copy/paste or dragging. */
|
|||
|
||||
chosenRange = [self selectionRangeForProposedRange: proposedRange
|
||||
granularity: granularity];
|
||||
[self setSelectedRange: chosenRange affinity: affinity
|
||||
stillSelecting: YES];
|
||||
|
||||
if (canDrag)
|
||||
{
|
||||
unsigned int mask = NSLeftMouseDraggedMask | NSLeftMouseUpMask;
|
||||
NSEvent *currentEvent;
|
||||
|
||||
currentEvent = [_window nextEventMatchingMask: mask
|
||||
untilDate: nil
|
||||
inMode: NSEventTrackingRunLoopMode
|
||||
dequeue: YES];
|
||||
if ([currentEvent type] == NSLeftMouseDragged)
|
||||
{
|
||||
if (![self dragSelectionWithEvent: theEvent
|
||||
offset: NSMakeSize(0, 0)
|
||||
slideBack: YES])
|
||||
{
|
||||
NSBeep();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Enter modal loop tracking the mouse */
|
||||
{
|
||||
unsigned int mask = NSLeftMouseDraggedMask | NSLeftMouseUpMask
|
||||
|
@ -4770,6 +4910,9 @@ other than copy/paste or dragging. */
|
|||
NSDate *distantPast = [NSDate distantPast];
|
||||
BOOL gettingPeriodic, gotPeriodic;
|
||||
|
||||
[self setSelectedRange: chosenRange affinity: affinity
|
||||
stillSelecting: YES];
|
||||
|
||||
currentEvent = [_window nextEventMatchingMask: mask
|
||||
untilDate: nil
|
||||
inMode: NSEventTrackingRunLoopMode
|
||||
|
@ -5113,3 +5256,69 @@ configuation! */
|
|||
|
||||
@end
|
||||
|
||||
@implementation NSTextStorage(NSTextViewUndoSupport)
|
||||
/* FIXME: Should this code be moved to NSTextStorage? */
|
||||
- (NSTextView *)_bestTextViewForUndo
|
||||
{
|
||||
int i, j;
|
||||
NSArray *textContainers;
|
||||
NSTextView *tv, *first = nil, *best = nil;
|
||||
NSWindow *win;
|
||||
|
||||
/* The "best" view will be one in the key window followed by one in the
|
||||
* main window. In either case, we prefer the window's first responder.
|
||||
* If no view is in the key or main window, we simply use the first text
|
||||
* view. Since -shouldChangeTextInRange:replacementString: returns NO
|
||||
* by default if a NSTextView is not editable, we consider only editable
|
||||
* views here.
|
||||
*/
|
||||
for (i = 0; i < [_layoutManagers count]; i++)
|
||||
{
|
||||
textContainers = [[_layoutManagers objectAtIndex: i] textContainers];
|
||||
for (j = 0; j < [textContainers count]; j++)
|
||||
{
|
||||
tv = [[textContainers objectAtIndex: j] textView];
|
||||
if ([tv isEditable])
|
||||
{
|
||||
win = [tv window];
|
||||
if (first == nil)
|
||||
first = tv;
|
||||
if ([win isKeyWindow])
|
||||
{
|
||||
if ([win firstResponder] == tv)
|
||||
return tv;
|
||||
else if (best == nil)
|
||||
best = tv;
|
||||
}
|
||||
else if ([win isMainWindow])
|
||||
{
|
||||
if ([win firstResponder] == tv)
|
||||
{
|
||||
if (best == nil || ![[best window] isKeyWindow])
|
||||
best = tv;
|
||||
}
|
||||
else if (best == nil)
|
||||
best = tv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return best != nil ? best : first;
|
||||
}
|
||||
|
||||
- (void)_undoReplaceCharactersInRange: (NSRange)undoRange
|
||||
withAttributedString: (NSAttributedString *)undoString
|
||||
selectedRange: (NSRange)selectedRange
|
||||
{
|
||||
NSTextView *tv = [self _bestTextViewForUndo];
|
||||
|
||||
if ([tv shouldChangeTextInRange: undoRange
|
||||
replacementString: undoString ? [undoString string] : @""])
|
||||
{
|
||||
[tv replaceCharactersInRange: undoRange
|
||||
withAttributedString: undoString];
|
||||
[tv setSelectedRange: selectedRange];
|
||||
[tv didChangeText];
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -1322,6 +1322,45 @@ and layout is left-to-right */
|
|||
[[self enclosingScrollView] scrollPageUp: sender];
|
||||
}
|
||||
|
||||
- (void) centerSelectionInVisibleArea: (id)sender
|
||||
{
|
||||
NSRange range;
|
||||
NSPoint new;
|
||||
NSRect rect, vRect;
|
||||
|
||||
vRect = [self visibleRect];
|
||||
range = [self selectedRange];
|
||||
if (range.length == 0)
|
||||
{
|
||||
rect =
|
||||
[_layoutManager insertionPointRectForCharacterIndex: range.location
|
||||
inTextContainer: _textContainer];
|
||||
}
|
||||
else
|
||||
{
|
||||
range = [_layoutManager glyphRangeForCharacterRange: range
|
||||
actualCharacterRange: NULL];
|
||||
rect = [_layoutManager boundingRectForGlyphRange: range
|
||||
inTextContainer: _textContainer];
|
||||
}
|
||||
|
||||
if (NSWidth(_bounds) <= NSWidth(vRect))
|
||||
new.x = 0;
|
||||
else if (NSWidth(rect) > NSWidth(vRect))
|
||||
new.x = NSMinX(rect);
|
||||
else
|
||||
new.x = NSMinX(rect) - (NSWidth(vRect) - NSWidth(rect)) / 2;
|
||||
|
||||
if (NSHeight(_bounds) <= NSHeight(vRect))
|
||||
new.y = 0;
|
||||
else if (NSHeight(rect) > NSHeight(vRect))
|
||||
new.y = NSMinY(rect);
|
||||
else
|
||||
new.y = NSMinY(rect) - (NSHeight(vRect) - NSHeight(rect)) / 2;
|
||||
|
||||
[self scrollPoint: new];
|
||||
}
|
||||
|
||||
|
||||
/* -selectAll: inherited from NSText */
|
||||
|
||||
|
@ -1342,15 +1381,15 @@ and layout is left-to-right */
|
|||
}
|
||||
|
||||
|
||||
/* The following method is bound to 'Control-t', and must work like
|
||||
* pressing 'Control-t' inside Emacs. For example, say that I type
|
||||
* 'Nicoal' in a NSTextView. Then, I press 'Control-t'. This should
|
||||
* swap the last two characters which were inserted, thus swapping the
|
||||
* 'a' and the 'l', and changing the text to read 'Nicola'. */
|
||||
/*
|
||||
TODO: description incorrect. should swap characters on either side of the
|
||||
insertion point. (see also: miswart)
|
||||
*/
|
||||
/* The following method is bound to 'Control-t', and works exactly like
|
||||
* pressing 'Control-t' inside Emacs, i.e., in general it swaps the
|
||||
* character immediately before and after the insertion point and moves
|
||||
* the insertion point forward by one character. If, however, the
|
||||
* insertion point is at the end of a line, it swaps the two characters
|
||||
* before the insertion point and does not move the insertion point.
|
||||
* Note that Mac OS X does not implement the special case at the end
|
||||
* of a line, but I consider Emacs' behavior more useful.
|
||||
*/
|
||||
- (void) transpose: (id)sender
|
||||
{
|
||||
NSRange range = [self selectedRange];
|
||||
|
@ -1358,16 +1397,26 @@ insertion point. (see also: miswart)
|
|||
NSString *replacementString;
|
||||
unichar chars[2];
|
||||
|
||||
/* Do nothing if we are at beginning of text. */
|
||||
if (range.location < 2)
|
||||
/* Do nothing if the selection is not empty or if we are at the
|
||||
* beginning of text. */
|
||||
if (range.length > 0 || range.location < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
range = NSMakeRange(range.location - 2, 2);
|
||||
range = NSMakeRange(range.location - 1, 2);
|
||||
|
||||
/* Eventually adjust the range if we are at the end of a line. */
|
||||
string = [_textStorage string];
|
||||
if (range.location + 1 == [string length]
|
||||
|| [string characterAtIndex: range.location + 1] == '\n')
|
||||
{
|
||||
if (range.location == 0)
|
||||
return;
|
||||
range.location -= 1;
|
||||
}
|
||||
|
||||
/* Get the two chars and swap them. */
|
||||
string = [_textStorage string];
|
||||
chars[1] = [string characterAtIndex: range.location];
|
||||
chars[0] = [string characterAtIndex: (range.location + 1)];
|
||||
|
||||
|
@ -1379,6 +1428,7 @@ insertion point. (see also: miswart)
|
|||
{
|
||||
[self replaceCharactersInRange: range
|
||||
withString: replacementString];
|
||||
[self setSelectedRange: NSMakeRange(range.location + 2, 0)];
|
||||
[self didChangeText];
|
||||
}
|
||||
}
|
||||
|
|
140
Source/NSTokenField.m
Normal file
140
Source/NSTokenField.m
Normal file
|
@ -0,0 +1,140 @@
|
|||
/** <title>NSTokenField</title>
|
||||
|
||||
<abstract>
|
||||
Token field control class for token entry. The default token is ",".
|
||||
</abstract>
|
||||
|
||||
Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
|
||||
Author: Gregory Casamento <greg.casamento@gmail.com>
|
||||
Date: July 2008
|
||||
|
||||
This file is part of the GNUstep GUI Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; see the file COPYING.LIB.
|
||||
If not, see <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "AppKit/NSApplication.h"
|
||||
#include "AppKit/NSCursor.h"
|
||||
#include "AppKit/NSGraphics.h"
|
||||
#include "AppKit/NSTokenField.h"
|
||||
#include "AppKit/NSTokenFieldCell.h"
|
||||
#include "AppKit/NSWindow.h"
|
||||
#include "AppKit/NSKeyValueBinding.h"
|
||||
#include <Foundation/NSNotification.h>
|
||||
#include "GSBindingHelpers.h"
|
||||
|
||||
static NSNotificationCenter *nc = nil;
|
||||
|
||||
/*
|
||||
* Class variables
|
||||
*/
|
||||
static Class usedCellClass;
|
||||
static Class tokenFieldCellClass;
|
||||
|
||||
@implementation NSTokenField
|
||||
|
||||
//
|
||||
// Class methods
|
||||
//
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSTokenField class])
|
||||
{
|
||||
[self setVersion: 1];
|
||||
tokenFieldCellClass = [NSTokenFieldCell class];
|
||||
usedCellClass = tokenFieldCellClass;
|
||||
nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
[self exposeBinding: NSEditableBinding];
|
||||
[self exposeBinding: NSTextColorBinding];
|
||||
}
|
||||
}
|
||||
|
||||
- (id) initWithFrame: (NSRect)frame
|
||||
{
|
||||
if((self = [super initWithFrame: frame]) == nil)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
// initialize...
|
||||
[_cell setTokenStyle: NSDefaultTokenStyle];
|
||||
[_cell setCompletionDelay: [_cell defaultCompletionDelay]];
|
||||
[_cell setTokenizingCharacterSet: [_cell defaultTokenizingCharacterSet]];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setting the Cell class
|
||||
*/
|
||||
+ (Class) cellClass
|
||||
{
|
||||
return usedCellClass;
|
||||
}
|
||||
|
||||
+ (void) setCellClass: (Class)factoryId
|
||||
{
|
||||
usedCellClass = factoryId ? factoryId : tokenFieldCellClass;
|
||||
}
|
||||
|
||||
// Style...
|
||||
- (NSTokenStyle)tokenStyle
|
||||
{
|
||||
return [_cell tokenStyle];
|
||||
}
|
||||
|
||||
- (void)setTokenStyle:(NSTokenStyle)style
|
||||
{
|
||||
[_cell setTokenStyle: style];
|
||||
}
|
||||
|
||||
// Completion delay...
|
||||
+ (NSTimeInterval)defaultCompletionDelay
|
||||
{
|
||||
return [usedCellClass defaultCompletionDelay];
|
||||
}
|
||||
|
||||
- (NSTimeInterval)completionDelay
|
||||
{
|
||||
return [_cell completionDelay];
|
||||
}
|
||||
|
||||
- (void)setCompletionDelay:(NSTimeInterval)delay
|
||||
{
|
||||
[_cell setCompletionDelay: delay];
|
||||
}
|
||||
|
||||
// Character set...
|
||||
+ (NSCharacterSet *)defaultTokenizingCharacterSet
|
||||
{
|
||||
return [usedCellClass defaultTokenizingCharacterSet];
|
||||
}
|
||||
|
||||
- (void)setTokenizingCharacterSet:(NSCharacterSet *)characterSet
|
||||
{
|
||||
[_cell setTokenizingCharacterSet: characterSet];
|
||||
}
|
||||
|
||||
- (NSCharacterSet *)tokenizingCharacterSet
|
||||
{
|
||||
return [_cell tokenizingCharacterSet];
|
||||
}
|
||||
@end
|
122
Source/NSTokenFieldCell.m
Normal file
122
Source/NSTokenFieldCell.m
Normal file
|
@ -0,0 +1,122 @@
|
|||
/** <title>NSTokenFieldCell</title>
|
||||
|
||||
<abstract>Cell class for the token field entry control</abstract>
|
||||
|
||||
Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
|
||||
Author: Gregory Casamento <greg.casamento@gmail.com>
|
||||
Date: July 2008
|
||||
This file is part of the GNUstep GUI Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; see the file COPYING.LIB.
|
||||
If not, see <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <Foundation/NSNotification.h>
|
||||
#include <Foundation/NSCharacterSet.h>
|
||||
#include "AppKit/NSControl.h"
|
||||
#include "AppKit/NSEvent.h"
|
||||
#include "AppKit/NSTokenField.h"
|
||||
#include "AppKit/NSTokenFieldCell.h"
|
||||
|
||||
|
||||
@implementation NSTokenFieldCell
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSTokenFieldCell class])
|
||||
{
|
||||
[self setVersion: 1];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(tokenizingCharacterSet);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
//
|
||||
// NSCoding protocol
|
||||
//
|
||||
- (void) encodeWithCoder: (NSCoder*)aCoder
|
||||
{
|
||||
[super encodeWithCoder: aCoder];
|
||||
|
||||
if ([aCoder allowsKeyedCoding])
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (NSCoder*)aDecoder
|
||||
{
|
||||
self = [super initWithCoder: aDecoder];
|
||||
|
||||
if ([aDecoder allowsKeyedCoding])
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
// Style...
|
||||
- (NSTokenStyle)tokenStyle
|
||||
{
|
||||
return tokenStyle;
|
||||
}
|
||||
|
||||
- (void)setTokenStyle:(NSTokenStyle)style
|
||||
{
|
||||
tokenStyle = style;
|
||||
}
|
||||
|
||||
// Completion delay...
|
||||
+ (NSTimeInterval)defaultCompletionDelay
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (NSTimeInterval)completionDelay
|
||||
{
|
||||
return completionDelay;
|
||||
}
|
||||
|
||||
- (void)setCompletionDelay:(NSTimeInterval)delay
|
||||
{
|
||||
completionDelay = delay;
|
||||
}
|
||||
|
||||
// Character set...
|
||||
+ (NSCharacterSet *)defaultTokenizingCharacterSet
|
||||
{
|
||||
return [NSCharacterSet characterSetWithCharactersInString: @","];
|
||||
}
|
||||
|
||||
- (void)setTokenizingCharacterSet:(NSCharacterSet *)characterSet
|
||||
{
|
||||
ASSIGN(tokenizingCharacterSet, characterSet);
|
||||
}
|
||||
|
||||
- (NSCharacterSet *)tokenizingCharacterSet
|
||||
{
|
||||
return tokenizingCharacterSet;
|
||||
}
|
||||
@end
|
|
@ -74,6 +74,7 @@
|
|||
#include "AppKit/PSOperators.h"
|
||||
#include "GNUstepGUI/GSDisplayServer.h"
|
||||
#include "GNUstepGUI/GSTrackingRect.h"
|
||||
#include "GNUstepGUI/GSNibLoading.h"
|
||||
#include "GSToolTips.h"
|
||||
#include "GSBindingHelpers.h"
|
||||
|
||||
|
@ -532,8 +533,8 @@ GSSetDragTypes(NSView* obj, NSArray *types)
|
|||
_bounds.origin = NSZeroPoint; // Set bounds rectangle
|
||||
_bounds.size = _frame.size;
|
||||
|
||||
//_frameMatrix = [NSAffineTransform new]; // Map fromsuperview to frame
|
||||
//_boundsMatrix = [NSAffineTransform new]; // Map from superview to bounds
|
||||
// _frameMatrix = [NSAffineTransform new]; // Map fromsuperview to frame
|
||||
// _boundsMatrix = [NSAffineTransform new]; // Map from superview to bounds
|
||||
_matrixToWindow = [NSAffineTransform new]; // Map to window coordinates
|
||||
_matrixFromWindow = [NSAffineTransform new]; // Map from window coordinates
|
||||
|
||||
|
@ -4402,8 +4403,8 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
|
|||
[super initWithCoder: aDecoder];
|
||||
|
||||
// initialize these here, since they're needed in either case.
|
||||
//_frameMatrix = [NSAffineTransform new]; // Map fromsuperview to frame
|
||||
//_boundsMatrix = [NSAffineTransform new]; // Map fromsuperview to bounds
|
||||
// _frameMatrix = [NSAffineTransform new]; // Map fromsuperview to frame
|
||||
// _boundsMatrix = [NSAffineTransform new]; // Map from superview to bounds
|
||||
_matrixToWindow = [NSAffineTransform new]; // Map to window coordinates
|
||||
_matrixFromWindow = [NSAffineTransform new];// Map from window coordinates
|
||||
|
||||
|
@ -4471,6 +4472,8 @@ static NSView* findByTag(NSView *view, int aTag, unsigned *level)
|
|||
e = [subs objectEnumerator];
|
||||
while ((sub = [e nextObject]) != nil)
|
||||
{
|
||||
NSAssert([sub class] != [NSCustomView class],
|
||||
NSInternalInconsistencyException);
|
||||
NSAssert([sub window] == nil,
|
||||
NSInternalInconsistencyException);
|
||||
NSAssert([sub superview] == nil,
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include <Foundation/NSSet.h>
|
||||
#include <Foundation/NSLock.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/NSUndoManager.h>
|
||||
|
||||
#include "AppKit/NSApplication.h"
|
||||
#include "AppKit/NSButton.h"
|
||||
|
@ -838,6 +839,7 @@ many times.
|
|||
frame.origin = NSZeroPoint;
|
||||
[_wv setFrame: frame];
|
||||
[_wv setWindowNumber: _windowNum];
|
||||
[_wv setDocumentEdited: _f.is_edited];
|
||||
[_wv setNeedsDisplay: YES];
|
||||
}
|
||||
}
|
||||
|
@ -980,8 +982,6 @@ many times.
|
|||
@"can be created.");
|
||||
|
||||
NSDebugLLog(@"NSWindow", @"NSWindow start of init\n");
|
||||
if (!windowDecorator)
|
||||
windowDecorator = [GSWindowDecorationView windowDecorator];
|
||||
|
||||
// FIXME: This hack is here to work around a gorm decoding problem.
|
||||
if (_windowNum)
|
||||
|
@ -1014,6 +1014,9 @@ many times.
|
|||
/* Create the window view */
|
||||
cframe.origin = NSZeroPoint;
|
||||
cframe.size = _frame.size;
|
||||
if (!windowDecorator)
|
||||
windowDecorator = [GSWindowDecorationView windowDecorator];
|
||||
|
||||
_wv = [windowDecorator newWindowDecorationViewWithFrame: cframe
|
||||
window: self];
|
||||
[_wv _viewWillMoveToWindow: self];
|
||||
|
@ -1091,12 +1094,12 @@ many times.
|
|||
|
||||
- (NSRect) contentRectForFrameRect: (NSRect)frameRect
|
||||
{
|
||||
return [isa contentRectForFrameRect: frameRect styleMask: _styleMask];
|
||||
return [_wv contentRectForFrameRect: frameRect styleMask: _styleMask];
|
||||
}
|
||||
|
||||
- (NSRect) frameRectForContentRect: (NSRect)contentRect
|
||||
{
|
||||
return [isa frameRectForContentRect: contentRect styleMask: _styleMask];
|
||||
return [_wv frameRectForContentRect: contentRect styleMask: _styleMask];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1112,12 +1115,14 @@ many times.
|
|||
previous content view. */
|
||||
- (void) setContentView: (NSView*)aView
|
||||
{
|
||||
if (aView == _contentView)
|
||||
return;
|
||||
|
||||
if (aView == nil)
|
||||
{
|
||||
aView = AUTORELEASE([[NSView alloc]
|
||||
initWithFrame:
|
||||
[NSWindow contentRectForFrameRect: _frame
|
||||
styleMask: _styleMask]]);
|
||||
[self contentRectForFrameRect: _frame]]);
|
||||
}
|
||||
if (_contentView != nil)
|
||||
{
|
||||
|
@ -1819,7 +1824,7 @@ many times.
|
|||
}
|
||||
|
||||
[self setFrameTopLeftPoint: topLeftPoint];
|
||||
cRect = [isa contentRectForFrameRect: _frame styleMask: _styleMask];
|
||||
cRect = [self contentRectForFrameRect: _frame];
|
||||
topLeftPoint.x = NSMinX(cRect);
|
||||
topLeftPoint.y = NSMaxY(cRect);
|
||||
|
||||
|
@ -2030,7 +2035,7 @@ many times.
|
|||
NSRect r = _frame;
|
||||
|
||||
r.size = aSize;
|
||||
r = [NSWindow frameRectForContentRect: r styleMask: _styleMask];
|
||||
r = [self frameRectForContentRect: r];
|
||||
r.origin = _frame.origin;
|
||||
[self setFrame: r display: YES];
|
||||
}
|
||||
|
@ -2769,8 +2774,6 @@ resetCursorRectsForView(NSView *theView)
|
|||
{
|
||||
NSWindow *mini = GSWindowWithNumber(_counterpart);
|
||||
[mini orderFront: self];
|
||||
// If the window is still visible, order it out.
|
||||
[self orderOut: self];
|
||||
}
|
||||
[nc postNotificationName: NSWindowDidMiniaturizeNotification
|
||||
object: self];
|
||||
|
@ -2981,6 +2984,16 @@ resetCursorRectsForView(NSView *theView)
|
|||
}
|
||||
}
|
||||
|
||||
- (void) undo: (id)sender
|
||||
{
|
||||
[[self undoManager] undo];
|
||||
}
|
||||
|
||||
- (void) redo: (id)sender
|
||||
{
|
||||
[[self undoManager] redo];
|
||||
}
|
||||
|
||||
/**
|
||||
If YES, then the window is released when the close method is called.
|
||||
*/
|
||||
|
@ -4755,6 +4768,73 @@ current key view.<br />
|
|||
_f.displays_when_screen_profile_changes = flag;
|
||||
}
|
||||
|
||||
/*
|
||||
* Menu item validation
|
||||
*/
|
||||
|
||||
- (BOOL)validateMenuItem: (NSMenuItem *)anItem
|
||||
{
|
||||
BOOL result = YES;
|
||||
SEL action = [anItem action];
|
||||
|
||||
if (sel_eq(action, @selector(performClose:)))
|
||||
{
|
||||
result = ([self styleMask] & NSClosableWindowMask) ? YES : NO;
|
||||
}
|
||||
else if (sel_eq(action, @selector(performMiniaturize:)))
|
||||
{
|
||||
result = ([self styleMask] & NSMiniaturizableWindowMask) ? YES : NO;
|
||||
}
|
||||
else if (sel_eq(action, @selector(performZoom:)))
|
||||
{
|
||||
result = ([self styleMask] & NSResizableWindowMask) ? YES : NO;
|
||||
}
|
||||
else if (sel_eq(action, @selector(undo:)))
|
||||
{
|
||||
NSUndoManager *undo = [self undoManager];
|
||||
if (undo == nil)
|
||||
{
|
||||
result = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([undo canUndo])
|
||||
{
|
||||
[anItem setTitle: [undo undoMenuItemTitle]];
|
||||
result = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
[anItem setTitle: [undo undoMenuTitleForUndoActionName: @""]];
|
||||
result = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sel_eq(action, @selector(redo:)))
|
||||
{
|
||||
NSUndoManager *undo = [self undoManager];
|
||||
if (undo == nil)
|
||||
{
|
||||
result = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([undo canRedo])
|
||||
{
|
||||
[anItem setTitle: [undo redoMenuItemTitle]];
|
||||
result = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
[anItem setTitle: [undo redoMenuTitleForUndoActionName: @""]];
|
||||
result = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assigning a delegate
|
||||
*/
|
||||
|
@ -4980,6 +5060,12 @@ current key view.<br />
|
|||
// Should only be defined on MS Windows
|
||||
return (void *)(intptr_t)_windowNum;
|
||||
}
|
||||
|
||||
- (NSWindow *) attachedSheet
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*
|
||||
|
|
|
@ -40,12 +40,20 @@
|
|||
|
||||
@implementation NSWindowController
|
||||
|
||||
- (id) initWithWindowNibName: (NSString *)windowNibName
|
||||
+ (void) initialize
|
||||
{
|
||||
return [self initWithWindowNibName: windowNibName owner: self];
|
||||
if (self == [NSWindowController class])
|
||||
{
|
||||
[self setVersion: 1];
|
||||
}
|
||||
}
|
||||
|
||||
- (id) initWithWindowNibName: (NSString *)windowNibName owner: (id)owner
|
||||
- (id) initWithWindowNibName: (NSString *)windowNibName
|
||||
{
|
||||
return [self initWithWindowNibName: windowNibName owner: self];
|
||||
}
|
||||
|
||||
- (id) initWithWindowNibName: (NSString *)windowNibName owner: (id)owner
|
||||
{
|
||||
if (windowNibName == nil)
|
||||
{
|
||||
|
@ -60,13 +68,16 @@
|
|||
}
|
||||
|
||||
self = [self initWithWindow: nil];
|
||||
if (!self)
|
||||
return nil;
|
||||
|
||||
ASSIGN(_window_nib_name, windowNibName);
|
||||
_owner = owner;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithWindowNibPath: (NSString *)windowNibPath
|
||||
owner: (id)owner
|
||||
owner: (id)owner
|
||||
{
|
||||
if (windowNibPath == nil)
|
||||
{
|
||||
|
@ -81,6 +92,9 @@
|
|||
}
|
||||
|
||||
self = [self initWithWindow: nil];
|
||||
if (!self)
|
||||
return nil;
|
||||
|
||||
ASSIGN(_window_nib_path, windowNibPath);
|
||||
_owner = owner;
|
||||
return self;
|
||||
|
@ -89,10 +103,12 @@
|
|||
- (id) initWithWindow: (NSWindow *)window
|
||||
{
|
||||
self = [super init];
|
||||
if (!self)
|
||||
return nil;
|
||||
|
||||
_window_frame_autosave_name = @"";
|
||||
ASSIGN(_window_frame_autosave_name, @"");
|
||||
_wcFlags.should_cascade = YES;
|
||||
_wcFlags.should_close_document = NO;
|
||||
//_wcFlags.should_close_document = NO;
|
||||
|
||||
[self setWindow: window];
|
||||
if (_window != nil)
|
||||
|
@ -191,7 +207,7 @@
|
|||
|
||||
- (void) setDocumentEdited: (BOOL)flag
|
||||
{
|
||||
[_window setDocumentEdited: flag];
|
||||
[[self window] setDocumentEdited: flag];
|
||||
}
|
||||
|
||||
- (void) setWindowFrameAutosaveName:(NSString *)name
|
||||
|
@ -310,32 +326,44 @@
|
|||
|
||||
if (_window != nil)
|
||||
{
|
||||
NSResponder *responder;
|
||||
|
||||
[nc removeObserver: self
|
||||
name: NSWindowWillCloseNotification
|
||||
object: _window];
|
||||
name: NSWindowWillCloseNotification
|
||||
object: _window];
|
||||
// Remove self from the responder chain
|
||||
responder = _window;
|
||||
while (responder && [responder nextResponder] != self)
|
||||
{
|
||||
responder = [responder nextResponder];
|
||||
}
|
||||
[responder setNextResponder: [self nextResponder]];
|
||||
[_window setWindowController: nil];
|
||||
}
|
||||
|
||||
ASSIGN (_window, aWindow);
|
||||
ASSIGN(_window, aWindow);
|
||||
|
||||
if (_window != nil)
|
||||
{
|
||||
[_window setWindowController: self];
|
||||
// Put self into the responder chain
|
||||
[self setNextResponder: [_window nextResponder]];
|
||||
[_window setNextResponder: self];
|
||||
[nc addObserver: self
|
||||
selector: @selector(_windowWillClose:)
|
||||
name: NSWindowWillCloseNotification
|
||||
object: _window];
|
||||
selector: @selector(_windowWillClose:)
|
||||
name: NSWindowWillCloseNotification
|
||||
object: _window];
|
||||
|
||||
/* For information on the following, see the description in
|
||||
-setDocument: */
|
||||
-setDocument: */
|
||||
if (_document == nil)
|
||||
{
|
||||
[_window setReleasedWhenClosed: NO];
|
||||
}
|
||||
{
|
||||
[_window setReleasedWhenClosed: NO];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_window setReleasedWhenClosed: YES];
|
||||
}
|
||||
{
|
||||
[_window setReleasedWhenClosed: YES];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -464,7 +492,25 @@
|
|||
|
||||
- (id) initWithCoder: (NSCoder *)coder
|
||||
{
|
||||
return [self init];
|
||||
if ([coder allowsKeyedCoding]
|
||||
|| [coder versionForClassName: @"NSWindowController"] >= 1)
|
||||
{
|
||||
self = [super initWithCoder: coder];
|
||||
if (!self)
|
||||
return nil;
|
||||
|
||||
ASSIGN(_window_frame_autosave_name, @"");
|
||||
_wcFlags.should_cascade = YES;
|
||||
//_wcFlags.should_close_document = NO;
|
||||
|
||||
return self;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* backward compatibility: old NSWindowController instances are not
|
||||
subclasses of NSResponder, but of NSObject */
|
||||
return [self init];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) encodeWithCoder: (NSCoder *)coder
|
||||
|
@ -472,6 +518,8 @@
|
|||
// What are we supposed to encode? Window nib name? Or should these
|
||||
// be empty, just to conform to NSCoding, so we do an -init on
|
||||
// unarchival. ?
|
||||
|
||||
[super encodeWithCoder: coder];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include <Foundation/NSPathUtilities.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/NSTask.h>
|
||||
#include <GNUstepBase/NSTask+GS.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSFileManager.h>
|
||||
#include <Foundation/NSNotificationQueue.h>
|
||||
|
@ -1037,6 +1038,7 @@ inFileViewerRootedAtPath: (NSString*)rootFullpath
|
|||
}
|
||||
else
|
||||
{
|
||||
*appName = nil;
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
@ -1219,14 +1221,14 @@ inFileViewerRootedAtPath: (NSString*)rootFullpath
|
|||
*/
|
||||
extension = [fullPath pathExtension];
|
||||
if ([extension isEqualToString: @"app"]
|
||||
|| [extension isEqualToString: @"debug"]
|
||||
|| [extension isEqualToString: @"profile"]
|
||||
|| [extension isEqualToString: @"bundle"])
|
||||
|| [extension isEqualToString: @"debug"]
|
||||
|| [extension isEqualToString: @"profile"]
|
||||
|| [extension isEqualToString: @"bundle"])
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
else if ([extension length] > 0
|
||||
&& [self getBestAppInRole: nil forExtension: extension] != nil)
|
||||
&& [self getBestAppInRole: nil forExtension: extension] != nil)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
@ -1272,14 +1274,7 @@ inFileViewerRootedAtPath: (NSString*)rootFullpath
|
|||
*/
|
||||
if (path == nil)
|
||||
{
|
||||
#ifdef GNUSTEP_BASE_LIBRARY
|
||||
path = RETAIN([[NSSearchPathForDirectoriesInDomains(
|
||||
GSToolsDirectory, NSSystemDomainMask, YES) objectAtIndex: 0]
|
||||
stringByAppendingPathComponent: @"make_services"]);
|
||||
#else
|
||||
path = RETAIN([@GNUSTEP_TOOLS_NO_DESTDIR
|
||||
stringByAppendingPathComponent: @"make_services"]);
|
||||
#endif
|
||||
path = [NSTask launchPathForTool: @"make_services"];
|
||||
}
|
||||
task = [NSTask launchedTaskWithLaunchPath: path
|
||||
arguments: nil];
|
||||
|
@ -1891,7 +1886,14 @@ inFileViewerRootedAtPath: (NSString*)rootFullpath
|
|||
}
|
||||
|
||||
iconPath = [[bundle infoDictionary] objectForKey: @"NSIcon"];
|
||||
|
||||
if(iconPath == nil)
|
||||
{
|
||||
/*
|
||||
* Try the CFBundleIconFile property.
|
||||
*/
|
||||
iconPath = [[bundle infoDictionary] objectForKey: @"CFBundleIconFile"];
|
||||
}
|
||||
|
||||
if (iconPath && [iconPath isAbsolutePath] == NO)
|
||||
{
|
||||
NSString *file = iconPath;
|
||||
|
@ -1917,7 +1919,7 @@ inFileViewerRootedAtPath: (NSString*)rootFullpath
|
|||
* try 'wrapper/app.png'
|
||||
*/
|
||||
if (iconPath == nil)
|
||||
{
|
||||
{
|
||||
NSString *str;
|
||||
|
||||
str = [fullPath lastPathComponent];
|
||||
|
@ -1929,11 +1931,15 @@ inFileViewerRootedAtPath: (NSString*)rootFullpath
|
|||
iconPath = [iconPath stringByAppendingPathExtension: @"tiff"];
|
||||
if ([mgr isReadableFileAtPath: iconPath] == NO)
|
||||
{
|
||||
iconPath = nil;
|
||||
iconPath = [iconPath stringByAppendingPathExtension: @"icns"];
|
||||
if ([mgr isReadableFileAtPath: iconPath] == NO)
|
||||
{
|
||||
iconPath = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (iconPath != nil)
|
||||
{
|
||||
image = [self _saveImageFor: iconPath];
|
||||
|
@ -2084,6 +2090,11 @@ inFileViewerRootedAtPath: (NSString*)rootFullpath
|
|||
NSDictionary *typeInfo = [extInfo objectForKey: appName];
|
||||
NSString *file = [typeInfo objectForKey: @"NSIcon"];
|
||||
|
||||
if(file == nil)
|
||||
{
|
||||
file = [typeInfo objectForKey: @"CFBundleTypeIconFile"];
|
||||
}
|
||||
|
||||
if (file && [file length] != 0)
|
||||
{
|
||||
if ([file isAbsolutePath] == NO)
|
||||
|
@ -2366,7 +2377,7 @@ inFileViewerRootedAtPath: (NSString*)rootFullpath
|
|||
|
||||
/*
|
||||
* If the requested role is 'nil', we can accept an app that is either
|
||||
* an Editor (preferred) or a Viewer.
|
||||
* an Editor (preferred) or a Viewer, or unknown.
|
||||
*/
|
||||
while ((appName = [enumerator nextObject]) != nil)
|
||||
{
|
||||
|
@ -2374,7 +2385,10 @@ inFileViewerRootedAtPath: (NSString*)rootFullpath
|
|||
|
||||
info = [apps objectForKey: appName];
|
||||
str = [info objectForKey: @"NSRole"];
|
||||
if (str == nil || [str isEqualToString: @"Editor"])
|
||||
/* NB. If str is nil or an empty string, there is no role set,
|
||||
* and we treat this as an Editor since the role is unrestricted.
|
||||
*/
|
||||
if ([str length] == 0 || [str isEqualToString: @"Editor"])
|
||||
{
|
||||
if (app != 0)
|
||||
{
|
||||
|
@ -2382,7 +2396,7 @@ inFileViewerRootedAtPath: (NSString*)rootFullpath
|
|||
}
|
||||
return YES;
|
||||
}
|
||||
else if ([str isEqualToString: @"Viewer"])
|
||||
if ([str isEqualToString: @"Viewer"])
|
||||
{
|
||||
if (app != 0)
|
||||
{
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
PACKAGE_NAME = gnustep-gui
|
||||
include $(GNUSTEP_MAKEFILES)/common.make
|
||||
#
|
||||
# The list of subproject directories
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue