<commit_before>import logging
from typing import List, Tuple

from generic.event import Event
from gi.repository import Gtk

from gaphor.abc import ActionProvider
from gaphor.core import action, event_handler
from gaphor.core.modeling import AttributeUpdated, Diagram, ModelFlushed
from gaphor.event import ActionEnabled
from gaphor.ui.abc import UIComponent
from gaphor.ui.diagrampage import DiagramPage
from gaphor.ui.event import DiagramClosed, DiagramOpened, DiagramSelectionChanged

log = logging.getLogger(__name__)


class Diagrams(UIComponent, ActionProvider):
    def __init__(
        self, event_manager, element_factory, properties, modeling_language, toolbox
    ):
        self.event_manager = event_manager
        self.element_factory = element_factory
        self.properties = properties
        self.modeling_language = modeling_language
        self.toolbox = toolbox
        self._notebook: Gtk.Notebook = None
        self._page_handler_ids: List[int] = []

    def open(self):
        """Open the diagrams component.

        Returns:
            The Gtk.Notebook.
        """

        self._notebook = Gtk.Notebook()
        self._notebook.props.scrollable = True
        self._notebook.show()

        self._notebook.connect("destroy", self._on_notebook_destroy)
        self._notebook.connect("switch-page", self._on_switch_page)
        self._page_handler_ids = [
            self._notebook.connect("page-added", self._on_page_changed),
            self._notebook.connect("page-removed", self._on_page_changed),
            self._notebook.connect("page-reordered", self._on_page_changed),
        ]

        self.event_manager.subscribe(self._on_show_diagram)
        self.event_manager.subscribe(self._on_close_diagram)
        self.event_manager.subscribe(self._on_name_change)
        self.event_manager.subscribe(self._on_flush_model)

        return self._notebook

    def close(self):
        """Close the diagrams component."""

        self.event_manager.unsubscribe(self._on_flush_model)
        self.event_manager.unsubscribe(self._on_name_change)
        self.event_manager.unsubscribe(self._on_close_diagram)
        self.event_manager.unsubscribe(self._on_show_diagram)
        if self._notebook:
            if Gtk.get_major_version() == 3:
                self._notebook.destroy()
            else:
                parent = self._notebook.get_parent()
                if parent:
                    parent.remove(self._notebook)
            self._notebook = None

    def get_current_diagram(self):
        """Returns the current page of the notebook.

        Returns (DiagramPage): The current diagram page.
        """

        if not self._notebook:
            return None
        page_num = self._notebook.get_current_page()
        child_widget = self._notebook.get_nth_page(page_num)
        return child_widget and child_widget.diagram_page.get_diagram()

    def get_current_view(self):
        """Returns the current view of the diagram page.

        Returns (GtkView): The current view.
        """
        if not self._notebook:
            return None
        page_num = self._notebook.get_current_page()
        child_widget = self._notebook.get_nth_page(page_num)
        return child_widget and child_widget.diagram_page.get_view()

    def create_tab(self, title, widget):
        """Creates a new Notebook tab with a label and close button.

        Args:
            title (str): The title of the tab, the diagram name.
            widget (Gtk.Widget): The child widget of the tab.
        """

        page_num = self._notebook.append_page(
            child=widget, tab_label=tab_label(title, widget, self.event_manager)
        )
        self._notebook.set_current_page(page_num)
        self._notebook.set_tab_reorderable(widget, True)

        view = widget.diagram_page.view
        self.event_manager.handle(
            DiagramSelectionChanged(
                view, view.selection.focused_item, view.selection.selected_items
            )
        )

    def _on_notebook_destroy(self, notebook):
        for id in self._page_handler_ids:
            notebook.disconnect(id)

    def _on_switch_page(self, notebook, page, new_page_num):
        view = page.diagram_page.view
        self.event_manager.handle(
            DiagramSelectionChanged(
                view, view.selection.focused_item, view.selection.selected_items
            )
        )

    def _on_page_changed(self, notebook, _page, _page_num):
        def diagram_ids():
            notebook = self._notebook
            if not notebook:
                return
            for page_num in range(notebook.get_n_pages()):
                page = notebook.get_nth_page(page_num)
                if page:
                    diagram = page.diagram_page.get_diagram()
                    if diagram:
                        yield diagram.id

        self.properties.set("opened-diagrams", list(diagram_ids()))
        log.debug(f"pages changed: {self.properties.get('opened-diagrams')}")

    @action(name="close-current-tab", shortcut="<Primary>w")
    def close_current_tab(self):
        diagram = self.get_current_diagram()
        self.event_manager.handle(DiagramClosed(diagram))

    @action(
        name="zoom-in",
        shortcut="<Primary>plus",
    )
    def zoom_in(self):
        view = self.get_current_view()
        if view:
            view.zoom(1.2)

    @action(
        name="zoom-out",
        shortcut="<Primary>minus",
    )
    def zoom_out(self):<commit_msg>Use Ctrl-= to zoom in, instead of Ctrl-+<commit_after>import logging
from typing import List, Tuple

from generic.event import Event
from gi.repository import Gtk

from gaphor.abc import ActionProvider
from gaphor.core import action, event_handler
from gaphor.core.modeling import AttributeUpdated, Diagram, ModelFlushed
from gaphor.event import ActionEnabled
from gaphor.ui.abc import UIComponent
from gaphor.ui.diagrampage import DiagramPage
from gaphor.ui.event import DiagramClosed, DiagramOpened, DiagramSelectionChanged

log = logging.getLogger(__name__)


class Diagrams(UIComponent, ActionProvider):
    def __init__(
        self, event_manager, element_factory, properties, modeling_language, toolbox
    ):
        self.event_manager = event_manager
        self.element_factory = element_factory
        self.properties = properties
        self.modeling_language = modeling_language
        self.toolbox = toolbox
        self._notebook: Gtk.Notebook = None
        self._page_handler_ids: List[int] = []

    def open(self):
        """Open the diagrams component.

        Returns:
            The Gtk.Notebook.
        """

        self._notebook = Gtk.Notebook()
        self._notebook.props.scrollable = True
        self._notebook.show()

        self._notebook.connect("destroy", self._on_notebook_destroy)
        self._notebook.connect("switch-page", self._on_switch_page)
        self._page_handler_ids = [
            self._notebook.connect("page-added", self._on_page_changed),
            self._notebook.connect("page-removed", self._on_page_changed),
            self._notebook.connect("page-reordered", self._on_page_changed),
        ]

        self.event_manager.subscribe(self._on_show_diagram)
        self.event_manager.subscribe(self._on_close_diagram)
        self.event_manager.subscribe(self._on_name_change)
        self.event_manager.subscribe(self._on_flush_model)

        return self._notebook

    def close(self):
        """Close the diagrams component."""

        self.event_manager.unsubscribe(self._on_flush_model)
        self.event_manager.unsubscribe(self._on_name_change)
        self.event_manager.unsubscribe(self._on_close_diagram)
        self.event_manager.unsubscribe(self._on_show_diagram)
        if self._notebook:
            if Gtk.get_major_version() == 3:
                self._notebook.destroy()
            else:
                parent = self._notebook.get_parent()
                if parent:
                    parent.remove(self._notebook)
            self._notebook = None

    def get_current_diagram(self):
        """Returns the current page of the notebook.

        Returns (DiagramPage): The current diagram page.
        """

        if not self._notebook:
            return None
        page_num = self._notebook.get_current_page()
        child_widget = self._notebook.get_nth_page(page_num)
        return child_widget and child_widget.diagram_page.get_diagram()

    def get_current_view(self):
        """Returns the current view of the diagram page.

        Returns (GtkView): The current view.
        """
        if not self._notebook:
            return None
        page_num = self._notebook.get_current_page()
        child_widget = self._notebook.get_nth_page(page_num)
        return child_widget and child_widget.diagram_page.get_view()

    def create_tab(self, title, widget):
        """Creates a new Notebook tab with a label and close button.

        Args:
            title (str): The title of the tab, the diagram name.
            widget (Gtk.Widget): The child widget of the tab.
        """

        page_num = self._notebook.append_page(
            child=widget, tab_label=tab_label(title, widget, self.event_manager)
        )
        self._notebook.set_current_page(page_num)
        self._notebook.set_tab_reorderable(widget, True)

        view = widget.diagram_page.view
        self.event_manager.handle(
            DiagramSelectionChanged(
                view, view.selection.focused_item, view.selection.selected_items
            )
        )

    def _on_notebook_destroy(self, notebook):
        for id in self._page_handler_ids:
            notebook.disconnect(id)

    def _on_switch_page(self, notebook, page, new_page_num):
        view = page.diagram_page.view
        self.event_manager.handle(
            DiagramSelectionChanged(
                view, view.selection.focused_item, view.selection.selected_items
            )
        )

    def _on_page_changed(self, notebook, _page, _page_num):
        def diagram_ids():
            notebook = self._notebook
            if not notebook:
                return
            for page_num in range(notebook.get_n_pages()):
                page = notebook.get_nth_page(page_num)
                if page:
                    diagram = page.diagram_page.get_diagram()
                    if diagram:
                        yield diagram.id

        self.properties.set("opened-diagrams", list(diagram_ids()))
        log.debug(f"pages changed: {self.properties.get('opened-diagrams')}")

    @action(name="close-current-tab", shortcut="<Primary>w")
    def close_current_tab(self):
        diagram = self.get_current_diagram()
        self.event_manager.handle(DiagramClosed(diagram))

    @action(
        name="zoom-in",
        shortcut="<Primary>equal",
    )
    def zoom_in(self):
        view = self.get_current_view()
        if view:
            view.zoom(1.2)

    @action(
        name="zoom-out",
        shortcut="<Primary>minus",
    )
    def zoom_out(self):
{'fraction_non_alphanumeric': 0.08881460065052403, 'fraction_numerical': 0.0005421033610408384, 'mean_word_length': 2.412145499383477, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, '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': '473275', 'n_tokens_mistral': 3211, 'n_tokens_neox': 3128, 'n_words': 628}