From 9d7faba385a6638ebc9038567fc2fe666c7ba062 Mon Sep 17 00:00:00 2001 From: Dmitriy Yefremov Date: Sat, 9 Dec 2017 16:25:54 +0300 Subject: [PATCH] dialogs refactoring --- app/eparser/bouquets.py | 2 +- app/ui/dialogs.glade | 2 +- app/ui/dialogs.py | 36 +++++++++++++++++++++++++++++------ app/ui/download_dialog.py | 4 ++-- app/ui/main_app_window.py | 38 ++++++++++++++++++++++++------------- app/ui/satellites_dialog.py | 25 +++++++++--------------- app/ui/settings_dialog.py | 17 +++++------------ 7 files changed, 73 insertions(+), 51 deletions(-) diff --git a/app/eparser/bouquets.py b/app/eparser/bouquets.py index 5d75373a..ec3e7771 100644 --- a/app/eparser/bouquets.py +++ b/app/eparser/bouquets.py @@ -63,7 +63,7 @@ def get_bouquet(path, name, bq_type): ids = [] for ch in list(filter(lambda x: len(x) > 1, chs_list.split("#SERVICE")[1:])): # filtering [''] if "#DESCRIPTION" in ch: # IPTV - ids.append(ch.strip()) + ids.append("#SERVICE{}".format(ch)) else: ch_data = ch.strip().split(":") ids.append("{}:{}:{}:{}".format(ch_data[3], ch_data[4], ch_data[5], ch_data[6])) diff --git a/app/ui/dialogs.glade b/app/ui/dialogs.glade index 59ef5b12..68e90cf3 100644 --- a/app/ui/dialogs.glade +++ b/app/ui/dialogs.glade @@ -514,7 +514,7 @@ dmitry.v.yefremov@gmail.com True document-open dialog - save + select-folder True diff --git a/app/ui/dialogs.py b/app/ui/dialogs.py index 8a2ff3b3..9c3d0309 100644 --- a/app/ui/dialogs.py +++ b/app/ui/dialogs.py @@ -1,28 +1,52 @@ """ Common module for showing dialogs """ +from enum import Enum + from . import Gtk -def show_dialog(dialog_name, transient, text=None, options=None): +class DialogType(Enum): + INPUT = "input_dialog" + MESSAGE = "" + CHOOSER = "path_chooser_dialog" + ERROR = "error_dialog" + QUESTION = "question_dialog" + ABOUT = "about_dialog" + + +def show_dialog(dialog_type: DialogType, transient, text=None, options=None, action_type=None, file_filter=None): """ Shows dialogs by name """ builder = Gtk.Builder() builder.add_from_file("app/ui/dialogs.glade") - dialog = builder.get_object(dialog_name) + dialog = builder.get_object(dialog_type.value) dialog.set_transient_for(transient) - if dialog_name == "path_chooser_dialog" and options: + if dialog_type is DialogType.CHOOSER and options: + if action_type is not None: + dialog.set_action(action_type) + if file_filter is not None: + dialog.add_filter(file_filter) dialog.set_current_folder(options["data_dir_path"]) + response = dialog.run() - if response == -12: - response = dialog.get_filename() if dialog.get_filename() else options["data_dir_path"] + if response == -12: # -12 for fix assertion 'gtk_widget_get_can_default (widget)' failed + path = options["data_dir_path"] + if dialog.get_filename(): + path = dialog.get_filename() + if action_type is not Gtk.FileChooserAction.OPEN: + path = path + "/" + + response = path dialog.destroy() + return response - if dialog_name == "input_dialog": + if dialog_type is DialogType.INPUT: entry = builder.get_object("input_entry") entry.set_text(text) response = dialog.run() txt = entry.get_text() dialog.destroy() + return txt if response == Gtk.ResponseType.OK else Gtk.ResponseType.CANCEL if text: diff --git a/app/ui/download_dialog.py b/app/ui/download_dialog.py index 2ddd28b1..7969da7c 100644 --- a/app/ui/download_dialog.py +++ b/app/ui/download_dialog.py @@ -1,7 +1,7 @@ from app.commons import run_idle, run_task from app.ftp import download_data, DownloadDataType, upload_data from . import Gtk -from .dialogs import show_dialog +from .dialogs import show_dialog, DialogType def show_download_dialog(transient, options, open_data): @@ -41,7 +41,7 @@ class DownloadDialog: @run_idle def on_send(self, item): - if show_dialog("question_dialog", self._dialog) != Gtk.ResponseType.CANCEL: + if show_dialog(DialogType.QUESTION, self._dialog) != Gtk.ResponseType.CANCEL: self.download(d_type=self.get_download_type()) def get_download_type(self): diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index efbb66a8..9fa1380d 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -8,7 +8,7 @@ from app.eparser import get_channels, get_bouquets, write_bouquets, write_channe from app.eparser.__constants import CAS, FLAG from app.properties import get_config, write_config from . import Gtk, Gdk, LOCKED_ICON, HIDE_ICON -from .dialogs import show_dialog +from .dialogs import show_dialog, DialogType from .download_dialog import show_download_dialog from .satellites_dialog import show_satellites_dialog from .settings_dialog import show_settings_dialog @@ -134,7 +134,7 @@ class MainAppWindow: self.move_items(Gdk.KEY_Down) def on_about_app(self, item): - show_dialog("about_dialog", self.__main_window) + show_dialog(DialogType.ABOUT, self.__main_window) def move_items(self, key): """ Move items in fav tree view """ @@ -181,7 +181,7 @@ class MainAppWindow: bq_selected = self.is_bouquet_selected() if not bq_selected: - show_dialog("error_dialog", self.__main_window, "Error. No bouquet is selected!") + show_dialog(DialogType.ERROR, self.__main_window, "Error. No bouquet is selected!") return fav_bouquet = self.__bouquets[bq_selected] @@ -224,7 +224,7 @@ class MainAppWindow: del fav_bouquet[int(model.get_path(itr)[0])] if model_name == self._BOUQUETS_LIST_NAME: if len(model.get_path(itr)) < 2: - show_dialog("error_dialog", self.__main_window, "This item is not allowed to be removed!") + show_dialog(DialogType.ERROR, self.__main_window, "This item is not allowed to be removed!") return else: self.delete_bouquet(bq_selected) @@ -278,7 +278,7 @@ class MainAppWindow: bq_name = "bouquet{}".format(count) key = "{}:{}".format(bq_name, bq_type) - response = show_dialog("input_dialog", self.__main_window, bq_name) + response = show_dialog(DialogType.INPUT, self.__main_window, bq_name) if response == Gtk.ResponseType.CANCEL: return @@ -305,7 +305,7 @@ class MainAppWindow: def on_bouquets_edit(self, view): """ Rename bouquets """ if not self.is_bouquet_selected(): - show_dialog("error_dialog", self.__main_window, "This item is not allowed to edit!") + show_dialog(DialogType.ERROR, self.__main_window, "This item is not allowed to edit!") return model, paths = view.get_selection().get_selected_rows() @@ -313,7 +313,7 @@ class MainAppWindow: if paths: itr = model.get_iter(paths[0]) bq_name, bq_type = model.get(itr, 0, 1) - response = show_dialog("input_dialog", self.__main_window, bq_name) + response = show_dialog(DialogType.INPUT, self.__main_window, bq_name) if response == Gtk.ResponseType.CANCEL: return @@ -341,7 +341,7 @@ class MainAppWindow: bq_selected = self.is_bouquet_selected() if not bq_selected: - show_dialog("error_dialog", self.__main_window, "Error. No bouquet is selected!") + show_dialog(DialogType.ERROR, self.__main_window, "Error. No bouquet is selected!") return model = view.get_model() @@ -420,7 +420,7 @@ class MainAppWindow: show_satellites_dialog(self.__main_window, self.__options) def on_data_open(self, model): - if show_dialog("path_chooser_dialog", self.__main_window, options=self.__options) == Gtk.ResponseType.CANCEL: + if show_dialog(DialogType.CHOOSER, self.__main_window, options=self.__options) == Gtk.ResponseType.CANCEL: return self.open_data() @@ -438,7 +438,7 @@ class MainAppWindow: self.append_bouquets(data_path) self.update_services_counts(len(self.__services_model)) except FileNotFoundError as e: - show_dialog("error_dialog", self.__main_window, getattr(e, "message", str(e)) + + show_dialog(DialogType.ERROR, self.__main_window, getattr(e, "message", str(e)) + "\n\nPlease, download files from receiver or setup your path for read data!") def append_blacklist(self, data_path): @@ -468,10 +468,10 @@ class MainAppWindow: self.__channels[ch.fav_id] = ch self.__services_model.append(ch) else: - show_dialog("error_dialog", self.__main_window, "Error opening data!") + show_dialog(DialogType.ERROR, self.__main_window, "Error opening data!") def on_data_save(self, *args): - if show_dialog("question_dialog", self.__main_window) == Gtk.ResponseType.CANCEL: + if show_dialog(DialogType.QUESTION, self.__main_window) == Gtk.ResponseType.CANCEL: return path = self.__options["data_dir_path"] @@ -721,14 +721,26 @@ class MainAppWindow: self.__data_count_label.set_text(str(data_count)) def on_import_m3u(self, item): - response = show_dialog("path_chooser_dialog", self.__main_window, options=self.__options) + file_filter = Gtk.FileFilter() + file_filter.add_pattern("*.m3u") + file_filter.set_name("m3u files") + response = show_dialog(dialog_type=DialogType.CHOOSER, + transient=self.__main_window, + options=self.__options, + action_type=Gtk.FileChooserAction.OPEN, + file_filter=file_filter) if response == Gtk.ResponseType.CANCEL: return + if not str(response).endswith("m3u"): + show_dialog(DialogType.ERROR, self.__main_window, text="No m3u file is selected!") + return + channels = parse_m3u(response) bq_selected = self.is_bouquet_selected() if channels and bq_selected: bq_services = self.__bouquets.get(bq_selected) + self.__fav_model.clear() for ch in channels: self.__channels[ch.fav_id] = ch bq_services.append(ch.fav_id) diff --git a/app/ui/satellites_dialog.py b/app/ui/satellites_dialog.py index a00671a3..65fdc02c 100644 --- a/app/ui/satellites_dialog.py +++ b/app/ui/satellites_dialog.py @@ -4,7 +4,7 @@ from math import fabs from app.commons import run_idle from app.eparser import get_satellites, write_satellites, Satellite, Transponder from . import Gtk, Gdk -from .dialogs import show_dialog +from .dialogs import show_dialog, DialogType def show_satellites_dialog(transient, options): @@ -73,17 +73,10 @@ class SatellitesDialog: self.destroy() def on_open(self, model): - builder = Gtk.Builder() - builder.add_objects_from_file("app/ui/dialogs.glade", ("path_chooser_dialog",)) - ch_dialog = builder.get_object("path_chooser_dialog") - ch_dialog.set_transient_for(self._dialog) - - if ch_dialog.run() == -12: - path = ch_dialog.get_filename() - if path: - self._data_path = path + response = show_dialog(dialog_type=DialogType.CHOOSER, transient=self._dialog, options=self._options) + if response != Gtk.ResponseType.CANCEL: + self._data_path = response self.on_satellites_list_load(model) - ch_dialog.destroy() @staticmethod def on_row_activated(view, path, column): @@ -117,7 +110,7 @@ class SatellitesDialog: try: satellites = get_satellites(self._data_path) except FileNotFoundError as e: - show_dialog("error_dialog", self._dialog, getattr(e, "message", str(e)) + + show_dialog(DialogType.ERROR, self._dialog, getattr(e, "message", str(e)) + "\n\nPlease, download files from receiver or setup your path for read data!") else: model.clear() @@ -178,7 +171,7 @@ class SatellitesDialog: if paths is None: return elif len(paths) == 0: - show_dialog("error_dialog", self._dialog, "No satellite is selected!") + show_dialog(DialogType.ERROR, self._dialog, "No satellite is selected!") return dialog = TransponderDialog(self._dialog, transponder) @@ -241,7 +234,7 @@ class SatellitesDialog: paths_count = len(paths) if paths_count > 1: - show_dialog("error_dialog", self._dialog, message) + show_dialog(DialogType.ERROR, self._dialog, message) return return paths @@ -256,7 +249,7 @@ class SatellitesDialog: model.remove(itr) def on_save(self, view): - if show_dialog("question_dialog", self._dialog) == Gtk.ResponseType.CANCEL: + if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL: return model = view.get_model() @@ -329,7 +322,7 @@ class TransponderDialog: tr = self.to_transponder() if self.is_accept(tr): return tr - show_dialog("error_dialog", self._dialog, "Please check your parameters and try again.") + show_dialog(DialogType.ERROR, self._dialog, "Please check your parameters and try again.") def destroy(self): self._dialog.destroy() diff --git a/app/ui/settings_dialog.py b/app/ui/settings_dialog.py index c98400a3..0ddbbfe9 100644 --- a/app/ui/settings_dialog.py +++ b/app/ui/settings_dialog.py @@ -1,4 +1,5 @@ from app.properties import write_config +from app.ui.dialogs import show_dialog, DialogType from . import Gtk @@ -12,6 +13,7 @@ class SettingsDialog: builder = Gtk.Builder() builder.add_objects_from_file("app/ui/dialogs.glade", ("settings_dialog", )) builder.connect_signals(handlers) + self._options = options self._dialog = builder.get_object("settings_dialog") self._dialog.set_transient_for(transient) self._host_field = builder.get_object("host_field") @@ -30,7 +32,6 @@ class SettingsDialog: self._satellites_xml_field.set_text(options["satellites_xml_path"]) self._data_dir_field = builder.get_object("data_dir_field") self._data_dir_field.set_text(options["data_dir_path"]) - self._current_data_path = options["data_dir_path"] if self._dialog.run() == Gtk.ResponseType.OK: options["host"] = self._host_field.get_text() @@ -45,17 +46,9 @@ class SettingsDialog: self._dialog.destroy() def on_data_dir_field_icon_press(self, entry, icon, event_button): - builder = Gtk.Builder() - builder.add_from_file("app/ui/dialogs.glade") - dialog = builder.get_object("path_chooser_dialog") - dialog.set_transient_for(self._dialog) - dialog.set_current_folder(self._current_data_path) - response = dialog.run() - if response == -12: # -12 for fix assertion 'gtk_widget_get_can_default (widget)' failed - entry.set_text(dialog.get_filename() if dialog.get_filename() else self._current_data_path) - dialog.destroy() - - return response + response = show_dialog(dialog_type=DialogType.CHOOSER, transient=self._dialog, options=self._options) + if response != Gtk.ResponseType.CANCEL: + entry.set_text(response) if __name__ == "__main__":