mirror of
https://github.com/DYefremov/DemonEditor.git
synced 2025-12-22 00:19:40 +01:00
cut-copy-paste impl for the bouquets list
This commit is contained in:
@@ -41,7 +41,8 @@ class MainAppWindow:
|
|||||||
_SERVICE_ELEMENTS = ("services_to_fav_move_popup_item", "services_edit_popup_item", "services_copy_popup_item",
|
_SERVICE_ELEMENTS = ("services_to_fav_move_popup_item", "services_edit_popup_item", "services_copy_popup_item",
|
||||||
"services_picon_popup_item", "services_create_bouquet_popup_item")
|
"services_picon_popup_item", "services_create_bouquet_popup_item")
|
||||||
|
|
||||||
_BOUQUET_ELEMENTS = ("edit_tool_button", "new_tool_button", "bouquets_new_popup_item", "bouquets_edit_popup_item")
|
_BOUQUET_ELEMENTS = ("edit_tool_button", "new_tool_button", "bouquets_new_popup_item", "bouquets_edit_popup_item",
|
||||||
|
"bouquets_cut_popup_item", "bouquets_copy_popup_item", "bouquets_paste_popup_item")
|
||||||
|
|
||||||
_COMMONS_ELEMENTS = ("edit_tool_button", "services_remove_popup_item", "bouquets_remove_popup_item",
|
_COMMONS_ELEMENTS = ("edit_tool_button", "services_remove_popup_item", "bouquets_remove_popup_item",
|
||||||
"fav_remove_popup_item")
|
"fav_remove_popup_item")
|
||||||
@@ -64,7 +65,8 @@ class MainAppWindow:
|
|||||||
"fav_insert_marker_popup_item", "fav_edit_popup_item", "fav_edit_sub_menu_popup_item",
|
"fav_insert_marker_popup_item", "fav_edit_popup_item", "fav_edit_sub_menu_popup_item",
|
||||||
"fav_locate_popup_item", "services_copy_popup_item", "services_picon_popup_item",
|
"fav_locate_popup_item", "services_copy_popup_item", "services_picon_popup_item",
|
||||||
"fav_picon_popup_item", "services_add_new_popup_item", "fav_iptv_popup_item",
|
"fav_picon_popup_item", "services_add_new_popup_item", "fav_iptv_popup_item",
|
||||||
"fav_copy_popup_item")
|
"fav_copy_popup_item", "bouquets_cut_popup_item", "bouquets_copy_popup_item",
|
||||||
|
"bouquets_paste_popup_item")
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
handlers = {"on_close_app": self.on_close_app,
|
handlers = {"on_close_app": self.on_close_app,
|
||||||
@@ -82,10 +84,13 @@ class MainAppWindow:
|
|||||||
"on_fav_selection": self.on_fav_selection,
|
"on_fav_selection": self.on_fav_selection,
|
||||||
"on_up": self.on_up,
|
"on_up": self.on_up,
|
||||||
"on_down": self.on_down,
|
"on_down": self.on_down,
|
||||||
"on_cut": self.on_cut,
|
"on_fav_cut": self.on_fav_cut,
|
||||||
|
"on_bouquets_cut": self.on_bouquets_cut,
|
||||||
"on_services_copy": self.on_services_copy,
|
"on_services_copy": self.on_services_copy,
|
||||||
"on_fav_copy": self.on_fav_copy,
|
"on_fav_copy": self.on_fav_copy,
|
||||||
"on_paste": self.on_paste,
|
"on_bouquets_copy": self.on_bouquets_copy,
|
||||||
|
"on_fav_paste": self.on_fav_paste,
|
||||||
|
"on_bouquets_paste": self.on_bouquets_paste,
|
||||||
"on_edit": self.on_rename,
|
"on_edit": self.on_rename,
|
||||||
"on_rename_for_bouquet": self.on_rename_for_bouquet,
|
"on_rename_for_bouquet": self.on_rename_for_bouquet,
|
||||||
"on_set_default_name_for_bouquet": self.on_set_default_name_for_bouquet,
|
"on_set_default_name_for_bouquet": self.on_set_default_name_for_bouquet,
|
||||||
@@ -145,9 +150,11 @@ class MainAppWindow:
|
|||||||
# Used for copy/paste. When adding the previous data will not be deleted.
|
# Used for copy/paste. When adding the previous data will not be deleted.
|
||||||
# Clearing only after the insertion!
|
# Clearing only after the insertion!
|
||||||
self._rows_buffer = []
|
self._rows_buffer = []
|
||||||
|
self._bouquets_buffer = []
|
||||||
self._services = {}
|
self._services = {}
|
||||||
self._bouquets = {}
|
self._bouquets = {}
|
||||||
self._extra_bouquets = {} # for bouquets with different names of services in bouquet and main list
|
# For bouquets with different names of services in bouquet and main list
|
||||||
|
self._extra_bouquets = {}
|
||||||
self._picons = {}
|
self._picons = {}
|
||||||
self._blacklist = set()
|
self._blacklist = set()
|
||||||
self._current_bq_name = None
|
self._current_bq_name = None
|
||||||
@@ -174,7 +181,7 @@ class MainAppWindow:
|
|||||||
self._main_window_box = builder.get_object("main_window_box")
|
self._main_window_box = builder.get_object("main_window_box")
|
||||||
self._player_drawing_area = builder.get_object("player_drawing_area")
|
self._player_drawing_area = builder.get_object("player_drawing_area")
|
||||||
self._player_box = builder.get_object("player_box")
|
self._player_box = builder.get_object("player_box")
|
||||||
# enabling events for the drawing area
|
# Enabling events for the drawing area
|
||||||
self._player_drawing_area.set_events(Gdk.ModifierType.BUTTON1_MASK)
|
self._player_drawing_area.set_events(Gdk.ModifierType.BUTTON1_MASK)
|
||||||
self._player_frame = builder.get_object("player_frame")
|
self._player_frame = builder.get_object("player_frame")
|
||||||
self._header_bar = builder.get_object("header_bar")
|
self._header_bar = builder.get_object("header_bar")
|
||||||
@@ -182,7 +189,7 @@ class MainAppWindow:
|
|||||||
self._ip_label = builder.get_object("ip_label")
|
self._ip_label = builder.get_object("ip_label")
|
||||||
self._ip_label.set_text(self._options.get(self._profile).get("host"))
|
self._ip_label.set_text(self._options.get(self._profile).get("host"))
|
||||||
self.update_profile_label()
|
self.update_profile_label()
|
||||||
# dynamically active elements depending on the selected view
|
# Dynamically active elements depending on the selected view
|
||||||
self._tool_elements = {k: builder.get_object(k) for k in self._DYNAMIC_ELEMENTS}
|
self._tool_elements = {k: builder.get_object(k) for k in self._DYNAMIC_ELEMENTS}
|
||||||
self._cas_label = builder.get_object("cas_label")
|
self._cas_label = builder.get_object("cas_label")
|
||||||
self._fav_count_label = builder.get_object("fav_count_label")
|
self._fav_count_label = builder.get_object("fav_count_label")
|
||||||
@@ -268,30 +275,65 @@ class MainAppWindow:
|
|||||||
return
|
return
|
||||||
move_items(key, self._fav_view if self._fav_view.is_focus() else self._bouquets_view)
|
move_items(key, self._fav_view if self._fav_view.is_focus() else self._bouquets_view)
|
||||||
|
|
||||||
def on_cut(self, view):
|
# ***************** Copy - Cut - Paste *********************#
|
||||||
for row in tuple(self.on_delete(view)):
|
|
||||||
self._rows_buffer.append(row)
|
|
||||||
|
|
||||||
def on_services_copy(self, view):
|
def on_services_copy(self, view):
|
||||||
self.on_copy(view, target=ViewTarget.FAV)
|
self.on_copy(view, target=ViewTarget.FAV)
|
||||||
|
|
||||||
def on_fav_copy(self, view):
|
def on_fav_copy(self, view):
|
||||||
self.on_copy(view, target=ViewTarget.SERVICES)
|
self.on_copy(view, target=ViewTarget.SERVICES)
|
||||||
|
|
||||||
def on_copy(self, view, target=ViewTarget.FAV):
|
def on_bouquets_copy(self, view):
|
||||||
|
self.on_copy(view, target=ViewTarget.BOUQUET)
|
||||||
|
|
||||||
|
def on_copy(self, view, target):
|
||||||
model, paths = view.get_selection().get_selected_rows()
|
model, paths = view.get_selection().get_selected_rows()
|
||||||
rows = None
|
rows = None
|
||||||
|
|
||||||
if target is ViewTarget.FAV:
|
if target is ViewTarget.FAV:
|
||||||
rows = [(0, *model[path][2, 3, 4, 5, 7, 16, 18, 8]) for path in paths]
|
rows = [(0, *model[path][2, 3, 4, 5, 7, 16, 18, 8]) for path in paths]
|
||||||
elif target is ViewTarget.SERVICES:
|
elif target is ViewTarget.SERVICES:
|
||||||
rows = [model[path][:] for path in paths]
|
rows = [model[path][:] for path in paths]
|
||||||
elif target is ViewTarget.BOUQUET:
|
elif target is ViewTarget.BOUQUET:
|
||||||
|
to_copy = list(map(model.get_iter, filter(lambda p: p.get_depth() == 2, paths)))
|
||||||
|
if to_copy:
|
||||||
|
self._bouquets_buffer.extend([model[i][:] for i in to_copy])
|
||||||
return
|
return
|
||||||
|
|
||||||
self._rows_buffer.extend(rows)
|
self._rows_buffer.extend(rows)
|
||||||
|
|
||||||
def on_paste(self, view):
|
def on_fav_cut(self, view):
|
||||||
|
self.on_cut(view, ViewTarget.FAV)
|
||||||
|
|
||||||
|
def on_bouquets_cut(self, view):
|
||||||
|
self.on_cut(view, ViewTarget.BOUQUET)
|
||||||
|
|
||||||
|
def on_cut(self, view, target=None):
|
||||||
|
if target is ViewTarget.FAV:
|
||||||
|
for row in tuple(self.on_delete(view)):
|
||||||
|
self._rows_buffer.append(row)
|
||||||
|
elif target is ViewTarget.BOUQUET:
|
||||||
|
model, paths = view.get_selection().get_selected_rows()
|
||||||
|
to_cut = list(map(model.get_iter, filter(lambda p: p.get_depth() == 2, paths)))
|
||||||
|
if to_cut:
|
||||||
|
self._bouquets_buffer.extend([model[i][:] for i in to_cut])
|
||||||
|
list(map(model.remove, to_cut))
|
||||||
|
|
||||||
|
def on_fav_paste(self, view):
|
||||||
|
self.on_paste(view, ViewTarget.FAV)
|
||||||
|
|
||||||
|
def on_bouquets_paste(self, view):
|
||||||
|
self.on_paste(view, ViewTarget.BOUQUET)
|
||||||
|
|
||||||
|
def on_paste(self, view, target):
|
||||||
selection = view.get_selection()
|
selection = view.get_selection()
|
||||||
|
|
||||||
|
if target is ViewTarget.FAV:
|
||||||
|
self.fav_paste(selection)
|
||||||
|
elif target is ViewTarget.BOUQUET:
|
||||||
|
self.bouquet_paste(selection)
|
||||||
|
self.on_view_focus(view, None)
|
||||||
|
|
||||||
|
def fav_paste(self, selection):
|
||||||
dest_index = 0
|
dest_index = 0
|
||||||
bq_selected = self.check_bouquet_selection()
|
bq_selected = self.check_bouquet_selection()
|
||||||
if not bq_selected:
|
if not bq_selected:
|
||||||
@@ -312,7 +354,27 @@ class MainAppWindow:
|
|||||||
self.update_fav_num_column(model)
|
self.update_fav_num_column(model)
|
||||||
|
|
||||||
self._rows_buffer.clear()
|
self._rows_buffer.clear()
|
||||||
self.on_view_focus(view, None)
|
|
||||||
|
def bouquet_paste(self, selection):
|
||||||
|
model, paths = selection.get_selected_rows()
|
||||||
|
if len(paths) > 1:
|
||||||
|
show_dialog(DialogType.ERROR, self._main_window, "Please, select only one item!")
|
||||||
|
return
|
||||||
|
|
||||||
|
path = paths[0]
|
||||||
|
dest_iter = model.get_iter(path)
|
||||||
|
|
||||||
|
if path.get_depth() == 1:
|
||||||
|
list(map(lambda r: model.append(dest_iter, r), self._bouquets_buffer))
|
||||||
|
self._bouquets_view.expand_all()
|
||||||
|
else:
|
||||||
|
p_iter = model.iter_parent(dest_iter)
|
||||||
|
dest_index = path.get_indices()[1] + 1
|
||||||
|
for index, row in enumerate(self._bouquets_buffer):
|
||||||
|
model.insert(p_iter, dest_index + index, row)
|
||||||
|
self._bouquets_buffer.clear()
|
||||||
|
|
||||||
|
# ***************** Deletion *********************#
|
||||||
|
|
||||||
def on_delete(self, item):
|
def on_delete(self, item):
|
||||||
""" Delete selected items from views
|
""" Delete selected items from views
|
||||||
@@ -390,6 +452,8 @@ class MainAppWindow:
|
|||||||
self._fav_model.clear()
|
self._fav_model.clear()
|
||||||
self._bouquets_model.remove(itr)
|
self._bouquets_model.remove(itr)
|
||||||
|
|
||||||
|
# ***************** ####### *********************#
|
||||||
|
|
||||||
def get_bouquet_file_name(self, bouquet):
|
def get_bouquet_file_name(self, bouquet):
|
||||||
bouquet_file_name = "{}userbouquet.{}.{}".format(self._options.get(self._profile).get("data_dir_path"),
|
bouquet_file_name = "{}userbouquet.{}.{}".format(self._options.get(self._profile).get("data_dir_path"),
|
||||||
*bouquet.split(":"))
|
*bouquet.split(":"))
|
||||||
@@ -850,10 +914,14 @@ class MainAppWindow:
|
|||||||
self.on_copy(view, ViewTarget.BOUQUET)
|
self.on_copy(view, ViewTarget.BOUQUET)
|
||||||
elif ctrl and key == Gdk.KEY_x or key == Gdk.KEY_X:
|
elif ctrl and key == Gdk.KEY_x or key == Gdk.KEY_X:
|
||||||
if model_name == self._FAV_LIST_NAME:
|
if model_name == self._FAV_LIST_NAME:
|
||||||
self.on_cut(view)
|
self.on_cut(view, ViewTarget.FAV)
|
||||||
|
elif model_name == self._BOUQUETS_LIST_NAME:
|
||||||
|
self.on_cut(view, ViewTarget.BOUQUET)
|
||||||
elif ctrl and key == Gdk.KEY_v or key == Gdk.KEY_V:
|
elif ctrl and key == Gdk.KEY_v or key == Gdk.KEY_V:
|
||||||
if model_name == self._FAV_LIST_NAME:
|
if model_name == self._FAV_LIST_NAME:
|
||||||
self.on_paste(view)
|
self.on_paste(view, ViewTarget.FAV)
|
||||||
|
elif model_name == self._BOUQUETS_LIST_NAME:
|
||||||
|
self.on_paste(view, ViewTarget.BOUQUET)
|
||||||
elif key == Gdk.KEY_Delete:
|
elif key == Gdk.KEY_Delete:
|
||||||
self.on_delete(view)
|
self.on_delete(view)
|
||||||
|
|
||||||
@@ -911,6 +979,8 @@ class MainAppWindow:
|
|||||||
self._tool_elements[elem].set_sensitive(False)
|
self._tool_elements[elem].set_sensitive(False)
|
||||||
for elem in self._BOUQUET_ELEMENTS:
|
for elem in self._BOUQUET_ELEMENTS:
|
||||||
self._tool_elements[elem].set_sensitive(not_empty)
|
self._tool_elements[elem].set_sensitive(not_empty)
|
||||||
|
if elem == "bouquets_paste_popup_item":
|
||||||
|
self._tool_elements[elem].set_sensitive(not_empty and self._bouquets_buffer)
|
||||||
if profile is Profile.NEUTRINO_MP:
|
if profile is Profile.NEUTRINO_MP:
|
||||||
for elem in self._LOCK_HIDE_ELEMENTS:
|
for elem in self._LOCK_HIDE_ELEMENTS:
|
||||||
self._tool_elements[elem].set_sensitive(not_empty)
|
self._tool_elements[elem].set_sensitive(not_empty)
|
||||||
|
|||||||
@@ -47,6 +47,51 @@ Author: Dmitriy Yefremov
|
|||||||
<signal name="activate" handler="on_new_bouquet" object="bouquets_tree_view" swapped="no"/>
|
<signal name="activate" handler="on_new_bouquet" object="bouquets_tree_view" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem" id="bouquets_popup_separator">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="bouquets_cut_popup_item">
|
||||||
|
<property name="label">gtk-cut</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="activate" handler="on_bouquets_cut" object="bouquets_tree_view" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="bouquets_copy_popup_item">
|
||||||
|
<property name="label">gtk-copy</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="activate" handler="on_bouquets_copy" object="bouquets_tree_view" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="bouquets_paste_popup_item">
|
||||||
|
<property name="label">gtk-paste</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="activate" handler="on_bouquets_paste" object="bouquets_tree_view" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem" id="bouquets_popup_separator_2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImageMenuItem" id="bouquets_edit_popup_item">
|
<object class="GtkImageMenuItem" id="bouquets_edit_popup_item">
|
||||||
<property name="label">gtk-edit</property>
|
<property name="label">gtk-edit</property>
|
||||||
@@ -58,6 +103,12 @@ Author: Dmitriy Yefremov
|
|||||||
<signal name="activate" handler="on_bouquets_edit" object="bouquets_tree_view" swapped="no"/>
|
<signal name="activate" handler="on_bouquets_edit" object="bouquets_tree_view" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem" id="bouquets_popup_separator_3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImageMenuItem" id="bouquets_remove_popup_item">
|
<object class="GtkImageMenuItem" id="bouquets_remove_popup_item">
|
||||||
<property name="label">gtk-remove</property>
|
<property name="label">gtk-remove</property>
|
||||||
@@ -122,7 +173,7 @@ Author: Dmitriy Yefremov
|
|||||||
<object class="GtkImage" id="extra_edit_image">
|
<object class="GtkImage" id="extra_edit_image">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="stock">gtk-find-and-replace</property>
|
<property name="stock">gtk-edit</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkImage" id="fav_iptv_list_config_image">
|
<object class="GtkImage" id="fav_iptv_list_config_image">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -351,7 +402,7 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<signal name="activate" handler="on_cut" object="fav_tree_view" swapped="no"/>
|
<signal name="activate" handler="on_fav_cut" object="fav_tree_view" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
@@ -373,7 +424,7 @@ Author: Dmitriy Yefremov
|
|||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<signal name="activate" handler="on_paste" object="fav_tree_view" swapped="no"/>
|
<signal name="activate" handler="on_fav_paste" object="fav_tree_view" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
|||||||
Reference in New Issue
Block a user