зеркало из https://github.com/mozilla/pjs.git
new in-window bookmark manager.
This commit is contained in:
Родитель
f0f2f1792c
Коммит
45e820f36d
|
@ -732,6 +732,8 @@
|
|||
F583E3C303B8228F01A80166,
|
||||
F5F415CB03B9223E01A80166,
|
||||
F527C90403BCD43601A80166,
|
||||
3F2CF8CD042A88B7005FD42F,
|
||||
3F2CF8D2042A8B30005FD42F,
|
||||
);
|
||||
isa = PBXHeadersBuildPhase;
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -886,6 +888,8 @@
|
|||
F583E3C003B8228701A80166,
|
||||
F5F415CC03B9223E01A80166,
|
||||
F527C90503BCD43601A80166,
|
||||
3F2CF8CE042A88B7005FD42F,
|
||||
3F2CF8D5042A8C47005FD42F,
|
||||
);
|
||||
isa = PBXSourcesBuildPhase;
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -1031,6 +1035,80 @@
|
|||
settings = {
|
||||
};
|
||||
};
|
||||
3F2CF8CB042A88B7005FD42F = {
|
||||
fileEncoding = 30;
|
||||
isa = PBXFileReference;
|
||||
path = ImageAndTextCell.h;
|
||||
refType = 2;
|
||||
};
|
||||
3F2CF8CC042A88B7005FD42F = {
|
||||
fileEncoding = 30;
|
||||
isa = PBXFileReference;
|
||||
path = ImageAndTextCell.m;
|
||||
refType = 2;
|
||||
};
|
||||
3F2CF8CD042A88B7005FD42F = {
|
||||
fileRef = 3F2CF8CB042A88B7005FD42F;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
3F2CF8CE042A88B7005FD42F = {
|
||||
fileRef = 3F2CF8CC042A88B7005FD42F;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
3F2CF8CF042A88B7005FD42F = {
|
||||
fileRef = 3F2CF8CB042A88B7005FD42F;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
3F2CF8D0042A88B7005FD42F = {
|
||||
fileRef = 3F2CF8CC042A88B7005FD42F;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
3F2CF8D1042A8B30005FD42F = {
|
||||
fileEncoding = 4;
|
||||
isa = PBXFileReference;
|
||||
name = BookmarksController.h;
|
||||
path = src/bookmarks/BookmarksController.h;
|
||||
refType = 4;
|
||||
};
|
||||
3F2CF8D2042A8B30005FD42F = {
|
||||
fileRef = 3F2CF8D1042A8B30005FD42F;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
3F2CF8D3042A8B30005FD42F = {
|
||||
fileRef = 3F2CF8D1042A8B30005FD42F;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
3F2CF8D4042A8C47005FD42F = {
|
||||
fileEncoding = 4;
|
||||
isa = PBXFileReference;
|
||||
name = BookmarksController.mm;
|
||||
path = src/bookmarks/BookmarksController.mm;
|
||||
refType = 4;
|
||||
};
|
||||
3F2CF8D5042A8C47005FD42F = {
|
||||
fileRef = 3F2CF8D4042A8C47005FD42F;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
3F2CF8D6042A8C47005FD42F = {
|
||||
fileRef = 3F2CF8D4042A8C47005FD42F;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
//3F0
|
||||
//3F1
|
||||
//3F2
|
||||
|
@ -2504,6 +2582,7 @@
|
|||
};
|
||||
F51842F30206168101A966FE = {
|
||||
children = (
|
||||
3F2CF8D1042A8B30005FD42F,
|
||||
F5C8D55203A2A42401A8016F,
|
||||
F5F94B900332532801026D5D,
|
||||
F5DE10E60209DC0601A967DF,
|
||||
|
@ -6344,6 +6423,7 @@
|
|||
F57074BA026BFD0101A80166,
|
||||
F53E012C02AEE93601A967F3,
|
||||
2EEC3E62028138714B000102,
|
||||
3F2CF8D4042A8C47005FD42F,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Bookmarks;
|
||||
|
@ -6996,6 +7076,7 @@
|
|||
};
|
||||
F5B950BA030C833301A96654 = {
|
||||
children = (
|
||||
3F2CF8CB042A88B7005FD42F,
|
||||
F5FDF166031AF47301DE816D,
|
||||
F5D98EBC031AC38601A96654,
|
||||
F558099D02F22168015DF512,
|
||||
|
@ -7025,6 +7106,7 @@
|
|||
F541495B02711A8301A80166,
|
||||
F541495F02711B0001A80166,
|
||||
F5FDF167031AF47301DE816D,
|
||||
3F2CF8CC042A88B7005FD42F,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Source;
|
||||
|
@ -7385,6 +7467,8 @@
|
|||
F583E3C403B8228F01A80166,
|
||||
F5F415CD03B9223E01A80166,
|
||||
F527C90603BCD43601A80166,
|
||||
3F2CF8CF042A88B7005FD42F,
|
||||
3F2CF8D3042A8B30005FD42F,
|
||||
);
|
||||
isa = PBXHeadersBuildPhase;
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -7540,6 +7624,8 @@
|
|||
F583E3C103B8228701A80166,
|
||||
F5F415CE03B9223E01A80166,
|
||||
F527C90703BCD43601A80166,
|
||||
3F2CF8D0042A88B7005FD42F,
|
||||
3F2CF8D6042A8C47005FD42F,
|
||||
);
|
||||
isa = PBXSourcesBuildPhase;
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
|
@ -11,13 +11,18 @@
|
|||
{CLASS = BookmarkItem; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{CLASS = BookmarkManagerView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
|
||||
{
|
||||
ACTIONS = {changeContainer = id; };
|
||||
CLASS = BookmarksController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
mAddFolderButton = NSButton;
|
||||
mAddItemButton = NSButton;
|
||||
mBookmarksSource = BookmarksDataSource;
|
||||
mContainerPane = NSTableView;
|
||||
mContainersSplit = NSSplitView;
|
||||
mItemPane = NSOutlineView;
|
||||
mHistorySource = HistoryDataSource;
|
||||
mInfoButton = NSButton;
|
||||
mItemPane = ExtendedOutlineView;
|
||||
mItemSearchSplit = NSSplitView;
|
||||
mSearchPane = NSTableView;
|
||||
};
|
||||
|
@ -184,6 +189,7 @@
|
|||
},
|
||||
{CLASS = LocationBar; LANGUAGE = ObjC; SUPERCLASS = NSView; },
|
||||
{CLASS = MainController; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{CLASS = NSObject; LANGUAGE = ObjC; },
|
||||
{CLASS = PageProxyIcon; LANGUAGE = ObjC; SUPERCLASS = NSImageView; },
|
||||
{
|
||||
CLASS = RDFOutlineViewDataSource;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>185 81 653 383 0 0 1280 832 </string>
|
||||
<string>263 57 653 383 0 0 1280 832 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>124</key>
|
||||
|
@ -45,6 +45,7 @@
|
|||
<array/>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>160</integer>
|
||||
<integer>731</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
|
|
Двоичные данные
camino/resources/localized/English.lproj/BrowserWindow.nib/objects.nib
сгенерированный
Двоичные данные
camino/resources/localized/English.lproj/BrowserWindow.nib/objects.nib
сгенерированный
Двоичный файл не отображается.
|
@ -9,7 +9,7 @@
|
|||
<key>266</key>
|
||||
<string>644 623 277 90 0 0 1600 1002 </string>
|
||||
<key>29</key>
|
||||
<string>191 940 433 44 0 0 1280 1002 </string>
|
||||
<string>191 773 433 44 0 0 1280 832 </string>
|
||||
<key>494</key>
|
||||
<string>569 607 185 78 0 0 1280 1002 </string>
|
||||
</dict>
|
||||
|
|
Двоичный файл не отображается.
|
@ -193,7 +193,7 @@ const int kReuseWindowOnAE = 2;
|
|||
[mBookmarksMenu setAutoenablesItems: NO];
|
||||
|
||||
// menubar bookmarks
|
||||
int firstBookmarkItem = [mBookmarksMenu indexOfItemWithTag:kBookmarksDividerTag];
|
||||
int firstBookmarkItem = [mBookmarksMenu indexOfItemWithTag:kBookmarksDividerTag] + 1;
|
||||
mMenuBookmarks = [[BookmarksMenu alloc] initWithMenu: mBookmarksMenu
|
||||
firstItem: firstBookmarkItem
|
||||
rootContent: [bmManager getRootContent]
|
||||
|
|
|
@ -0,0 +1,244 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "BookmarksController.h"
|
||||
#import "ImageAndTextCell.h"
|
||||
#import "BookmarksDataSource.h"
|
||||
#import "HistoryDataSource.h"
|
||||
|
||||
|
||||
@interface BookmarksController(PRIVATE)
|
||||
- (void) setCanEditSelectedContainerContents:(BOOL)inCanEdit;
|
||||
@end
|
||||
|
||||
|
||||
@implementation BookmarksController
|
||||
|
||||
#if 0
|
||||
- (id) init
|
||||
{
|
||||
if ( self = [super init] )
|
||||
{
|
||||
mAddItemButton = nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// - windowDidLoad
|
||||
//
|
||||
// Perform some extra initialization when the window finishes loading
|
||||
// that we can't do in IB.
|
||||
//
|
||||
- (void)windowDidLoad
|
||||
{
|
||||
// hide the search panel
|
||||
|
||||
// the standard table item doesn't handle text and icons. Replace it
|
||||
// with a custom cell that does.
|
||||
ImageAndTextCell* imageAndTextCell = [[[ImageAndTextCell alloc] init] autorelease];
|
||||
[imageAndTextCell setEditable: YES];
|
||||
[imageAndTextCell setWraps: NO];
|
||||
NSTableColumn* itemNameColumn = [mItemPane tableColumnWithIdentifier: @"Name"];
|
||||
[itemNameColumn setDataCell:imageAndTextCell];
|
||||
NSTableColumn* containerNameColumn = [mContainerPane tableColumnWithIdentifier: @"Name"];
|
||||
[containerNameColumn setDataCell:imageAndTextCell];
|
||||
|
||||
// set up the font on the item view to be smaller
|
||||
NSArray* columns = [mItemPane tableColumns];
|
||||
if ( columns ) {
|
||||
int numColumns = [columns count];
|
||||
NSFont* smallerFont = [NSFont systemFontOfSize:11];
|
||||
for ( int i = 0; i < numColumns; ++i )
|
||||
[[[columns objectAtIndex:i] dataCell] setFont:smallerFont];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// - splitViewDidResizeSubviews:
|
||||
//
|
||||
// Called when one of the views got resized. We want to ensure that the "add bookmark
|
||||
// item" button gets lined up with the left edge of the item panel. If the container/item
|
||||
// split was the one that changed, move it accordingly
|
||||
//
|
||||
- (void)splitViewDidResizeSubviews:(NSNotification *)notification
|
||||
{
|
||||
const int kButtonGutter = 8;
|
||||
|
||||
if ( [notification object] == mContainersSplit ) {
|
||||
// get the position of the item view relative to the window and set the button
|
||||
// to that X value. Yes, this will fall down if the bookmark view is inset from the window
|
||||
// but i think we can safely assume it won't be.
|
||||
NSRect windowRect = [mItemPane convertRect:[mItemPane bounds] toView:nil];
|
||||
NSRect newButtonLocation = [mAddItemButton frame];
|
||||
newButtonLocation.origin.x = windowRect.origin.x;
|
||||
[mAddItemButton setFrame:newButtonLocation];
|
||||
[mAddItemButton setNeedsDisplay:YES];
|
||||
|
||||
// offset by the width of the button and the gutter and we've got the location
|
||||
// of the add folder button next to it.
|
||||
newButtonLocation.origin.x += newButtonLocation.size.width + kButtonGutter;
|
||||
[mAddFolderButton setFrame:newButtonLocation];
|
||||
[mAddFolderButton setNeedsDisplay:YES];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// - splitView:canCollapseSubview:
|
||||
//
|
||||
// Called when appkit wants to ask if it can collapse a subview. The only subview
|
||||
// of our splits that we allow to be hidden is the search panel.
|
||||
//
|
||||
- (BOOL)splitView:(NSSplitView *)sender canCollapseSubview:(NSView *)subview
|
||||
{
|
||||
BOOL retVal = NO;
|
||||
// subview will be a NSScrollView, so we have to get the superview of the
|
||||
// search pane for comparison.
|
||||
if ( sender == mItemSearchSplit && subview == [mSearchPane superview] )
|
||||
retVal = YES;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
- (float)splitView:(NSSplitView *)sender constrainMinCoordinate:(float)proposedCoord ofSubviewAt:(int)offset
|
||||
{
|
||||
const int kMinimumContainerSplitWidth = 150;
|
||||
float retVal = proposedCoord;
|
||||
if ( sender == mContainersSplit )
|
||||
retVal = kMinimumContainerSplitWidth;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
- (void) focus
|
||||
{
|
||||
[[mItemPane window] makeFirstResponder:mItemPane];
|
||||
}
|
||||
|
||||
|
||||
- (int)numberOfRowsInTableView:(NSTableView *)tableView
|
||||
{
|
||||
int numRows = 0;
|
||||
if ( tableView == mContainerPane ) {
|
||||
// hack for now, history and bookmarks
|
||||
numRows = 2;
|
||||
}
|
||||
else if ( tableView == mSearchPane ) {
|
||||
// hack just to display something.
|
||||
numRows = 5;
|
||||
}
|
||||
return numRows;
|
||||
}
|
||||
|
||||
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
|
||||
{
|
||||
id itemString = nil;
|
||||
if ( tableView == mContainerPane ) {
|
||||
if ( row == kBookmarksMenuContainer )
|
||||
itemString = NSLocalizedString(@"Bookmarks Menu", @"Bookmarks Menu");
|
||||
else
|
||||
itemString = NSLocalizedString(@"History", @"History");
|
||||
}
|
||||
else if ( tableView == mSearchPane ) {
|
||||
if ( [[tableColumn identifier] isEqualToString:@"Name"] )
|
||||
itemString = @"<Search result here>";
|
||||
else
|
||||
itemString = @"<URL result here>";
|
||||
}
|
||||
return itemString;
|
||||
}
|
||||
|
||||
|
||||
- (void)tableView:(NSTableView *)inTableView willDisplayCell:(id)inCell forTableColumn:(NSTableColumn *)inTableColumn row:(int)inRowIndex
|
||||
{
|
||||
if ( inTableView == mContainerPane ) {
|
||||
if ( inRowIndex == kBookmarksMenuContainer )
|
||||
[inCell setImage:[NSImage imageNamed:@"bookicon"]];
|
||||
else if ( inRowIndex == kHistoryContainer )
|
||||
[inCell setImage:[NSImage imageNamed:@"historyicon"]];
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction) changeContainer:(id)aSender
|
||||
{
|
||||
[self selectContainer:[aSender clickedRow]];
|
||||
}
|
||||
|
||||
- (void) setCanEditSelectedContainerContents:(BOOL)inCanEdit
|
||||
{
|
||||
[mItemPane setAllowsEditing:inCanEdit];
|
||||
|
||||
// update buttons
|
||||
[mAddItemButton setEnabled:inCanEdit];
|
||||
[mAddFolderButton setEnabled:inCanEdit];
|
||||
[mInfoButton setEnabled:inCanEdit];
|
||||
}
|
||||
|
||||
- (void) selectContainer:(int)inRowIndex
|
||||
{
|
||||
[mContainerPane selectRow:inRowIndex byExtendingSelection:NO];
|
||||
if ( inRowIndex == kBookmarksMenuContainer ) {
|
||||
[mItemPane setDataSource:mBookmarksSource];
|
||||
[mItemPane setDelegate:mBookmarksSource];
|
||||
[mBookmarksSource ensureBookmarks];
|
||||
[mBookmarksSource restoreFolderExpandedStates];
|
||||
[self setCanEditSelectedContainerContents:YES];
|
||||
|
||||
[mItemPane setDoubleAction: @selector(openBookmark:)];
|
||||
[mItemPane setDeleteAction: @selector(deleteBookmarks:)];
|
||||
}
|
||||
else if ( inRowIndex == kHistoryContainer ) {
|
||||
[mItemPane setDataSource:mHistorySource];
|
||||
[mItemPane setDelegate:mHistorySource];
|
||||
[mHistorySource ensureDataSourceLoaded];
|
||||
[mItemPane reloadData];
|
||||
[self setCanEditSelectedContainerContents:NO];
|
||||
|
||||
[mItemPane setDoubleAction: @selector(openHistoryItem:)];
|
||||
[mItemPane setDeleteAction: @selector(deleteHistoryItems:)];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) selectLastContainer
|
||||
{
|
||||
// we need to call selectContainer: in order to get all the appropriate
|
||||
// stuff hooked up.
|
||||
[self selectContainer:[mContainerPane selectedRow]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Appkit/Appkit.h>
|
||||
|
||||
#import "MainController.h"
|
||||
#import "BookmarksToolbar.h"
|
||||
#import "ExtendedOutlineView.h"
|
||||
#import "BookmarksService.h"
|
||||
|
||||
// data source for the bookmarks sidebar. We make one per browser window.
|
||||
@interface BookmarksDataSource : NSObject<BookmarksClient>
|
||||
{
|
||||
// BookmarksService* mBookmarks;
|
||||
BOOL mRegisteredClient;
|
||||
|
||||
IBOutlet id mOutlineView;
|
||||
IBOutlet id mBrowserWindowController;
|
||||
IBOutlet id mEditBookmarkButton;
|
||||
IBOutlet id mDeleteBookmarkButton;
|
||||
|
||||
NSString* mCachedHref;
|
||||
}
|
||||
|
||||
-(id) init;
|
||||
-(void) windowClosing;
|
||||
|
||||
-(void) ensureBookmarks;
|
||||
|
||||
-(IBAction)addBookmark:(id)aSender;
|
||||
-(void)endAddBookmark: (int)aCode;
|
||||
|
||||
-(IBAction)deleteBookmarks: (id)aSender;
|
||||
-(void)deleteBookmark: (id)aItem;
|
||||
|
||||
-(IBAction)addFolder:(id)aSender;
|
||||
|
||||
-(void)addBookmark:(id)aSender useSelection:(BOOL)aSel isFolder:(BOOL)aIsFolder URL:(NSString*)aURL title:(NSString*)aTitle;
|
||||
-(void)addBookmark:(id)aSender withParent:(BookmarkItem*)bmItem isFolder:(BOOL)aIsFolder URL:(NSString*)aURL title:(NSString*)aTitle;
|
||||
|
||||
- (IBAction)openBookmark: (id)aSender;
|
||||
- (IBAction)openBookmarkInNewTab:(id)aSender;
|
||||
- (IBAction)openBookmarkInNewWindow:(id)aSender;
|
||||
|
||||
- (IBAction)showBookmarkInfo:(id)aSender;
|
||||
- (BOOL)haveSelectedRow;
|
||||
|
||||
// Datasource methods.
|
||||
- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item;
|
||||
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item;
|
||||
- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item;
|
||||
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item;
|
||||
- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item;
|
||||
|
||||
- (BOOL)outlineView:(NSOutlineView *)ov writeItems:(NSArray*)items toPasteboard:(NSPasteboard*)pboard;
|
||||
- (NSDragOperation)outlineView:(NSOutlineView*)ov validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(int)index;
|
||||
- (BOOL)outlineView:(NSOutlineView*)ov acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(int)index;
|
||||
|
||||
- (void)reloadDataForItem:(id)item reloadChildren: (BOOL)aReloadChildren;
|
||||
|
||||
// Delegate methods
|
||||
- (void)outlineViewItemWillExpand:(NSNotification *)notification;
|
||||
- (void)outlineViewItemWillCollapse:(NSNotification *)notification;
|
||||
|
||||
@end
|
|
@ -21,6 +21,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Simon Fraser <sfraser@netscape.com>
|
||||
* Max Horn <max@quendi.de>
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
|
@ -42,6 +43,7 @@
|
|||
#import "BookmarksDataSource.h"
|
||||
#import "BookmarkInfoController.h"
|
||||
#import "SiteIconProvider.h"
|
||||
#import "ImageAndTextCell.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIContent.h"
|
||||
|
@ -52,7 +54,6 @@
|
|||
|
||||
@interface BookmarksDataSource(Private)
|
||||
|
||||
- (void)restoreFolderExpandedStates;
|
||||
- (void)refreshChildrenOfItem:(nsIContent*)item;
|
||||
|
||||
@end
|
||||
|
@ -78,6 +79,19 @@ const int kBookmarksRootItemTag = -2;
|
|||
|
||||
-(void) awakeFromNib
|
||||
{
|
||||
NSTableColumn *tableColumn = nil;
|
||||
NSButtonCell *imageAndTextCell = nil;
|
||||
|
||||
// Insert custom cell types into the table view, the standard one does text only.
|
||||
//XXX take this out when we switch to the in-window bookmarks because it's
|
||||
//XXX done by the BookmarksController (as it should be)
|
||||
tableColumn = [mOutlineView tableColumnWithIdentifier: @"Name"];
|
||||
imageAndTextCell = [[[ImageAndTextCell alloc] init] autorelease];
|
||||
[imageAndTextCell setEditable: YES];
|
||||
[imageAndTextCell setWraps: NO];
|
||||
[tableColumn setDataCell:imageAndTextCell];
|
||||
[tableColumn setEditable: YES];
|
||||
|
||||
// make sure these are disabled at the start since the outliner
|
||||
// starts off with no selection.
|
||||
[mEditBookmarkButton setEnabled:NO];
|
||||
|
@ -523,8 +537,8 @@ const int kBookmarksRootItemTag = -2;
|
|||
// outlineView:shouldEditTableColumn:item: (delegate method)
|
||||
//
|
||||
// Called by the outliner to determine whether or not we should allow the
|
||||
// user to edit this item. We're leaving it off for now, becaue there are
|
||||
// some usability issues with inline editing (no undo, Escape doesn't work).
|
||||
// user to edit this item. We always return NO, because we invoke the
|
||||
// edit methods manually.
|
||||
//
|
||||
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item
|
||||
{
|
||||
|
@ -579,58 +593,50 @@ const int kBookmarksRootItemTag = -2;
|
|||
{
|
||||
if (!mRegisteredClient) return nil;
|
||||
|
||||
NSString *columnName = [tableColumn identifier];
|
||||
id retValue = nil;
|
||||
|
||||
if ([columnName isEqualToString: @"name"])
|
||||
{
|
||||
NSFileWrapper *fileWrapper = [[NSFileWrapper alloc] initRegularFileWithContents:nil];
|
||||
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] initWithFileWrapper:fileWrapper];
|
||||
|
||||
//Set cell's textual contents
|
||||
//[cellValue replaceCharactersInRange:NSMakeRange(0, [cellValue length]) withString:[NSString stringWith_nsAString: nameAttr]];
|
||||
NSMutableAttributedString* cellValue = [[[NSMutableAttributedString alloc] initWithString:[item name]] autorelease];
|
||||
|
||||
//Create an attributed string to hold the empty attachment, then release the components.
|
||||
NSMutableAttributedString* attachmentAttrString = [NSMutableAttributedString attributedStringWithAttachment:textAttachment];
|
||||
[textAttachment release];
|
||||
[fileWrapper release];
|
||||
|
||||
//Get the cell of the text attachment.
|
||||
NSCell* attachmentAttrStringCell = (NSCell *)[(NSTextAttachment *)[attachmentAttrString attribute:NSAttachmentAttributeName atIndex:0 effectiveRange:nil] attachmentCell];
|
||||
|
||||
NSImage* bookmarkImage = [[BookmarksManager sharedBookmarksManager] createIconForBookmarkItem:item useSiteIcon:NO];
|
||||
[attachmentAttrStringCell setImage:bookmarkImage];
|
||||
|
||||
//Insert the image
|
||||
[cellValue replaceCharactersInRange:NSMakeRange(0, 0) withAttributedString:attachmentAttrString];
|
||||
|
||||
//Tweak the baseline to vertically center the text.
|
||||
[cellValue addAttribute:NSBaselineOffsetAttributeName
|
||||
value:[NSNumber numberWithFloat:-3.0]
|
||||
range:NSMakeRange(0, 1)];
|
||||
retValue = cellValue;
|
||||
NSString *columnName = [tableColumn identifier];
|
||||
if ([columnName isEqualToString: @"Name"]) {
|
||||
// Return data as an NSString. We'll deal with the icon later.
|
||||
retValue = [item name];
|
||||
}
|
||||
else if ([columnName isEqualToString: @"url"])
|
||||
{
|
||||
else if ([columnName isEqualToString: @"URL"]) {
|
||||
if ([item isFolder]) {
|
||||
#if 0
|
||||
int numKids = [item getNumberOfChildren];
|
||||
NSString* itemCountStr = [NSString stringWithFormat:NSLocalizedString(@"Contains Items", @"%d Items"),
|
||||
numKids];
|
||||
NSMutableDictionary* colorAttributes = nil; //XXXX fill in color attribute
|
||||
retValue = [[NSAttributedString alloc] initWithString:itemCountStr attributes:colorAttributes];
|
||||
#endif
|
||||
}
|
||||
else
|
||||
retValue = [item url];
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(NSCell *)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
|
||||
{
|
||||
// set the image on the name column. the url column doesn't have an image.
|
||||
if ([[tableColumn identifier] isEqualToString: @"Name"]) {
|
||||
NSImage* image = [[BookmarksManager sharedBookmarksManager] createIconForBookmarkItem:item useSiteIcon:YES];
|
||||
[cell setImage:image];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
|
||||
{
|
||||
// object is really an NSString, even though objectValueForTableColumn returns NSAttributedStrings.
|
||||
BookmarkItem* bmItem = (BookmarkItem*)item;
|
||||
NSString *columnName = [tableColumn identifier];
|
||||
if ( [columnName isEqualTo:@"name"] )
|
||||
if ( [columnName isEqualTo:@"Name"] )
|
||||
{
|
||||
const unichar kAttachmentCharacter = NSAttachmentCharacter;
|
||||
|
||||
NSMutableString* mutableString = [NSMutableString stringWithString:object];
|
||||
[mutableString replaceOccurrencesOfString:[NSString stringWithCharacters:&kAttachmentCharacter length:1] withString:@"" options:0 range:NSMakeRange(0, [mutableString length])];
|
||||
|
||||
BookmarkItem* bmItem = (BookmarkItem*)item;
|
||||
[bmItem setName:mutableString];
|
||||
[bmItem setName:object];
|
||||
[bmItem itemChanged:YES];
|
||||
}
|
||||
else if ( [columnName isEqualTo:@"URL"] ) {
|
||||
[bmItem setUrl:object];
|
||||
[bmItem itemChanged:YES];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Mozilla browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2002 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Joe Hewitt <hewitt@netscape.com> (Original Author)
|
||||
*/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import "ExtendedOutlineView.h"
|
||||
|
||||
@interface BookmarksOutlineView : ExtendedOutlineView {
|
||||
|
||||
}
|
||||
|
||||
@end
|
|
@ -169,7 +169,7 @@ protected:
|
|||
|
||||
|
||||
|
||||
@interface BookmarkItem : NSObject
|
||||
@interface BookmarkItem : NSObject <NSCopying>
|
||||
{
|
||||
nsIContent* mContentNode;
|
||||
NSImage* mSiteIcon;
|
||||
|
|
|
@ -47,6 +47,7 @@ class nsIBrowserHistory;
|
|||
class nsIDOMEvent;
|
||||
class nsIDOMNode;
|
||||
|
||||
@class BookmarksController;
|
||||
|
||||
//
|
||||
// ThrobberHandler
|
||||
|
@ -80,35 +81,6 @@ class nsIDOMNode;
|
|||
|
||||
#pragma mark -
|
||||
|
||||
@interface BookmarksController : NSObject
|
||||
{
|
||||
IBOutlet NSButton* mAddItemButton;
|
||||
IBOutlet NSButton* mAddFolderButton;
|
||||
|
||||
IBOutlet NSSplitView* mContainersSplit; // vertical split
|
||||
IBOutlet NSSplitView* mItemSearchSplit; // horizontal split
|
||||
IBOutlet NSOutlineView* mItemPane;
|
||||
IBOutlet NSTableView* mSearchPane; // shows search results, can be hidden
|
||||
}
|
||||
|
||||
// Set focus to something in the bookmark manager view
|
||||
- (void) focus;
|
||||
|
||||
- (void) windowDidLoad;
|
||||
|
||||
// NSSplitView delegate methods
|
||||
//- (void)splitView:(NSSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize;
|
||||
- (float)splitView:(NSSplitView *)sender constrainMinCoordinate:(float)proposedCoord ofSubviewAt:(int)offset;
|
||||
//- (float)splitView:(NSSplitView *)sender constrainMaxCoordinate:(float)proposedCoord ofSubviewAt:(int)offset;
|
||||
//- (void)splitViewWillResizeSubviews:(NSNotification *)notification;
|
||||
- (void)splitViewDidResizeSubviews:(NSNotification *)notification;
|
||||
- (BOOL)splitView:(NSSplitView *)sender canCollapseSubview:(NSView *)subview;
|
||||
//- (float)splitView:(NSSplitView *)splitView constrainSplitPosition:(float)proposedPosition ofSubviewAt:(int)index;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
typedef enum
|
||||
{
|
||||
eNewTabEmpty,
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#import "UserDefaults.h"
|
||||
#import "PageProxyIcon.h"
|
||||
#import "AutoCompleteTextField.h"
|
||||
#import "BookmarksController.h"
|
||||
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
|
@ -78,7 +79,10 @@
|
|||
|
||||
#include <QuickTime/QuickTime.h>
|
||||
|
||||
#define USE_DRAWER_FOR_BOOKMARKS 1
|
||||
#define USE_DRAWER_FOR_BOOKMARKS 0
|
||||
#if USE_DRAWER_FOR_BOOKMARKS
|
||||
#import "ImageAndTextCell.h"
|
||||
#endif
|
||||
|
||||
static NSString *BrowserToolbarIdentifier = @"Browser Window Toolbar";
|
||||
static NSString *BackToolbarItemIdentifier = @"Back Toolbar Item";
|
||||
|
@ -933,18 +937,18 @@ static NSArray* sToolbarDefaults = nil;
|
|||
|
||||
-(IBAction)manageBookmarks: (id)aSender
|
||||
{
|
||||
if ([mSidebarDrawer state] == NSDrawerClosedState)
|
||||
[self toggleSidebar: self];
|
||||
if ( ![mContentView isBookmarkManagerVisible] )
|
||||
[self toggleBookmarkManager: self];
|
||||
|
||||
[mSidebarTabView selectFirstTabViewItem:self];
|
||||
[mBookmarksController selectContainer:kBookmarksMenuContainer];
|
||||
}
|
||||
|
||||
-(IBAction)manageHistory: (id)aSender
|
||||
{
|
||||
if ([mSidebarDrawer state] == NSDrawerClosedState)
|
||||
[self toggleSidebar: self];
|
||||
if ( ![mContentView isBookmarkManagerVisible] )
|
||||
[self toggleBookmarkManager: self];
|
||||
|
||||
[mSidebarTabView selectTabViewItemAtIndex:1];
|
||||
[mBookmarksController selectContainer:kHistoryContainer];
|
||||
}
|
||||
|
||||
- (void)importBookmarks: (NSString*)aURLSpec
|
||||
|
@ -2150,9 +2154,14 @@ static NSArray* sToolbarDefaults = nil;
|
|||
|
||||
// swap out between content and bookmarks.
|
||||
[mContentView toggleBookmarkManager:sender];
|
||||
|
||||
#if !USE_DRAWER_FOR_BOOKMARKS
|
||||
//XXXXXX needed until we can turn this on full time, since it's a nib change.
|
||||
mSidebarBookmarksDataSource->mOutlineView = mBookmarksController->mItemPane;
|
||||
[mSidebarBookmarksDataSource ensureBookmarks];
|
||||
mHistoryDataSource->mOutlineView = mBookmarksController->mItemPane;
|
||||
#endif
|
||||
|
||||
[mBookmarksController selectLastContainer];
|
||||
|
||||
// if we're now showing the bm manager, force it to have focus,
|
||||
// otherwise give focus back to gecko.
|
||||
|
@ -2298,95 +2307,3 @@ static Boolean movieControllerFilter(MovieController mc, short action, void *par
|
|||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation BookmarksController
|
||||
|
||||
#if 0
|
||||
- (id) init
|
||||
{
|
||||
if ( self = [super init] )
|
||||
{
|
||||
mAddItemButton = nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// - splitViewDidResizeSubviews:
|
||||
//
|
||||
// Called when one of the views got resized. We want to ensure that the "add bookmark
|
||||
// item" button gets lined up with the left edge of the item panel. If the container/item
|
||||
// split was the one that changed, move it accordingly
|
||||
//
|
||||
- (void)splitViewDidResizeSubviews:(NSNotification *)notification
|
||||
{
|
||||
const int kButtonGutter = 8;
|
||||
|
||||
if ( [notification object] == mContainersSplit ) {
|
||||
// get the position of the item view relative to the window and set the button
|
||||
// to that X value. Yes, this will fall down if the bookmark view is inset from the window
|
||||
// but i think we can safely assume it won't be.
|
||||
NSRect windowRect = [mItemPane convertRect:[mItemPane bounds] toView:nil];
|
||||
NSRect newButtonLocation = [mAddItemButton frame];
|
||||
newButtonLocation.origin.x = windowRect.origin.x;
|
||||
[mAddItemButton setFrame:newButtonLocation];
|
||||
[mAddItemButton setNeedsDisplay:YES];
|
||||
|
||||
// offset by the width of the button and the gutter and we've got the location
|
||||
// of the add folder button next to it.
|
||||
newButtonLocation.origin.x += newButtonLocation.size.width + kButtonGutter;
|
||||
[mAddFolderButton setFrame:newButtonLocation];
|
||||
[mAddFolderButton setNeedsDisplay:YES];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// - splitView:canCollapseSubview:
|
||||
//
|
||||
// Called when appkit wants to ask if it can collapse a subview. The only subview
|
||||
// of our splits that we allow to be hidden is the search panel.
|
||||
//
|
||||
- (BOOL)splitView:(NSSplitView *)sender canCollapseSubview:(NSView *)subview
|
||||
{
|
||||
BOOL retVal = NO;
|
||||
// subview will be a NSScrollView, so we have to get the superview of the
|
||||
// search pane for comparison.
|
||||
if ( sender == mItemSearchSplit && subview == [mSearchPane superview] )
|
||||
retVal = YES;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
- (void)windowDidLoad
|
||||
{
|
||||
// hide the search panel
|
||||
|
||||
// set up the font on the item view to be smaller
|
||||
NSArray* columns = [mItemPane tableColumns];
|
||||
if ( columns ) {
|
||||
int numColumns = [columns count];
|
||||
NSFont* smallerFont = [NSFont systemFontOfSize:11];
|
||||
for ( int i = 0; i < numColumns; ++i )
|
||||
[[[columns objectAtIndex:i] dataCell] setFont:smallerFont];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (float)splitView:(NSSplitView *)sender constrainMinCoordinate:(float)proposedCoord ofSubviewAt:(int)offset
|
||||
{
|
||||
const int kMinimumContainerSplitWidth = 150;
|
||||
float retVal = proposedCoord;
|
||||
if ( sender == mContainersSplit )
|
||||
retVal = kMinimumContainerSplitWidth;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
- (void) focus
|
||||
{
|
||||
[[mItemPane window] makeFirstResponder:mItemPane];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -24,14 +24,20 @@
|
|||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
@interface ExtendedOutlineView : NSOutlineView {
|
||||
@interface ExtendedOutlineView : NSOutlineView
|
||||
{
|
||||
SEL mDeleteAction;
|
||||
|
||||
NSRect mOldFrameRect;
|
||||
int mOldRows;
|
||||
BOOL mDelegateTooltipStringForItem;
|
||||
|
||||
int mRowToBeEdited, mColumnToBeEdited;
|
||||
BOOL mAllowsEditing;
|
||||
}
|
||||
|
||||
-(void)setAllowsEditing:(BOOL)inAllow;
|
||||
|
||||
-(void)keyDown:(NSEvent*)aEvent;
|
||||
|
||||
-(void)setDeleteAction: (SEL)deleteAction;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* David Hyatt <hyatt@netscape.com> (Original Author)
|
||||
* Max Horn <max@quendi.de> (Context menu & tooltip code)
|
||||
* Max Horn <max@quendi.de> (Context menu, tooltip code, and editing)
|
||||
*/
|
||||
|
||||
#import "ExtendedOutlineView.h"
|
||||
|
@ -33,7 +33,10 @@
|
|||
- (id)initWithFrame:(NSRect)frame
|
||||
{
|
||||
if ( (self = [super initWithFrame:frame]) ) {
|
||||
mDeleteAction = 0;
|
||||
mDeleteAction = nil;
|
||||
mAllowsEditing = YES;
|
||||
mRowToBeEdited = mColumnToBeEdited = 0;
|
||||
|
||||
// FIXME - this method is *never* called for items that are archived in a nib!
|
||||
// Luckily, object memory is zeroed, so mDeleteAction will be 0 anyway.
|
||||
// I recommend that this method just be removed.
|
||||
|
@ -41,7 +44,8 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void)awakeFromNib {
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
// Setup the initial NSToolTipRects
|
||||
[self _updateToolTipRect];
|
||||
}
|
||||
|
@ -189,6 +193,140 @@
|
|||
return [self menu];
|
||||
}
|
||||
|
||||
|
||||
- (void)textDidEndEditing:(NSNotification *)aNotification
|
||||
{
|
||||
// Fake our own notification. We pretend that the editing was canceled due to a
|
||||
// mouse click. This prevents outlineviw from selecting another cell for editing.
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:NSIllegalTextMovement] forKey:@"NSTextMovement"];
|
||||
NSNotification *fakeNotification = [NSNotification notificationWithName:[aNotification name] object:[aNotification object] userInfo:userInfo];
|
||||
|
||||
[super textDidEndEditing:fakeNotification];
|
||||
|
||||
// Make ourself first responder again
|
||||
[[self window] makeFirstResponder:self];
|
||||
}
|
||||
|
||||
|
||||
- (void)_cancelEditItem
|
||||
{
|
||||
mRowToBeEdited = -1;
|
||||
[[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(editItem:) object:nil];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Start editing a given item. Used to start editing delayed.
|
||||
//
|
||||
- (void)_editItem:(id)dummy
|
||||
{
|
||||
int row = mRowToBeEdited;
|
||||
|
||||
// Cancel any other scheduled edits+ [self _cancelEditItem];
|
||||
|
||||
// Only start the editing if the selection didn't change in the meantime
|
||||
// (e.g. because arrow keys were used to change it).
|
||||
if (row > 0 && row == [self selectedRow])
|
||||
[self editColumn:mColumnToBeEdited row:row withEvent:nil select:YES];
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle mouse clicks, allowing them to start inline editing.
|
||||
* We start editing under two conditions:
|
||||
* 1) For clicks together with the alt/option modifier key immediatly
|
||||
* 2) For clicks on already selected items after a short delay
|
||||
* Rule 2 only is enabled if the outline view is first responder of the main
|
||||
* window, otherwise odd behaviour takes placed when the user clicks into
|
||||
* a background window on a selected item - editing would start, which is
|
||||
* not the correct result (at least if we want to match Finder).
|
||||
*
|
||||
* There are some other catchfalls and quirks we have to consider, for details
|
||||
* read the comments in the code.
|
||||
*/
|
||||
- (void)mouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
// the data isn't always allowed to be edited (eg, rendevous or history). Bail
|
||||
// if we've been told to not allow editing.
|
||||
if ( !mAllowsEditing ) {
|
||||
[super mouseDown:theEvent];
|
||||
return;
|
||||
}
|
||||
|
||||
// Record some state information before calling the super implementation,
|
||||
// as these might change. E.g. if we are not yet first repsonder, the click
|
||||
// might make us first responder.
|
||||
BOOL wasFirstResponder = ([[self window] firstResponder] == self);
|
||||
BOOL wasMainWindow = [[self window] isMainWindow];
|
||||
BOOL wasClickInTextPartOfCell = NO;
|
||||
int oldEditRow = [self editedRow];
|
||||
int oldRow = ([self numberOfSelectedRows] == 1) ? [self selectedRow] : -1;
|
||||
|
||||
// Now call the super implementation. It will only return after the mouseUp
|
||||
// occured, since it does drag&drop handling etc.
|
||||
[super mouseDown:theEvent];
|
||||
|
||||
// If this was a double click, we cancel any scheduled edit requests and return
|
||||
if ([theEvent clickCount] > 1) {
|
||||
[self _cancelEditItem];
|
||||
return;
|
||||
}
|
||||
|
||||
// Detect if the selection changed (ignoring multi-selections)
|
||||
int newRow = ([self numberOfSelectedRows] == 1) ? [self selectedRow] : -1;
|
||||
|
||||
// If the selection did change, we need to cancel any scheduled edit requests.
|
||||
if (oldRow != newRow && oldRow != -1)
|
||||
[self _cancelEditItem];
|
||||
|
||||
// Little trick: if editing was already in progress, then the field editor
|
||||
// will be first responder. For our purposes this is the same as if we
|
||||
// were first responder, so pretend it were so.
|
||||
if (oldEditRow >= 0)
|
||||
wasFirstResponder = YES;
|
||||
|
||||
// If we already were first responder of the main window, and the click was
|
||||
// inside a row and it was the left mouse button, then we investigate further
|
||||
// and check if we need to start editing.
|
||||
if (wasFirstResponder && wasMainWindow && newRow >= 0 && ([theEvent type] == NSLeftMouseDown)) {
|
||||
|
||||
// Check whether the click was inside the text part of a cell. For now, we do
|
||||
// this a bit hackishly and assume the cell image is set and has width 20,
|
||||
// and there is a gap of 3 pixels between image and label.
|
||||
NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
int clickedRow = [self rowAtPoint:point];
|
||||
mColumnToBeEdited = [self columnAtPoint:point];
|
||||
if (clickedRow >= 0 && mColumnToBeEdited >= 0)
|
||||
{
|
||||
NSRect rect = [self frameOfCellAtColumn:mColumnToBeEdited row:clickedRow];
|
||||
rect.size.width = 20.0 + 3.0;
|
||||
wasClickInTextPartOfCell = ! NSPointInRect(point, rect);
|
||||
}
|
||||
|
||||
// Do not start editing for clicks on the icon part (to match Finder's behaviour).
|
||||
if (wasClickInTextPartOfCell) {
|
||||
|
||||
if ([theEvent modifierFlags] & NSAlternateKeyMask)
|
||||
{
|
||||
// If the alt key was pressed, start editing right away
|
||||
mRowToBeEdited = newRow;
|
||||
[self _editItem:nil];
|
||||
}
|
||||
else if (oldRow == newRow) {
|
||||
// If the click was into an already selected row, start editing
|
||||
// after a short (1 second) delay - unless it gets canceled before
|
||||
// of course, e.g. by a click someplace else.
|
||||
mRowToBeEdited = newRow;
|
||||
[self performSelector:@selector(_editItem:) withObject:nil afterDelay:1.0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)setAllowsEditing:(BOOL)inAllow
|
||||
{
|
||||
mAllowsEditing = inAllow;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
|
|
@ -331,9 +331,10 @@
|
|||
if (!mDataSource || !aItem)
|
||||
return nil;
|
||||
|
||||
// The table column's identifier is the RDF Resource URI of the property being displayed in
|
||||
// that column, e.g. "http://home.netscape.com/NC-rdf#Name"
|
||||
NSString* columnPropertyURI = [aTableColumn identifier];
|
||||
// The table column's identifier is the last part of the RDF Resource URI of the property
|
||||
// being displayed in that column, e.g. "http://home.netscape.com/NC-rdf#Name"
|
||||
NSString* columnPropertyURI = [NSString stringWithFormat:@"http://home.netscape.com/NC-rdf#%@",
|
||||
[aTableColumn identifier]];
|
||||
NSString* propString = [self getPropertyString:columnPropertyURI forItem:aItem];
|
||||
|
||||
return [self createCellContents:propString withColumn:columnPropertyURI byItem:aItem];
|
||||
|
|
|
@ -57,6 +57,7 @@ class HistoryDataSourceObserver;
|
|||
- (id)createCellContents:(NSString*)inValue withColumn:(NSString*)inColumn byItem:(id) inItem;
|
||||
|
||||
- (NSString *)outlineView:(NSOutlineView *)outlineView tooltipStringForItem:(id)inItem;
|
||||
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(NSCell *)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item;
|
||||
|
||||
- (void)enableObserver;
|
||||
- (void)disableObserver;
|
||||
|
|
|
@ -260,45 +260,14 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
|||
//
|
||||
// createCellContents:withColumn:byItem
|
||||
//
|
||||
// override to create an NSAttributedString instead of just the string with the
|
||||
// given text. We add an icon and adjust the positioning of the text w/in the cell
|
||||
// override to look up the URL if the name is empty. We'll obviously always have a
|
||||
// name.
|
||||
//
|
||||
-(id) createCellContents:(NSString*)inValue withColumn:(NSString*)inColumn byItem:(id) inItem
|
||||
{
|
||||
if ([inValue length] == 0)
|
||||
inValue = [self getPropertyString:@"http://home.netscape.com/NC-rdf#URL" forItem:inItem];
|
||||
|
||||
NSMutableAttributedString *cellValue = [[[NSMutableAttributedString alloc] initWithString:inValue] autorelease];
|
||||
|
||||
if ([inColumn isEqualToString:@"http://home.netscape.com/NC-rdf#Name"])
|
||||
{
|
||||
NSFileWrapper *fileWrapper = [[NSFileWrapper alloc] initRegularFileWithContents:nil];
|
||||
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] initWithFileWrapper:fileWrapper];
|
||||
|
||||
// Create an attributed string to hold the empty attachment, then release the components.
|
||||
NSMutableAttributedString *attachmentAttrString = [NSMutableAttributedString attributedStringWithAttachment:textAttachment];
|
||||
[textAttachment release];
|
||||
[fileWrapper release];
|
||||
|
||||
//Get the cell of the text attachment.
|
||||
NSCell* attachmentAttrStringCell = (NSCell *)[(NSTextAttachment *)[attachmentAttrString attribute:
|
||||
NSAttachmentAttributeName atIndex:0 effectiveRange:nil] attachmentCell];
|
||||
|
||||
if ([self outlineView:mOutlineView isItemExpandable:inItem])
|
||||
[attachmentAttrStringCell setImage:[NSImage imageNamed:@"folder"]];
|
||||
else
|
||||
[attachmentAttrStringCell setImage:[NSImage imageNamed:@"smallbookmark"]];
|
||||
|
||||
//Insert the image
|
||||
[cellValue replaceCharactersInRange:NSMakeRange(0, 0) withAttributedString:attachmentAttrString];
|
||||
|
||||
//Tweak the baseline to vertically center the text.
|
||||
[cellValue addAttribute:NSBaselineOffsetAttributeName
|
||||
value:[NSNumber numberWithFloat:-5.0]
|
||||
range:NSMakeRange(0, 1)];
|
||||
}
|
||||
|
||||
return cellValue;
|
||||
return inValue;
|
||||
}
|
||||
|
||||
|
||||
|
@ -457,4 +426,15 @@ HistoryDataSourceObserver::OnChange(nsIRDFDataSource*, nsIRDFResource*,
|
|||
return nil;
|
||||
}
|
||||
|
||||
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(NSCell *)inCell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
|
||||
{
|
||||
// set the image on the name column. the url column doesn't have an image.
|
||||
if ([[tableColumn identifier] isEqualToString: @"Name"]) {
|
||||
if ( [outlineView isExpandable: item] )
|
||||
[inCell setImage:[NSImage imageNamed:@"folder"]];
|
||||
else
|
||||
[inCell setImage:[NSImage imageNamed:@"globe_ico"]];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Загрузка…
Ссылка в новой задаче