| ... |
... |
@@ -67,6 +67,19 @@ def __init__(self, account): |
|
67
|
67
|
|
|
68
|
68
|
self._roster = self._ui.roster_treeview
|
|
69
|
69
|
|
|
|
70
|
+ # Drag and Drop
|
|
|
71
|
+ entries = [Gtk.TargetEntry.new(
|
|
|
72
|
+ 'ROSTER_ITEM',
|
|
|
73
|
+ Gtk.TargetFlags.SAME_APP,
|
|
|
74
|
+ 0)]
|
|
|
75
|
+ self._roster.enable_model_drag_source(
|
|
|
76
|
+ Gdk.ModifierType.BUTTON1_MASK,
|
|
|
77
|
+ entries,
|
|
|
78
|
+ Gdk.DragAction.MOVE)
|
|
|
79
|
+ self._roster.enable_model_drag_dest(entries, Gdk.DragAction.DEFAULT)
|
|
|
80
|
+ self._roster.connect('drag-drop', self._on_drag_drop)
|
|
|
81
|
+ self._roster.connect('drag-data-received', self._on_drag_data_received)
|
|
|
82
|
+
|
|
70
|
83
|
self._ui.contact_column.set_cell_data_func(self._ui.text_renderer,
|
|
71
|
84
|
self._text_cell_data_func)
|
|
72
|
85
|
self.connect('destroy', self._on_destroy)
|
| ... |
... |
@@ -142,6 +155,74 @@ def _on_account_state(self, _event): |
|
142
|
155
|
def _on_theme_update(self, _event):
|
|
143
|
156
|
self.redraw()
|
|
144
|
157
|
|
|
|
158
|
+ @staticmethod
|
|
|
159
|
+ def _on_drag_drop(treeview, drag_context, _x_coord, _y_coord,
|
|
|
160
|
+ timestamp):
|
|
|
161
|
+ treeview.stop_emission_by_name('drag-drop')
|
|
|
162
|
+ target_list = treeview.drag_dest_get_target_list()
|
|
|
163
|
+ target = treeview.drag_dest_find_target(drag_context, target_list)
|
|
|
164
|
+ treeview.drag_get_data(drag_context, target, timestamp)
|
|
|
165
|
+ return True
|
|
|
166
|
+
|
|
|
167
|
+ def _on_drag_data_received(self, treeview, _drag_context, x_coord,
|
|
|
168
|
+ y_coord, _selection_data, _info, _timestamp):
|
|
|
169
|
+ treeview.stop_emission_by_name('drag-data-received')
|
|
|
170
|
+ if treeview.get_selection().count_selected_rows() == 0:
|
|
|
171
|
+ # No selections, nothing dragged from treeview
|
|
|
172
|
+ return
|
|
|
173
|
+
|
|
|
174
|
+ drop_info = treeview.get_dest_row_at_pos(x_coord, y_coord)
|
|
|
175
|
+ if not drop_info:
|
|
|
176
|
+ return
|
|
|
177
|
+
|
|
|
178
|
+ model = treeview.get_model()
|
|
|
179
|
+ path_dest, _position = drop_info
|
|
|
180
|
+
|
|
|
181
|
+ # Source: the row being dragged
|
|
|
182
|
+ path_source = treeview.get_selection().get_selected_rows()[1][0]
|
|
|
183
|
+ iter_source = model.get_iter(path_source)
|
|
|
184
|
+ iter_source_parent = model.iter_parent(iter_source)
|
|
|
185
|
+ if iter_source_parent is None:
|
|
|
186
|
+ # Dragged a group
|
|
|
187
|
+ return
|
|
|
188
|
+
|
|
|
189
|
+ source_group = model[iter_source_parent][Column.JID_OR_GROUP]
|
|
|
190
|
+ delimiter = self._client.get_module('Delimiter').delimiter
|
|
|
191
|
+ source_groups = source_group.split(delimiter)
|
|
|
192
|
+ if DEFAULT_GROUP in source_groups:
|
|
|
193
|
+ source_groups = []
|
|
|
194
|
+ jid = model[iter_source][Column.JID_OR_GROUP]
|
|
|
195
|
+ name = model[iter_source][Column.TEXT]
|
|
|
196
|
+
|
|
|
197
|
+ # Destination: the row receiving the drop
|
|
|
198
|
+ iter_dest = model.get_iter(path_dest)
|
|
|
199
|
+ iter_dest_parent = model.iter_parent(iter_dest)
|
|
|
200
|
+ if iter_dest_parent is None:
|
|
|
201
|
+ # Dropped on a group
|
|
|
202
|
+ dest_group = model[iter_dest][Column.JID_OR_GROUP]
|
|
|
203
|
+ else:
|
|
|
204
|
+ dest_group = model[iter_dest_parent][Column.JID_OR_GROUP]
|
|
|
205
|
+
|
|
|
206
|
+ dest_groups = dest_group.split(delimiter)
|
|
|
207
|
+ if DEFAULT_GROUP in dest_groups:
|
|
|
208
|
+ # Dropped into DEFAULT_GROUP, remove all groups
|
|
|
209
|
+ print('remoing all groups')
|
|
|
210
|
+ # self._client.get_module('Roster').update_contact(jid, name, [])
|
|
|
211
|
+ return
|
|
|
212
|
+
|
|
|
213
|
+ print('source groups')
|
|
|
214
|
+ print(source_groups)
|
|
|
215
|
+ print('dest groups')
|
|
|
216
|
+ print(dest_groups)
|
|
|
217
|
+ if source_groups == dest_groups:
|
|
|
218
|
+ # Dropped into source group
|
|
|
219
|
+ return
|
|
|
220
|
+ groups = list(set(dest_groups) - set(source_groups))
|
|
|
221
|
+ print('final groups')
|
|
|
222
|
+ print(groups)
|
|
|
223
|
+ print('setting new groups')
|
|
|
224
|
+ # self._client.get_module('Roster').update_contact(jid, name, groups)
|
|
|
225
|
+
|
|
145
|
226
|
def _on_show_offline(self, action, param):
|
|
146
|
227
|
action.set_state(param)
|
|
147
|
228
|
app.settings.set('showoffline', param.get_boolean())
|