diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index 2efc26a6..f0ec1a89 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -885,8 +885,9 @@ class Application(Gtk.Application): uris = data.get_uris() if txt: self.receive_selection(view=view, drop_info=view.get_dest_row_at_pos(x, y), data=txt) - elif len(uris) == 1: - self.on_assign_picon(view, uris[0]) + elif len(uris) == 2: + from urllib.parse import unquote, urlparse + self.on_assign_picon(view, urlparse(unquote(uris[0])).path, urlparse(unquote(uris[1])).path + "/") def on_bq_view_drag_data_received(self, view, drag_context, x, y, data, info, time): model_name, model = get_model_data(view) @@ -2522,22 +2523,12 @@ class Application(Gtk.Application): update_picons_data(self._settings.picons_local_path, self._picons) append_picons(self._picons, self._services_model) - def on_assign_picon(self, view, path=None): - assign_picon(self.get_target_view(view), - self._services_view, - self._fav_view, - self._main_window, - self._picons, - self._settings, - self._services, - path) + def on_assign_picon(self, view, src_path=None, dst_path=None): + assign_picon(self.get_target_view(view), self._services_view, self._fav_view, self._main_window, + self._picons, self._settings, self._services, src_path, dst_path) def on_remove_picon(self, view): - remove_picon(self.get_target_view(view), - self._services_view, - self._fav_view, - self._picons, - self._settings) + remove_picon(self.get_target_view(view), self._services_view, self._fav_view, self._picons, self._settings) def on_reference_picon(self, view): """ Copying picon id to clipboard """ diff --git a/app/ui/main_helper.py b/app/ui/main_helper.py index bcb83f8e..51167e33 100644 --- a/app/ui/main_helper.py +++ b/app/ui/main_helper.py @@ -367,16 +367,16 @@ def append_picons(picons, model): GLib.idle_add(lambda: next(app, False), priority=GLib.PRIORITY_LOW) -def assign_picon(target, srv_view, fav_view, transient, picons, settings, services, p_path=None): +def assign_picon(target, srv_view, fav_view, transient, picons, settings, services, src_path=None, dst_path=None): view = srv_view if target is ViewTarget.SERVICES else fav_view model, paths = view.get_selection().get_selected_rows() - if not p_path: - p_path = get_chooser_dialog(transient, settings, "*.png files", ("*.png",)) - if p_path == Gtk.ResponseType.CANCEL: + if not src_path: + src_path = get_chooser_dialog(transient, settings, "*.png files", ("*.png",)) + if src_path == Gtk.ResponseType.CANCEL: return - if not str(p_path).endswith(".png") or not os.path.isfile(p_path): + if not str(src_path).endswith(".png") or not os.path.isfile(src_path): show_dialog(DialogType.ERROR, transient, text="No png file is selected!") return @@ -394,10 +394,10 @@ def assign_picon(target, srv_view, fav_view, transient, picons, settings, servic picon_id = services.get(fav_id)[Column.SRV_PICON_ID] if picon_id: - picons_path = settings.picons_local_path + picons_path = dst_path or settings.picons_local_path os.makedirs(os.path.dirname(picons_path), exist_ok=True) picon_file = picons_path + picon_id - shutil.copy(p_path, picon_file) + shutil.copy(src_path, picon_file) picon = get_picon_pixbuf(picon_file) picons[picon_id] = picon model.set_value(itr, p_pos, picon) @@ -411,7 +411,8 @@ def set_picon(fav_id, model, picon, fav_id_pos, picon_pos): for row in model: if row[fav_id_pos] == fav_id: row[picon_pos] = picon - break + return True + return True def remove_picon(target, srv_view, fav_view, picons, settings): diff --git a/app/ui/picons_manager.glade b/app/ui/picons_manager.glade index a570ab29..f1c5059a 100644 --- a/app/ui/picons_manager.glade +++ b/app/ui/picons_manager.glade @@ -28,12 +28,11 @@ Author: Dmitriy Yefremov --> - - + @@ -43,11 +42,27 @@ Author: Dmitriy Yefremov - - picons_list_store + + picons_dest_list_store - - picons_filter_model + + picons_dst_filter_model + + + + + + + + + + + + + picons_src_list_store + + + picons_src_filter_model @@ -125,7 +140,7 @@ Author: Dmitriy Yefremov True - True + False True Cancel True @@ -148,7 +163,7 @@ Author: Dmitriy Yefremov False - True + False False Load providers center @@ -171,7 +186,7 @@ Author: Dmitriy Yefremov False - True + False False Receive picons center @@ -204,7 +219,7 @@ Author: Dmitriy Yefremov True - True + False True Transfer to receiver True @@ -226,7 +241,7 @@ Author: Dmitriy Yefremov True - True + False True Download from the receiver @@ -247,7 +262,7 @@ Author: Dmitriy Yefremov True - True + False True Remove all picons from the receiver @@ -272,7 +287,7 @@ Author: Dmitriy Yefremov - True + False False Convert center @@ -288,13 +303,34 @@ Author: Dmitriy Yefremov end - 3 + 4 + + + + + True + False + False + Details + False + + + True + False + gtk-dialog-info + + + + + + end + 5 True - True + False True Filter @@ -310,7 +346,7 @@ Author: Dmitriy Yefremov end - 3 + 4 @@ -352,21 +388,6 @@ Author: Dmitriy Yefremov 5 vertical 5 - - - True - False - select-folder - - - - - - False - True - 0 - - False @@ -454,42 +475,307 @@ Author: Dmitriy Yefremov - + True True - in + True - + True - True - 5 - picons_sort_model - 5 - 5 - 1 - 5 - True - - - - + False + vertical + 2 - - 128 + + True + False + + + False + 2 + + + True + False + False + False + center + True + + + + 0 + 0 + + + + + True + False + Filter + + + 1 + 0 + + + + + False + True + 0 + + + + + True + False + Source: + + + False + True + 3 + + - - 0 - + + False + True + 0 + - - center + + True + False + select-folder + + - - 1 - + + False + True + 1 + + + + + True + True + in + + + True + True + picons_src_sort_model + False + 1 + True + + + + + + + + + column + + + + 0 + + + + + + + column + + + + 1 + + + + + + + False + column + + + + 2 + + + + + + + + + True + True + 2 + + + True + True + + + + + True + False + vertical + 2 + + + True + False + + + True + False + Destination: + + + False + True + 3 + + + + + False + 2 + + + True + False + False + False + center + right + True + True + + + + 1 + 0 + + + + + True + False + Filter + + + 0 + 0 + + + + + False + True + end + 0 + + + + + False + True + 0 + + + + + True + False + select-folder + + + + + False + True + 1 + + + + + True + True + in + + + True + True + picons_dst_sort_model + False + 1 + True + + + + + + + + column + + + + 0 + + + + + + + column + + + + 1 + + + + + + + False + column + + + + 2 + + + + + + + + + True + True + 3 + + + + + True + True + @@ -498,6 +784,70 @@ Author: Dmitriy Yefremov 4 + + + False + other + + + False + 6 + end + + + False + False + 0 + + + + + False + 10 + + + 128 + 72 + True + False + gtk-missing-image + 6 + + + + False + True + 0 + + + + + True + False + + + False + True + 1 + + + + + False + False + 0 + + + + + + + + False + True + 6 + + diff --git a/app/ui/picons_manager.py b/app/ui/picons_manager.py index ec121db7..0371297d 100644 --- a/app/ui/picons_manager.py +++ b/app/ui/picons_manager.py @@ -5,7 +5,7 @@ import subprocess import tempfile from pathlib import Path -from gi.repository import GLib, GdkPixbuf, GObject +from gi.repository import GLib, GdkPixbuf from app.commons import run_idle, run_task, run_with_delay from app.connections import upload_data, DownloadType, download_data, remove_picons @@ -13,7 +13,8 @@ from app.settings import SettingsType, Settings from app.tools.picons import PiconsParser, parse_providers, Provider, convert_to from app.tools.satellites import SatellitesParser, SatelliteSource from .dialogs import show_dialog, DialogType, get_message -from .main_helper import update_entry_data, append_text_to_tview, scroll_to, on_popup_menu, get_base_model +from .main_helper import update_entry_data, append_text_to_tview, scroll_to, on_popup_menu, get_base_model, set_picon, \ + get_picon_pixbuf from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, TV_ICON, Column @@ -29,6 +30,8 @@ class PiconsDialog: self._current_process = None self._terminate = False self._filter_binding = None + self._services = None + self._current_picon_info = None handlers = {"on_receive": self.on_receive, "on_load_providers": self.on_load_providers, @@ -45,17 +48,21 @@ class PiconsDialog: "on_position_edited": self.on_position_edited, "on_visible_page": self.on_visible_page, "on_convert": self.on_convert, - "on_picons_folder_changed": self.on_picons_folder_changed, + "on_picons_src_changed": self.on_picons_src_changed, + "on_picons_dest_changed": self.on_picons_dest_changed, "on_picons_view_drag_drop": self.on_picons_view_drag_drop, "on_picons_view_drag_data_received": self.on_picons_view_drag_data_received, "on_picons_view_drag_data_get": self.on_picons_view_drag_data_get, - "on_picons_view_realize": self.on_picons_view_realize, + "on_picon_info_image_drag_data_received": self.on_picon_info_image_drag_data_received, + "on_picons_dest_view_realize": self.on_picons_dest_view_realize, "on_satellites_view_realize": self.on_satellites_view_realize, "on_satellite_selection": self.on_satellite_selection, "on_select_all": self.on_select_all, "on_unselect_all": self.on_unselect_all, "on_filter_toggled": self.on_filter_toggled, + "on_fiter_srcs_toggled": self.on_fiter_srcs_toggled, "on_filter_services_switch": self.on_filter_services_switch, + "on_picon_activated": self.on_picon_activated, "on_popup_menu": on_popup_menu} builder = Gtk.Builder() @@ -64,17 +71,23 @@ class PiconsDialog: self._dialog = builder.get_object("picons_dialog") self._dialog.set_transient_for(transient) - self._picons_view = builder.get_object("picons_view") + self._picons_src_view = builder.get_object("picons_src_view") + self._picons_dest_view = builder.get_object("picons_dest_view") self._providers_view = builder.get_object("providers_view") self._satellites_view = builder.get_object("satellites_view") - self._picons_filter_model = builder.get_object("picons_filter_model") - self._picons_filter_model.set_visible_func(self.picons_filter_function) - self._explorer_path_button = builder.get_object("explorer_path_button") + self._picons_src_filter_model = builder.get_object("picons_src_filter_model") + self._picons_src_filter_model.set_visible_func(self.picons_src_filter_function) + self._picons_dst_filter_model = builder.get_object("picons_dst_filter_model") + self._picons_dst_filter_model.set_visible_func(self.picons_dst_filter_function) + self._explorer_src_path_button = builder.get_object("explorer_src_path_button") + self._explorer_dest_path_button = builder.get_object("explorer_dest_path_button") self._expander = builder.get_object("expander") self._text_view = builder.get_object("text_view") self._info_bar = builder.get_object("info_bar") self._filter_bar = builder.get_object("filter_bar") self._filter_button = builder.get_object("filter_button") + self._src_filter_button = builder.get_object("src_filter_button") + self._dst_filter_button = builder.get_object("dst_filter_button") self._picons_filter_entry = builder.get_object("picons_filter_entry") self._ip_entry = builder.get_object("ip_entry") self._picons_entry = builder.get_object("picons_entry") @@ -83,6 +96,9 @@ class PiconsDialog: self._info_bar = builder.get_object("info_bar") self._info_bar = builder.get_object("info_bar") self._message_label = builder.get_object("info_bar_message_label") + self._info_check_button = builder.get_object("info_check_button") + self._picon_info_image = builder.get_object("picon_info_image") + self._picon_info_label = builder.get_object("picon_info_label") self._load_providers_button = builder.get_object("load_providers_button") self._receive_button = builder.get_object("receive_button") self._convert_button = builder.get_object("convert_button") @@ -104,8 +120,12 @@ class PiconsDialog: self._load_providers_button.bind_property("visible", self._receive_button, "visible") self._load_providers_button.bind_property("visible", builder.get_object("download_box_separator"), "visible") self._filter_bar.bind_property("search-mode-enabled", self._filter_bar, "visible") - self._explorer_path_button.bind_property("sensitive", builder.get_object("picons_view_sw"), "sensitive") + self._explorer_src_path_button.bind_property("sensitive", builder.get_object("picons_view_sw"), "sensitive") self._filter_button.bind_property("active", builder.get_object("filter_service_box"), "visible") + self._filter_button.bind_property("active", builder.get_object("src_title_grid"), "visible") + self._filter_button.bind_property("active", builder.get_object("dst_title_grid"), "visible") + self._filter_button.bind_property("visible", self._info_check_button, "visible") + self._info_check_button.bind_property("active", builder.get_object("explorer_info_bar"), "visible") # Init drag-and-drop self.init_drag_and_drop() # Style @@ -132,28 +152,34 @@ class PiconsDialog: def show(self): self._dialog.show() - def on_picons_view_realize(self, view): - self._explorer_path_button.set_current_folder(self._settings.picons_local_path) + def on_picons_dest_view_realize(self, view): + self._services = {s.picon_id: s for s in self._app.current_services.values() if s.picon_id} + self._explorer_dest_path_button.select_filename(self._settings.picons_local_path) - def on_picons_folder_changed(self, button): + def on_picons_src_changed(self, button): + self.update_picons_data(self._picons_src_view, button) + + def on_picons_dest_changed(self, button): + self.update_picon_info() + self.update_picons_data(self._picons_dest_view, button) + + def update_picons_data(self, view, button): path = button.get_filename() if not path or not os.path.exists(path): return - self.update_picons_data(path) - - def update_picons_data(self, path): - GLib.idle_add(self._explorer_path_button.set_sensitive, False) - gen = self.update_picons(path) + GLib.idle_add(button.set_sensitive, False) + gen = self.update_picons(path, view, button) GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW) - def update_picons(self, path): - p_model = self._picons_view.get_model() + def update_picons(self, path, view, button): + p_model = view.get_model() if not p_model: + button.set_sensitive(True) return model = get_base_model(p_model) - self._picons_view.set_model(None) + view.set_model(None) factor = self._app.DEL_FACTOR for index, itr in enumerate([row.iter for row in model]): @@ -165,43 +191,49 @@ class PiconsDialog: if self._terminate: return - try: - p = GdkPixbuf.Pixbuf.new_from_file_at_scale("{}/{}".format(path, file), 100, 60, True) - except GLib.GError as e: - pass - else: - yield model.append((p, file, path)) + p_path = "{}/{}".format(path, file) + p = self.get_pixbuf_at_scale(p_path, 72, 48, True) + if p: + yield model.append((p, file, p_path)) - self._picons_view.set_model(p_model) - self._explorer_path_button.set_sensitive(True) + view.set_model(p_model) + button.set_sensitive(True) yield True def update_picons_from_file(self, view, uri): """ Adds picons in the view on dragging from file system. """ - model = get_base_model(view.get_model()) from urllib.parse import unquote, urlparse path = Path(urlparse(unquote(uri)).path.strip()) f_path = str(path.resolve()) if not f_path: return + model = get_base_model(view.get_model()) + if path.is_file(): - try: - p = GdkPixbuf.Pixbuf.new_from_file_at_scale(f_path, 100, 60, True) - except GLib.GError: - pass - else: - model.append((p, path.name, str(path.parent))) + p = self.get_pixbuf_at_scale(f_path, 72, 48, True) + if p: + model.append((p, path.name, f_path)) elif path.is_dir(): - self._explorer_path_button.set_current_folder(f_path + "/") + self._explorer_src_path_button.select_filename(f_path) + + def get_pixbuf_at_scale(self, path, width, height, p_ratio): + try: + return GdkPixbuf.Pixbuf.new_from_file_at_scale(path, width, height, p_ratio) + except GLib.GError: + pass # ***************** Drag-and-drop ********************* # def init_drag_and_drop(self): - self._picons_view.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [], Gdk.DragAction.COPY) - self._picons_view.drag_source_add_uri_targets() - self._picons_view.enable_model_drag_dest([], Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) - self._picons_view.drag_dest_add_text_targets() + self._picons_src_view.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [], Gdk.DragAction.COPY) + self._picons_src_view.drag_source_add_uri_targets() + + self._picons_src_view.enable_model_drag_dest([], Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) + self._picons_src_view.drag_dest_add_text_targets() + + self._picon_info_image.drag_dest_set(Gtk.DestDefaults.ALL, [], Gdk.DragAction.COPY) + self._picon_info_image.drag_dest_add_uri_targets() def on_picons_view_drag_drop(self, view, drag_context, x, y, time): view.stop_emission_by_name("drag_drop") @@ -222,13 +254,11 @@ class PiconsDialog: if src == self._app.BQ_MODEL_NAME: return - path, pos = view.get_dest_item_at_pos(x, y) or (None, None) + path, pos = view.get_dest_row_at_pos(x, y) or (None, None) if not path: return model = view.get_model() - row = model[path][:] - p_path = "{}/{}".format(row[-1], row[1]) if src == self._app.FAV_MODEL_NAME: target_view = self._app.fav_view c_id = Column.FAV_ID @@ -237,7 +267,7 @@ class PiconsDialog: c_id = Column.SRV_FAV_ID t_mod = target_view.get_model() - self._app.on_assign_picon(target_view, p_path) + self._app.on_assign_picon(target_view, model[path][-1]) self.show_assign_info([t_mod.get_value(t_mod.get_iter_from_string(itr), c_id) for itr in itr_str.split(",")]) @run_idle @@ -251,12 +281,39 @@ class PiconsDialog: self.append_output("Picon assignment for the service:\n{}\n{}\n".format(info, " * " * 30)) def on_picons_view_drag_data_get(self, view, drag_context, data, info, time): - model = view.get_model() - path = view.get_selected_items()[0] - row = model[path][:] - data.set_uris(["{}/{}".format(row[-1], row[1])]) + model, path = view.get_selection().get_selected_rows() + if path: + data.set_uris([Path(model[path][-1]).as_uri(), + Path(self._explorer_dest_path_button.get_filename()).as_uri()]) - # ******************** ####### ************************* # + def on_picon_info_image_drag_data_received(self, img, drag_context, x, y, data, info, time): + if not self._current_picon_info: + self.show_info_message("No selected item!", Gtk.MessageType.ERROR) + return + + uris = data.get_uris() + if len(uris) == 2: + name, fav_id = self._current_picon_info + from urllib.parse import unquote, urlparse + src = urlparse(unquote(uris[0])).path + dst = "{}/{}".format(urlparse(unquote(uris[1])).path, name) + if src != dst: + shutil.copy(src, dst) + for row in get_base_model(self._picons_dest_view.get_model()): + if name == row[1]: + row[0] = self.get_pixbuf_at_scale(row[-1], 72, 48, True) + img.set_from_pixbuf(self.get_pixbuf_at_scale(row[-1], 100, 60, True)) + + gen = self.update_picon_in_lists(dst, fav_id) + GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW) + + def update_picon_in_lists(self, dst, fav_id): + picon = get_picon_pixbuf(dst) + p_pos = Column.SRV_PICON + yield set_picon(fav_id, get_base_model(self._app.services_view.get_model()), picon, Column.SRV_FAV_ID, p_pos) + yield set_picon(fav_id, get_base_model(self._app.fav_view.get_model()), picon, Column.FAV_ID, p_pos) + + # ******************** Downloader ************************* # def on_satellites_view_realize(self, view): self.get_satellites(view) @@ -438,7 +495,7 @@ class PiconsDialog: return settings = Settings(self._settings.settings) - settings.picons_local_path = self._explorer_path_button.get_filename() + "/" + settings.picons_local_path = self._explorer_src_path_button.get_filename() + "/" self.show_info_message(get_message("Please, wait..."), Gtk.MessageType.INFO) self.run_func(lambda: upload_data(settings=settings, download_type=DownloadType.PICONS, @@ -451,7 +508,7 @@ class PiconsDialog: return settings = Settings(self._settings.settings) - settings.picons_local_path = self._explorer_path_button.get_filename() + "/" + settings.picons_local_path = self._explorer_src_path_button.get_filename() + "/" self.run_func(lambda: download_data(settings=settings, download_type=DownloadType.PICONS, callback=self.append_output), True) @@ -476,7 +533,7 @@ class PiconsDialog: finally: GLib.idle_add(self._header_download_box.set_sensitive, True) if update: - self.on_picons_folder_changed(self._explorer_path_button) + self.on_picons_src_changed(self._explorer_src_path_button) def on_info_bar_close(self, bar=None, resp=None): self._info_bar.set_visible(False) @@ -506,13 +563,20 @@ class PiconsDialog: view.get_model().foreach(lambda mod, path, itr: mod.set_value(itr, 7, select)) self.update_receive_button_state() + # *********************** Filter **************************** # + def on_filter_toggled(self, button): active = button.get_active() self._filter_bar.set_search_mode(active) if not active: self._picons_filter_entry.set_text("") + def on_fiter_srcs_toggled(self, filter_model): + """ Activates re-filtering for model when filter check-button has toggled. """ + GLib.idle_add(filter_model.refilter, priority=GLib.PRIORITY_LOW) + def on_filter_services_switch(self, button, state): + """ Activates or deactivates filtering in the main list of services. """ if state: self._filter_binding = self._picons_filter_entry.bind_property("text", self._app.filter_entry, "text") self._app.filter_entry.set_text(self._picons_filter_entry.get_text()) @@ -521,17 +585,20 @@ class PiconsDialog: self._filter_binding.unbind() self._app.filter_entry.set_text("") - def on_url_changed(self, entry): - suit = self._PATTERN.search(entry.get_text()) - entry.set_name("GtkEntry" if suit else "digit-entry") - self._load_providers_button.set_sensitive(suit if suit else False) - @run_with_delay(1) def on_picons_filter_changed(self, entry): - GLib.idle_add(self._picons_filter_model.refilter, priority=GLib.PRIORITY_LOW) + GLib.idle_add(self._picons_src_filter_model.refilter, priority=GLib.PRIORITY_LOW) + GLib.idle_add(self._picons_dst_filter_model.refilter, priority=GLib.PRIORITY_LOW) - def picons_filter_function(self, model, itr, data): - if self._picons_filter_model is None or self._picons_filter_model == "None": + def picons_src_filter_function(self, model, itr, data): + return self.filter_function(itr, model, self._src_filter_button.get_active()) + + def picons_dst_filter_function(self, model, itr, data): + return self.filter_function(itr, model, self._dst_filter_button.get_active()) + + def filter_function(self, itr, model, active): + """ Main filtering function. """ + if any((not active, model is None, model == "None")): return True t = model.get_value(itr, 1) @@ -542,6 +609,40 @@ class PiconsDialog: return txt in t.upper() or t in ( map(lambda s: s.picon_id, filter(lambda s: txt in s.service.upper(), self._app.current_services.values()))) + def on_picon_activated(self, view): + if self._info_check_button.get_active(): + model, path = view.get_selection().get_selected_rows() + if not path: + return + + row = model[path][:] + name, path = row[1], row[-1] + srv = self._services.get(row[1], None) + self.update_picon_info(name, path, srv) + + def update_picon_info(self, name=None, path=None, srv=None): + self._picon_info_image.set_from_pixbuf(self.get_pixbuf_at_scale(path, 100, 60, True) if path else None) + self._picon_info_label.set_text(self.get_service_info(srv)) + self._current_picon_info = (name, srv.fav_id) if srv else None + + def get_service_info(self, srv): + """ Returns short info about the service. """ + if not srv: + return "" + + if srv.service_type == "IPTV": + return self._app.get_hint_for_srv_list(srv) + + header, ref = self._app.get_hint_header_info(srv) + return "{} {}: {}\n{}: {} {}: {}\n{}".format(header.rstrip(), get_message("Package"), srv.package, + get_message("System"), srv.system, get_message("Freq"), srv.freq, + ref) + + def on_url_changed(self, entry): + suit = self._PATTERN.search(entry.get_text()) + entry.set_name("GtkEntry" if suit else "digit-entry") + self._load_providers_button.set_sensitive(suit if suit else False) + def on_position_edited(self, render, path, value): model = self._providers_view.get_model() model.set_value(model.get_iter(path), 2, value) @@ -554,7 +655,7 @@ class PiconsDialog: is_explorer = name == "explorer" self._filter_button.set_visible(is_explorer) if is_explorer: - self.on_picons_folder_changed(self._explorer_path_button) + self.on_picons_dest_changed(self._explorer_dest_path_button) @run_idle def on_convert(self, item):