Compare commits

...

10 Commits

Author SHA1 Message Date
c147f78e1d BeamMeUp 2026-01-04 18:02:19 +01:00
14fd4f82f7 GTK4 2026-01-04 17:30:20 +01:00
079251a2e8 Builds on modern 2026-01-04 16:01:06 +01:00
Thibault Martin
d90681d9ae Remove all github mentions 2020-05-22 12:07:09 +02:00
Anatoli Babenia
ceab699bd2 Updated install instructions (fixes #29) 2020-05-18 15:40:40 +00:00
Julian Sparber
3610dff0b6 Window: add HdyColumn 2019-11-07 13:30:59 +00:00
Julian Sparber
6c1f07d8a5 CI: add ci file 2019-11-07 13:33:49 +01:00
Christopher Davis
cd05cf042f settings.ui: Use correct app name for primary menu
When switching over to the primary menu, the wrong app name was used by accident.

This commit fixes that.
2019-11-07 12:19:09 +00:00
Christopher Davis
87210a9849 appdata: Change "MVP" to a valid version number
With Flatpak being stricter about appdata validation, this
is required.
2019-11-07 12:18:11 +00:00
Christopher Davis
48f65ec3d7 Add flatpak manifest
This allows for us to set up flatpak CI and
build easily using GNOME Builder.
2019-11-07 12:18:11 +00:00
47 changed files with 1004 additions and 1352 deletions

1
.gitignore vendored
View File

@@ -32,3 +32,4 @@ Makefile
_build/ _build/
.flatpak-builder/ .flatpak-builder/
flatpak/ flatpak/
/subprojects/

93
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,93 @@
include: 'https://gitlab.gnome.org/GNOME/citemplates/raw/master/flatpak/flatpak_ci_initiative.yml'
variables:
GIT_SUBMODULE_STRATEGY: normal
BUNDLE: "com.frac_tion.teleport.flatpak"
.build_template: &distro_build
script:
- meson _build
- ninja -C _build install
stages:
- flatpak
- build
- review
- deploy
##################
# Fedora Rawhide #
##################
fedora:rawhide:
image: fedora:rawhide
stage: build
before_script:
- dnf install -y gcc meson ninja-build gettext gtk-doc glib2-devel gtk3-devel
gnome-online-accounts-devel libpeas-devel evolution-data-server-devel
rest-devel json-glib-devel
<<: *distro_build
only:
- schedules
- web
- tags
################
# Ubuntu Devel #
################
ubuntu:devel:
image: ubuntu:devel
stage: build
before_script:
# Ubuntu requires running update to fetch metadata and find packges
- apt update
- apt install -y gcc meson gettext gtk-doc-tools libglib2.0-dev git libgtk-3-dev
libgoa-1.0-dev libpeas-dev libecal1.2-dev libedataserver1.2-dev
librest-dev libjson-glib-dev
<<: *distro_build
only:
- schedules
- web
- tags
##################
# Flatpak Bundle #
##################
flatpak:master:
extends: .flatpak
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master
stage: flatpak
variables:
MANIFEST_PATH: "com.frac_tion.teleport.json"
RUNTIME_REPO: "https://nightly.gnome.org/gnome-nightly.flatpakrepo"
# Replace with your application name, as written in the manifest
FLATPAK_MODULE: "teleport"
# Make sure to keep this in sync with the Flatpak manifest, all arguments
# are passed except the config-args because we build it ourselves
MESON_ARGS: "-Dtracing=true -Dprofile=development"
APP_ID: "com.frac_tion.teleport"
review:
extends: .review
stage: review
dependencies:
- flatpak:master
stop_review:
extends: .stop_review
stage: review
flatpak:nightly:
extends: .publish_nightly
dependencies:
- flatpak:master

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "subprojects/libhandy"]
path = subprojects/libhandy
url = https://source.puri.sm/Librem5/libhandy.git

View File

@@ -10,13 +10,10 @@ Teleport is designed to be a replacement for using USB keys or emailing stuff to
![Screenshot of a Teleport notification](docs/screenshots/notification.png) ![Screenshot of a Teleport notification](docs/screenshots/notification.png)
## Install ## 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. Teleport is currently in early development, but you can try it by installing it
via GNOME Software or via [flatpak](http://flatpak.org).
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 flatpak install flathub com.frac_tion.teleport
``` ```
## Roadmap ## Roadmap
@@ -31,7 +28,7 @@ It's still early days, but we have exciting plans for the future. While Teleport
#### Archlinux #### Archlinux
``` ```
pacman -S base-devel libsoup avahi gtk3 meson pacman -S base-devel libsoup avahi gtk3 meson
git clone https://github.com/frac-tion/teleport.git git clone https://gitlab.gnome.org/jsparber/teleport
cd teleport cd teleport
./configure ./configure
sudo make install sudo make install
@@ -40,7 +37,7 @@ It's still early days, but we have exciting plans for the future. While Teleport
#### Ubuntu #### Ubuntu
``` ```
apt install pkg-config libsoup2.4-dev libavahi-client3 libavahi-client-dev libgtk-3-dev meson apt install pkg-config libsoup2.4-dev libavahi-client3 libavahi-client-dev libgtk-3-dev meson
git clone https://github.com/frac-tion/teleport.git git clone https://gitlab.gnome.org/jsparber/teleport
cd teleport cd teleport
./configure ./configure
make make

1
configure vendored
View File

@@ -78,7 +78,6 @@ echooption() {
} }
sanitycheck MESON 'meson' sanitycheck MESON 'meson'
sanitycheck MESONTEST 'mesontest'
sanitycheck NINJA 'ninja' 'ninja-build' sanitycheck NINJA 'ninja' 'ninja-build'
declare -A default_options=( declare -A default_options=(

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<gresources> <gresources>
<gresource prefix="/com/frac_tion/teleport"> <gresource prefix="/org/nekoweb/n0va/BeamMeUp">
<file preprocess="xml-stripblanks">window.ui</file> <file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">settings.ui</file> <file preprocess="xml-stripblanks">settings.ui</file>
<file preprocess="xml-stripblanks">device_settings.ui</file> <file preprocess="xml-stripblanks">device_settings.ui</file>

View File

@@ -1,60 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyleft 2017 Julian Sparber <julian@sparber.net> -->
<component type="desktop">
<id>com.frac_tion.teleport.desktop</id>
<metadata_license>CC0</metadata_license>
<project_license>AGPL-3.0+</project_license>
<name>Teleport</name>
<summary>Share files over the local network</summary>
<description>
<p>
Teleport is a fast way to share files over the local network. It's
designed to be a replacement for using USB keys or emailing stuff to
yourself just to move them on another device on your desk.
</p>
</description>
<screenshots>
<screenshot type="default">
<caption>Teleport window with multiple devices</caption>
<image width="1366" height="768">https://gitlab.gnome.org/jsparber/teleport/raw/master/data/screenshots/window.png</image>
</screenshot>
<screenshot type="default">
<caption>Teleport notification</caption>
<image width="1366" height="768">https://gitlab.gnome.org/jsparber/teleport/raw/master/data/screenshots/notification.png</image>
</screenshot>
</screenshots>
<url type="homepage">https://gitlab.gnome.org/jsparber/teleport</url>
<url type="bugtracker">https://gitlab.gnome.org/jsparber/teleport/issues</url>
<project_group>GNOME</project_group>
<kudos>
<kudo>AppMenu</kudo>
<kudo>HiDpiIcon</kudo>
<kudo>ModernToolkit</kudo>
<kudo>Notifications</kudo>
</kudos>
<update_contact>julian@sparber.net</update_contact>
<translation type="gettext">teleport</translation>
<releases>
<release version="0.0.1" date="2018-10-28">
<description>
<p>
Some small fixes.
</p>
</description>
</release>
<release version="MVP" date="2017-10-29">
<description>
<p>
This basic initial version sends files chose via the file chooser or
drag and drop. The Downloads directory can be set from the menu.
</p>
</description>
</release>
</releases>
</component>

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 999 B

After

Width:  |  Height:  |  Size: 999 B

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

Before

Width:  |  Height:  |  Size: 266 KiB

After

Width:  |  Height:  |  Size: 266 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 648 KiB

After

Width:  |  Height:  |  Size: 648 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -1,10 +1,9 @@
desktop = 'com.frac_tion.teleport.desktop' desktop = 'org.nekoweb.n0va.BeamMeUp.desktop'
i18n.merge_file( i18n.merge_file(
desktop,
type: 'desktop',
input: desktop + '.in', input: desktop + '.in',
output: desktop, output: desktop,
type: 'desktop',
po_dir: po_dir, po_dir: po_dir,
install: true, install: true,
install_dir: join_paths(teleport_datadir, 'applications') install_dir: join_paths(teleport_datadir, 'applications')
@@ -12,8 +11,8 @@ i18n.merge_file(
# Appdata file. # Appdata file.
appdata_file = i18n.merge_file( appdata_file = i18n.merge_file(
input: 'com.frac_tion.teleport.appdata.xml.in', input: 'org.nekoweb.n0va.BeamMeUp.appdata.xml.in',
output: 'com.frac_tion.teleport.appdata.xml', output: 'org.nekoweb.n0va.BeamMeUp.appdata.xml',
po_dir: po_dir, po_dir: po_dir,
install: true, install: true,
install_dir: join_paths(get_option('datadir'), 'appdata'), install_dir: join_paths(get_option('datadir'), 'appdata'),
@@ -40,10 +39,17 @@ endif
# install_dir: teleport_schemadir # install_dir: teleport_schemadir
#) #)
schema_dir = join_paths(get_option('prefix'), get_option('datadir'), 'glib-2.0', 'schemas')
install_data( install_data(
'com.frac_tion.teleport.gschema.xml', 'org.nekoweb.n0va.BeamMeUp.gschema.xml',
install_dir: teleport_schemadir install_dir: schema_dir
) )
# Compile the schemas after installation
glib_compiled_schemas = find_program('glib-compile-schemas', required: false)
if glib_compiled_schemas.found()
meson.add_install_script(glib_compiled_schemas, schema_dir)
endif
#subdir('appdata') #subdir('appdata')
subdir('icons') subdir('icons')

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyleft 2017 Julian Sparber <julian@sparber.net> -->
<component type="desktop">
<id>org.nekoweb.n0va.BeamMeUp.desktop</id>
<metadata_license>CC0</metadata_license>
<project_license>AGPL-3.0+</project_license>
<name>BeamMeUp</name>
<summary>Share files over the local network</summary>
<description>
<p>
BeamMeUp is a fast way to share files over the local network. It's
designed to be a replacement for using USB keys or emailing stuff to
yourself just to move them on another device on your desk.
</p>
</description>
<url type="homepage">https://git.krzak.org/N0VA/BeamMeUp</url>
<url type="bugtracker">https://git.krzak.org/N0VA/BeamMeUp/issues</url>
<update_contact>n0va@krzak.org</update_contact>
<translation type="gettext">BeamMeUp</translation>
<releases>
<release version="0.0.1" date="2018-10-28">
<description>
<p>
Some small fixes.
</p>
</description>
</release>
<release version="0.0.0" date="2017-10-29">
<description>
<p>
This basic initial version sends files chose via the file chooser or
drag and drop. The Downloads directory can be set from the menu.
</p>
</description>
</release>
</releases>
</component>

View File

@@ -1,7 +1,7 @@
[Desktop Entry] [Desktop Entry]
Name=Teleport Name=BeamMeUp
Comment=Share files on the local network Comment=Share files on the local network
Exec=teleport Exec=BeamMeUp
Icon=com.frac_tion.teleport Icon=org.nekoweb.n0va.BeamMeUp
Type=Application Type=Application
Categories=GTK;GNOME;Utility; Categories=GTK;GNOME;Utility;

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<schemalist> <schemalist>
<schema path="/com/frac_tion/teleport/" id="com.frac_tion.teleport"> <schema path="/org/nekoweb/n0va/BeamMeUp/" id="org.nekoweb.n0va.BeamMeUp">
<key name="download-dir" type="s"> <key name="download-dir" type="s">
<default>'~/Downloads'</default> <default>'~/Downloads'</default>
<summary>Download directory</summary> <summary>Download directory</summary>

View File

@@ -1,5 +1,5 @@
project( project(
'teleport', 'BeamMeUp',
'c', 'c',
version: '0.0.1', version: '0.0.1',
license: 'AGPL3+', license: 'AGPL3+',
@@ -51,11 +51,11 @@ config_h.set('NDEBUG', not teleport_debug)
# package # package
set_defines = [ set_defines = [
['PACKAGE', meson.project_name()], ['PACKAGE', meson.project_name()],
['PACKAGE_BUGREPORT', 'https://github.com/frac-tion/teleport/issues'], ['PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/jsparber/teleport/-/issues'],
['PACKAGE_NAME', meson.project_name()], ['PACKAGE_NAME', meson.project_name()],
['PACKAGE_STRING', '@0@ @1@'.format(meson.project_name(), teleport_version)], ['PACKAGE_STRING', '@0@ @1@'.format(meson.project_name(), teleport_version)],
['PACKAGE_TARNAME', meson.project_name()], ['PACKAGE_TARNAME', meson.project_name()],
['PACKAGE_URL', 'https://github.com/frac-tion/teleport'], ['PACKAGE_URL', 'https://gitlab.gnome.org/jsparber/teleport'],
['PACKAGE_VERSION', teleport_version], ['PACKAGE_VERSION', teleport_version],
['VERSION', teleport_version], ['VERSION', teleport_version],
# i18n # i18n
@@ -146,13 +146,15 @@ endif
add_project_arguments(common_flags + compiler_flags, language: 'c') add_project_arguments(common_flags + compiler_flags, language: 'c')
glib_dep = dependency('glib-2.0', version: '>= 2.43.4') glib_dep = dependency('glib-2.0', version: '>= 2.66')
gtk_dep = dependency('gtk+-3.0', version: '>= 3.22.0') gtk_dep = dependency('gtk4', version: '>= 4.0.0')
libadwaita_dep = dependency('libadwaita-1', version: '>= 1.0.0')
teleport_deps = [ teleport_deps = [
glib_dep, glib_dep,
gtk_dep, gtk_dep,
dependency('gio-2.0', version: '>= 2.43.4'), libadwaita_dep,
dependency('gio-2.0', version: '>= 2.66'),
dependency('libsoup-2.4'), dependency('libsoup-2.4'),
dependency('avahi-client'), dependency('avahi-client'),
cc.find_library('m', required: true) cc.find_library('m', required: true)

View File

@@ -0,0 +1,64 @@
{
"app-id": "com.frac_tion.teleport",
"runtime": "org.gnome.Platform",
"runtime-version": "master",
"sdk": "org.gnome.Sdk",
"command": "teleport",
"finish-args": [
"--share=network",
"--share=ipc",
"--socket=x11",
"--socket=wayland",
"--system-talk-name=org.freedesktop.Avahi",
"--talk-name=org.freedesktop.FileManager1",
"--filesystem=home",
"--env=GSETTINGS_SCHEMA_DIR=/app/share/glib-2.0/schemas",
"--filesystem=xdg-run/dconf",
"--filesystem=~/.config/dconf:ro",
"--talk-name=ca.desrt.dconf",
"--env=DCONF_USER_CONFIG_DIR=.config/dconf"
],
"cleanup": ["/include", "/lib/pkgconfig",
"/share/pkgconfig", "/share/aclocal",
"/man", "/share/man", "/share/gtk-doc",
"/share/vala",
"*.la", "*.a"],
"modules": [
{
"name": "avahi",
"cleanup": [ "/bin" ],
"config-opts": [
"--with-distro=none",
"--enable-gobject",
"--with-xml=expat",
"--disable-libdaemon",
"--disable-libevent",
"--disable-core-docs",
"--disable-manpages",
"--disable-mono",
"--disable-qt3",
"--disable-qt4",
"--disable-qt5",
"--disable-python",
"--disable-gtk",
"--disable-gtk3"
],
"sources": [
{
"type": "git",
"url": "https://github.com/lathiat/avahi.git"
}
]
},
{
"name": "teleport",
"buildsystem": "meson",
"sources": [
{
"type": "git",
"url": "https://gitlab.gnome.org/jsparber/teleport.git"
}
]
}
]
}

View File

@@ -1,34 +1,34 @@
/* teleport-app.c /* beam-me-up-app.c
* *
* Copyright 2017 Julian Sparber <julian@sparber.com> * Copyright 2017 Julian Sparber <julian@sparber.com>
* *
* Teleport is free software: you can redistribute it and/or modify * Teleport is free software: you can redistribute and/or modify
* it under the terms of the GNU Affero General Public License as published by * it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <gtk/gtk.h> #include <adwaita.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
#include "teleport-app.h" #include "beam-me-up-app.h"
#include "teleport-peer.h" #include "beam-me-up-peer.h"
#include "teleport-window.h" #include "beam-me-up-window.h"
#include "teleport-browser.h" #include "beam-me-up-browser.h"
#include "teleport-publish.h" #include "beam-me-up-publish.h"
#include "teleport-server.h" #include "beam-me-up-server.h"
#include "teleport-get.h" #include "beam-me-up-get.h"
static void save_file_callback (GSimpleAction *simple, static void save_file_callback (GSimpleAction *simple,
@@ -84,13 +84,13 @@ typedef struct
struct _TeleportApp { struct _TeleportApp {
GtkApplication parent; AdwApplication parent;
/*< private >*/ /*< private >*/
TeleportAppPrivate *priv; TeleportAppPrivate *priv;
}; };
G_DEFINE_TYPE_WITH_PRIVATE (TeleportApp, teleport_app, GTK_TYPE_APPLICATION); G_DEFINE_TYPE_WITH_PRIVATE (TeleportApp, teleport_app, ADW_TYPE_APPLICATION);
static void static void
@@ -231,12 +231,12 @@ open_file_callback (GSimpleAction *simple,
g_variant_get_string (g_variant_get_child_value (parameter, 3), NULL), g_variant_get_string (g_variant_get_child_value (parameter, 3), NULL),
g_variant_get_string (g_variant_get_child_value (parameter, 2), NULL)); g_variant_get_string (g_variant_get_child_value (parameter, 2), NULL));
gtk_show_uri_on_window (NULL, g_filename_to_uri(path, NULL, NULL), GDK_CURRENT_TIME, NULL); gtk_show_uri (NULL, g_filename_to_uri(path, NULL, NULL), GDK_CURRENT_TIME);
} }
void void
create_user_notification (const char *file_name, const int file_size, const char *origin_device, GVariant *target) { create_user_notification (const char *file_name, const int file_size, const char *origin_device, GVariant *target) {
GNotification *notification = g_notification_new ("Teleport"); GNotification *notification = g_notification_new ("BeamMeUp");
TeleportAppPrivate *priv = mainApplication->priv; TeleportAppPrivate *priv = mainApplication->priv;
g_notification_set_body (notification, g_notification_set_body (notification,
@@ -251,14 +251,11 @@ create_user_notification (const char *file_name, const int file_size, const char
g_notification_set_priority (notification, G_NOTIFICATION_PRIORITY_HIGH); g_notification_set_priority (notification, G_NOTIFICATION_PRIORITY_HIGH);
g_application_send_notification ((GApplication *) mainApplication, NULL, notification); g_application_send_notification ((GApplication *) mainApplication, NULL, notification);
g_object_unref (notification); g_object_unref (notification);
//the example says I have to unref it but it gives a critival error
//https://developer.gnome.org/glib/stable/gvariant-format-strings.html
//g_variant_unref (target);
} }
void void
create_finished_notification (const char *origin, const int filesize, const char *filename, GVariant *target) { create_finished_notification (const char *origin, const int filesize, const char *filename, GVariant *target) {
GNotification *notification = g_notification_new ("Teleport"); GNotification *notification = g_notification_new ("BeamMeUp");
TeleportAppPrivate *priv = mainApplication->priv; TeleportAppPrivate *priv = mainApplication->priv;
g_notification_set_body (notification, g_notification_set_body (notification,
@@ -289,7 +286,6 @@ mainLoopRemovePeerCallback (gpointer peer) {
GtkWidget *window = priv->window; GtkWidget *window = priv->window;
update_remote_device_list_remove((TeleportWindow *) window, (Peer *) peer); update_remote_device_list_remove((TeleportWindow *) window, (Peer *) peer);
//if (teleport_peer_get_number (priv->peerList) == 0)
if (teleport_peer_get_number (priv->peerList) == 0) if (teleport_peer_get_number (priv->peerList) == 0)
teleport_show_no_device_message (TELEPORT_WINDOW (window), TRUE); teleport_show_no_device_message (TELEPORT_WINDOW (window), TRUE);
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
@@ -307,7 +303,6 @@ callback_remove_peer (GObject *instance, Peer *peer, gpointer window) {
void void
callback_notify_user (GObject *instance, gchar *name, gpointer window) { callback_notify_user (GObject *instance, gchar *name, gpointer window) {
//create_user_notification("icon.png", 2000, "Mark's laptop");
} }
GSettings * GSettings *
@@ -374,10 +369,10 @@ teleport_app_startup (GApplication *app) {
/* CSS style */ /* CSS style */
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ()); provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
gtk_css_provider_load_from_resource (GTK_CSS_PROVIDER (provider), gtk_css_provider_load_from_resource (GTK_CSS_PROVIDER (provider),
"com/frac_tion/teleport/style.css"); "/org/nekoweb/n0va/BeamMeUp/style.css");
gtk_style_context_add_provider_for_screen (gdk_screen_get_default(), gtk_style_context_add_provider_for_display (gdk_display_get_default(),
provider, provider,
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref (provider); g_object_unref (provider);
/* PeerList */ /* PeerList */
@@ -398,15 +393,12 @@ teleport_app_activate (GApplication *app) {
TeleportAppPrivate *priv; TeleportAppPrivate *priv;
priv = mainApplication->priv; priv = mainApplication->priv;
gtk_widget_show (priv->window);
gtk_window_present (GTK_WINDOW (priv->window)); gtk_window_present (GTK_WINDOW (priv->window));
} }
static void static void
teleport_app_finalize (GObject *object) teleport_app_finalize (GObject *object)
{ {
/*TeleportAppPrivate priv = mainApplication->priv;
g_clear_object (&priv->settings);*/
G_OBJECT_CLASS (teleport_app_parent_class)->finalize (object); G_OBJECT_CLASS (teleport_app_parent_class)->finalize (object);
} }
@@ -436,45 +428,45 @@ teleport_app_show_about (GSimpleAction *simple,
gpointer user_data) gpointer user_data)
{ {
TeleportAppPrivate *priv = TELEPORT_APP (user_data)->priv; TeleportAppPrivate *priv = TELEPORT_APP (user_data)->priv;
char *copyright; g_autofree char *copyright = NULL;
GDateTime *date; g_autoptr(GDateTime) date = g_date_time_new_now_local ();
int created_year = 2017; int created_year = 2017;
AdwAboutDialog *dialog;
static const gchar *authors[] = { static const char *developers[] = {
"Julian Sparber <julian@sparber.net>", "N0\\A <n0va@krzak.org>",
NULL NULL
}; };
static const gchar *artists[] = { static const char *original_authors[] = {
"Julian Sparber <julian@sparber.net>",
"Tobias Bernard <tbernard@gnome.org>", "Tobias Bernard <tbernard@gnome.org>",
NULL NULL
}; };
date = g_date_time_new_now_local ();
if (g_date_time_get_year (date) <= created_year) if (g_date_time_get_year (date) <= created_year)
{ {
copyright = g_strdup_printf (("Copyright \xC2\xA9 %d " copyright = g_strdup_printf ("Copyright \xC2\xA9 %d The Teleport authors", created_year);
"The Teleport authors"), created_year);
} }
else else
{ {
copyright = g_strdup_printf (("Copyright \xC2\xA9 %d\xE2\x80\x93%d " copyright = g_strdup_printf ("Copyright \xC2\xA9 %d\xE2\x80\x93%d The Teleport authors", created_year, g_date_time_get_year (date));
"The Telport authors"), created_year, g_date_time_get_year (date));
} }
gtk_show_about_dialog (GTK_WINDOW (priv->window), dialog = ADW_ABOUT_DIALOG (adw_about_dialog_new ());
"program-name", ("Teleport"),
"version", VERSION, adw_about_dialog_set_application_name (dialog, "BeamMeUp");
"copyright", copyright, adw_about_dialog_set_version (dialog, VERSION);
"license-type", GTK_LICENSE_AGPL_3_0, adw_about_dialog_set_copyright (dialog, copyright);
"authors", authors, adw_about_dialog_set_license_type (dialog, GTK_LICENSE_AGPL_3_0);
"artists", artists, adw_about_dialog_set_developers (dialog, developers);
"logo-icon-name", "com.frac_tion.teleport", adw_about_dialog_set_application_icon (dialog, "org.nekoweb.n0va.BeamMeUp");
"translator-credits", ("translator-credits"), adw_about_dialog_set_translator_credits (dialog, "translator-credits");
NULL); adw_about_dialog_set_website (dialog, "https://git.krzak.org/N0VA/BeamMeUp");
g_free (copyright);
g_date_time_unref (date); adw_about_dialog_add_acknowledgement_section (dialog, "Original Authors", original_authors);
adw_dialog_present (ADW_DIALOG (dialog), priv->window);
} }
@@ -485,25 +477,39 @@ teleport_app_quit (GSimpleAction *simple,
{ {
TeleportAppPrivate *priv = TELEPORT_APP (user_data)->priv; TeleportAppPrivate *priv = TELEPORT_APP (user_data)->priv;
gtk_widget_destroy (priv->window); gtk_window_destroy (GTK_WINDOW (priv->window));
} }
TeleportApp * TeleportApp *
teleport_app_new (void) teleport_app_new (void)
{ {
return g_object_new (TELEPORT_APP_TYPE, return g_object_new (TELEPORT_APP_TYPE,
"application-id", "com.frac_tion.teleport",
"application-id", "org.nekoweb.n0va.BeamMeUp",
"flags", G_APPLICATION_HANDLES_OPEN, "flags", G_APPLICATION_HANDLES_OPEN,
NULL); NULL);
} }
static void static void
teleport_app_init (TeleportApp *app) { teleport_app_init (TeleportApp *app) {
TeleportAppPrivate *priv = teleport_app_get_instance_private (app); TeleportAppPrivate *priv = teleport_app_get_instance_private (app);
app->priv = priv; app->priv = priv;
priv->settings = g_settings_new ("com.frac_tion.teleport");
priv->settings = g_settings_new ("org.nekoweb.n0va.BeamMeUp");
init_settings (priv->settings); init_settings (priv->settings);
} }

View File

@@ -1,4 +1,4 @@
/* teleport-app.h /* beam-me-up-app.h
* *
* Copyright 2017 Julian Sparber <julian@sparber.com> * Copyright 2017 Julian Sparber <julian@sparber.com>
* *
@@ -19,12 +19,12 @@
#ifndef __TELEPORT_APP_H #ifndef __TELEPORT_APP_H
#define __TELEPORT_APP_H #define __TELEPORT_APP_H
#include <gtk/gtk.h> #include <adwaita.h>
#include "teleport-peer.h" #include "beam-me-up-peer.h"
#define TELEPORT_APP_TYPE (teleport_app_get_type ()) #define TELEPORT_APP_TYPE (teleport_app_get_type ())
G_DECLARE_FINAL_TYPE (TeleportApp, teleport_app, TELEPORT, APP, GtkApplication) G_DECLARE_FINAL_TYPE (TeleportApp, teleport_app, TELEPORT, APP, AdwApplication)
TeleportApp *teleport_app_new (void); TeleportApp *teleport_app_new (void);

View File

@@ -1,4 +1,4 @@
/* teleport-browser.c /* beam-me-up-browser.c
* *
* Copyright 2017 Julian Sparber <julian@sparber.com> * Copyright 2017 Julian Sparber <julian@sparber.com>
* *
@@ -26,9 +26,9 @@
#include <avahi-common/error.h> #include <avahi-common/error.h>
#include <avahi-common/thread-watch.h> #include <avahi-common/thread-watch.h>
#include "teleport-browser.h" #include "beam-me-up-browser.h"
#include "teleport-app.h" #include "beam-me-up-app.h"
#include "teleport-peer.h" #include "beam-me-up-peer.h"
static AvahiThreadedPoll *threaded_poll = NULL; static AvahiThreadedPoll *threaded_poll = NULL;
static AvahiClient *client = NULL; static AvahiClient *client = NULL;
@@ -187,7 +187,7 @@ teleport_browser_run_avahi_service (TeleportPeer *peers)
if (!(avahi_service_browser_new(client, if (!(avahi_service_browser_new(client,
AVAHI_IF_UNSPEC, AVAHI_IF_UNSPEC,
AVAHI_PROTO_INET, AVAHI_PROTO_INET,
"_teleport._tcp", "_beammeup._tcp",
NULL, NULL,
0, 0,
browse_callback, browse_callback,

View File

@@ -1,4 +1,4 @@
/* teleport-browser.h /* beam-me-up-browser.h
* *
* Copyright 2017 Julian Sparber <julian@sparber.com> * Copyright 2017 Julian Sparber <julian@sparber.com>
* *
@@ -19,7 +19,7 @@
#ifndef __TELEPORT_BROWSER_H #ifndef __TELEPORT_BROWSER_H
#define __TELEPORT_BROWSER_H #define __TELEPORT_BROWSER_H
#include "teleport-peer.h" #include "beam-me-up-peer.h"
int teleport_browser_run_avahi_service(TeleportPeer *); int teleport_browser_run_avahi_service(TeleportPeer *);
void teleport_browser_avahi_shutdown(void); void teleport_browser_avahi_shutdown(void);

View File

@@ -1,4 +1,4 @@
/* teleport-get.c /* beam-me-up-get.c
* *
* Copyright 2017 Julian Sparber <julian@sparber.com> * Copyright 2017 Julian Sparber <julian@sparber.com>
* *
@@ -21,9 +21,9 @@
#endif #endif
#include <libsoup/soup.h> #include <libsoup/soup.h>
#include "teleport-app.h" #include "beam-me-up-app.h"
#include "teleport-window.h" #include "beam-me-up-window.h"
#include "teleport-get.h" #include "beam-me-up-get.h"
static int saveFile (SoupMessage *, const gchar *, const gchar *); static int saveFile (SoupMessage *, const gchar *, const gchar *);
static gchar * getFilePath (const gchar *, const gchar *); static gchar * getFilePath (const gchar *, const gchar *);

View File

@@ -1,4 +1,4 @@
/* teleport-get.h /* beam-me-up-get.h
* *
* Copyright 2017 Julian Sparber <julian@sparber.com> * Copyright 2017 Julian Sparber <julian@sparber.com>
* *

View File

@@ -1,4 +1,4 @@
/* teleport-peer.c /* beam-me-up-peer.c
* *
* Copyright 2017 Julian Sparber <julian@sparber.com> * Copyright 2017 Julian Sparber <julian@sparber.com>
* *
@@ -17,7 +17,7 @@
*/ */
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "teleport-peer.h" #include "beam-me-up-peer.h"
enum { enum {
ADD, REMOVE, N_SIGNALS ADD, REMOVE, N_SIGNALS

View File

@@ -1,4 +1,4 @@
/* teleport-peer.h /* beam-me-up-peer.h
* *
* Copyright 2017 Julian Sparber <julian@sparber.com> * Copyright 2017 Julian Sparber <julian@sparber.com>
* *

View File

@@ -35,9 +35,9 @@
#include <avahi-common/timeval.h> #include <avahi-common/timeval.h>
#include <avahi-common/thread-watch.h> #include <avahi-common/thread-watch.h>
#include "teleport-app.h" #include "beam-me-up-app.h"
#include "teleport-peer.h" #include "beam-me-up-peer.h"
#include "teleport-publish.h" #include "beam-me-up-publish.h"
static AvahiThreadedPoll *threaded_poll = NULL; static AvahiThreadedPoll *threaded_poll = NULL;
static AvahiEntryGroup *group = NULL; static AvahiEntryGroup *group = NULL;
@@ -119,8 +119,8 @@ static void create_services(AvahiClient *c) {
* the service type (IPP vs. BSD LPR). Only services with the * the service type (IPP vs. BSD LPR). Only services with the
* same name should be put in the same entry group. */ * same name should be put in the same entry group. */
/* Add the service for Teleport */ /* Add the service for BeamMeUp */
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_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, "_beammeup._tcp", NULL, NULL, 3000, "test=blah", r, NULL)) < 0) {
if (ret == AVAHI_ERR_COLLISION) if (ret == AVAHI_ERR_COLLISION)
goto collision; goto collision;

View File

@@ -1,4 +1,4 @@
/* teleport-publish.h /* beam-me-up-publish.h
* *
* Copyright 2017 Julian Sparber <julian@sparber.com> * Copyright 2017 Julian Sparber <julian@sparber.com>
* *

View File

@@ -0,0 +1,238 @@
/* beam-me-up-remote-device.c
*
* Copyright 2017 Julian Sparber <julian@sparber.com>
*
* Teleport is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <adwaita.h>
#include "beam-me-up-remote-device.h"
#include "beam-me-up-peer.h"
#include "beam-me-up-server.h"
enum
{
PROP_0,
PROP_PEER,
LAST_PROP
};
struct _TeleportRemoteDevice
{
AdwActionRow parent;
GtkWidget *send_btn;
/* data */
Peer *peer;
};
G_DEFINE_TYPE (TeleportRemoteDevice, teleport_remote_device, ADW_TYPE_ACTION_ROW)
static void
teleport_remote_device_finalize (GObject *object)
{
G_OBJECT_CLASS (teleport_remote_device_parent_class)->finalize (object);
}
static void
teleport_remote_device_dispose (GObject *object)
{
G_OBJECT_CLASS (teleport_remote_device_parent_class)->dispose (object);
}
static void
teleport_remote_device_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
TeleportRemoteDevice *self = TELEPORT_REMOTE_DEVICE (object);
switch (prop_id)
{
case PROP_PEER:
g_value_set_pointer (value, self->peer);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
teleport_remote_device_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
TeleportRemoteDevice *self = TELEPORT_REMOTE_DEVICE (object);
switch (prop_id)
{
case PROP_PEER:
teleport_remote_device_set_peer (self, g_value_get_pointer (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
teleport_remote_device_class_init (TeleportRemoteDeviceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = teleport_remote_device_dispose;
object_class->finalize = teleport_remote_device_finalize;
object_class->get_property = teleport_remote_device_get_property;
object_class->set_property = teleport_remote_device_set_property;
g_object_class_install_property (object_class,
PROP_PEER,
g_param_spec_pointer ("peer",
"Peer of the row",
"The peer that this row represents",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
gtk_widget_class_set_template_from_resource (widget_class, "/org/nekoweb/n0va/BeamMeUp/remote_list.ui");
gtk_widget_class_bind_template_child (widget_class, TeleportRemoteDevice, send_btn);
}
static void
on_file_chooser_response (GtkNativeDialog *dialog,
int response,
gpointer user_data)
{
Peer *device = user_data;
if (response == GTK_RESPONSE_ACCEPT)
{
g_autoptr(GFile) file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
g_autofree char *filename = g_file_get_path (file);
if (filename)
{
g_print("Chosen file is %s\n", filename);
teleport_server_add_route (g_compute_checksum_for_string (G_CHECKSUM_SHA256, filename, -1), g_strdup(filename), device->ip);
}
}
g_object_unref (dialog);
}
static void
open_file_picker(GtkButton *btn,
Peer *device) {
GtkFileChooserNative *dialog;
GtkRoot *root;
g_print("Open file chooser for submitting a file to %s with Address %s\n", device->name, device->ip);
root = gtk_widget_get_root (GTK_WIDGET (btn));
if (GTK_IS_WINDOW (root))
{
dialog = gtk_file_chooser_native_new ("Open File",
GTK_WINDOW (root),
GTK_FILE_CHOOSER_ACTION_OPEN,
("_Open"),
("_Cancel"));
g_signal_connect (dialog, "response", G_CALLBACK (on_file_chooser_response), device);
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
}
}
static void
send_file_to_device (GFile *file, Peer *device)
{
g_autofree gchar *filename = g_file_get_path (file);
if (g_file_query_exists (file, NULL)) {
teleport_server_add_route (g_compute_checksum_for_string (G_CHECKSUM_SHA256, filename, -1), g_strdup(filename), device->ip);
}
else {
g_print ("File doesn't exist: %s\n", filename);
}
}
static gboolean
on_drop (GtkDropTarget *target,
const GValue *value,
double x,
double y,
gpointer user_data)
{
TeleportRemoteDevice *self = user_data;
if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
{
GSList *list = g_value_get_boxed (value);
for (GSList *l = list; l != NULL; l = l->next)
{
send_file_to_device (G_FILE (l->data), self->peer);
}
return TRUE;
}
return FALSE;
}
static void
teleport_remote_device_init (TeleportRemoteDevice *self)
{
GtkDropTarget *target;
gtk_widget_init_template (GTK_WIDGET (self));
target = gtk_drop_target_new (GDK_TYPE_FILE_LIST, GDK_ACTION_COPY);
g_signal_connect (target, "drop", G_CALLBACK (on_drop), self);
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (target));
}
GtkWidget*
teleport_remote_device_new (Peer *peer)
{
return g_object_new (TELEPORT_TYPE_REMOTE_DEVICE,
"peer", peer,
NULL);
}
Peer *
teleport_remote_device_get_peer (GtkWidget *widget)
{
TeleportRemoteDevice *row;
g_return_val_if_fail (TELEPORT_IS_REMOTE_DEVICE (widget), NULL);
row = TELEPORT_REMOTE_DEVICE (widget);
return row->peer;
}
void
teleport_remote_device_set_peer (TeleportRemoteDevice *widget,
Peer *peer)
{
g_return_if_fail (TELEPORT_IS_REMOTE_DEVICE (widget));
widget->peer = peer;
if (peer)
{
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (widget), peer->name);
g_signal_connect (widget->send_btn, "clicked", G_CALLBACK (open_file_picker), peer);
}
}
void
teleport_remote_device_destroy (TeleportRemoteDevice *self)
{
}

View File

@@ -1,4 +1,4 @@
/* teleport-remote-device.c /* beam-me-up-remote-device.c
* *
* Copyright 2017 Julian Sparber <julian@sparber.com> * Copyright 2017 Julian Sparber <julian@sparber.com>
* *
@@ -19,15 +19,14 @@
#ifndef TELEPORT_REMOTE_DEVICE_H #ifndef TELEPORT_REMOTE_DEVICE_H
#define TELEPORT_REMOTE_DEVICE_H #define TELEPORT_REMOTE_DEVICE_H
#include <glib-object.h> #include <adwaita.h>
#include <gtk/gtk.h> #include "beam-me-up-peer.h"
#include "teleport-peer.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define TELEPORT_TYPE_REMOTE_DEVICE (teleport_remote_device_get_type()) #define TELEPORT_TYPE_REMOTE_DEVICE (teleport_remote_device_get_type())
G_DECLARE_FINAL_TYPE (TeleportRemoteDevice, teleport_remote_device, TELEPORT, REMOTE_DEVICE, GtkFrame) G_DECLARE_FINAL_TYPE (TeleportRemoteDevice, teleport_remote_device, TELEPORT, REMOTE_DEVICE, AdwActionRow)
GtkWidget * teleport_remote_device_new (Peer * ); GtkWidget * teleport_remote_device_new (Peer * );

View File

@@ -1,4 +1,4 @@
/* teleport-server.c /* beam-me-up-server.c
* *
* Copyright 2017 Julian Sparber <julian@sparber.com> * Copyright 2017 Julian Sparber <julian@sparber.com>
* *
@@ -22,9 +22,9 @@
#include <glib.h> #include <glib.h>
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include "teleport-server.h" #include "beam-me-up-server.h"
#include "teleport-get.h" #include "beam-me-up-get.h"
#include "teleport-app.h" #include "beam-me-up-app.h"
static int port; static int port;
static SoupServer *glob_server; static SoupServer *glob_server;
@@ -232,7 +232,7 @@ teleport_server_run (void) {
GError *error = NULL; GError *error = NULL;
port = 3000; port = 3000;
glob_server = soup_server_new (SOUP_SERVER_SERVER_HEADER, "teleport-httpd ", glob_server = soup_server_new (SOUP_SERVER_SERVER_HEADER, "beam-me-up-httpd ",
NULL); NULL);
soup_server_listen_all (glob_server, port, 0, &error); soup_server_listen_all (glob_server, port, 0, &error);

View File

@@ -1,4 +1,4 @@
/* teleport-server.h /* beam-me-up-server.h
* *
* Copyright 2017 Julian Sparber <julian@sparber.com> * Copyright 2017 Julian Sparber <julian@sparber.com>
* *

View File

@@ -1,33 +1,33 @@
/* teleport-window.c /* beam-me-up-window.c
* *
* Copyright 2017 Julian Sparber <julian@sparber.com> * Copyright 2017 Julian Sparber <julian@sparber.com>
* *
* Teleport is free software: you can redistribute it and/or modify * Teleport is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by * it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <gtk/gtk.h> #include <adwaita.h>
#include <string.h> #include <string.h>
#include "teleport-app.h" #include "beam-me-up-app.h"
#include "teleport-window.h" #include "beam-me-up-window.h"
#include "teleport-server.h" #include "beam-me-up-server.h"
#include "teleport-peer.h" #include "beam-me-up-peer.h"
#include "teleport-remote-device.h" #include "beam-me-up-remote-device.h"
struct _TeleportWindow struct _TeleportWindow
{ {
GtkApplicationWindow parent; AdwApplicationWindow parent;
}; };
typedef struct _TeleportWindowPrivate TeleportWindowPrivate; typedef struct _TeleportWindowPrivate TeleportWindowPrivate;
@@ -37,27 +37,51 @@ struct _TeleportWindowPrivate
GtkWidget *gears; GtkWidget *gears;
GtkWidget *this_device_settings_button; GtkWidget *this_device_settings_button;
GtkWidget *remote_devices_box; GtkWidget *remote_devices_box;
GtkWidget *this_device_name_label; AdwActionRow *this_device_row;
GtkWidget *remote_no_devices; GtkWidget *remote_no_devices;
GtkWidget *remote_no_avahi; GtkWidget *remote_no_avahi;
GtkWidget *this_device_settings_entry; GtkWidget *this_device_settings_entry;
}; };
G_DEFINE_TYPE_WITH_PRIVATE(TeleportWindow, teleport_window, GTK_TYPE_APPLICATION_WINDOW); G_DEFINE_TYPE_WITH_PRIVATE(TeleportWindow, teleport_window, ADW_TYPE_APPLICATION_WINDOW);
static void static void
change_download_directory_cb (GtkWidget *widget, on_download_dir_response (GtkNativeDialog *dialog,
gpointer user_data) { int response,
GSettings *settings; gpointer user_data)
gchar * newDownloadDir; {
settings = (GSettings *)user_data; GSettings *settings = user_data;
newDownloadDir = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); if (response == GTK_RESPONSE_ACCEPT)
g_print ("Change download directory\n"); {
g_settings_set_string (settings, g_autoptr(GFile) file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
"download-dir", g_autofree char *path = g_file_get_path (file);
newDownloadDir); if (path)
g_free(newDownloadDir); {
g_print ("Change download directory to %s\n", path);
g_settings_set_string (settings, "download-dir", path);
}
}
g_object_unref (dialog);
}
static void
on_choose_download_dir_clicked (GtkButton *btn,
gpointer user_data)
{
GSettings *settings = user_data;
GtkFileChooserNative *dialog;
GtkRoot *root = gtk_widget_get_root (GTK_WIDGET (btn));
dialog = gtk_file_chooser_native_new ("Choose Download Directory",
GTK_WINDOW (root),
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
"_Select",
"_Cancel");
g_signal_connect (dialog, "response", G_CALLBACK (on_download_dir_response), settings);
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
} }
static gboolean static gboolean
@@ -69,7 +93,7 @@ valid_device_name (const gchar *name) {
static gchar * static gchar *
get_new_name (GtkWidget *widget) { get_new_name (GtkWidget *widget) {
return g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (widget)))); return g_strstrip (g_strdup (gtk_editable_get_text (GTK_EDITABLE (widget))));
} }
static void static void
@@ -79,16 +103,6 @@ on_new_device_name (GtkWidget *widget,
gtk_widget_set_sensitive (GTK_WIDGET (data), valid_device_name (name)); gtk_widget_set_sensitive (GTK_WIDGET (data), valid_device_name (name));
} }
static void
update_download_directory (GSettings *settings,
gchar *key,
gpointer *data) {
if (g_strcmp0 (key, "download-dir") == 0) {
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (data),
g_settings_get_string(settings, key));
}
}
static void static void
on_click_this_device_settings_button (GtkWidget *widget, on_click_this_device_settings_button (GtkWidget *widget,
gpointer user_data) { gpointer user_data) {
@@ -106,46 +120,96 @@ static void
on_show_popover (GtkPopover *widget, on_show_popover (GtkPopover *widget,
gpointer data) { gpointer data) {
TeleportWindowPrivate *priv = (TeleportWindowPrivate *) data; TeleportWindowPrivate *priv = (TeleportWindowPrivate *) data;
gtk_entry_set_text(GTK_ENTRY (priv->this_device_settings_entry), gtk_editable_set_text(GTK_EDITABLE (priv->this_device_settings_entry),
g_settings_get_string(teleport_app_get_settings (), g_settings_get_string(teleport_app_get_settings (),
"device-name")); "device-name"));
} }
static void
update_download_dir_display (GtkWidget *label,
GtkWidget *icon,
const char *path)
{
g_autoptr(GFile) file = g_file_new_for_path (path);
g_autoptr(GFileInfo) info = g_file_query_info (file,
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON,
G_FILE_QUERY_INFO_NONE,
NULL, NULL);
if (info)
{
GIcon *gicon = g_file_info_get_symbolic_icon (info);
gtk_label_set_text (GTK_LABEL (label), g_file_info_get_display_name (info));
if (gicon)
gtk_image_set_from_gicon (GTK_IMAGE (icon), gicon);
}
else
{
gtk_label_set_text (GTK_LABEL (label), path);
gtk_image_set_from_icon_name (GTK_IMAGE (icon), "folder-symbolic");
}
}
static void
on_download_dir_setting_changed (GSettings *settings,
const char *key,
gpointer user_data)
{
GtkBuilder *builder = user_data;
GtkWidget *label = GTK_WIDGET (gtk_builder_get_object (builder, "settings_download_directory_label"));
GtkWidget *icon = GTK_WIDGET (gtk_builder_get_object (builder, "settings_download_directory_icon"));
g_autofree char *path = g_settings_get_string (settings, key);
update_download_dir_display (label, icon, path);
}
static void static void
teleport_window_init (TeleportWindow *win) teleport_window_init (TeleportWindow *win)
{ {
TeleportWindowPrivate *priv; TeleportWindowPrivate *priv;
GtkBuilder *builder; GtkBuilder *builder;
GtkWidget *menu; GtkWidget *menu;
GtkFileChooserButton *downloadDir; GtkWidget *downloadDirBtn;
GtkWidget *downloadDirLabel;
GtkWidget *downloadDirIcon;
GSettings *settings = teleport_app_get_settings (); GSettings *settings = teleport_app_get_settings ();
priv = teleport_window_get_instance_private (win); priv = teleport_window_get_instance_private (win);
g_type_ensure (ADW_TYPE_CLAMP);
g_type_ensure (ADW_TYPE_TOOLBAR_VIEW);
g_type_ensure (ADW_TYPE_ACTION_ROW);
gtk_widget_init_template (GTK_WIDGET (win)); gtk_widget_init_template (GTK_WIDGET (win));
builder = gtk_builder_new_from_resource ("/com/frac_tion/teleport/settings.ui"); builder = gtk_builder_new_from_resource ("/org/nekoweb/n0va/BeamMeUp/settings.ui");
menu = GTK_WIDGET (gtk_builder_get_object (builder, "settings")); menu = GTK_WIDGET (gtk_builder_get_object (builder, "settings"));
downloadDir = GTK_FILE_CHOOSER_BUTTON (gtk_builder_get_object (builder, "settings_download_directory")); downloadDirBtn = GTK_WIDGET (gtk_builder_get_object (builder, "settings_download_directory"));
downloadDirLabel = GTK_WIDGET (gtk_builder_get_object (builder, "settings_download_directory_label"));
downloadDirIcon = GTK_WIDGET (gtk_builder_get_object (builder, "settings_download_directory_icon"));
gtk_menu_button_set_popover(GTK_MENU_BUTTON (priv->gears), menu); gtk_menu_button_set_popover(GTK_MENU_BUTTON (priv->gears), menu);
g_settings_bind (settings, "device-name", g_settings_bind (settings, "device-name",
priv->this_device_name_label, "label", priv->this_device_row, "title",
G_SETTINGS_BIND_GET); G_SETTINGS_BIND_GET);
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (downloadDir), /* Initial update */
g_settings_get_string(settings, g_autofree char *path = g_settings_get_string (settings, "download-dir");
"download-dir")); update_download_dir_display (downloadDirLabel, downloadDirIcon, path);
g_signal_connect (downloadDir, "file-set", G_CALLBACK (change_download_directory_cb), settings); /* Update on change */
g_signal_connect (settings, "changed", G_CALLBACK (update_download_directory), downloadDir); g_signal_connect_data (settings, "changed::download-dir",
G_CALLBACK (on_download_dir_setting_changed),
g_object_ref (builder),
(GClosureNotify)g_object_unref, 0);
g_signal_connect (downloadDirBtn, "clicked", G_CALLBACK (on_choose_download_dir_clicked), settings);
g_object_unref (builder); g_object_unref (builder);
/* Add popover for device settings */ /* Add popover for device settings */
builder = gtk_builder_new_from_resource ("/com/frac_tion/teleport/device_settings.ui"); builder = gtk_builder_new_from_resource ("/org/nekoweb/n0va/BeamMeUp/device_settings.ui");
menu = GTK_WIDGET (gtk_builder_get_object (builder, "device-settings")); menu = GTK_WIDGET (gtk_builder_get_object (builder, "device-settings"));
gtk_menu_button_set_popover(GTK_MENU_BUTTON (priv->this_device_settings_button), menu); gtk_menu_button_set_popover(GTK_MENU_BUTTON (priv->this_device_settings_button), menu);
@@ -182,24 +246,12 @@ update_remote_device_list(TeleportWindow *win,
priv = teleport_window_get_instance_private (win); priv = teleport_window_get_instance_private (win);
gtk_widget_hide (priv->remote_no_devices); gtk_widget_set_visible (priv->remote_no_devices, FALSE);
remote_device = teleport_remote_device_new (device); remote_device = teleport_remote_device_new (device);
gtk_box_pack_end (GTK_BOX (priv->remote_devices_box), gtk_box_append (GTK_BOX (priv->remote_devices_box),
remote_device, remote_device);
TRUE,
TRUE,
0);
}
static void
remove_remote_peer (GtkWidget *widget,
gpointer data)
{
if (TELEPORT_IS_REMOTE_DEVICE (widget) && teleport_remote_device_get_peer(widget) == ((Peer *) data)) {
gtk_widget_destroy (widget);
}
} }
void void
@@ -207,12 +259,18 @@ update_remote_device_list_remove(TeleportWindow *win,
Peer *device) Peer *device)
{ {
TeleportWindowPrivate *priv; TeleportWindowPrivate *priv;
GtkWidget *child;
priv = teleport_window_get_instance_private (win); priv = teleport_window_get_instance_private (win);
gtk_container_foreach (GTK_CONTAINER(priv->remote_devices_box), child = gtk_widget_get_first_child (priv->remote_devices_box);
remove_remote_peer, while (child) {
device); GtkWidget *next = gtk_widget_get_next_sibling (child);
if (TELEPORT_IS_REMOTE_DEVICE (child) && teleport_remote_device_get_peer(child) == device) {
gtk_box_remove (GTK_BOX (priv->remote_devices_box), child);
}
child = next;
}
} }
static void static void
@@ -227,11 +285,11 @@ teleport_window_class_init (TeleportWindowClass *class)
G_OBJECT_CLASS (class)->dispose = teleport_window_dispose; G_OBJECT_CLASS (class)->dispose = teleport_window_dispose;
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class), gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/com/frac_tion/teleport/window.ui"); "/org/nekoweb/n0va/BeamMeUp/window.ui");
gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, gears); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, gears);
gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, this_device_settings_button); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, this_device_settings_button);
gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, this_device_name_label); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, this_device_row);
gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, remote_no_devices); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, remote_no_devices);
gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, remote_devices_box); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, remote_devices_box);
gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, remote_no_avahi); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, remote_no_avahi);
@@ -248,10 +306,7 @@ teleport_show_no_device_message (TeleportWindow *self, gboolean show)
{ {
TeleportWindowPrivate *priv; TeleportWindowPrivate *priv;
priv = teleport_window_get_instance_private (self); priv = teleport_window_get_instance_private (self);
if (show) gtk_widget_set_visible (priv->remote_no_devices, show);
gtk_widget_show (priv->remote_no_devices);
else
gtk_widget_hide (priv->remote_no_devices);
} }
void void
@@ -259,16 +314,11 @@ teleport_show_no_avahi_message (TeleportWindow *self, gboolean show)
{ {
TeleportWindowPrivate *priv; TeleportWindowPrivate *priv;
priv = teleport_window_get_instance_private (self); priv = teleport_window_get_instance_private (self);
if (show) gtk_widget_set_visible (priv->remote_no_avahi, show);
gtk_widget_show (priv->remote_no_avahi);
else
gtk_widget_hide (priv->remote_no_avahi);
} }
void void
teleport_window_open (TeleportWindow *win, teleport_window_open (TeleportWindow *win,
GFile *file) GFile *file)
{ {
//TeleportWindowPrivate *priv; }
//priv = teleport_window_get_instance_private (win);
}

View File

@@ -1,4 +1,4 @@
/* teleport-window.h /* beam-me-up-window.h
* *
* Copyright 2017 Julian Sparber <julian@sparber.com> * Copyright 2017 Julian Sparber <julian@sparber.com>
* *
@@ -19,16 +19,16 @@
#ifndef __TELEPORT_WINDOW_H #ifndef __TELEPORT_WINDOW_H
#define __TELEPORT_WINDOW_H #define __TELEPORT_WINDOW_H
#include <gtk/gtk.h> #include <adwaita.h>
#include "teleport-app.h" #include "beam-me-up-app.h"
#include "teleport-peer.h" #include "beam-me-up-peer.h"
#define TELEPORT_WINDOW_TYPE (teleport_window_get_type ()) #define TELEPORT_WINDOW_TYPE (teleport_window_get_type ())
G_DECLARE_FINAL_TYPE (TeleportWindow, G_DECLARE_FINAL_TYPE (TeleportWindow,
teleport_window, teleport_window,
TELEPORT, TELEPORT,
WINDOW, WINDOW,
GtkApplicationWindow) AdwApplicationWindow)
TeleportWindow *teleport_window_new (TeleportApp *); TeleportWindow *teleport_window_new (TeleportApp *);
void teleport_window_open (TeleportWindow *, void teleport_window_open (TeleportWindow *,

View File

@@ -1,53 +1,40 @@
<?xml version="1.0"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<!-- interface-requires gtk+ 3.0 --> <requires lib="gtk" version="4.0"/>
<object id="device-settings" class="GtkPopover"> <object class="GtkPopover" id="device-settings">
<child> <property name="child">
<object class="GtkGrid"> <object class="GtkBox">
<property name="visible">True</property> <property name="margin-start">10</property>
<property name="margin">10</property> <property name="margin-end">10</property>
<property name="column-spacing">6</property> <property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child> <child>
<object class="GtkLabel"> <object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Device name</property> <property name="label" translatable="yes">Device name</property>
<property name="halign">GTK_ALIGN_START</property> <property name="halign">start</property>
<property name="margin_bottom">6</property>
</object> </object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkEntry" id="this_device_settings_entry"> <object class="GtkBox">
<property name="visible">True</property> <property name="spacing">6</property>
<child>
<object class="GtkEntry" id="this_device_settings_entry">
<property name="hexpand">True</property>
</object>
</child>
<child>
<object class="GtkButton" id="this_device_settings_button">
<property name="label" translatable="yes">Rename</property>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
</object> </object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="this_device_settings_button">
<property name="visible">True</property>
<property name="label" translatable="yes">Rename</property>
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child> </child>
</object> </object>
</child> </property>
</object> </object>
</interface> </interface>

View File

@@ -16,12 +16,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <gtk/gtk.h> #include <adwaita.h>
#include "teleport-app.h" #include "beam-me-up-app.h"
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
adw_init ();
return g_application_run (G_APPLICATION (teleport_app_new ()), argc, argv); return g_application_run (G_APPLICATION (teleport_app_new ()), argc, argv);
} }

View File

@@ -1,13 +1,12 @@
headers = files( headers = files(
'teleport-remote-device.h', 'beam-me-up-remote-device.h',
'teleport-browser.h', 'beam-me-up-browser.h',
'teleport-get.h', 'beam-me-up-get.h',
'teleport-publish.h', 'beam-me-up-publish.h',
'teleport-server.h', 'beam-me-up-server.h',
'teleport-window.h', 'beam-me-up-window.h',
'teleport-peer.h', 'beam-me-up-peer.h',
'teleport-app.h' 'beam-me-up-app.h'
) )
install_headers(headers, subdir: meson.project_name()) install_headers(headers, subdir: meson.project_name())
@@ -18,22 +17,22 @@ install_headers(headers, subdir: meson.project_name())
################ ################
sources = files( sources = files(
'teleport-remote-device.c', 'beam-me-up-remote-device.c',
'teleport-browser.c', 'beam-me-up-browser.c',
'teleport-get.c', 'beam-me-up-get.c',
'teleport-publish.c', 'beam-me-up-publish.c',
'teleport-server.c', 'beam-me-up-server.c',
'teleport-app.c', 'beam-me-up-app.c',
'teleport-window.c', 'beam-me-up-window.c',
'teleport-peer.c', 'beam-me-up-peer.c',
'main.c' 'main.c'
) )
sources += gnome.compile_resources( sources += gnome.compile_resources(
'teleport-resources', 'BeamMeUp-resources',
join_paths(data_dir, 'teleport.gresource.xml'), join_paths(data_dir, 'BeamMeUp.gresource.xml'),
source_dir: [ data_dir, join_paths(meson.build_root(), 'plugins') ], source_dir: [ data_dir, join_paths(meson.build_root(), 'plugins') ],
c_name: 'teleport', c_name: 'BeamMeUp',
# dependencies: plugins_confs, # dependencies: plugins_confs,
export: true export: true
) )
@@ -78,10 +77,10 @@ ldflags = [ '-Wl,--export-dynamic' ]
############### ###############
# teleport # # BeamMeUp #
############### ###############
teleport = executable( BeamMeUp = executable(
meson.project_name(), meson.project_name(),
sources, sources,
include_directories: incs, include_directories: incs,
@@ -98,8 +97,8 @@ teleport = executable(
# Private library # # Private library #
################### ###################
libteleport = shared_library( libBeamMeUp = shared_library(
'teleport', 'BeamMeUp',
sources: sources, sources: sources,
version: libversion, version: libversion,
soversion: soversion, soversion: soversion,
@@ -108,9 +107,8 @@ libteleport = shared_library(
c_args: cflags c_args: cflags
) )
libteleport_dep = declare_dependency( libBeamMeUp_dep = declare_dependency(
link_with: libteleport, link_with: libBeamMeUp,
include_directories: src_inc, include_directories: src_inc,
dependencies: teleport_deps dependencies: teleport_deps
) )

View File

@@ -1,75 +1,15 @@
<?xml version="1.0"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<!-- interface-requires gtk+ 3.0 --> <requires lib="gtk" version="4.0"/>
<template class="TeleportRemoteDevice" parent="GtkFrame"> <requires lib="libadwaita" version="1.0"/>
<property name="visible">True</property> <template class="TeleportRemoteDevice" parent="AdwActionRow">
<property name="can_focus">False</property> <property name="activatable">True</property>
<property name="shadow_type">in</property> <property name="selectable">True</property>
<property name="shadow_type">none</property>
<style>
<class name="frame"/>
</style>
<child> <child>
<object class="GtkListBox"> <object class="GtkButton" id="send_btn">
<property name="visible">True</property> <property name="valign">center</property>
<property name="can_focus">True</property> <property name="label" translatable="yes">Send File</property>
<property name="selection_mode">none</property>
<child>
<object class="GtkListBoxRow" id="remote_device_row">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activatable">True</property>
<property name="selectable">True</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">0</property>
<property name="column_spacing">32</property>
<property name="margin">12</property>
<property name="margin_start">16</property>
<property name="valign">center</property>
<child>
<object class="GtkLabel" id="device_name">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="valign">end</property>
<property name="label" translatable="yes">Jan's Librem</property>
<property name="use_underline">True</property>
<style>
<class name="device-name"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="send_btn">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="label" translatable="yes">Send File</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object> </object>
</child> </child>
</template>> </template>
</interface> </interface>

View File

@@ -1,128 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface> <interface>
<requires lib="gtk+" version="3.16"/> <requires lib="gtk" version="4.0"/>
<object class="GtkPopover" id="settings"> <object class="GtkPopover" id="settings">
<property name="can_focus">False</property> <property name="child">
<child>
<object class="GtkBox"> <object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="margin">12</property> <property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="spacing">12</property>
<child> <child>
<object class="GtkGrid"> <object class="GtkBox">
<property name="visible">True</property> <property name="orientation">vertical</property>
<property name="can_focus">False</property> <property name="spacing">6</property>
<child> <child>
<object class="GtkLabel"> <object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_bottom">6</property>
<property name="label" translatable="yes">Save received files in:</property> <property name="label" translatable="yes">Save received files in:</property>
<property name="xalign">0</property> <property name="xalign">0</property>
</object> </object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkFileChooserButton" id="settings_download_directory"> <object class="GtkButton" id="settings_download_directory">
<property name="visible">True</property> <property name="child">
<property name="can_focus">False</property> <object class="GtkBox">
<property name="action">select-folder</property> <property name="spacing">6</property>
<property name="title" translatable="yes">Choose download dir</property> <child>
<object class="GtkImage" id="settings_download_directory_icon">
<property name="icon-name">folder-symbolic</property>
</object>
</child>
<child>
<object class="GtkLabel" id="settings_download_directory_label">
<property name="label" translatable="yes">Choose download dir</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
</object>
</child>
</object>
</property>
</object> </object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child> </child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child> <child>
<object class="GtkLabel"> <object class="GtkLabel">
<property name="can_focus">False</property> <property name="margin-top">6</property>
<property name="margin_top">18</property> <property name="label" translatable="yes">Automatically enable BeamMeUp on these networks:</property>
<property name="margin_bottom">6</property>
<property name="label" translatable="yes">Automatically enable Teleport on these networks:</property>
<property name="xalign">0</property> <property name="xalign">0</property>
</object> </object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">2</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkListBox" id="general-listbox"> <object class="GtkListBox" id="general-listbox">
<property name="can_focus">False</property> <property name="selection-mode">none</property>
<property name="selection_mode">none</property> <style>
<class name="boxed-list"/>
</style>
<child> <child>
<object class="GtkListBoxRow" id="primary-button-row-1"> <object class="GtkListBoxRow" id="primary-button-row-1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activatable">False</property> <property name="activatable">False</property>
<child> <child>
<object class="GtkGrid" id="primary-button-grid-1"> <object class="GtkBox">
<property name="visible">True</property> <property name="margin-start">12</property>
<property name="can_focus">False</property> <property name="margin-end">6</property>
<property name="margin_left">12</property> <property name="margin-top">6</property>
<property name="margin_right">6</property> <property name="margin-bottom">6</property>
<property name="margin_start">12</property> <property name="spacing">12</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="column_spacing">16</property>
<child> <child>
<object class="GtkLabel" id="device-name-lable-1"> <object class="GtkLabel" id="device-name-lable-1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
<property name="label" translatable="yes">o2-WLAN09</property> <property name="label" translatable="yes">o2-WLAN09</property>
<property name="use_underline">True</property>
<property name="xalign">0</property> <property name="xalign">0</property>
</object> </object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkGrid"> <object class="GtkButton" id="localSettings-1">
<property name="visible">True</property> <property name="icon-name">window-close-symbolic</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkButton" id="localSettings-1">
<property name="height_request">35</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">window-close-symbolic</property>
</object>
</child>
<style>
<class name="image-button"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<style> <style>
<class name="linked"/> <class name="flat"/>
</style> </style>
</object> </object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child> </child>
</object> </object>
</child> </child>
@@ -130,128 +91,52 @@
</child> </child>
<child> <child>
<object class="GtkListBoxRow" id="primary-button-row"> <object class="GtkListBoxRow" id="primary-button-row">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activatable">False</property> <property name="activatable">False</property>
<child> <child>
<object class="GtkGrid" id="primary-button-grid"> <object class="GtkBox">
<property name="visible">True</property> <property name="margin-start">12</property>
<property name="can_focus">False</property> <property name="margin-end">6</property>
<property name="margin_left">12</property> <property name="margin-top">6</property>
<property name="margin_right">6</property> <property name="margin-bottom">6</property>
<property name="margin_start">12</property> <property name="spacing">12</property>
<property name="margin_end">6</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="column_spacing">16</property>
<child> <child>
<object class="GtkLabel" id="device-name-lable"> <object class="GtkLabel" id="device-name-lable">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
<property name="label" translatable="yes">Add Network</property> <property name="label" translatable="yes">Add Network</property>
<property name="use_underline">True</property>
<property name="xalign">0</property> <property name="xalign">0</property>
</object> </object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkGrid"> <object class="GtkButton" id="localSettings">
<property name="visible">True</property> <property name="icon-name">list-add-symbolic</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkButton" id="localSettings">
<property name="height_request">35</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">list-add-symbolic</property>
</object>
</child>
<style>
<class name="image-button"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<style> <style>
<class name="linked"/> <class name="flat"/>
</style> </style>
</object> </object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child> </child>
</object> </object>
</child> </child>
</object> </object>
</child> </child>
</object> </object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">2</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child> </child>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkSeparator"> <object class="GtkSeparator">
<property name="visible">True</property> <property name="margin-top">6</property>
<property name="can_focus">False</property>
<property name="margin_top">6</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkModelButton"> <object class="GtkButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.about</property> <property name="action_name">app.about</property>
<property name="text" translatable="yes">_About Fragments</property> <property name="label" translatable="yes">About BeamMeUp</property>
<style>
<class name="flat"/>
</style>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child> </child>
</object> </object>
</child> </property>
</object> </object>
</interface> </interface>

View File

@@ -1,429 +0,0 @@
/* teleport-remote-device.c
*
* Copyright 2017 Julian Sparber <julian@sparber.com>
*
* Teleport is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gtk/gtk.h>
#include "teleport-remote-device.h"
#include "teleport-peer.h"
#include "teleport-server.h"
enum {
TARGET_INT32,
TARGET_STRING,
TARGET_URIS,
TARGET_ROOTWIN
};
enum
{
PROP_0,
PROP_PEER,
LAST_PROP
};
/* 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);
struct _TeleportRemoteDevice
{
GtkFrame parent;
GtkWidget *remote_device_row;
GtkWidget *device_name;
GtkWidget *send_btn;
/* data */
Peer *peer;
};
G_DEFINE_TYPE (TeleportRemoteDevice, teleport_remote_device, GTK_TYPE_FRAME)
/*
* GObject overrides
*/
static void
teleport_remote_device_finalize (GObject *object)
{
//TeleportRemoteDevice *self = TELEPORT_REMOTE_DEVICE (object);
G_OBJECT_CLASS (teleport_remote_device_parent_class)->finalize (object);
}
static void
teleport_remote_device_dispose (GObject *object)
{
G_OBJECT_CLASS (teleport_remote_device_parent_class)->dispose (object);
}
static void
teleport_remote_device_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
TeleportRemoteDevice *self = TELEPORT_REMOTE_DEVICE (object);
switch (prop_id)
{
case PROP_PEER:
g_value_set_pointer (value, self->peer);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
teleport_remote_device_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
TeleportRemoteDevice *self = TELEPORT_REMOTE_DEVICE (object);
switch (prop_id)
{
case PROP_PEER:
teleport_remote_device_set_peer (self, g_value_get_pointer (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
teleport_remote_device_class_init (TeleportRemoteDeviceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = teleport_remote_device_dispose;
object_class->finalize = teleport_remote_device_finalize;
object_class->get_property = teleport_remote_device_get_property;
object_class->set_property = teleport_remote_device_set_property;
/**
* TeleportRemoteDevice::peer:
*
* The peer that this row represents, or %NULL.
*/
g_object_class_install_property (object_class,
PROP_PEER,
g_param_spec_pointer ("peer",
"Peer of the row",
"The peer that this row represents",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
/*g_param_spec_object ("peer",
"Task of the row",
"The task that this row represents",
(Peer *),
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
*/
gtk_widget_class_set_template_from_resource (widget_class, "/com/frac_tion/teleport/remote_list.ui");
gtk_widget_class_bind_template_child (widget_class, TeleportRemoteDevice, remote_device_row);
gtk_widget_class_bind_template_child (widget_class, TeleportRemoteDevice, device_name);
gtk_widget_class_bind_template_child (widget_class, TeleportRemoteDevice, send_btn);
}
static void
open_file_picker(GtkButton *btn,
Peer *device) {
GtkFileChooserNative *dialog;
GtkWidget * window;
GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
gint res;
g_print("Open file chooser for submitting a file to %s with Address %s\n", device->name, device->ip);
window = gtk_widget_get_toplevel (GTK_WIDGET (btn));
if (gtk_widget_is_toplevel (window))
{
dialog = gtk_file_chooser_native_new ("Open File",
GTK_WINDOW(window),
action,
("_Open"),
("_Cancel"));
res = gtk_native_dialog_run (GTK_NATIVE_DIALOG (dialog));
if (res == GTK_RESPONSE_ACCEPT)
{
char *filename;
GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog);
filename = gtk_file_chooser_get_filename (chooser);
g_print("Choosen file is %s\n", filename);
g_object_unref (dialog);
teleport_server_add_route (g_compute_checksum_for_string (G_CHECKSUM_SHA256, filename, -1), filename, device->ip);
g_free (filename);
}
else
{
g_object_unref (dialog);
}
}
}
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_remote_device_init (TeleportRemoteDevice *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
/* Make the widget a DnD destination. */
gtk_drag_dest_set
(
GTK_WIDGET (self->remote_device_row), /* widget that will accept a drop */
GTK_DEST_DEFAULT_MOTION /* default actions for dest on DnD */
| GTK_DEST_DEFAULT_HIGHLIGHT,
target_list, /* lists of target to support */
n_targets, /* size of list */
GDK_ACTION_COPY /* what to do with data after dropped */
);
}
GtkWidget*
teleport_remote_device_new (Peer *peer)
{
return g_object_new (TELEPORT_TYPE_REMOTE_DEVICE,
"peer", peer,
NULL);
}
/**
* teleport_remote_device_get_peer:
* @row: a #TeleportRemoteDevice
*
* Retrieves the #Peer that @row manages, or %NULL if none
* is set.
*
* Returns: (transfer none): the internal peer of @row
*/
Peer *
teleport_remote_device_get_peer (GtkWidget *widget)
{
TeleportRemoteDevice *row;
g_return_val_if_fail (TELEPORT_IS_REMOTE_DEVICE (widget), NULL);
row = TELEPORT_REMOTE_DEVICE (widget);
return row->peer;
}
void
teleport_remote_device_set_peer (TeleportRemoteDevice *widget,
Peer *peer)
{
g_return_if_fail (TELEPORT_IS_REMOTE_DEVICE (widget));
widget->peer = peer;
/*
we need to create a peer object instate of a struct to be able to bind it
if (!g_set_object (&widget->peer, peer))
return;
g_object_bind_property (peer,
"name",
widget->device_name,
"label",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
*/
if (peer)
{
gtk_label_set_text(GTK_LABEL (widget->device_name), peer->name);
g_signal_connect (widget->send_btn, "clicked", G_CALLBACK (open_file_picker), peer);
g_signal_connect (widget, "drag-data-received",
G_CALLBACK(drag_data_received_handl), peer);
g_signal_connect (widget, "drag-leave",
G_CALLBACK (drag_leave_handl), peer);
g_signal_connect (widget, "drag-motion",
G_CALLBACK (drag_motion_handl), peer);
g_signal_connect (widget, "drag-drop",
G_CALLBACK (drag_drop_handl), peer);
}
}
/**
* teleport_remote_device_destroy:
* @self: a #TeleportRemoteDevice
*
* Destroy @self after hiding it.
*/
void
teleport_remote_device_destroy (TeleportRemoteDevice *self)
{
}

View File

@@ -1,161 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<!-- interface-requires gtk+ 3.8 --> <requires lib="gtk" version="4.0"/>
<template class="TeleportWindow" parent="GtkApplicationWindow"> <requires lib="libadwaita" version="1.0"/>
<property name="title" translatable="yes">Teleport</property> <template class="TeleportWindow" parent="AdwApplicationWindow">
<property name="title" translatable="yes">BeamMeUp</property>
<property name="default_width">650</property> <property name="default_width">650</property>
<property name="default_height">500</property> <property name="default_height">500</property>
<child> <property name="content">
<object class="GtkAdjustment" id="adjustment1"> <object class="AdwToolbarView">
<property name="lower">-1</property> <child type="top">
<property name="upper">1</property> <object class="AdwHeaderBar" id="header">
</object> <property name="show-end-title-buttons">True</property>
<object class="GtkAdjustment" id="adjustment11"> <child type="end">
<property name="lower">-1</property> <object class="GtkMenuButton" id="gears">
<property name="upper">1</property> <property name="icon-name">emblem-system-symbolic</property>
</object> <property name="tooltip-text" translatable="yes">Settings</property>
<object class="GtkAdjustment" id="adjustment4"> </object>
<property name="lower">100</property> </child>
<property name="upper">1000</property> </object>
<property name="value">400</property> </child>
<property name="step_increment">100</property> <property name="content">
<property name="page_increment">100</property> <object class="GtkScrolledWindow" id="scrolled-window">
</object> <property name="hscrollbar-policy">never</property>
<object class="GtkScrolledWindow" id="scrolled-window"> <property name="child">
<property name="visible">True</property> <object class="AdwClamp">
<property name="can_focus">True</property> <property name="maximum-size">600</property>
<property name="shadow_type">none</property> <property name="child">
<property name="hscrollbar_policy">never</property> <object class="GtkBox" id="general-container">
<child> <property name="margin-top">12</property>
<object class="GtkBox" id="general-container"> <property name="margin-bottom">12</property>
<property name="visible">True</property> <property name="margin-start">24</property>
<property name="can_focus">False</property> <property name="margin-end">24</property>
<property name="halign">center</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="margin_left">24</property>
<property name="margin_right">24</property>
<property name="orientation">vertical</property>
<property name="width-request">500</property>
<child>
<object class="GtkFrame" id="general-frame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="shadow_type">in</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="shadow_type">none</property>
<child type="label">
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="spacing">24</property>
<child> <child>
<object class="GtkLabel" id="this-device-label"> <object class="GtkBox">
<property name="visible">True</property> <property name="orientation">vertical</property>
<property name="can_focus">False</property> <property name="spacing">12</property>
<property name="halign">start</property>
<property name="label" translatable="yes">This device</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">6</property>
<property name="label" translatable="yes">How your device appears to others</property>
<style>
<class name="dim-label"/>
</style>
<attributes>
<attribute name="scale" value="0.9"/>
</attributes>
</object>
</child>
</object>
</child>
<child>
<object class="GtkFrame" id="general-frame-listbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkListBox" id="this-device-listbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
<child> <child>
<object class="GtkListBoxRow" id="this-device-row"> <object class="GtkBox">
<property name="visible">True</property> <property name="orientation">vertical</property>
<property name="can_focus">False</property>
<property name="activatable">false</property>
<child> <child>
<object class="GtkGrid" id="this-device-grid"> <object class="GtkLabel" id="this-device-label">
<property name="visible">True</property> <property name="halign">start</property>
<property name="can_focus">False</property> <property name="label" translatable="yes">This device</property>
<property name="row_spacing">0</property> <style>
<property name="column_spacing">16</property> <class name="heading"/>
<property name="margin">12</property> </style>
<property name="margin_start">16</property> </object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<property name="margin-top">6</property>
<property name="label" translatable="yes">How your device appears to others</property>
<style>
<class name="dim-label"/>
<class name="caption"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBox" id="this-device-listbox">
<property name="selection-mode">none</property>
<style>
<class name="boxed-list"/>
</style>
<child>
<object class="AdwActionRow" id="this_device_row">
<property name="title" translatable="yes">Angela's Thinkpad</property>
<property name="activatable">False</property>
<child> <child>
<object class="GtkLabel" id="this_device_name_label"> <object class="GtkMenuButton" id="this_device_settings_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="expand">True</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Angela's Thinkpad</property>
<property name="use_underline">True</property>
<style>
<class name="device-name"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property> <property name="valign">center</property>
<property name="column_homogeneous">True</property> <property name="icon-name">document-edit-symbolic</property>
<style> <style>
<class name="linked"/> <class name="flat"/>
</style> </style>
<child>
<object class="GtkMenuButton" id="this_device_settings_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="use-popover">True</property>
<property name="height_request">35</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">document-edit-symbolic</property>
</object>
</child>
<style>
<class name="image-button"/>
</style>
</object>
</child>
</object> </object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">2</property>
</packing>
</child> </child>
</object> </object>
</child> </child>
@@ -163,159 +87,109 @@
</child> </child>
</object> </object>
</child> </child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkFrame" id="remote-devices-frame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="shadow_type">none</property>
<property name="label_yalign">0.45</property>
<child type="label">
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child> <child>
<object class="GtkLabel" id="remote-devices-network-label"> <object class="GtkBox">
<property name="visible">True</property> <property name="orientation">vertical</property>
<property name="can_focus">False</property> <property name="spacing">12</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Other devices on the local network</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">6</property>
<property name="label" translatable="yes">Drag and drop files on devices to send them</property>
<style>
<class name="dim-label"/>
</style>
<attributes>
<attribute name="scale" value="0.9"/>
</attributes>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="remote_devices_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<property name="margin_top">6</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkFrame" id="remote_no_avahi">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="shadow_type">in</property>
<child> <child>
<object class="GtkListBox"> <object class="GtkBox">
<property name="visible">True</property> <property name="orientation">vertical</property>
<property name="can_focus">True</property>
<property name="selection_mode">none</property>
<child> <child>
<object class="GtkListBoxRow"> <object class="GtkLabel" id="remote-devices-network-label">
<property name="visible">True</property> <property name="halign">start</property>
<property name="can_focus">False</property> <property name="label" translatable="yes">Other devices on the local network</property>
<property name="activatable">False</property> <style>
<property name="selectable">False</property> <class name="heading"/>
<child> </style>
<object class="GtkAlignment"> </object>
<property name="visible">True</property> </child>
<property name="can_focus">False</property> <child>
<property name="top_padding">50</property> <object class="GtkLabel">
<property name="bottom_padding">50</property> <property name="halign">start</property>
<child> <property name="margin-top">6</property>
<object class="GtkBox"> <property name="label" translatable="yes">Drag and drop files on devices to send them</property>
<property name="visible">True</property> <style>
<property name="spacing">20</property> <class name="dim-label"/>
<property name="orientation">vertical</property> <class name="caption"/>
<child> </style>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="max-width-chars">40</property>
<property name="halign">center</property>
<property name="wrap">True</property>
<property name="justify">center</property>
<property name="label">The Avahi daemon is not running. You can run this command to start it now:</property>
</object>
</child>
<child>
<object class="GtkEntry">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="editable">False</property>
<property name="width-request">206</property>
<property name="text">systemctl start avahi-daemon</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object> </object>
</child> </child>
</object> </object>
</child> </child>
</object>
</child>
<child>
<object class="GtkFrame" id="remote_no_devices">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="shadow_type">in</property>
<child> <child>
<object class="GtkListBox"> <object class="GtkBox" id="remote_devices_box">
<property name="visible">True</property> <property name="spacing">6</property>
<property name="can_focus">True</property> <property name="orientation">vertical</property>
<property name="selection_mode">none</property>
<child> <child>
<object class="GtkListBoxRow"> <object class="GtkFrame" id="remote_no_avahi">
<property name="visible">True</property> <property name="child">
<property name="can_focus">False</property> <object class="GtkListBox">
<property name="activatable">False</property> <property name="selection-mode">none</property>
<property name="selectable">False</property>
<child>
<object class="GtkAlignment">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="top_padding">50</property>
<property name="bottom_padding">50</property>
<child> <child>
<object class="GtkBox"> <object class="GtkListBoxRow">
<property name="visible">True</property> <property name="activatable">False</property>
<property name="spacing">20</property> <property name="selectable">False</property>
<property name="orientation">vertical</property> <property name="child">
<child> <object class="GtkBox">
<object class="GtkLabel"> <property name="margin-top">50</property>
<property name="visible">True</property> <property name="margin-bottom">50</property>
<property name="can_focus">False</property> <property name="spacing">20</property>
<property name="label">Searching for other devices...</property> <property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="max-width-chars">40</property>
<property name="halign">center</property>
<property name="wrap">True</property>
<property name="justify">center</property>
<property name="label" translatable="yes">The Avahi daemon is not running. You can run this command to start it now:</property>
</object>
</child>
<child>
<object class="GtkEntry">
<property name="halign">center</property>
<property name="editable">False</property>
<property name="text">systemctl start avahi-daemon</property>
</object>
</child>
</object> </object>
</child> </property>
<child>
<object class="GtkSpinner">
<property name="visible">True</property>
<property name="active">True</property>
</object>
</child>
</object> </object>
</child> </child>
</object> </object>
</child> </property>
</object>
</child>
<child>
<object class="GtkFrame" id="remote_no_devices">
<property name="child">
<object class="GtkListBox">
<property name="selection-mode">none</property>
<child>
<object class="GtkListBoxRow">
<property name="activatable">False</property>
<property name="selectable">False</property>
<property name="child">
<object class="GtkBox">
<property name="margin-top">50</property>
<property name="margin-bottom">50</property>
<property name="spacing">20</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Searching for other devices...</property>
</object>
</child>
<child>
<object class="GtkSpinner">
<property name="spinning">True</property>
</object>
</child>
</object>
</property>
</object>
</child>
</object>
</property>
</object> </object>
</child> </child>
</object> </object>
@@ -323,56 +197,12 @@
</object> </object>
</child> </child>
</object> </object>
</child> </property>
</object> </object>
</child> </property>
</object> </object>
</child> </property>
</object> </object>
</child> </property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_close_button">True</property>
<property name="decoration_layout">:close</property>
<property name="title" translatable="yes">Teleport</property>
<child>
<object class="GtkSwitch" id="visible-on-network-switch">
<property name="visible">False</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="visible-on-network-label">
<property name="visible">False</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Visible on network</property>
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkMenuButton" id="gears">
<property name="visible">True</property>
<property name="direction">none</property>
<property name="use-popover">True</property>
<style>
<class name="image-button"/>
</style>
</object>
<packing>
<property name="pack-type">end</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</template> </template>
</interface> </interface>

1
subprojects/libhandy Submodule

Submodule subprojects/libhandy added at 1d47eeb88b