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:
Adam Fedor 2008-12-22 00:14:39 +00:00
commit a0ed4f9ca6
108 changed files with 9452 additions and 5918 deletions

View file

@ -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

1618
ChangeLog

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -1,3 +1,4 @@
PACKAGE_NAME = gnustep-gui
include $(GNUSTEP_MAKEFILES)/common.make
DOCUMENT_NAME = AppKit

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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 */

View file

@ -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

View file

@ -66,6 +66,8 @@ enum {
id _delegate;
NSAlertStyle _style;
BOOL _shows_help;
id _modalDelegate;
SEL _didEndSelector;
int _result;
}

View file

@ -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

View file

@ -493,11 +493,5 @@ enum {
inView: (NSView*)controlView;
@end
//
// Function which should be somewhere else
//
inline NSSize
_sizeForBorderType (NSBorderType aType);
#endif // _GNUstep_H_NSCell

View file

@ -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;
}

View file

@ -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__ */

View file

@ -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

View file

@ -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;

View file

@ -70,7 +70,7 @@ enum {
NSSize _originalMinSize;
NSSize _originalSize;
NSString *_requiredFileType;
NSArray *_allowedFileTypes;
NSString *_directory;
NSString *_fullFileName;

View file

@ -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

View file

@ -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

View 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

View 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

View file

@ -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

View file

@ -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;

View file

@ -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 \

Binary file not shown.

View file

@ -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
View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)
{

View file

@ -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 \

View file

@ -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)\" \

View file

@ -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]);

View file

@ -30,7 +30,7 @@
#include <AppKit/AppKit.h>
#include "GNUstepGUI/GSModelLoaderFactory.h"
#include "GNUstepGUI/GSNibTemplates.h"
#include "GNUstepGUI/GSGormLoading.h"
@interface GSGormLoader : GSModelLoader
@end

View file

@ -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;

View file

@ -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: ");
}

View file

@ -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;

View file

@ -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

View file

@ -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,

View file

@ -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.
*/

View file

@ -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];

View file

@ -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

View file

@ -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;

View file

@ -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];
}

View file

@ -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] == '\''

View file

@ -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];

View 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

View 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

View file

@ -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);

View file

@ -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

View file

@ -174,13 +174,6 @@
[self label]];
return desc;
}
- (void) instantiateWithInstantiator: (id<GSInstantiator>)instantiator
{
_src = [instantiator instantiateObject: _src];
_dst = [instantiator instantiateObject: _dst];
}
@end
@implementation NSNibControlConnector

View file

@ -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)
{

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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];

View file

@ -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"]];

View file

@ -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

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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);
}

View file

@ -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

View file

@ -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"];
}

View file

@ -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"])

View file

@ -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

View file

@ -27,7 +27,7 @@
Boston, MA 02110-1301, USA.
*/
#import <GNUstepGUI/GSNibCompatibility.h>
#import <GNUstepGUI/GSNibLoading.h>
#import <Foundation/NSString.h>
@implementation NSNibAXAttributeConnector

View file

@ -27,7 +27,7 @@
Boston, MA 02110-1301, USA.
*/
#import <GNUstepGUI/GSNibCompatibility.h>
#import <GNUstepGUI/GSNibLoading.h>
#import <Foundation/NSString.h>
@implementation NSNibAXRelationshipConnector

View file

@ -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>

View file

@ -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];

View file

@ -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];

View file

@ -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)
{

View file

@ -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>
*/

View file

@ -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
{

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -71,6 +71,8 @@
{
[[GSTheme theme] drawDarkButton: cellFrame withClip: cellFrame];
}
[self _drawBackgroundWithFrame: cellFrame inView: controlView];
}
- (void) setHighlighted: (BOOL)flag

View file

@ -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];
}

View file

@ -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;

View file

@ -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

View file

@ -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
View 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
View 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

View file

@ -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,

View file

@ -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
/*

View file

@ -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

View file

@ -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)
{

View file

@ -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