def on_drag_data_received(self, widget: Gtk.Widget, drag_context: Gdk.DragContext, x: int, y: int, data: Gtk.SelectionData, info: int, time: int) -> None: if info == TARGET_ENTRY_TEXT: uris = data.get_text().split('\n') for uri in uris: # Skip empty items if not uri: continue p = urlparse(unquote_plus(uri)) filename = os.path.abspath(os.path.join(p.netloc, p.path)) self.emit('document-import', filename)
def on_frame_image_drag_data_received(self, widget: Gtk.AspectFrame, drag_context: Gdk.DragContext, x: int, y: int, data: Gtk.SelectionData, info: int, time: int): uri: str = data.get_data().strip().decode() logger.debug('Dropped URI: {}', uri) if not uri: logger.debug( 'Something wrong with desktop environment. No URI is given.') return chosen_file = Gio.file_new_for_uri(uri) self.btn_img_chooser.select_uri(uri) content_type = guess_content_type(chosen_file) logger.debug('Content type: {}', content_type) self.process_passed_image_file(chosen_file, content_type) self.grab_focus_on_event_box()
def drag_recv(self, _widget: Gtk.Widget, context: Gdk.DragContext, x: int, y: int, selection: Gtk.SelectionData, _info: int, time: int) -> None: uris = list(selection.get_uris()) context.finish(True, False, time) path = self.get_path_at_pos(x, y) if path: tree_iter = self.get_iter(path[0]) device = self.get(tree_iter, "device")["device"] command = f"blueman-sendto --device={device['Address']}" launch(command, paths=uris, name=_("File Sender")) context.finish(True, False, time) else: context.finish(False, False, time)
def on_tree_grouped_drag_data_received(self, w: Gtk.TreeView, context, x, y, selection: Gtk.SelectionData, info, etime): model: Gtk.TreeStore = w.get_model() dungeon_id_str = str(selection.get_data(), 'utf-8') if dungeon_id_str == '': return dungeon_id = int(dungeon_id_str) dungeon_iter = self._find_dungeon_iter(model, dungeon_id) assert dungeon_iter is not None drop_info = w.get_dest_row_at_pos(x, y) if drop_info: path, position = drop_info iter = model.get_iter(path) did_drag = True # Did we drag onto a group or a dungeon in a group? new_group_iter = self._get_group_iter(model, iter, position) old_group_iter = self._get_group_iter(model, dungeon_iter, Gtk.TreeViewDropPosition.INTO_OR_BEFORE) if not new_group_iter: # After/Before top level: # Don't do anything if position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE or position == Gtk.TreeViewDropPosition.INTO_OR_AFTER: # Inside top level, dungeon: # Build new group dungeon_id_insert = model[iter][1] before_iter = model.iter_previous(iter) assert iter is not None model.remove(iter) if before_iter is None: new_iter = model.insert(None, 0, self._generate_group_row( dungeon_id_insert )) else: new_iter = model.insert_after(model.iter_parent(before_iter), before_iter, self._generate_group_row( dungeon_id_insert )) model.append(new_iter, self._generate_dungeon_row(dungeon_id_insert)) model.append(new_iter, self._generate_dungeon_row(dungeon_id)) w.expand_row(model.get_path(new_iter), False) elif old_group_iter is not None: self._reinsert(model, dungeon_id, self._generate_dungeon_row(dungeon_id)) else: did_drag = False else: if new_group_iter == iter: # Inside top level, group: # Add to end of group assert new_group_iter is not None model.append(new_group_iter, self._generate_dungeon_row(dungeon_id)) else: # After/Before in group / Inside in group: # Add it to group after/before this element if position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE or position == Gtk.TreeViewDropPosition.BEFORE: assert new_group_iter is not None model.insert_before(new_group_iter, iter, self._generate_dungeon_row(dungeon_id)) else: assert new_group_iter is not None model.insert_after(new_group_iter, iter, self._generate_dungeon_row(dungeon_id)) if did_drag: assert dungeon_iter is not None # Remove the original iter. model.remove(dungeon_iter) # Check if group headers (main id) needs to be rewritten: if old_group_iter: self._rewrite_group_header_id_and_pos(model, old_group_iter) if new_group_iter and new_group_iter != old_group_iter: self._rewrite_group_header_id_and_pos(model, new_group_iter) if old_group_iter and old_group_iter != new_group_iter: # If was in group: # Remove from group # (If removing dungeons from a group, recalculate group id, name, # position and if it even still needs to exist) if model.iter_n_children(old_group_iter) < 2: # Remove group dungeon_id_that_was_in_group = model[model.iter_nth_child(old_group_iter, 0)][1] assert old_group_iter is not None model.remove(old_group_iter) self._reinsert(model, dungeon_id_that_was_in_group, self._generate_dungeon_row(dungeon_id_that_was_in_group)) # Select the newly inserted. dungeon_iter = self._find_dungeon_iter(model, dungeon_id) w.get_selection().select_iter(dungeon_iter) w.scroll_to_cell(model.get_path(dungeon_iter), None, True, 0.5, 0.5) if context.get_actions() == Gdk.DragAction.MOVE: # We remove the source data manual. context.finish(True, False, etime)
def on_tree_grouped_drag_data_get(self, w: Gtk.TreeView, context, selection: Gtk.SelectionData, target_id, etime): model, treeiter = w.get_selection().get_selected() dungeon_id = model[treeiter][1] was_group = model[treeiter][0] if not was_group: selection.set(selection.get_target(), 8, bytes(dungeon_id, 'utf-8'))
def on_drag_data_received(self, widget: Gtk.Widget, drag_context: Gdk.DragContext, x: int, y: int, data: Gtk.SelectionData, info: int, time: int) -> None: print(f'Drag info: {info}') # Handle normal dnd from other apps with files as a target if info == TARGET_ENTRY_TEXT: uris = data.get_text().split('\n') print(data.get_text()) for uri in uris: # Skip empty items if not uri: continue p = urlparse(unquote_plus(uri)) filename = os.path.abspath(os.path.join(p.netloc, p.path)) self.emit('document-import', filename) # Handle reordering and moving inside Norka's virtual filesystem elif info == TARGET_ENTRY_REORDER: origin_item = self.selected_folder if self.is_folder_selected else self.selected_document dest_path = self.view.get_path_at_pos(x, y) if not dest_path: print("No dest path") return dest_iter = self.model.get_iter(dest_path) dest_item_id = self.model.get_value(dest_iter, 3) if dest_item_id == -1: dest_item = Folder(title=self.model.get_value(dest_iter, 1), path=self.model.get_value(dest_iter, 2)) else: dest_item = self.storage.get(dest_item_id) # Don't move item to itself :) if origin_item.absolute_path == dest_item.absolute_path: print("Don't move item to itself") return # Create folders when doc dropped onto doc # After creation rename dialog should appear if isinstance(dest_item, Document): folder_id = self.create_folder( f'{origin_item.title} + {dest_item.title}', self.current_folder_path) if folder_id: folder = self.storage.get_folder(folder_id) self.storage.move(origin_item.document_id, folder.absolute_path) self.storage.move(dest_item.document_id, folder.absolute_path) self.reload_items() return # For folders, we have to move folder and its content to destination if isinstance(origin_item, Folder): print( f'Folder "{origin_item.title}": "{origin_item.path}" -> "{dest_item.absolute_path}"' ) self.storage.move_folder(origin_item, dest_item.absolute_path) self.reload_items() # For regular documents it is easy to move - just update the `path`. else: if self.storage.update(origin_item.document_id, {'path': dest_item.absolute_path}): print( f'Moved {origin_item.title} to {dest_item.absolute_path}' ) self.reload_items() Gtk.drag_finish( drag_context, True, drag_context.get_selected_action() == Gdk.DragAction.MOVE, time)