Commit 6ed8cc5f authored by Nico Alt's avatar Nico Alt

More revision, solid base, inspiration by other programs

This is a squash merge of `complete-revision`.

Parts of the changes are heavily inspired by GNOME Lollypop.
parent 1b912a6a
......@@ -641,7 +641,7 @@ the exclusion of warranty; and each file should have at least 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/>.
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper
mail.
......@@ -657,4 +657,4 @@ the specific requirements.
You should also get your employer (if you work as a programmer) or
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. For more information on this, and how to apply and follow
the GNU AGPL, see <http://www.gnu.org/licenses/>.
the GNU AGPL, see <https://www.gnu.org/licenses/>.
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>app.briar.gtk.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<metadata_license>CC-BY-4.0</metadata_license>
<project_license>GPL-3.0-or-later</project_license>
<description>
</description>
......
[Desktop Entry]
Name=Briar GTK
Name=Briar
Exec=briar-gtk
Terminal=false
Type=Application
......
......@@ -44,8 +44,8 @@ pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.proje
gnome = import('gnome')
gnome.compile_resources('briar-gtk',
'ui/gresource.xml',
'ui/app.briar.gtk.gresource.xml',
gresource_bundle: true,
install: true,
install_dir: pkgdatadir,
)
\ No newline at end of file
)
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/app/briar/gtk">
<file preprocess="xml-stripblanks" compressed="true">ui/setup.ui</file>
<file compressed="true">ui/application.css</file>
<file compressed="true" preprocess="xml-stripblanks">ui/login.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/setup.ui</file>
</gresource>
</gresources>
.test {
color: red;
}
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkGrid" id="login">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="margin_left">18</property>
<property name="margin_right">18</property>
<property name="margin_top">18</property>
<property name="margin_bottom">18</property>
<child>
<object class="GtkGrid" id="password_grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="password_label">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Password</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="password_entry">
<property name="visible">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="login_button">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Sign in</property>
<signal name="clicked" handler="on_login_pressed"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkGrid" id="setup">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="margin_left">18</property>
<property name="margin_right">18</property>
<property name="margin_top">18</property>
<property name="margin_bottom">18</property>
<child>
<object class="GtkGrid" id="username_grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="username_label">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Nickname</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="username_entry">
<property name="visible">True</property>
<property name="placeholder_text" translatable="yes">Choose your nickname</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="username_next">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Next</property>
<signal name="clicked" handler="on_username_button_clicked"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkGrid" id="password_grid">
<property name="visible">False</property>
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="password_label">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Password</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="password_entry">
<property name="visible">True</property>
<property name="placeholder_text" translatable="yes">Choose your password</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="password_confirm_entry">
<property name="visible">True</property>
<property name="placeholder_text" translatable="yes">Confirm your password</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="password_next">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Next</property>
<signal name="clicked" handler="on_password_button_clicked"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
......@@ -6,8 +6,8 @@ project(
i18n = import('i18n')
subdir('res')
subdir('data')
subdir('src')
subdir('po')
meson.add_install_script('build-aux/meson/postinstall.py')
\ No newline at end of file
meson.add_install_script('src/meson_post_install.py')
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-03-24 23:15+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../data/ui/login.ui:23 ../data/ui/setup.ui:64
msgid "Password"
msgstr ""
#: ../data/ui/login.ui:43
msgid "Sign in"
msgstr ""
#: ../data/ui/setup.ui:23
msgid "Nickname"
msgstr ""
#: ../data/ui/setup.ui:33
msgid "Choose your nickname"
msgstr ""
#: ../data/ui/setup.ui:44 ../data/ui/setup.ui:95
msgid "Next"
msgstr ""
#: ../data/ui/setup.ui:74
msgid "Choose your password"
msgstr ""
#: ../data/ui/setup.ui:84
msgid "Confirm your password"
msgstr ""
#: ../data/ui/login.ui:23 ../data/ui/setup.ui:64
msgid "Password"
msgstr "Passwort"
#: ../data/ui/login.ui:43
msgid "Sign in"
msgstr ""
#: ../data/ui/setup.ui:23
msgid "Nickname"
msgstr "Nutzername"
#: ../data/ui/setup.ui:33
msgid "Choose your nickname"
msgstr ""
#: ../data/ui/setup.ui:44 ../data/ui/setup.ui:95
msgid "Next"
msgstr ""
#: ../data/ui/setup.ui:74
msgid "Choose your password"
msgstr ""
#: ../data/ui/setup.ui:84
msgid "Confirm your password"
msgstr ""
#: ../data/ui/login.ui:23 ../data/ui/setup.ui:64
msgid "Password"
msgstr ""
#: ../data/ui/login.ui:43
msgid "Sign in"
msgstr ""
#: ../data/ui/setup.ui:23
msgid "Nickname"
msgstr ""
#: ../data/ui/setup.ui:33
msgid "Choose your nickname"
msgstr ""
#: ../data/ui/setup.ui:44 ../data/ui/setup.ui:95
msgid "Next"
msgstr "Seguir"
#: ../data/ui/setup.ui:74
msgid "Choose your password"
msgstr ""
#: ../data/ui/setup.ui:84
msgid "Confirm your password"
msgstr ""
i18n.gettext('briar-gtk', preset: 'glib')
\ No newline at end of file
i18n.gettext('briar-gtk', preset: 'glib')
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="BriarGtkWindow" parent="GtkApplicationWindow">
<property name="default-width">600</property>
<property name="default-height">300</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header_bar">
<property name="visible">True</property>
<property name="show-close-button">True</property>
<property name="title">Welcome to Briar</property>
</object>
</child>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="margin_left">18</property>
<property name="margin_right">18</property>
<property name="margin_top">18</property>
<property name="margin_bottom">18</property>
<child>
<object class="GtkGrid" id="username_grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="username_label">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Nickname</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="username_entry">
<property name="visible">True</property>
<property name="placeholder_text" translatable="yes">Choose your nickname</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="username_next">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Next</property>
<signal name="clicked" handler="on_username_button_clicked"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkGrid" id="password_grid">
<property name="visible">False</property>
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="password_label">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Password</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="password_entry">
<property name="visible">True</property>
<property name="placeholder_text" translatable="yes">Choose your password</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="password_confirm_entry">
<property name="visible">True</property>
<property name="placeholder_text" translatable="yes">Confirm your password</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="password_next">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Next</property>
<signal name="clicked" handler="on_password_button_clicked"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>
#!@PYTHON@
# briar-gtk.in
#
# Copyright 2019 Nico Alt
#
# This program is free software: you can redistribute it and/or modify
......@@ -15,27 +13,34 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# Initial version based on GNOME Lollypop
# https://gitlab.gnome.org/World/lollypop/blob/1.0.2/lollypop.in
import gettext
import locale
import os
import sys
import signal
import gettext
import sys
VERSION = '@VERSION@'
pkgdatadir = '@pkgdatadir@'
localedir = '@localedir@'
sys.path.insert(1, pkgdatadir)
signal.signal(signal.SIGINT, signal.SIG_DFL)
gettext.install('briar-gtk', localedir)
if __name__ == '__main__':
locale.bindtextdomain('briar-gtk', localedir)
locale.textdomain('briar-gtk')
gettext.bindtextdomain('briar-gtk', localedir)
gettext.textdomain('briar-gtk')
import gi
from gi.repository import Gio
resource = Gio.Resource.load(os.path.join(pkgdatadir, 'briar-gtk.gresource'))
resource._register()
from briar_gtk import main
sys.exit(main.main(VERSION))
from briar.gtk.application import Application
sys.exit(Application("@VERSION@").run(sys.argv))
# window.py
#
# Copyright 2019 Nico Alt
# Copyright (c) 2019 Nico Alt
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -13,31 +11,32 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from gi.repository import Gtk
from .gi_composites import GtkTemplate
from subprocess import Popen, PIPE
@GtkTemplate(ui='/app/briar/gtk/ui/setup.ui')
class BriarSetupWindow(Gtk.ApplicationWindow):
__gtype_name__ = 'BriarGtkWindow'
class Api:
username_grid = GtkTemplate.Child()
username_entry = GtkTemplate.Child()
def __init__(self, headless_jar, debug=False):
self.headless_jar = headless_jar
password_grid = GtkTemplate.Child()
password_entry = GtkTemplate.Child()
password_confirm_entry = GtkTemplate.Child()
def has_account(self):
from pathlib import Path
home = str(Path.home())
from os.path import isdir, join
return isdir(join(home, ".briar", "db"))
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.init_template()
def login(self, password):
p = Popen(['java', '-jar', self.headless_jar, '-v'],
stdin=PIPE, universal_newlines=True)
p.communicate(password + '\n')
def on_username_button_clicked(self, button):
self.username_grid.set_visible(False)
self.password_grid.set_visible(True)
self.username = self.username_entry.get_text()
def register(self, credentials):
p = Popen(['java', '-jar', self.headless_jar, '-v'],
stdin=PIPE, universal_newlines=True)
p.communicate(credentials[0] + '\n' + credentials[1] +
'\n' + credentials[1] + '\n')
def on_password_button_clicked(self, button):
self.password = self.password_entry.get_text()
def stop(self):
pass
......@@ -11,7 +11,7 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# Originally coming from
# https://code.briarproject.org/grote/briar-cli-python-demo/blob/master/briar-cli.py
......
# Copyright (c) 2019 Nico Alt
# Copyright (c) 2014-2018 Cedric Bellegarde <cedric.bellegarde@adishatz.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# Initial version based on GNOME Lollypop
# https://gitlab.gnome.org/World/lollypop/blob/1.0.2/lollypop/application.py
from briar.api.api import Api
from briar.gtk.window import Window
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gdk, Gio, GLib, Gtk
class Application(Gtk.Application):
def __init__(self, version):
super().__init__(application_id='app.briar.gtk',
flags=Gio.ApplicationFlags.FLAGS_NONE)
self.__version = version
self.set_property("register-session", True)
self.window = None
self.debug = True # TODO: Change this in production
GLib.set_application_name("Briar")
GLib.set_prgname("briar-gtk")
self.api = Api('/app/briar/briar-headless.jar', self.debug)
self.connect("activate", self.__on_activate)
self.register(None)
def init(self):
cssProviderFile = Gio.File.new_for_uri(
"resource:///app/briar/gtk/ui/application.css")
cssProvider = Gtk.CssProvider()
cssProvider.load_from_file(cssProviderFile)
screen = Gdk.Screen.get_default()
styleContext = Gtk.StyleContext()
styleContext.add_provider_for_screen(screen, cssProvider,
Gtk.STYLE_PROVIDER_PRIORITY_USER)
def do_startup(self):
Gtk.Application.do_startup(self)
if self.window is None:
self.init()
self.window = Window()
self.window.show()
def quit(self):
self.api.stop()
self.window.hide()
Gio.Application.quit(self)
def __on_activate(self, application):
pass
# Copyright (c) 2019 Nico Alt
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from briar.gtk.define import App
from briar.gtk.logger import Logger
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class Container(Gtk.Overlay):
def __init__(self):
Gtk.Overlay.__init__(self)
self.__setup_view()
def __setup_view(self):
Logger.debug("Api has account: %s", App().api.has_account())
self.builder = Gtk.Builder()
if not App().api.has_account():
self.builder.add_from_resource("/app/briar/gtk/ui/setup.ui")
self.add(self.builder.get_object("setup"))
else:
self.builder.add_from_resource("/app/briar/gtk/ui/login.ui")
self.add(self.builder.get_object("login"))
self.builder.connect_signals(self)
def on_username_button_clicked(self, button):
self.builder.get_object("username_grid").set_visible(False)
self.builder.get_object("password_grid").set_visible(True)
self.username = self.builder.get_object("username_entry").get_text()
def on_password_button_clicked(self, button):
password = self.builder.get_object("password_entry").get_text()
App().api.register((self.username, password)) # TODO: callback
def on_login_pressed(self, button):
password = self.builder.get_object("password_entry").get_text()
App().api.login(password) # TODO: callback
# main.py
#
# Copyright 2019 Nico Alt
# Copyright (c) 2019 Nico Alt
# Copyright (c) 2014-2018 Cedric Bellegarde <cedric.bellegarde@adishatz.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -13,30 +12,11 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
import gi