diff --git a/README.md b/README.md
index a21ff97..1bb834d 100644
--- a/README.md
+++ b/README.md
@@ -11,6 +11,16 @@ Teleport is designed to be a replacement for using USB keys or emailing stuff to

+## Install
+Teleport is currently in early development, but you can try it by installing it via [flatpak](http://flatpak.org). If you're running a modern GNU/Linux distro you should already have flatpak, or be able to install it from your repositories.
+
+If you have GNOME Software (or another GUI app to install flatpaks), just [download this file](http://frac-tion.com/teleport-flatpak/teleport.flatpakref) and open it in Software (your browser should offer to do that before downloading).
+
+Otherwise you can also install it from the command line:
+```
+flatpak install --from http://frac-tion.com/teleport-flatpak/teleport.flatpakref
+```
+
## Roadmap
We are currently working on an MVP for a native GNOME app that only sends files, but longer term we are interested in doing things like:
* drag & drop files to send them
diff --git a/src/settings.ui b/src/settings.ui
index 6279722..91ec01f 100644
--- a/src/settings.ui
+++ b/src/settings.ui
@@ -21,11 +21,11 @@
-
-
-
- True
- false
- Browse...
- 12
-
-
- 1
- 1
- 1
- 1
-
-
False
diff --git a/src/teleport-browser.c b/src/teleport-browser.c
index 22fa513..15961a4 100644
--- a/src/teleport-browser.c
+++ b/src/teleport-browser.c
@@ -184,8 +184,8 @@ int teleport_browser_run_avahi_service(TeleportPeer *peers) {
}
/* create some browsers on the client object here, if you wish */
- //if (!(avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", NULL, 0, browse_callback, client))) {
- if (!(avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_INET, "_http._tcp", NULL, 0, browse_callback, client))) {
+ //if (!(avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_teleport._tcp", NULL, 0, browse_callback, client))) {
+ if (!(avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_INET, "_teleport._tcp", NULL, 0, browse_callback, client))) {
/* so something bad */
return 1;
}
diff --git a/src/teleport-peer.c b/src/teleport-peer.c
index aed0925..759bfde 100644
--- a/src/teleport-peer.c
+++ b/src/teleport-peer.c
@@ -58,7 +58,7 @@ teleport_peer_init (TeleportPeer *self)
self->list = g_array_new (FALSE, FALSE, sizeof(Peer *));
}
-gchar * teleport_peer_get_name (TeleportPeer *self, gint index, GError **error)
+gchar *teleport_peer_get_name (TeleportPeer *self, gint index, GError **error)
{
Peer *element;
//g_return_if_fail (TELEPORT_IS_PEER (self));
@@ -69,7 +69,7 @@ gchar * teleport_peer_get_name (TeleportPeer *self, gint index, GError **error)
return element->name;
}
-gchar * teleport_peer_get_ip (TeleportPeer *self, gint index, GError **error)
+gchar *teleport_peer_get_ip (TeleportPeer *self, gint index, GError **error)
{
//g_return_if_fail (TELEPORT_IS_PEER (self));
//g_return_if_fail (error == NULL || *error == NULL);
@@ -86,7 +86,7 @@ gint teleport_peer_get_port (TeleportPeer *self, gint index, GError **error)
return element->port;
}
-void teleport_peer_add_peer (TeleportPeer *self, gchar * name, gchar * ip, gint port)
+void teleport_peer_add_peer (TeleportPeer *self, gchar *name, gchar *ip, gint port)
{
Peer *new = g_new(Peer, 1);
new->ip = ip;
diff --git a/src/teleport-publish.c b/src/teleport-publish.c
index 21c9482..4cde514 100644
--- a/src/teleport-publish.c
+++ b/src/teleport-publish.c
@@ -102,12 +102,12 @@ static void create_services(AvahiClient *c) {
* same name should be put in the same entry group. */
/* Add the service for Teleport */
- if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, "_http._tcp", NULL, NULL, 3000, "test=blah", r, NULL)) < 0) {
+ if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, "_teleport._tcp", NULL, NULL, 3000, "test=blah", r, NULL)) < 0) {
if (ret == AVAHI_ERR_COLLISION)
goto collision;
- fprintf(stderr, "Failed to add _http._tcp service: %s\n", avahi_strerror(ret));
+ fprintf(stderr, "Failed to add _teleport._tcp service: %s\n", avahi_strerror(ret));
goto fail;
}
diff --git a/src/teleport-window.c b/src/teleport-window.c
index 64c5ca6..63048c5 100644
--- a/src/teleport-window.c
+++ b/src/teleport-window.c
@@ -6,6 +6,26 @@
#include "teleport-peer.h"
GtkWidget *find_child(GtkWidget *, const gchar *);
+
+enum {
+ TARGET_INT32,
+ TARGET_STRING,
+ TARGET_URIS,
+ TARGET_ROOTWIN
+};
+
+/* datatype (string), restrictions on DnD (GtkTargetFlags), datatype (int) */
+static GtkTargetEntry target_list[] = {
+ //{ "INTEGER", 0, TARGET_INT32 },
+ //{ "STRING", 0, TARGET_STRING },
+ //{ "text/plain", 0, TARGET_STRING },
+ { "text/uri-list", 0, TARGET_URIS }
+ //{ "application/octet-stream", 0, TARGET_STRING },
+ //{ "application/x-rootwindow-drop", 0, TARGET_ROOTWIN }
+};
+
+static guint n_targets = G_N_ELEMENTS (target_list);
+
TeleportWindow *mainWin;
struct _TeleportWindow
@@ -26,13 +46,167 @@ struct _TeleportWindowPrivate
G_DEFINE_TYPE_WITH_PRIVATE(TeleportWindow, teleport_window, GTK_TYPE_APPLICATION_WINDOW);
+static void
+change_download_directory_cb (GtkWidget *widget,
+ gpointer user_data) {
+ GSettings *settings;
+ gchar * newDownloadDir;
+ settings = (GSettings *)user_data;
+
+ newDownloadDir = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+ g_print ("Change download directory\n");
+ g_settings_set_string (settings,
+ "download-dir",
+ newDownloadDir);
+ g_free(newDownloadDir);
+}
+
+static void
+send_file_to_device (gchar *uri, gpointer data)
+{
+ Peer *device = (Peer *) data;
+ GFile *file = g_file_new_for_uri (uri);
+ gchar *filename = NULL;
+ if (g_file_query_exists (file, NULL)) {
+ filename = g_file_get_path (file);
+ teleport_server_add_route (g_compute_checksum_for_string (G_CHECKSUM_SHA256, filename, -1), g_strdup(filename), device->ip);
+ g_free (filename);
+ }
+ else {
+ g_print ("File doesn't exist: %s\n", uri);
+ }
+ g_object_unref(file);
+}
+static void
+drag_data_received_handl
+(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
+ GtkSelectionData *selection_data, guint target_type, guint time,
+ gpointer data)
+{
+ glong *_idata;
+ gchar *_sdata;
+ gchar **uris;
+
+ gboolean dnd_success = FALSE;
+ gboolean delete_selection_data = FALSE;
+
+ /* Deal with what we are given from source */
+ if((selection_data != NULL) && (gtk_selection_data_get_length(selection_data) >= 0))
+ {
+ if (gdk_drag_context_get_suggested_action(context) == GDK_ACTION_ASK)
+ {
+ /* Ask the user to move or copy, then set the context action. */
+ }
+
+ if (gdk_drag_context_get_suggested_action(context) == GDK_ACTION_MOVE)
+ delete_selection_data = TRUE;
+
+ /* Check that we got the format we can use */
+ switch (target_type)
+ {
+ case TARGET_INT32:
+ _idata = (glong*)gtk_selection_data_get_data(selection_data);
+ g_print ("integer: %ld", *_idata);
+ dnd_success = TRUE;
+ break;
+
+ case TARGET_STRING:
+ _sdata = (gchar*)gtk_selection_data_get_data(selection_data);
+ g_print ("string: %s", _sdata);
+ dnd_success = TRUE;
+ break;
+
+ case TARGET_URIS:
+ uris = gtk_selection_data_get_uris(selection_data);
+ if (uris != NULL && uris[1] == NULL) {
+ send_file_to_device (uris[0], data);
+ dnd_success = TRUE;
+ }
+ break;
+
+ default:
+ g_print ("Something bad!");
+ }
+ }
+
+ if (dnd_success == FALSE)
+ {
+ g_print ("DnD data transfer failed!\n");
+ g_print ("You can not drag more then one file!\n");
+ }
+
+ gtk_drag_finish (context, dnd_success, delete_selection_data, time);
+}
+
+/* Emitted when a drag is over the destination */
+static gboolean
+drag_motion_handl
+(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint t,
+ gpointer user_data)
+{
+ // Fancy stuff here. This signal spams the console something horrible.
+ //const gchar *name = gtk_widget_get_name (widget);
+ //g_print ("%s: drag_motion_handl\n", name);
+ return FALSE;
+}
+
+/* Emitted when a drag leaves the destination */
+static void
+drag_leave_handl
+(GtkWidget *widget, GdkDragContext *context, guint time, gpointer user_data)
+{
+}
+
+/* Emitted when the user releases (drops) the selection. It should check that
+ * the drop is over a valid part of the widget (if its a complex widget), and
+ * itself to return true if the operation should continue. Next choose the
+ * target type it wishes to ask the source for. Finally call gtk_drag_get_data
+ * which will emit "drag-data-get" on the source. */
+static gboolean
+drag_drop_handl
+(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time,
+ gpointer user_data)
+{
+ gboolean is_valid_drop_site;
+ GdkAtom target_type;
+
+ /* Check to see if (x,y) is a valid drop site within widget */
+ is_valid_drop_site = TRUE;
+
+ /* If the source offers a target */
+ if (gdk_drag_context_list_targets (context))
+ {
+ /* Choose the best target type */
+ target_type = GDK_POINTER_TO_ATOM
+ (g_list_nth_data (gdk_drag_context_list_targets(context), TARGET_INT32));
+
+
+ /* Request the data from the source. */
+ gtk_drag_get_data
+ (
+ widget, /* will receive 'drag-data-received' signal */
+ context, /* represents the current state of the DnD */
+ target_type, /* the target type we want */
+ time /* time stamp */
+ );
+ }
+ /* No target offered by source => error */
+ else
+ {
+ is_valid_drop_site = FALSE;
+ }
+
+ return is_valid_drop_site;
+}
+
+
static void
teleport_window_init (TeleportWindow *win)
{
TeleportWindowPrivate *priv;
GtkBuilder *builder;
GtkWidget *menu;
- GtkEntry *downloadDir;
+ GtkFileChooserButton *downloadDir;
mainWin = win;
priv = teleport_window_get_instance_private (win);
@@ -50,7 +224,6 @@ teleport_window_init (TeleportWindow *win)
}
}
-
if (g_settings_get_user_value (priv->settings, "device-name") == NULL) {
g_settings_set_string (priv->settings,
"device-name",
@@ -61,22 +234,57 @@ teleport_window_init (TeleportWindow *win)
builder = gtk_builder_new_from_resource ("/com/frac_tion/teleport/settings.ui");
menu = GTK_WIDGET (gtk_builder_get_object (builder, "settings"));
- downloadDir = GTK_ENTRY (gtk_builder_get_object (builder, "settings_download_directory"));
+ downloadDir = GTK_FILE_CHOOSER_BUTTON (gtk_builder_get_object (builder, "settings_download_directory"));
gtk_menu_button_set_popover(GTK_MENU_BUTTON (priv->gears), menu);
gtk_label_set_text (GTK_LABEL (priv->this_device_name_label),
g_settings_get_string (priv->settings, "device-name"));
- g_settings_bind (priv->settings, "download-dir",
- downloadDir, "text",
- G_SETTINGS_BIND_DEFAULT);
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (downloadDir),
+ g_settings_get_string(priv->settings,
+ "download-dir"));
+
+ g_signal_connect (downloadDir, "file-set", G_CALLBACK (change_download_directory_cb), priv->settings);
+ /*g_settings_bind (priv->settings, "download-dir",
+ GTK_FILE_CHOOSER (downloadDir), "current-folder",
+ G_SETTINGS_BIND_DEFAULT);
+ */
//g_object_unref (menu);
//g_object_unref (label);
g_object_unref (builder);
}
+
+/*Doing Dnd init stuff */
+static void
+add_dnd (GtkWidget *widget, gpointer data)
+{
+ /* Make the widget a DnD destination. */
+ gtk_drag_dest_set
+ (
+ widget, /* widget that will accept a drop */
+ GTK_DEST_DEFAULT_ALL,
+ target_list, /* lists of target to support */
+ n_targets, /* size of list */
+ GDK_ACTION_COPY /* what to do with data after dropped */
+ );
+
+ /* All possible destination signals */
+ g_signal_connect (widget, "drag-data-received",
+ G_CALLBACK(drag_data_received_handl), data);
+
+ g_signal_connect (widget, "drag-leave",
+ G_CALLBACK (drag_leave_handl), data);
+
+ g_signal_connect (widget, "drag-motion",
+ G_CALLBACK (drag_motion_handl), data);
+
+ g_signal_connect (widget, "drag-drop",
+ G_CALLBACK (drag_drop_handl), data);
+}
+
static void
open_file_picker(GtkButton *btn,
Peer *device) {
@@ -135,6 +343,9 @@ update_remote_device_list(TeleportWindow *win,
send_btn = GTK_BUTTON (gtk_builder_get_object (builder_remote_list, "send_btn"));
g_signal_connect (send_btn, "clicked", G_CALLBACK (open_file_picker), device);
+ //Add drag n drop
+ add_dnd (row, device);
+
//line = GTK_WIDGET (gtk_builder_get_object (builder_remote_list, "remote_space_row"));
//gtk_list_box_insert(GTK_LIST_BOX(priv->remote_devices_list), line, -1);
g_object_unref (builder_remote_list);
diff --git a/src/window.ui b/src/window.ui
index c996a13..a500e6d 100644
--- a/src/window.ui
+++ b/src/window.ui
@@ -33,6 +33,8 @@
center
12
12
+ 24
+ 24
vertical
500
@@ -140,7 +142,7 @@
True
False
- emblem-system-symbolic
+ document-edit-symbolic