<commit_before>// Copyright 2010 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package walk

import . "github.com/lxn/go-winapi"

type widgetListObserver interface {
	onInsertingWidget(index int, widget Widget) error
	onInsertedWidget(index int, widget Widget) error
	onRemovingWidget(index int, widget Widget) error
	onRemovedWidget(index int, widget Widget) error
	onClearingWidgets() error
	onClearedWidgets() error
}

type WidgetList struct {
	items    []Widget
	observer widgetListObserver
}

func newWidgetList(observer widgetListObserver) *WidgetList {
	return &WidgetList{observer: observer}
}

func (l *WidgetList) Add(item Widget) error {
	return l.Insert(len(l.items), item)
}

func (l *WidgetList) At(index int) Widget {
	return l.items[index]
}

func (l *WidgetList) Clear() error {
	observer := l.observer
	if observer != nil {
		if err := observer.onClearingWidgets(); err != nil {
			return err
		}
	}

	oldItems := l.items
	l.items = l.items[:0]

	if observer != nil {
		if err := observer.onClearedWidgets(); err != nil {
			l.items = oldItems
			return err
		}
	}

	return nil
}

func (l *WidgetList) Index(item Widget) int {
	for i, widget := range l.items {
		if widget == item {
			return i
		}
	}

	return -1
}

func (l *WidgetList) Contains(item Widget) bool {
	return l.Index(item) > -1
}

func (l *WidgetList) indexHandle(handle HWND) int {
	for i, widget := range l.items {
		if widget.BaseWidget().hWnd == handle {
			return i
		}
	}

	return -1
}

func (l *WidgetList) containsHandle(handle HWND) bool {
	return l.indexHandle(handle) > -1
}

func (l *WidgetList) insertIntoSlice(index int, item Widget) {
	l.items = append(l.items, nil)
	copy(l.items[index+1:], l.items[index:])
	l.items[index] = item
}

func (l *WidgetList) Insert(index int, item Widget) error {
	observer := l.observer
	if observer != nil {
		if err := observer.onInsertingWidget(index, item); err != nil {
			return err
		}
	}

	l.insertIntoSlice(index, item)

	if observer != nil {
		if err := observer.onInsertedWidget(index, item); err != nil {
			l.items = append(l.items[:index], l.items[index+1:]...)
			return err
		}
	}

	return nil<commit_msg>WidgetList: Protect against duplicate widget insertion<commit_after>// Copyright 2010 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package walk

import . "github.com/lxn/go-winapi"

type widgetListObserver interface {
	onInsertingWidget(index int, widget Widget) error
	onInsertedWidget(index int, widget Widget) error
	onRemovingWidget(index int, widget Widget) error
	onRemovedWidget(index int, widget Widget) error
	onClearingWidgets() error
	onClearedWidgets() error
}

type WidgetList struct {
	items    []Widget
	observer widgetListObserver
}

func newWidgetList(observer widgetListObserver) *WidgetList {
	return &WidgetList{observer: observer}
}

func (l *WidgetList) Add(item Widget) error {
	return l.Insert(len(l.items), item)
}

func (l *WidgetList) At(index int) Widget {
	return l.items[index]
}

func (l *WidgetList) Clear() error {
	observer := l.observer
	if observer != nil {
		if err := observer.onClearingWidgets(); err != nil {
			return err
		}
	}

	oldItems := l.items
	l.items = l.items[:0]

	if observer != nil {
		if err := observer.onClearedWidgets(); err != nil {
			l.items = oldItems
			return err
		}
	}

	return nil
}

func (l *WidgetList) Index(item Widget) int {
	for i, widget := range l.items {
		if widget == item {
			return i
		}
	}

	return -1
}

func (l *WidgetList) Contains(item Widget) bool {
	return l.Index(item) > -1
}

func (l *WidgetList) indexHandle(handle HWND) int {
	for i, widget := range l.items {
		if widget.BaseWidget().hWnd == handle {
			return i
		}
	}

	return -1
}

func (l *WidgetList) containsHandle(handle HWND) bool {
	return l.indexHandle(handle) > -1
}

func (l *WidgetList) insertIntoSlice(index int, item Widget) {
	l.items = append(l.items, nil)
	copy(l.items[index+1:], l.items[index:])
	l.items[index] = item
}

func (l *WidgetList) Insert(index int, item Widget) error {
	if l.Contains(item) {
		return newError("cannot insert same widget multiple times")
	}

	observer := l.observer
	if observer != nil {
		if err := observer.onInsertingWidget(index, item); err != nil {
			return err
		}
	}

	l.insertIntoSlice(index, item)

	if observer != nil {
		if err := observer.onInsertedWidget(index, item); err != nil {
			l.items = append(l.items[:index], l.items[index+1:]...)
			return err
		}
	}

	return nil
{'fraction_non_alphanumeric': 0.12267818574514039, 'fraction_numerical': 0.004751619870410367, 'mean_word_length': 3.839080459770115, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '1401657', 'n_tokens_mistral': 1677, 'n_tokens_neox': 1583, 'n_words': 477}