Introduce file widget menu with "Save as..." and "Open" actions (#1080)
This commit is contained in:
parent
975b37c498
commit
25db512297
|
@ -88,6 +88,19 @@
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuButton" id="file_menu">
|
||||||
|
<property name="visible">False</property>
|
||||||
|
<property name="relief">none</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="icon-name">open-menu-symbolic</property>
|
||||||
|
<property name="icon-size">1</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
|
|
@ -15,12 +15,18 @@ public class FileDefaultWidget : EventBox {
|
||||||
[GtkChild] public unowned Image content_type_image;
|
[GtkChild] public unowned Image content_type_image;
|
||||||
[GtkChild] public unowned Spinner spinner;
|
[GtkChild] public unowned Spinner spinner;
|
||||||
[GtkChild] public unowned EventBox stack_event_box;
|
[GtkChild] public unowned EventBox stack_event_box;
|
||||||
|
[GtkChild] public MenuButton file_menu;
|
||||||
|
|
||||||
|
public ModelButton file_open_button;
|
||||||
|
public ModelButton file_save_button;
|
||||||
|
|
||||||
private FileTransfer.State state;
|
private FileTransfer.State state;
|
||||||
|
|
||||||
public FileDefaultWidget() {
|
public FileDefaultWidget() {
|
||||||
this.enter_notify_event.connect(on_pointer_entered);
|
this.enter_notify_event.connect(on_pointer_entered);
|
||||||
this.leave_notify_event.connect(on_pointer_left);
|
this.leave_notify_event.connect(on_pointer_left);
|
||||||
|
file_open_button = new ModelButton() { text=_("Open"), visible=true };
|
||||||
|
file_save_button = new ModelButton() { text=_("Save as..."), visible=true };
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update_file_info(string? mime_type, FileTransfer.State state, long size) {
|
public void update_file_info(string? mime_type, FileTransfer.State state, long size) {
|
||||||
|
@ -35,6 +41,15 @@ public class FileDefaultWidget : EventBox {
|
||||||
case FileTransfer.State.COMPLETE:
|
case FileTransfer.State.COMPLETE:
|
||||||
mime_label.label = mime_description;
|
mime_label.label = mime_description;
|
||||||
image_stack.set_visible_child_name("content_type_image");
|
image_stack.set_visible_child_name("content_type_image");
|
||||||
|
Gtk.PopoverMenu popover_menu = new Gtk.PopoverMenu();
|
||||||
|
Box file_menu_box = new Box(Orientation.VERTICAL, 0) { margin=10, visible=true };
|
||||||
|
file_menu_box.add(file_open_button);
|
||||||
|
file_menu_box.add(file_save_button);
|
||||||
|
popover_menu.add(file_menu_box);
|
||||||
|
file_menu.popover = popover_menu;
|
||||||
|
file_menu.clicked.connect(() => {
|
||||||
|
popover_menu.visible = true;
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case FileTransfer.State.IN_PROGRESS:
|
case FileTransfer.State.IN_PROGRESS:
|
||||||
mime_label.label = _("Downloading %s…").printf(get_size_string(size));
|
mime_label.label = _("Downloading %s…").printf(get_size_string(size));
|
||||||
|
@ -67,17 +82,22 @@ public class FileDefaultWidget : EventBox {
|
||||||
if (state == FileTransfer.State.NOT_STARTED) {
|
if (state == FileTransfer.State.NOT_STARTED) {
|
||||||
image_stack.set_visible_child_name("download_image");
|
image_stack.set_visible_child_name("download_image");
|
||||||
}
|
}
|
||||||
|
if (state == FileTransfer.State.COMPLETE) {
|
||||||
|
file_menu.visible = true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool on_pointer_left(Gdk.EventCrossing event) {
|
private bool on_pointer_left(Gdk.EventCrossing event) {
|
||||||
if (event.detail == Gdk.NotifyType.INFERIOR) return false;
|
if (event.detail == Gdk.NotifyType.INFERIOR) return false;
|
||||||
|
if (file_menu.popover.visible == true) return false;
|
||||||
|
|
||||||
event.get_window().set_cursor(new Cursor.for_display(Gdk.Display.get_default(), CursorType.XTERM));
|
event.get_window().set_cursor(new Cursor.for_display(Gdk.Display.get_default(), CursorType.XTERM));
|
||||||
content_type_image.opacity = 0.5;
|
content_type_image.opacity = 0.5;
|
||||||
if (state == FileTransfer.State.NOT_STARTED) {
|
if (state == FileTransfer.State.NOT_STARTED) {
|
||||||
image_stack.set_visible_child_name("content_type_image");
|
image_stack.set_visible_child_name("content_type_image");
|
||||||
}
|
}
|
||||||
|
file_menu.visible = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,8 @@ public class FileDefaultWidgetController : Object {
|
||||||
public FileDefaultWidgetController(FileDefaultWidget widget) {
|
public FileDefaultWidgetController(FileDefaultWidget widget) {
|
||||||
this.widget = widget;
|
this.widget = widget;
|
||||||
widget.button_release_event.connect(on_clicked);
|
widget.button_release_event.connect(on_clicked);
|
||||||
|
widget.file_open_button.clicked.connect(open_file);
|
||||||
|
widget.file_save_button.clicked.connect(save_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_file_transfer(FileTransfer file_transfer, StreamInteractor stream_interactor) {
|
public void set_file_transfer(FileTransfer file_transfer, StreamInteractor stream_interactor) {
|
||||||
|
@ -160,15 +162,54 @@ public class FileDefaultWidgetController : Object {
|
||||||
widget.update_file_info(file_transfer.mime_type, file_transfer.state, file_transfer.size);
|
widget.update_file_info(file_transfer.mime_type, file_transfer.state, file_transfer.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void open_file() {
|
||||||
|
try{
|
||||||
|
AppInfo.launch_default_for_uri(file_uri, null);
|
||||||
|
} catch (Error err) {
|
||||||
|
warning("Failed to open %s - %s", file_uri, err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void save_as(Gtk.Dialog dialog, int response_id) {
|
||||||
|
var save_dialog = dialog as Gtk.FileChooserDialog;
|
||||||
|
File file_src;
|
||||||
|
switch (response_id) {
|
||||||
|
case Gtk.ResponseType.ACCEPT:
|
||||||
|
file_src = GLib.File.new_for_uri(file_uri);
|
||||||
|
try{
|
||||||
|
file_src.copy(save_dialog.get_file(), GLib.FileCopyFlags.OVERWRITE, null);
|
||||||
|
} catch (Error err) {
|
||||||
|
warning("Failed copy file %s - %s", file_uri, err.message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dialog.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void save_file() {
|
||||||
|
var save_dialog = new Gtk.FileChooserDialog("Save as...", this as Gtk.Window, Gtk.FileChooserAction.SAVE, Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL, Gtk.Stock.SAVE, Gtk.ResponseType.ACCEPT);
|
||||||
|
save_dialog.set_do_overwrite_confirmation(true);
|
||||||
|
save_dialog.set_modal(true);
|
||||||
|
try {
|
||||||
|
(save_dialog as Gtk.FileChooser).set_current_name(GLib.Uri.escape_string(GLib.Path.get_basename(file_uri)));
|
||||||
|
(save_dialog as Gtk.FileChooser).set_uri(GLib.Uri.escape_string(GLib.Path.get_basename(GLib.Uri.unescape_string(file_uri))));
|
||||||
|
} catch (GLib.Error error) {
|
||||||
|
warning("Faild to open save dialog: %s\n", error.message);
|
||||||
|
}
|
||||||
|
save_dialog.response.connect(save_as);
|
||||||
|
save_dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
private bool on_clicked(EventButton event_button) {
|
private bool on_clicked(EventButton event_button) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case FileTransfer.State.COMPLETE:
|
case FileTransfer.State.COMPLETE:
|
||||||
if (event_button.button == 1) {
|
if (event_button.button == 1 && this.widget.file_menu.popover.visible == false) {
|
||||||
try{
|
open_file();
|
||||||
AppInfo.launch_default_for_uri(file_uri, null);
|
}
|
||||||
} catch (Error err) {
|
if (event_button.button == 3 && this.widget.file_menu.popover.visible == false) {
|
||||||
warning("Failed to open %s - %s", file_uri, err.message);
|
save_file();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FileTransfer.State.NOT_STARTED:
|
case FileTransfer.State.NOT_STARTED:
|
||||||
|
|
Loading…
Reference in a new issue