예제 #1
0
파일: searchbar.py 프로젝트: Depau/GSub
    def __init__(self, stack_switcher, search_button, dropdown):
        Gtk.Revealer.__init__(self)
        self.timeout = None
        self.stack_switcher = stack_switcher
        self._search_button = search_button
        self.dropdown = dropdown
        self._searchContainer = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, halign=Gtk.Align.CENTER)
        self._searchContainer.get_style_context().add_class('linked')

        self._search_entry = Gd.TaggedEntry(width_request=500, halign=Gtk.Align.CENTER)
        self._search_entry.connect("changed", self.search_entry_timeout)
        self._search_entry.show()
        self._searchContainer.add(self._search_entry)

        arrow = Gtk.Image.new_from_icon_name('pan-down-symbolic',
                                             Gtk.IconSize.BUTTON)
        self._dropDownButton = Gtk.ToggleButton()
        self._dropDownButton.add(arrow)
        self._dropDownButton.get_style_context().add_class('image-button')
        self._dropDownButton.connect("toggled", self._drop_down_button_toggled)
        self._dropDownButton.show_all()
        self._searchContainer.add(self._dropDownButton)

        self._search_entry.connect("tag-button-clicked", self._search_entry_tag_button_clicked)

        self._searchContainer.show_all()
        self.add(self._searchContainer)
예제 #2
0
    def __init__(self, application):
        super().__init__()

        self._coregrilo = application.props.coregrilo
        self._selection_mode = False
        self._timeout = None

        self._entry = Gd.TaggedEntry()
        self._entry.props.halign = Gtk.Align.CENTER
        self._entry.props.visible = True
        self._entry.props.width_request = 500

        self._selection_menu = SelectionBarMenuButton()

        self.bind_property(
            "selection-mode", self, "show-close-button",
            GObject.BindingFlags.INVERT_BOOLEAN
            | GObject.BindingFlags.SYNC_CREATE)
        self.bind_property(
            "selection-mode", self._cancel_button, "visible")
        self.bind_property(
            "selection-mode", self._select_button, "visible",
            GObject.BindingFlags.INVERT_BOOLEAN)
        self.bind_property(
            "selection-mode", self._select_button, "active",
            GObject.BindingFlags.BIDIRECTIONAL)
        self.bind_property(
            "selected-songs-count", self._selection_menu,
            "selected-songs-count")
        self.bind_property(
            "search-mode-active", self._search_button, "active",
            GObject.BindingFlags.BIDIRECTIONAL
            | GObject.BindingFlags.SYNC_CREATE)
        self.bind_property(
            "selection-mode", self._search_button, "visible",
            GObject.BindingFlags.INVERT_BOOLEAN
            | GObject.BindingFlags.SYNC_CREATE)

        self.connect(
            "notify::selection-mode-allowed",
            self._on_selection_mode_allowed_changed)

        self.connect(
            "notify::search-mode-active", self._on_search_mode_changed)
        self.connect("notify::search-state", self._search_state_changed)

        self._entry.connect("changed", self._search_entry_timeout)
예제 #3
0
    def __init__(self, stack_switcher, search_button, dropdown):
        Gtk.Revealer.__init__(self)
        self.timeout = None
        self.stack_switcher = stack_switcher
        self._search_button = search_button
        self.dropdown = dropdown
        self._searchContainer = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL,
                                        halign=Gtk.Align.CENTER)
        self._searchContainer.get_style_context().add_class('linked')

        self._search_entry = Gd.TaggedEntry(width_request=500,
                                            halign=Gtk.Align.CENTER)
        self._search_entry.connect("changed", self.search_entry_timeout)
        self._search_entry.show()
        self._searchContainer.add(self._search_entry)

        self._dropDownButtonArrow = Gtk.Arrow(arrow_type=Gtk.ArrowType.DOWN,
                                              shadow_type=Gtk.ShadowType.NONE)
        self._dropDownButton = Gtk.ToggleButton()
        self._dropDownButton.add(self._dropDownButtonArrow)
        self._dropDownButton.get_style_context().add_class('raised')
        self._dropDownButton.get_style_context().add_class('image-button')
        self._dropDownButton.connect("toggled", self._drop_down_button_toggled)
        self._dropDownButton.show_all()
        self._searchContainer.add(self._dropDownButton)

        self._search_entry.connect("tag-button-clicked",
                                   self._search_entry_tag_button_clicked)

        self._searchContainer.show_all()
        toolbar = Gtk.Toolbar()
        toolbar.get_style_context().add_class("search-bar")
        toolbar.show()
        self.add(toolbar)

        item = Gtk.ToolItem()
        item.set_expand(True)
        item.show()
        toolbar.insert(item, 0)
        item.add(self._searchContainer)
예제 #4
0
class FindAndReplaceWindow(Gtk.Window):
    __gtype_name__ = "FindAndReplaceWindow"

    # Child widgets. Keep them alphabetically sorted
    btn_find_previous = GtkTemplate.Child()
    btn_find_or_replace_all = GtkTemplate.Child()
    btn_replace = GtkTemplate.Child()
    btn_skip = GtkTemplate.Child()
    btnbox_existing_text = GtkTemplate.Child()
    btnbox_replace_with = GtkTemplate.Child()
    chkbtn_use_regex = GtkTemplate.Child()
    chkbtn_use_similarity_srch = GtkTemplate.Child()
    chkbtn_whole_word = GtkTemplate.Child()
    img_search_notif = GtkTemplate.Child()
    lbl_search_notif = GtkTemplate.Child()
    menubtn_existing_text = GtkTemplate.Child()
    menubtn_replace_with = GtkTemplate.Child()
    menubtn_sound_like = GtkTemplate.Child()
    menubtn_use_similarity_srch = GtkTemplate.Child()
    rvlr_advanced_options = GtkTemplate.Child()
    rvlr_replace_with = GtkTemplate.Child()
    rvlr_search_notif = GtkTemplate.Child()
    stk_find_or_replace = GtkTemplate.Child()
    tglbtn_replace = GtkTemplate.Child()

    # Custom non-buildable widgets
    tagent_existing_text = Gd.TaggedEntry()
    tagent_replace_with = Gd.TaggedEntry()

    # Null objects. Keep them alphabetically sorted
    #
    # Don't forget to disconnect all the external widget signals
    # on this object destroy
    parent = Gtk.ApplicationWindow()

    # Other variables. Keep them alphabetically sorted
    search_flag = Gtk.TextSearchFlags.CASE_INSENSITIVE

    # Properties' storage. Keep them alphabetically sorted
    _replace_mode = True
    _advanced_mode = False

    #---------------------------------
    # The init function
    #
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.init_template()

        # Set null variables
        self.parent = self.get_transient_for()
        self.parent_handler = self.parent.txtbfr_buffer.connect(
            "mark-set", self.on_parent_text_buffer_mark_set)

        # We've to set these properties manually because GtkTemplate
        # doesn't do it well. Keep them alphabetically sorted
        self.btnbox_existing_text.set_homogeneous(False)
        self.btnbox_replace_with.set_homogeneous(False)
        self.menubtn_sound_like.set_sensitive(False)
        self.menubtn_use_similarity_srch.set_sensitive(False)

        # Init widgets
        parent_selected_text = \
            self.match_parent_selected_text(self.search_flag)[2]

        if parent_selected_text:
            self.tagent_existing_text.set_text(parent_selected_text)

        # Init custom widgets. Keep in mind that we don't use "show_all()"
        # since it can break the GTK Template "visible" property
        self.btnbox_existing_text.pack_start(self.tagent_existing_text, True,
                                             True, 0)
        self.tagent_existing_text.connect("changed",
                                          self.on_tagent_existing_text_changed)
        self.tagent_existing_text.show()

        self.btnbox_replace_with.pack_start(self.tagent_replace_with, True,
                                            True, 0)
        self.tagent_replace_with.set_icon_from_icon_name(
            Gtk.EntryIconPosition.PRIMARY, "edit-find-replace-symbolic")
        self.tagent_replace_with.show()

    #-----------------------------------
    # Properties. Keep them alphabetically sorted
    #
    # Advanced Mode property
    def get_advanced_mode(self):
        return self._advanced_mode

    def set_advanced_mode(self, value):
        # Save the value first
        self._advanced_mode = value

        # Refresh the integrations
        self.rvlr_advanced_options.set_reveal_child(value)
        self.menubtn_existing_text.set_visible(value)
        self.menubtn_replace_with.set_visible(value)

    # Replace Mode property
    def get_replace_mode(self):
        return self._replace_mode

    def set_replace_mode(self, value):
        widget = self.btn_find_or_replace_all
        stylectx = widget.get_style_context()

        # Save the value first
        self._replace_mode = value

        # Refresh the integrations
        self.rvlr_replace_with.set_reveal_child(value)
        if value:
            stylectx.add_class("destructive-action")
            widget.set_label("Replace All")
        else:
            stylectx.remove_class("destructive-action")
            widget.set_label("Find All")
        self.refresh_match_integration()

    #---------------------------------------------
    # Integration refreshment functions / procedures. Keep them
    # alphabetically sorted
    #
    def refresh_match_integration(self):
        matching, keyword = \
            self.match_parent_selected_text(self.search_flag)[0:2]
        widget = self.stk_find_or_replace

        widget.set_sensitive(keyword != "")
        if matching:
            if self.get_replace_mode():
                widget.set_visible_child_name("replace_act")
            else:
                widget.set_visible_child_name("main_act")
        else:
            widget.set_visible_child_name("main_act")

    #-----------------------------------
    # Other functions / procedures. Keep them alphabetically sorted
    #
    def find_and_select(self, direction):
        selected_text_matching, keyword, y, _buffer, selection_bounds = \
            self.match_parent_selected_text(self.search_flag)
        search_options = keyword, self.search_flag, None
        cursor_iter = Gtk.TextIter()
        found = False
        match = None
        icon = ""
        label = ""

        if selected_text_matching:
            if direction == Direction.FORWARD:
                cursor_iter = selection_bounds[1]
            elif direction == Direction.BACKWARD:
                cursor_iter = selection_bounds[0]
        else:
            cursor_iter = _buffer.get_iter_at_mark(_buffer.get_insert())

        for x in range(2):
            # Search once more from the start or the end of the documents
            # if nothing matching at first trial
            if direction == Direction.FORWARD:
                if x == 1:
                    cursor_iter = _buffer.get_start_iter()
                match = cursor_iter.forward_search(*search_options)
            elif direction == Direction.BACKWARD:
                if x == 1:
                    cursor_iter = _buffer.get_end_iter()
                match = cursor_iter.backward_search(*search_options)

            if match:
                found = True
                if x == 1:
                    icon = "dialog-information-symbolic"
                    if direction == Direction.FORWARD:
                        label = "Reached the end of the document"
                    elif direction == Direction.BACKWARD:
                        label = "Reached the beginning of the document"
                break

        if found:
            _buffer.select_range(*match)
        else:
            icon = "dialog-error-symbolic"
            label = "Search key not found"

        if label:
            self.lbl_search_notif.set_label(label)
            self.img_search_notif.set_from_icon_name(
                icon, Gtk.IconSize.LARGE_TOOLBAR)
            self.rvlr_search_notif.set_reveal_child(True)

    def match_parent_selected_text(self, flag):
        _buffer = self.parent.txtbfr_buffer
        selection_bounds = _buffer.get_selection_bounds()
        selected_text = ""
        keyword = self.tagent_existing_text.get_text()
        matching = False

        if selection_bounds:
            selected_text = _buffer.get_text(*selection_bounds, True)
            if keyword:  # don't merge this "if" statement to the parent "if"
                if flag == Gtk.TextSearchFlags.CASE_INSENSITIVE:
                    if selected_text.lower() == keyword.lower():
                        matching = True
                elif selected_text == keyword:
                    matching = True

        return matching, keyword, selected_text, _buffer, selection_bounds

    #--------------------------------------
    # Callbacks functions / procedures. Keep them alphabetically sorted
    #
    @GtkTemplate.Callback
    def on_btn_close_search_notif_clicked(self, widget):
        self.rvlr_search_notif.set_reveal_child(False)

    @GtkTemplate.Callback
    def on_btn_find_next_clicked(self, widget):
        self.rvlr_search_notif.set_reveal_child(False)
        self.find_and_select(Direction.FORWARD)

    @GtkTemplate.Callback
    def on_btn_find_previous_clicked(self, widget):
        self.rvlr_search_notif.set_reveal_child(False)
        self.find_and_select(Direction.BACKWARD)

    @GtkTemplate.Callback
    def on_btn_replace_clicked(self, widget):
        matching, x, y, _buffer, z = \
            self.match_parent_selected_text(self.search_flag)

        self.rvlr_search_notif.set_reveal_child(False)
        if matching:
            _buffer.delete_selection(False, False)
            _buffer.insert_at_cursor(self.tagent_replace_with.get_text(), -1)
        self.stk_find_or_replace.set_visible_child_name("main_act")

    @GtkTemplate.Callback
    def on_btn_skip_clicked(self, widget):
        self.rvlr_search_notif.set_reveal_child(False)
        self.stk_find_or_replace.set_visible_child_name("main_act")

    @GtkTemplate.Callback
    def on_chkbtn_sound_like_toggled(self, widget):
        self.menubtn_sound_like.set_sensitive(widget.get_active())

    @GtkTemplate.Callback
    def on_chkbtn_use_regex_toggled(self, widget):
        active = widget.get_active()

        self.chkbtn_use_similarity_srch.set_sensitive(not active)
        self.chkbtn_whole_word.set_sensitive(not active)
        self.chkbtn_whole_word.set_inconsistent(active)

    @GtkTemplate.Callback
    def on_chkbtn_use_similarity_srch_toggled(self, widget):
        active = widget.get_active()

        self.menubtn_use_similarity_srch.set_sensitive(active)
        self.chkbtn_use_regex.set_sensitive(not active)

    @GtkTemplate.Callback
    def on_FindAndReplaceWindow_destroy(self, widget):
        self.parent.txtbfr_buffer.disconnect(self.parent_handler)

    @GtkTemplate.Callback
    def on_tglbtn_replace_toggled(self, widget):
        self.set_replace_mode(widget.get_active())

    def on_parent_text_buffer_mark_set(self, location, mark, widget):
        self.refresh_match_integration()

    @GtkTemplate.Callback
    def on_rdbtn_options_mode_toggled(self, widget):
        self.set_advanced_mode(widget.get_name() == "advanced_mode")

    @GtkTemplate.Callback
    def on_tagent_existing_text_changed(self, widget):
        self.refresh_match_integration()