<commit_before>/*
 * CPToolbar.j
 * AppKit
 *
 * Portions based on NSToolbar.m (11/10/2008) in Cocotron (http://www.cocotron.org/)
 * Copyright (c) 2006-2007 <NAME>
 *
 * Created by <NAME>.
 * Copyright 2008, 280 North, Inc.
 *
 * 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.1 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; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

@import <Foundation/CPObject.j>

@import "CPPopUpButton.j"
@import "CPToolbarItem.j"

#include "CoreGraphics/CGGeometry.h"


/*
    @global
    @group CPToolbarDisplayMode
*/
CPToolbarDisplayModeDefault             = 0;
/*
    @global
    @group CPToolbarDisplayMode
*/
CPToolbarDisplayModeIconAndLabel        = 1;
/*
    @global
    @group CPToolbarDisplayMode
*/
CPToolbarDisplayModeIconOnly            = 2;
/*
    @global
    @group CPToolbarDisplayMode
*/
CPToolbarDisplayModeLabelOnly           = 3;

var CPToolbarsByIdentifier              = nil;
var CPToolbarConfigurationsByIdentifier = nil;

/*!
    @ingroup appkit
    @class CPToolbar

    A CPToolbar is displayed at the top of a window with multiple
    buttons (tools) that offer the user quick access to features.

    @par Delegate Methods

    @delegate -(CPArray)toolbarDefaultItemIdentifiers:(CPToolbar)toolbar;
    Called to obtain the toolbar's default item identifiers. Required.
    @param toolbar the toolbar to obtain identifiers for
    @return an array of default item identifiers in the order on the toolbar

    @delegate -(CPArray)toolbarAllowedItemIdentifiers:(CPToolbar)toolbar;
    Called to obtain the toolbar's default item identifiers. Required.
    @param toolbar the toolbar to obtain identifiers for
    @return an array of default item identifiers in the order on the toolbar

    @delegate - (CPToolbarItem)toolbar:(CPToolbar)toolbar itemForItemIdentifier:(CPString)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag;
    Called to obtain a toolbar item. Required.
    @param toolbar the toolbar the item belongs to
    @param itemIdentifier the identifier of the toolbar item
    @param flag \c YES means the item will be placed in the toolbar. \c NO means the item will be displayed for
    some other purpose (non-functional)
    @return the toolbar item or \c nil if no such item belongs in the toolbar
*/
@implementation CPToolbar : CPObject
{
    CPString                _identifier;
    CPToolbarDisplayMode    _displayMode;
    BOOL                    _showsBaselineSeparator;
    BOOL                    _allowsUserCustomization;
    BOOL                    _isVisible;

    id                      _delegate;

    CPArray                 _itemIdentifiers;

    CPDictionary            _identifiedItems;
    CPArray                 _defaultItems;
    CPArray                 _allowedItems;
    CPArray                 _selectableItems;

    CPArray                 _items;
    CPArray                 _itemsSortedByVisibilityPriority;

    CPView                  _toolbarView;
    CPWindow                _window;
}

/* @ignore */
+ (void)initialize
{
    if (self != [CPToolbar class])
        return;

    CPToolbarsByIdentifier = [CPDictionary dictionary];
    CPToolbarConfigurationsByIdentifier = [CPDictionary dictionary];
}

/* @ignore */
+ (void)_addToolbar:(CPToolbar)toolbar forIdentifier:(CPString)identifier
{
    var toolbarsSharingIdentifier = [CPToolbarsByIdentifier objectForKey:identifier];

    if (!toolbarsSharingIdentifier)
    {
        toolbarsSharingIdentifier = []
        [CPToolbarsByIdentifier setObject:toolbarsSharingIdentifier forKey:identifier];
    }

    [toolbarsSharingIdentifier addObject:toolbar];
}

- (id)init
{
    return [self initWithIdentifier:@""];
}

/*!
    Initializes the toolbar with the specified identifier.
    @param anIdentifier the identifier for the toolbar
    @return the initialized toolbar
*/
- (id)initWithIdentifier:(CPString)anIdentifier
{
    self = [super init];

    if (self)
    {
        _items = [];

        _identifier = anIdentifier;
        _isVisible = YES;

        [CPToolbar _addToolbar:self forIdentifier:_identifier];
    }

    return self;
}


/*!
    Sets the toolbar's display mode. NOT YET IMPLEMENTED.
*/
- (void)setDisplayMode:(CPToolbarDisplayMode)aDisplayMode
{

}

/*!
    Returns the toolbar's identifier
*/
- (CPString)identifier
{
    return _identifier;
}

/*!
    Returns the toolbar's delegate
*/
- (id)delegate
{
    return _delegate;
}

/*!
    Returns \c YES if the toolbar is currently visible
*/
- (BOOL)isVisible
{
    return _isVisible;
}

/*!
    Sets whether the toolbar should be visible.
    @param aFlag \c YES makes the toolbar visible
*/
- (void)setVisible:(BOOL)aFlag
{
    if (_isVisible === aFlag)
        return;

    _isVisible = aFlag;

    [_window _noteToolbarChanged];
}

- (CPWindow)_window
{
    return _window;
}

- (void)_setWindow:(CPWindow)aWindow
{
    _window = aWindow;
}

/*!
    Sets the delegate for the toolbar.
    @param aDelegate the new toolbar delegate
*/
- (void)setDelegate:(id)aDelegate
{
    if (_delegate === aDelegate)
        return;

    _delegate = aDelegate;

    [self _reloadToolbarItems];
}

/* @ignore */
- (void)_loadConfiguration
{

}

/* @ignore */
- (CPView)_toolbarView
{
    if (!_toolbarView)
    {
        _toolbarView = [[_CPToolbarView alloc] initWithFrame:CPRectMake(0.0, 0.0, 1200.0, 59.0)];

        [_toolbarView setToolbar:self];
        [_toolbarView setAutoresizingMask:CPViewWidthSizable];
        [_toolbarView reloadToolbarItems];
    }

    return _toolbarView;
}

/* @ignore */
- (void)_reloadToolbarItems
{
    // As of OS X 10.5 (Leopard), toolbar items can be set in IB and a
    // toolbar delegate is optional. Toolbar items can be combined from
    // both IB and a delegate (see Apple's NSToolbar guide for IB, for more details).

    // _defaultItems may have been loaded from Cib
    _itemIdentifiers = [_defaultItems valueForKey:@"itemIdentifier"] || [];

    if (_delegate)
    {
        var itemIdentifiersFromDelegate = [[_delegate toolbarDefaultItemIdentifiers:self] mutableCopy];

        if (itemIdentifiersFromDelegate)
            _itemIdentifiers = [_itemIdentifiers arrayByAddingObjectsFromArray:itemIdentifiersFromDelegate];
    }

    var index = 0,
        count = [_itemIdentifiers count];

    _items = [];

    for (; index < count; ++index)
    {
        var identifier = _itemIdentifiers[index],
            item = [CPToolbarItem _standardItemWithItemIdentifier:identifier];

        // May come from a Cib.
        if (!item)
            item = [_identifiedItems objectForKey:identifier];

        if (!item && _delegate)
            item = [_delegate toolbar:self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:YES];

        item = [item copy];

        if (item === nil)
            [CPException raise:CPInvalidArgumentException
                         reason:@"Toolbar delegate " + _delegate + " returned nil toolbar item for identifier \"" + identifier + "\""];

        item._toolbar = self;

        [_items addObject:item];
    }

//    _items = [[self _defaultToolbarItems] mutableCopy];

    // Store items sorted by priority.  We want items to be removed first at the end of the array,
    // items to be removed last at the front.

    _itemsSortedByVisibilityPriority = [_items sortedArrayUsingFunction:_CPToolbarItemVisibilityPriorityCompare context:NULL];

    [_toolbarView reloadToolbarItems];
}

/*!
    Returns all the items in this toolbar.
*/
- (CPArray)items
{
    return _items;
}

/*!
    Returns all the visible items in this toolbar
*/
- (CPArray)visibleItems
{
    return [_toolbarView visibleItems];
}

/*!
    Returns the toolbar items sorted by their \c visibilityPriority(ies).
*/
- (CPArray)itemsSortedByVisibilityPriority
{
    return _itemsSortedByVisibilityPriority;
}

- (void)validateVisibleToolbarItems<commit_msg>Fixed: CPToolbar validateVisibleItems was called validateVisibleToolbarItems.<commit_after>/*
 * CPToolbar.j
 * AppKit
 *
 * Portions based on NSToolbar.m (11/10/2008) in Cocotron (http://www.cocotron.org/)
 * Copyright (c) 2006-2007 <NAME>
 *
 * Created by <NAME>.
 * Copyright 2008, 280 North, Inc.
 *
 * 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.1 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; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

@import <Foundation/CPObject.j>

@import "CPPopUpButton.j"
@import "CPToolbarItem.j"

#include "CoreGraphics/CGGeometry.h"


/*
    @global
    @group CPToolbarDisplayMode
*/
CPToolbarDisplayModeDefault             = 0;
/*
    @global
    @group CPToolbarDisplayMode
*/
CPToolbarDisplayModeIconAndLabel        = 1;
/*
    @global
    @group CPToolbarDisplayMode
*/
CPToolbarDisplayModeIconOnly            = 2;
/*
    @global
    @group CPToolbarDisplayMode
*/
CPToolbarDisplayModeLabelOnly           = 3;

var CPToolbarsByIdentifier              = nil;
var CPToolbarConfigurationsByIdentifier = nil;

/*!
    @ingroup appkit
    @class CPToolbar

    A CPToolbar is displayed at the top of a window with multiple
    buttons (tools) that offer the user quick access to features.

    @par Delegate Methods

    @delegate -(CPArray)toolbarDefaultItemIdentifiers:(CPToolbar)toolbar;
    Called to obtain the toolbar's default item identifiers. Required.
    @param toolbar the toolbar to obtain identifiers for
    @return an array of default item identifiers in the order on the toolbar

    @delegate -(CPArray)toolbarAllowedItemIdentifiers:(CPToolbar)toolbar;
    Called to obtain the toolbar's default item identifiers. Required.
    @param toolbar the toolbar to obtain identifiers for
    @return an array of default item identifiers in the order on the toolbar

    @delegate - (CPToolbarItem)toolbar:(CPToolbar)toolbar itemForItemIdentifier:(CPString)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag;
    Called to obtain a toolbar item. Required.
    @param toolbar the toolbar the item belongs to
    @param itemIdentifier the identifier of the toolbar item
    @param flag \c YES means the item will be placed in the toolbar. \c NO means the item will be displayed for
    some other purpose (non-functional)
    @return the toolbar item or \c nil if no such item belongs in the toolbar
*/
@implementation CPToolbar : CPObject
{
    CPString                _identifier;
    CPToolbarDisplayMode    _displayMode;
    BOOL                    _showsBaselineSeparator;
    BOOL                    _allowsUserCustomization;
    BOOL                    _isVisible;

    id                      _delegate;

    CPArray                 _itemIdentifiers;

    CPDictionary            _identifiedItems;
    CPArray                 _defaultItems;
    CPArray                 _allowedItems;
    CPArray                 _selectableItems;

    CPArray                 _items;
    CPArray                 _itemsSortedByVisibilityPriority;

    CPView                  _toolbarView;
    CPWindow                _window;
}

/* @ignore */
+ (void)initialize
{
    if (self != [CPToolbar class])
        return;

    CPToolbarsByIdentifier = [CPDictionary dictionary];
    CPToolbarConfigurationsByIdentifier = [CPDictionary dictionary];
}

/* @ignore */
+ (void)_addToolbar:(CPToolbar)toolbar forIdentifier:(CPString)identifier
{
    var toolbarsSharingIdentifier = [CPToolbarsByIdentifier objectForKey:identifier];

    if (!toolbarsSharingIdentifier)
    {
        toolbarsSharingIdentifier = []
        [CPToolbarsByIdentifier setObject:toolbarsSharingIdentifier forKey:identifier];
    }

    [toolbarsSharingIdentifier addObject:toolbar];
}

- (id)init
{
    return [self initWithIdentifier:@""];
}

/*!
    Initializes the toolbar with the specified identifier.
    @param anIdentifier the identifier for the toolbar
    @return the initialized toolbar
*/
- (id)initWithIdentifier:(CPString)anIdentifier
{
    self = [super init];

    if (self)
    {
        _items = [];

        _identifier = anIdentifier;
        _isVisible = YES;

        [CPToolbar _addToolbar:self forIdentifier:_identifier];
    }

    return self;
}


/*!
    Sets the toolbar's display mode. NOT YET IMPLEMENTED.
*/
- (void)setDisplayMode:(CPToolbarDisplayMode)aDisplayMode
{

}

/*!
    Returns the toolbar's identifier
*/
- (CPString)identifier
{
    return _identifier;
}

/*!
    Returns the toolbar's delegate
*/
- (id)delegate
{
    return _delegate;
}

/*!
    Returns \c YES if the toolbar is currently visible
*/
- (BOOL)isVisible
{
    return _isVisible;
}

/*!
    Sets whether the toolbar should be visible.
    @param aFlag \c YES makes the toolbar visible
*/
- (void)setVisible:(BOOL)aFlag
{
    if (_isVisible === aFlag)
        return;

    _isVisible = aFlag;

    [_window _noteToolbarChanged];
}

- (CPWindow)_window
{
    return _window;
}

- (void)_setWindow:(CPWindow)aWindow
{
    _window = aWindow;
}

/*!
    Sets the delegate for the toolbar.
    @param aDelegate the new toolbar delegate
*/
- (void)setDelegate:(id)aDelegate
{
    if (_delegate === aDelegate)
        return;

    _delegate = aDelegate;

    [self _reloadToolbarItems];
}

/* @ignore */
- (void)_loadConfiguration
{

}

/* @ignore */
- (CPView)_toolbarView
{
    if (!_toolbarView)
    {
        _toolbarView = [[_CPToolbarView alloc] initWithFrame:CPRectMake(0.0, 0.0, 1200.0, 59.0)];

        [_toolbarView setToolbar:self];
        [_toolbarView setAutoresizingMask:CPViewWidthSizable];
        [_toolbarView reloadToolbarItems];
    }

    return _toolbarView;
}

/* @ignore */
- (void)_reloadToolbarItems
{
    // As of OS X 10.5 (Leopard), toolbar items can be set in IB and a
    // toolbar delegate is optional. Toolbar items can be combined from
    // both IB and a delegate (see Apple's NSToolbar guide for IB, for more details).

    // _defaultItems may have been loaded from Cib
    _itemIdentifiers = [_defaultItems valueForKey:@"itemIdentifier"] || [];

    if (_delegate)
    {
        var itemIdentifiersFromDelegate = [[_delegate toolbarDefaultItemIdentifiers:self] mutableCopy];

        if (itemIdentifiersFromDelegate)
            _itemIdentifiers = [_itemIdentifiers arrayByAddingObjectsFromArray:itemIdentifiersFromDelegate];
    }

    var index = 0,
        count = [_itemIdentifiers count];

    _items = [];

    for (; index < count; ++index)
    {
        var identifier = _itemIdentifiers[index],
            item = [CPToolbarItem _standardItemWithItemIdentifier:identifier];

        // May come from a Cib.
        if (!item)
            item = [_identifiedItems objectForKey:identifier];

        if (!item && _delegate)
            item = [_delegate toolbar:self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:YES];

        item = [item copy];

        if (item === nil)
            [CPException raise:CPInvalidArgumentException
                         reason:@"Toolbar delegate " + _delegate + " returned nil toolbar item for identifier \"" + identifier + "\""];

        item._toolbar = self;

        [_items addObject:item];
    }

//    _items = [[self _defaultToolbarItems] mutableCopy];

    // Store items sorted by priority.  We want items to be removed first at the end of the array,
    // items to be removed last at the front.

    _itemsSortedByVisibilityPriority = [_items sortedArrayUsingFunction:_CPToolbarItemVisibilityPriorityCompare context:NULL];

    [_toolbarView reloadToolbarItems];
}

/*!
    Returns all the items in this toolbar.
*/
- (CPArray)items
{
    return _items;
}

/*!
    Returns all the visible items in this toolbar
*/
- (CPArray)visibleItems
{
    return [_toolbarView visibleItems];
}

/*!
    Returns the toolbar items sorted by their \c visibilityPriority(ies).
*/
- (CPArray)itemsSortedByVisibilityPriority
{
    return _itemsSortedByVisibilityPriority;
}

/*!
    Validates the visible toolbar items by sending a validate message to
    each visible toolbar item.
*/
- (void)validateVisibleItems
{'fraction_non_alphanumeric': 0.08387096774193549, 'fraction_numerical': 0.00656891495601173, 'mean_word_length': 2.9442516770761045, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4466909', 'n_tokens_mistral': 4993, 'n_tokens_neox': 4644, 'n_words': 1481}