Description: <short summary of the patch>
 TODO: Put a short summary on the line above and replace this paragraph
 with a longer explanation of this change. Complete the meta-information
 with other relevant fields (see below for details). To make it easier, the
 information below has been extracted from the changelog. Adjust it or drop
 it.
 .
 nuntius-linux (0.2.0-5) unstable; urgency=medium
 .
   * Address footprint accuracy in package description (closes: #827439)
   * Secure copyright format URL
   * Hotwire appdatadir per lintian whining
Author: Barak A. Pearlmutter <bap@debian.org>
Bug-Debian: https://bugs.debian.org/827439

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: 2018-09-12

--- /dev/null
+++ nuntius-linux-0.2.0/.tx/config
@@ -0,0 +1,8 @@
+[main]
+host = https://www.transifex.com
+type = PO
+
+[nuntius-linux.strings]
+file_filter = po/<lang>.po
+source_file = po/nuntius.pot
+source_lang = en
\ No newline at end of file
--- nuntius-linux-0.2.0.orig/Makefile.am
+++ nuntius-linux-0.2.0/Makefile.am
@@ -3,16 +3,14 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
 SUBDIRS = po
 
 # desktop file
-# (we can't use INTLTOOL_DESKTOP_RULE here due to lp#605826)
-%.desktop: %.desktop.in
-	$(AM_V_GEN) $(MKDIR_P) $(dir $@); LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
-applicationsdir = $(datadir)/applications
-applications_DATA = data/org.holylobster.nuntius.desktop
-dist_noinst_DATA = data/org.holylobster.nuntius.desktop.in
+desktopdir = $(datadir)/applications
+desktop_in_files = data/org.holylobster.nuntius.desktop.in
+desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
+@INTLTOOL_DESKTOP_RULE@
 
 # autostart file
 autostartdir = $(sysconfdir)/xdg/autostart
-autostart_DATA = $(applications_DATA)
+autostart_DATA = $(desktop_DATA)
 
 # appdata file
 appdatadir = $(datadir)/appdata
@@ -23,11 +21,15 @@ appdata_in_files = data/org.holylobster.
 # DBus service file
 servicedir = $(datadir)/dbus-1/services
 service_DATA = data/org.holylobster.nuntius.service
-dist_noinst_DATA += data/org.holylobster.nuntius.service.in
+dist_noinst_DATA = data/org.holylobster.nuntius.service.in
 
 data/org.holylobster.nuntius.service: data/org.holylobster.nuntius.service.in Makefile
 	$(AM_V_GEN) $(MKDIR_P) $(dir $@); sed -e "s|\@bindir\@|$(bindir)|" $< > $@
 
+# gsettings
+gsettings_SCHEMAS = data/org.holylobster.nuntius.gschema.xml
+@GSETTINGS_RULES@
+
 data_icons_public_icons = \
 	hicolor_apps_16x16_nuntius.png \
 	hicolor_apps_22x22_nuntius.png \
@@ -60,7 +62,8 @@ data-icons-uninstall-icons:
 AM_CPPFLAGS = \
 	-DGETTEXT_PACKAGE=\""$(GETTEXT_PACKAGE)"\" \
 	-DGNOMELOCALEDIR=\""$(localedir)"\" \
-	-DDATADIR=\""$(datadir)"\"
+	-DDATADIR=\""$(datadir)"\" \
+	-DTOOLSDIR=\""$(libexecdir)/$(PACKAGE)"\"
 
 AM_VALAFLAGS = \
 	--target-glib=2.40 \
@@ -71,7 +74,7 @@ AM_VALAFLAGS = \
 	--pkg posix \
 	--gresources  $(top_srcdir)/src/resources/nuntius.gresource.xml
 
-bin_PROGRAMS = nuntius
+bin_PROGRAMS = nuntius qrtest
 
 BUILT_SOURCES = \
 	src/resources.c
@@ -80,6 +83,9 @@ resource_files = $(shell $(GLIB_COMPILE_
 src/resources.c: $(top_srcdir)/src/resources/nuntius.gresource.xml $(resource_files)
 	$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(top_srcdir)/src/resources --generate-source $<
 
+toolsdir = $(libexecdir)/$(PACKAGE)
+tools_SCRIPTS = createcert.sh
+
 VALA_SOURCES = \
 	src/application.vala \
 	src/appslistpanel.vala \
@@ -87,14 +93,19 @@ VALA_SOURCES = \
 	src/connection.vala \
 	src/notification.vala \
 	src/notificationapp.vala \
+	src/notificationcounter.vala \
 	src/notificationsview.vala \
+	src/qrimage.vala \
+	src/smsnotification.vala \
+	src/testview.vala \
 	src/window.vala \
 	src/main.vala
 
 nuntius_SOURCES = \
 	$(BUILT_SOURCES) \
 	$(VALA_SOURCES) \
-	src/config.vapi
+	src/config.vapi \
+	src/qrencode.vapi
 
 AM_CFLAGS = \
 	$(NUNTIUS_CFLAGS) \
@@ -107,21 +118,33 @@ nuntius_LDADD = \
 	$(NUNTIUS_LIBS) \
 	-lm
 
+qrtest_SOURCES = \
+	tests/qrtest.vala \
+	src/qrimage.vala \
+	src/qrencode.vapi
+
+qrtest_LDFLAGS = -export-dynamic
+qrtest_LDADD = \
+	$(NUNTIUS_LIBS) \
+	-lm
+
+check-local: $(desktop_DATA)
+	$(DESKTOP_FILE_VALIDATE) $(desktop_DATA)
+
 install-data-local: data-icons-install-icons
 
 uninstall-local: data-icons-uninstall-icons
 
 EXTRA_DIST = \
-	$(applications_DATA) \
 	$(appdata_in_files) \
+	$(desktop_in_files) \
 	$(resource_files) \
-	data/org.holylobster.nuntius.appdata.xml \
 	src/resources/nuntius.gresource.xml \
 	$(addprefix data/icons/,$(data_icons_public_icons))
 
 CLEANFILES = \
 	$(appdata_DATA) \
-	$(applications_DATA) \
+	$(desktop_DATA) \
 	$(service_DATA)
 
 MAINTAINERCLEANFILES = \
--- nuntius-linux-0.2.0.orig/README.md
+++ nuntius-linux-0.2.0/README.md
@@ -1,37 +1,40 @@
 Nuntius
 ===================================
 
-##Introduction
+## Introduction
 Nuntius delivers notifications from your phone or tablet to your computer over Bluetooth.
 
 Nuntius is an Open Source project from HolyLobster.
 
 To use Nuntius you will need to install a companion tool on your phone or tablet and pair it via Bluetooth.
+You will also need to restart your session to auto-start nuntius.
 
 For more information on the project and the companion tools to install on the computer check https://github.com/holylobster
 
-##The Icon
+## The Icon
 You may have questions on the icon. Nice shot.
 In fact most of the Nuntius development time has been spent on the icon design concept.
 If you have suggestions on how to improve it we are very open... but... we think it is hardly possible to do better than this.
 
-##Packages
+## Packages
 You can install Nuntius from:
 
- * Fedora: yum install nuntius
+ * Fedora: `dnf install nuntius` (use `yum` instead of `dnf` on Fedora <= 21)
  * [Arch Linux (AUR)](https://aur.archlinux.org/packages/nuntius/)
+ * [Debian](https://packages.debian.org/nuntius) and Debian derivatives: `sudo apt install nuntius`
 
 You will need to install Nuntius also on your phone or tablet.
 
-At the moment Nuntius is available for Android, check here
+At the moment Nuntius is available for Android.
 
- * https://github.com/holylobster/nuntius-android
+ * Nuntius-Android [Development Repository](https://github.com/holylobster/nuntius-android)
+ * Nuntius for Android [on Google Play](https://play.google.com/store/apps/details?id=org.holylobster.nuntius)
 
-##Getting in touch
+## Getting in touch
 We have an IRC channel: #nuntius on the irc.gnome.org server.
 Feel free to join and talk to us! Note that the channel is new and there are not many people (yet!) so be patient and hang around if you do not receive a reply immediately.
 
-##Some tips to debug
+## Some tips to debug
  * Launch the bluetooth dameon as "sudo  /usr/libexec/bluetooth/bluetoothd -d -n"
  * Using bluetoothctl
    * I had to set "agent on", "default-agent" and "trust 98:D6:F7:73:03:F1"
@@ -39,4 +42,3 @@ Feel free to join and talk to us! Note t
  * /var/log/messages gives also some information about bluetoothd if you do not run it directly
  * run "sudo btmon > btmon.log" to get information from the devices that try to connect to the computer
    * This is very useful to see to which uuid is trying to connect and what kind of errors it gets
-
--- nuntius-linux-0.2.0.orig/autogen.sh
+++ nuntius-linux-0.2.0/autogen.sh
@@ -1,28 +1,6 @@
 #!/bin/sh
 # Run this to generate all the initial makefiles, etc.
+set -e
 
-test -n "$srcdir" || srcdir=`dirname "$0"`
-test -n "$srcdir" || srcdir=.
-
-OLDDIR=`pwd`
-cd $srcdir
-
-AUTORECONF=`which autoreconf`
-if test -z $AUTORECONF; then
-    echo "*** No autoreconf found, please install it ***"
-    exit 1
-fi
-
-INTLTOOLIZE=`which intltoolize`
-if test -z $INTLTOOLIZE; then
-    echo "*** No intltoolize found, please install the intltool package ***"
-    exit 1
-fi
-
-git submodule update --init --recursive
-
-autopoint --force || exit $?
-AUTOPOINT='intltoolize --automake --copy' autoreconf --force --install --verbose
-
-cd $OLDDIR
-test -n "$NOCONFIGURE" || "$srcdir/configure" "$@"
+autopoint --force
+AUTOPOINT='intltoolize --automake --copy' autoreconf --force --install --verbose $@
--- nuntius-linux-0.2.0.orig/configure.ac
+++ nuntius-linux-0.2.0/configure.ac
@@ -1,6 +1,6 @@
-AC_PREREQ(2.63)
+AC_PREREQ([2.69])
 
-AC_INIT([nuntius], [0.2.0])
+AC_INIT([nuntius],[0.2.0])
 
 dnl http://people.gnome.org/~walters/docs/build-api.txt
 dnl We don't support separate builddir when building from git
@@ -10,7 +10,7 @@ AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_HEADERS(config.h)
 AC_CONFIG_SRCDIR(src/main.vala)
 
-AM_INIT_AUTOMAKE([1.11 tar-ustar dist-xz no-dist-gzip foreign])
+AM_INIT_AUTOMAKE([1.11 tar-ustar dist-xz no-dist-gzip foreign subdir-objects -Wall])
 m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
 
 IT_PROG_INTLTOOL([0.50.1])
@@ -25,20 +25,25 @@ AC_PROG_CC_STDC
 AC_PROG_INSTALL
 AM_PROG_VALAC([0.23.3])
 
+AC_PATH_PROG(DESKTOP_FILE_VALIDATE, desktop-file-validate, /bin/true)
 AC_PATH_PROG(GLIB_COMPILE_RESOURCES, glib-compile-resources)
 
+GLIB_GSETTINGS
+
 PKG_PROG_PKG_CONFIG
 
 PKG_CHECK_MODULES(NUNTIUS, [
     gio-2.0 >= 2.40
     gio-unix-2.0 >= 2.38
     glib-2.0 >= 2.38
-    gtk+-3.0 >= 3.10.0
+    gtk+-3.0 >= 3.14.0
     json-glib-1.0 >= 0.16.2
+    libqrencode >= 3.1.0
 ])
 
 AC_CONFIG_FILES([
     Makefile
+    data/org.holylobster.nuntius.gschema.xml
     po/Makefile.in
 ])
 
--- /dev/null
+++ nuntius-linux-0.2.0/createcert.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+function try {
+    "$@"
+    local status=$?
+    if [ $status -ne 0 ]; then
+        echo -e "\nError with $1" >&2
+        exit $?
+    fi
+    return $status
+}
+
+function create_cert() {
+    if [[ ! -f $HOME/.config/nuntius/nuntius.pem || ! -f $HOME/.config/nuntius/nuntius.key ]]; then
+        echo "Creating cert..."
+        cd $HOME/.config/nuntius
+        try openssl genrsa -out nuntius.key 2048
+        try openssl req -new -key nuntius.key -out nuntius.csr -subj "/O=Holylobster/OU=Nuntius"
+        try openssl x509 -req -days 3650 -in nuntius.csr -signkey nuntius.key -out nuntius.crt
+        try openssl x509 -in nuntius.crt -out nuntius.pem
+        exit $?
+    else
+        echo "Certificate already exist..."
+        exit 0
+    fi
+}
+
+if [[ ! -d $HOME/.config/nuntius ]]; then
+    echo "Creating nuntius config directory..."
+    mkdir -p $HOME/.config/nuntius
+fi
+
+create_cert
+
+# ex:set ts=4 et:
--- /dev/null
+++ nuntius-linux-0.2.0/data/org.holylobster.nuntius.gschema.xml.in
@@ -0,0 +1,21 @@
+<schemalist gettext-domain="@GETTEXT_PACKAGE@">
+  <schema id="org.holylobster.nuntius.state" path="/org/holylobster/nuntius/state/">
+    <child schema="org.holylobster.nuntius.state.window" name="window"/>
+  </schema>
+  <schema id="org.holylobster.nuntius.state.window" path="/org/holylobster/nuntius/state/window/">
+    <key type="i" name="state">
+      <default>0</default>
+      <summary>Window state</summary>
+      <description>
+        State of the window, e.g. maximized.
+      </description>
+    </key>
+    <key type="(ii)" name="size">
+      <default>(870, 690)</default>
+      <summary>Window width and height</summary>
+      <description>
+        Width and height of the window.
+      </description>
+    </key>
+  </schema>
+</schemalist>
--- nuntius-linux-0.2.0.orig/po/LINGUAS
+++ nuntius-linux-0.2.0/po/LINGUAS
@@ -1,4 +1,3 @@
-#
 # nuntius translations
 # please keep this list sorted alphabetically
 de
--- nuntius-linux-0.2.0.orig/po/POTFILES.in
+++ nuntius-linux-0.2.0/po/POTFILES.in
@@ -1,4 +1,11 @@
+# List of source files containing translatable strings.
+# Please keep this file sorted alphabetically.
 data/org.holylobster.nuntius.appdata.xml.in
 data/org.holylobster.nuntius.desktop.in
+[type: gettext/gsettings]data/org.holylobster.nuntius.gschema.xml.in
+src/application.vala
+src/appslist.vala
+[type: gettext/glade]src/resources/gtk/menus.ui
 [type: gettext/glade]src/resources/ui/appslistpanel.ui
 [type: gettext/glade]src/resources/ui/window.ui
+src/smsnotification.vala
--- /dev/null
+++ nuntius-linux-0.2.0/po/POTFILES.skip
@@ -0,0 +1,5 @@
+# List of source files that should *not* be translated.
+# Please keep this file sorted alphabetically.
+src/application.c
+src/appslist.c
+src/smsnotification.c
--- nuntius-linux-0.2.0.orig/po/de.po
+++ nuntius-linux-0.2.0/po/de.po
@@ -5,38 +5,113 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: \n"
+"Project-Id-Version: nuntius-linux\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-03-11 11:24+0100\n"
+"POT-Creation-Date: 2016-07-15 17:00+0200\n"
 "PO-Revision-Date: 2015-03-11 18:29+0100\n"
 "Last-Translator: Raphael Guttenberger <raphaelguttenberger@gmail.com>\n"
 "Language-Team: \n"
 "Language: de\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
 #: ../data/org.holylobster.nuntius.appdata.xml.in.h:1
 msgid ""
 "Nuntius delivers notifications from your phone or tablet to your computer "
 "over Bluetooth."
 msgstr ""
-"Nuntius sendet Benachrichtigungen von deinem Handy oder Tablet direkt an deinen Computer"
-"über Bluetooth."
+"Nuntius sendet Benachrichtigungen von deinem Handy oder Tablet direkt an "
+"deinen Computer über Bluetooth."
+
 #: ../data/org.holylobster.nuntius.appdata.xml.in.h:2
 msgid ""
 "To use Nuntius you will need to install a companion tool on your phone or "
 "tablet and pair it via Bluetooth."
 msgstr ""
-"Um Nuntius zu benutzen, musst du ein Hilfstool auf deinem Handy oder"
-"Tablet installieren und es über Bluetooth mit deinem PC verbinden."
+"Um Nuntius zu benutzen, musst du ein Hilfstool auf deinem Handy oder Tablet "
+"installieren und es über Bluetooth mit deinem PC verbinden."
+
 #: ../data/org.holylobster.nuntius.desktop.in.h:1
 msgid ""
 "Deliver notifications from your phone or tablet to your computer over "
 "Bluetooth"
 msgstr ""
-"Sende Benachrichtigungen von deinem Handy oder Tablet an deinen PC über"
+"Sende Benachrichtigungen von deinem Handy oder Tablet an deinen PC über "
 "Bluetooth"
+
 #: ../data/org.holylobster.nuntius.desktop.in.h:2
 msgid "notifications;"
+msgstr "Benachrichtigungen;"
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:1
+msgid "Window state"
+msgstr ""
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:2
+msgid "State of the window, e.g. maximized."
+msgstr ""
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:3
+msgid "Window width and height"
+msgstr ""
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:4
+msgid "Width and height of the window."
+msgstr ""
+
+#: ../src/application.vala:144
+msgid "Connect to a specific server"
+msgstr ""
+
+#: ../src/application.vala:297
+msgid "Certificate Fingerprint"
+msgstr ""
+
+#: ../src/application.vala:300
+msgid "_OK"
+msgstr ""
+
+#: ../src/application.vala:469 ../src/resources/ui/window.ui.h:1
+msgid "Nuntius"
+msgstr ""
+
+#: ../src/application.vala:472
+msgid ""
+"Deliver notifications from your phone or tablet to your computer over "
+"Bluetooth."
+msgstr ""
+"Sende Benachrichtigungen von deinem Handy oder Tablet an deinen PC über "
+"Bluetooth."
+
+#: ../src/application.vala:477
+msgid "translator-credits"
+msgstr "Raphael Guttenberger <raphaelguttenberger@gmail.com>, 2015"
+
+#: ../src/appslist.vala:75
+msgid "Blacklist this application"
+msgstr ""
+
+#. namespace Nuntius
+#. ex:set ts=4 et:
+#: ../src/resources/gtk/menus.ui.h:1
+msgid "Show _QR Code"
+msgstr ""
+
+#: ../src/resources/gtk/menus.ui.h:2
+msgid "_About"
+msgstr ""
+
+#: ../src/resources/ui/appslistpanel.ui.h:1
+msgid "Type to search"
+msgstr ""
+
+#: ../src/resources/ui/window.ui.h:2
+msgid "All Applications"
+msgstr ""
+
+#. FIXME: just a test message until we have UI to type the reply
+#: ../src/smsnotification.vala:63
+msgid "Reply"
 msgstr ""
-"Benachrichtigungen"
--- nuntius-linux-0.2.0.orig/po/es.po
+++ nuntius-linux-0.2.0/po/es.po
@@ -1,23 +1,21 @@
 # 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.
 # Daniel Mustieles <daniel.mustieles@gmail.com>, 2015.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
+"Project-Id-Version: nuntius-linux\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-03-11 11:24+0100\n"
+"POT-Creation-Date: 2016-07-15 17:00+0200\n"
 "PO-Revision-Date: 2015-03-12 11:41+0100\n"
 "Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
 "Language-Team: Español; Castellano <gnome-es-list@gnome.org>\n"
-"Language: \n"
+"Language: es\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Gtranslator 2.91.6\n"
 
 #: ../data/org.holylobster.nuntius.appdata.xml.in.h:1
 msgid ""
@@ -46,3 +44,74 @@ msgstr ""
 #: ../data/org.holylobster.nuntius.desktop.in.h:2
 msgid "notifications;"
 msgstr "notificaciones;"
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:1
+msgid "Window state"
+msgstr ""
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:2
+msgid "State of the window, e.g. maximized."
+msgstr ""
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:3
+msgid "Window width and height"
+msgstr ""
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:4
+msgid "Width and height of the window."
+msgstr ""
+
+#: ../src/application.vala:144
+msgid "Connect to a specific server"
+msgstr ""
+
+#: ../src/application.vala:297
+msgid "Certificate Fingerprint"
+msgstr ""
+
+#: ../src/application.vala:300
+msgid "_OK"
+msgstr ""
+
+#: ../src/application.vala:469 ../src/resources/ui/window.ui.h:1
+msgid "Nuntius"
+msgstr ""
+
+#: ../src/application.vala:472
+msgid ""
+"Deliver notifications from your phone or tablet to your computer over "
+"Bluetooth."
+msgstr ""
+"Enviar notificaciones desde su teléfono o tableta a su equipo mediante "
+"Bluetooth."
+
+#: ../src/application.vala:477
+msgid "translator-credits"
+msgstr "Daniel Mustieles <daniel.mustieles@gmail.com>, 2015"
+
+#: ../src/appslist.vala:75
+msgid "Blacklist this application"
+msgstr ""
+
+#. namespace Nuntius
+#. ex:set ts=4 et:
+#: ../src/resources/gtk/menus.ui.h:1
+msgid "Show _QR Code"
+msgstr ""
+
+#: ../src/resources/gtk/menus.ui.h:2
+msgid "_About"
+msgstr ""
+
+#: ../src/resources/ui/appslistpanel.ui.h:1
+msgid "Type to search"
+msgstr ""
+
+#: ../src/resources/ui/window.ui.h:2
+msgid "All Applications"
+msgstr ""
+
+#. FIXME: just a test message until we have UI to type the reply
+#: ../src/smsnotification.vala:63
+msgid "Reply"
+msgstr ""
--- nuntius-linux-0.2.0.orig/po/pl.po
+++ nuntius-linux-0.2.0/po/pl.po
@@ -1,34 +1,30 @@
-# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-# Aviary.pl
-# Jeśli masz jakiekolwiek uwagi odnoszące się do tłumaczenia lub chcesz
-# pomóc w jego rozwijaniu i pielęgnowaniu, napisz do nas:
-# gnomepl@aviary.pl
-# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-# Piotr Drąg <piotrdrag@gmail.com>, 2015.
-# Aviary.pl <gnomepl@aviary.pl>, 2015.
+# Polish translation for nuntius-linux.
+# Copyright © 2015-2016 the nuntius-linux authors.
+# This file is distributed under the same license as the nuntius-linux package.
+# Piotr Drąg <piotrdrag@gmail.com>, 2015-2016.
+# Aviary.pl <community-poland@mozilla.org>, 2015-2016.
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: nuntius-linux\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-03-10 20:10+0100\n"
-"PO-Revision-Date: 2015-03-10 20:11+0100\n"
+"POT-Creation-Date: 2016-08-29 18:54+0200\n"
+"PO-Revision-Date: 2016-08-29 18:55+0200\n"
 "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
-"Language-Team: Polish <gnomepl@aviary.pl>\n"
+"Language-Team: Polish <community-poland@mozilla.org>\n"
 "Language: pl\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
 "|| n%100>=20) ? 1 : 2);\n"
-"X-Poedit-Language: Polish\n"
-"X-Poedit-Country: Poland\n"
 
 #: ../data/org.holylobster.nuntius.appdata.xml.in.h:1
 msgid ""
 "Nuntius delivers notifications from your phone or tablet to your computer "
 "over Bluetooth."
 msgstr ""
-"Nuntius wyświetla powiadomienia z telefonu lub tabletu na komputerze za "
+"Nuntius wyświetla powiadomienia z telefonu lub tabletu na komputerze za "
 "pomocą Bluetooth."
 
 #: ../data/org.holylobster.nuntius.appdata.xml.in.h:2
@@ -37,14 +33,14 @@ msgid ""
 "tablet and pair it via Bluetooth."
 msgstr ""
 "Aby użyć programu Nuntius, należy zainstalować uzupełniające narzędzie na "
-"telefonie lub tablecie i połączyć je z komputerem za pomocą Bluetooth."
+"telefonie lub tablecie i połączyć je z komputerem za pomocą Bluetooth."
 
 #: ../data/org.holylobster.nuntius.desktop.in.h:1
 msgid ""
 "Deliver notifications from your phone or tablet to your computer over "
 "Bluetooth"
 msgstr ""
-"Wyświetlanie powiadomień z telefonu lub tabletu na komputerze za pomocą "
+"Wyświetlanie powiadomień z telefonu lub tabletu na komputerze za pomocą "
 "Bluetooth"
 
 #: ../data/org.holylobster.nuntius.desktop.in.h:2
@@ -52,3 +48,76 @@ msgid "notifications;"
 msgstr ""
 "powiadomienia;powiadamianie;notyfikacje;wiadomości;komunikaty;telefon;tablet;"
 "smartfon;phablet;fablet;android;"
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:1
+msgid "Window state"
+msgstr "Stan okna"
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:2
+msgid "State of the window, e.g. maximized."
+msgstr "Stan okna, tzn. czy jest zmaksymalizowane."
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:3
+msgid "Window width and height"
+msgstr "Szerokość i wysokość okna"
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:4
+msgid "Width and height of the window."
+msgstr "Szerokość i wysokość okna."
+
+#: ../src/application.vala:144
+msgid "Connect to a specific server"
+msgstr "Łączy z podanym serwerem"
+
+#: ../src/application.vala:297
+msgid "Certificate Fingerprint"
+msgstr "Odcisk certyfikatu"
+
+#: ../src/application.vala:300
+msgid "_OK"
+msgstr "_OK"
+
+#: ../src/application.vala:469 ../src/resources/ui/window.ui.h:1
+msgid "Nuntius"
+msgstr "Nuntius"
+
+#: ../src/application.vala:472
+msgid ""
+"Deliver notifications from your phone or tablet to your computer over "
+"Bluetooth."
+msgstr ""
+"Wyświetlanie powiadomień z telefonu lub tabletu na komputerze za pomocą "
+"Bluetooth."
+
+#: ../src/application.vala:477
+msgid "translator-credits"
+msgstr ""
+"Piotr Drąg <piotrdrag@gmail.com>, 2015-2016\n"
+"Aviary.pl <community-poland@mozilla.org>, 2015-2016"
+
+#: ../src/appslist.vala:75
+msgid "Blacklist this application"
+msgstr "Dodaj program do czarnej listy"
+
+#. namespace Nuntius
+#. ex:set ts=4 et:
+#: ../src/resources/gtk/menus.ui.h:1
+msgid "Show _QR Code"
+msgstr "Wyświetl kod _QR"
+
+#: ../src/resources/gtk/menus.ui.h:2
+msgid "_About"
+msgstr "_O programie"
+
+#: ../src/resources/ui/appslistpanel.ui.h:1
+msgid "Type to search"
+msgstr "Wyszukiwanie"
+
+#: ../src/resources/ui/window.ui.h:2
+msgid "All Applications"
+msgstr "Wszystkie programy"
+
+#. FIXME: just a test message until we have UI to type the reply
+#: ../src/smsnotification.vala:63
+msgid "Reply"
+msgstr "Odpowiedz"
--- nuntius-linux-0.2.0.orig/po/sk.po
+++ nuntius-linux-0.2.0/po/sk.po
@@ -1,22 +1,21 @@
 # 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.
+# Dušan Kazik <prescott66@gmail.com>, 2015.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: \n"
+"Project-Id-Version: nuntius-linux\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-03-11 11:24+0100\n"
-"PO-Revision-Date: 2015-03-11 13:12+0100\n"
+"POT-Creation-Date: 2016-07-15 17:00+0200\n"
+"PO-Revision-Date: 2015-03-20 18:28+0100\n"
+"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
+"Language-Team: \n"
+"Language: sk\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
-"Language-Team: \n"
-"X-Generator: Poedit 1.7.4\n"
 "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-"Language: sk\n"
 
 #: ../data/org.holylobster.nuntius.appdata.xml.in.h:1
 msgid ""
@@ -31,8 +30,8 @@ msgid ""
 "To use Nuntius you will need to install a companion tool on your phone or "
 "tablet and pair it via Bluetooth."
 msgstr ""
-"Na používanie programu Nuntius budete musieť vo vašom telefóne alebo "
-"tablete nainštalovať spoločný nástroj a spárovať ho cez Bluetooth."
+"Na používanie programu Nuntius budete musieť vo vašom telefóne alebo tablete "
+"nainštalovať spoločný nástroj a spárovať ho cez Bluetooth."
 
 #: ../data/org.holylobster.nuntius.desktop.in.h:1
 msgid ""
@@ -45,3 +44,75 @@ msgstr ""
 #: ../data/org.holylobster.nuntius.desktop.in.h:2
 msgid "notifications;"
 msgstr "oznámenia;upozornenia;"
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:1
+msgid "Window state"
+msgstr "Stav okna"
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:2
+msgid "State of the window, e.g. maximized."
+msgstr "Stav okna, napr. maximalizované."
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:3
+msgid "Window width and height"
+msgstr "Šírka a výška okna"
+
+#: ../data/org.holylobster.nuntius.gschema.xml.in.h:4
+msgid "Width and height of the window."
+msgstr "Šírka a výška okna."
+
+#: ../src/application.vala:144
+msgid "Connect to a specific server"
+msgstr ""
+
+#: ../src/application.vala:297
+msgid "Certificate Fingerprint"
+msgstr ""
+
+#: ../src/application.vala:300
+msgid "_OK"
+msgstr ""
+
+#: ../src/application.vala:469 ../src/resources/ui/window.ui.h:1
+msgid "Nuntius"
+msgstr "Nuntius"
+
+#: ../src/application.vala:472
+msgid ""
+"Deliver notifications from your phone or tablet to your computer over "
+"Bluetooth."
+msgstr ""
+"Doručenie oznámení z vášho telefónu alebo tabletu do vášho počítača cez "
+"Bluetooth."
+
+#: ../src/application.vala:477
+msgid "translator-credits"
+msgstr "Dušan Kazik <prescott66@gmail.com>, 2015"
+
+#: ../src/appslist.vala:75
+#, fuzzy
+msgid "Blacklist this application"
+msgstr "Všetky aplikácie"
+
+#. namespace Nuntius
+#. ex:set ts=4 et:
+#: ../src/resources/gtk/menus.ui.h:1
+msgid "Show _QR Code"
+msgstr ""
+
+#: ../src/resources/gtk/menus.ui.h:2
+msgid "_About"
+msgstr "_O programe"
+
+#: ../src/resources/ui/appslistpanel.ui.h:1
+msgid "Type to search"
+msgstr "Text na vyhľadanie"
+
+#: ../src/resources/ui/window.ui.h:2
+msgid "All Applications"
+msgstr "Všetky aplikácie"
+
+#. FIXME: just a test message until we have UI to type the reply
+#: ../src/smsnotification.vala:63
+msgid "Reply"
+msgstr ""
--- nuntius-linux-0.2.0.orig/src/application.vala
+++ nuntius-linux-0.2.0/src/application.vala
@@ -34,72 +34,116 @@ public interface BluezProfileManager : O
     public abstract void unregister_profile(ObjectPath profile) throws IOError;
 }
 
-[DBus (name = "org.bluez.Profile1")]
-public class BluezProfile : Object {
-    HashTable<ObjectPath, DeviceConnection>? connections;
+public class Connections : Object {
+    private HashTable<string, Connection>? connections;
 
-    public BluezProfile(Cancellable cancellable) {
-        connections = new HashTable<ObjectPath, DeviceConnection>(str_hash, str_equal);
-
-        cancellable.connect(() => {
-            connections.remove_all();
-        });
-    }
-
-    public void release() {
-        print("release method called\n");
+    construct {
+        connections = new HashTable<string, Connection>(str_hash, str_equal);
     }
 
-    public void new_connection(ObjectPath device, Socket socket, HashTable<string, Variant> fd_properties) {
-        print("new_connection method called for device: %s\n", device);
-        var connection = new DeviceConnection(device, socket);
-
-        connections.insert(device, connection);
+    public void add_connection(Connection connection) {
+        connections.insert(connection.server_name, connection);
         connection.notify["connected"].connect(() => {
             if (!connection.connected) {
-                connections.remove(connection.device);
-                print("removed connection for device '%s'\n", connection.device);
+                connections.remove(connection.server_name);
+                print("removed connection for device '%s'\n",
+                      connection.server_name);
             }
         });
 
         connection.notification_posted.connect((notification) => {
-            var app = GLib.Application.get_default();
-            (app as Application).add_notification(notification);
+            var app = (Application) GLib.Application.get_default();
+            app.add_notification(notification);
+        });
+
+        connection.sms_received.connect((sms_notification) => {
+            var app = (Application) GLib.Application.get_default();
+            app.add_sms_notification(sms_notification);
         });
 
         connection.notification_removed.connect((id, package_name) => {
-            var app = GLib.Application.get_default();
-            (app as Application).mark_notification_read(id, package_name);
+            var app = (Application) GLib.Application.get_default();
+            app.mark_notification_read(id, package_name);
         });
     }
 
-    public void request_disconnection(ObjectPath device) {
-        print("request_disconnection method called for devices: %s\n", device);
-
-        var device_connection = connections.lookup(device);
-        if (device_connection != null) {
-            connections.remove(device);
+    public void remove_connection(string server_name) {
+        var connection = connections.lookup(server_name);
+        if (connection != null) {
+            connections.remove(server_name);
         }
     }
 
-    public bool has_any_device_connected() {
+    public bool is_connected() {
         return connections.size() > 0;
     }
 
-    public bool get_device_connected(ObjectPath device) {
-        return connections.get(device) != null;
+    public bool get_connected(string server_name) {
+        return connections.get(server_name) != null;
     }
 }
 
+[DBus (name = "org.bluez.Profile1")]
+public class BluezProfile : Object {
+    private Connections connections;
+
+    public BluezProfile(Connections connections) {
+        this.connections = connections;
+    }
+
+    public void release() {
+        print("release method called\n");
+    }
+
+    public void new_connection(ObjectPath device, Socket socket, HashTable<string, Variant> fd_properties) {
+        print("new_connection method called for device: %s\n", device);
+        var connection = new Connection(device,
+                                        SocketConnection.factory_create_connection(socket));
+
+        connections.add_connection(connection);
+    }
+
+    public void request_disconnection(ObjectPath device) {
+        print("request_disconnection method called for devices: %s\n", device);
+
+        connections.remove_connection(device);
+    }
+}
+
+private enum TcpConnectionStatus {
+    DISCONNECTED,
+    CONNECTING,
+    CONNECTED
+}
+
 public class Application : Gtk.Application {
-    Cancellable? cancellable;
-    DBusObjectManager manager;
-    BluezProfileManager? profile_manager;
-    BluezProfile? profile;
-    uint connect_devices_id;
-    bool first_activation;
-    Window window;
-    List<NotificationApp> _notification_apps;
+    private Cancellable? cancellable;
+    private Connections connections;
+    private DBusObjectManager manager;
+    private BluezProfileManager? profile_manager;
+    private BluezProfile? profile;
+    private uint connect_devices_id;
+    private bool first_activation;
+    private bool cert_created;
+    private Window window;
+    private string connect_host;
+    private TcpConnectionStatus tcp_status;
+    private TlsCertificate? cert;
+    private List<NotificationApp> _notification_apps;
+    private List<SmsNotification> sms_notifications;
+
+    private const GLib.ActionEntry[] app_entries = {
+        { "about", on_about_activate },
+        { "show-qrcode", on_show_qrcode_activate },
+        { "open-notifications-view", on_open_notifications_view_activate, "(ss)"},
+        { "send-sms", on_send_sms_activate, "(ss)"}
+    };
+
+    private const OptionEntry[] options = {
+        {"connect", '\0', 0, OptionArg.STRING, null,
+         N_("Connect to a specific server"), null},
+        {null}
+    };
 
     public signal void notification_app_added(NotificationApp notification_app);
 
@@ -108,12 +152,16 @@ public class Application : Gtk.Applicati
     }
 
     public Application() {
-        Object(application_id: "org.holylobster.nuntius");
+        Object(application_id: "org.holylobster.nuntius",
+               flags: ApplicationFlags.HANDLES_COMMAND_LINE);
+        add_main_option_entries(options);
     }
 
     construct {
         cancellable = new Cancellable();
+        cert_created = false;
         first_activation = true;
+        tcp_status = TcpConnectionStatus.DISCONNECTED;
         _notification_apps = new List<NotificationApp>();
     }
 
@@ -137,6 +185,8 @@ public class Application : Gtk.Applicati
         // Since it works as a daemon keep a hold forever on the primary instance
         hold();
 
+        add_action_entries(app_entries, this);
+
         var css_provider = new Gtk.CssProvider();
         try {
             var file = File.new_for_uri("resource:///org/holylobster/nuntius/css/nuntius-style.css");
@@ -148,7 +198,8 @@ public class Application : Gtk.Applicati
                                                  css_provider,
                                                  Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
 
-        profile = new BluezProfile(cancellable);
+        connections = new Connections();
+        profile = new BluezProfile(connections);
 
         var profile_path = new ObjectPath(get_dbus_object_path() + "/Profile");
 
@@ -177,6 +228,8 @@ public class Application : Gtk.Applicati
         } catch (Error e) {
             warning("%s", e.message);
         }
+
+        create_cert();
     }
 
     private void ensure_window() {
@@ -188,19 +241,134 @@ public class Application : Gtk.Applicati
         }
     }
 
+    private string? spawn_command(string[] args) {
+        try {
+            string[] spawn_args = args;
+            string[] spawn_env = Environ.get ();
+            string ls_stdout;
+            string ls_stderr;
+            int ls_status;
+
+            Process.spawn_sync (".",
+                                spawn_args,
+                                spawn_env,
+                                SpawnFlags.SEARCH_PATH,
+                                null,
+                                out ls_stdout,
+                                out ls_stderr,
+                                out ls_status);
+            return ls_stdout;
+
+        } catch (SpawnError e) {
+            stdout.printf ("Error: %s\n", e.message);
+            return null;
+        }
+    }
+
+    private void create_cert() {
+        var path_to_conf = GLib.Path.build_filename(GLib.Environment.get_user_config_dir(), "nuntius");
+        var cert_path = GLib.Path.build_filename(path_to_conf, "nuntius.pem");
+        var key_path = GLib.Path.build_filename(path_to_conf, "nuntius.key");
+        var file = File.new_for_path(cert_path);
+        if (!file.query_exists()) {
+            var script = GLib.Path.build_filename(Config.TOOLSDIR, "createcert.sh");
+            string[] spawn_args = { script };
+            spawn_command(spawn_args);
+            cert_created = true;
+        }
+        try {
+            cert = new TlsCertificate.from_files(cert_path, key_path);
+        } catch (Error e) {
+            warning("Failed to load certificate: %s", e.message);
+        }
+    }
+
+    private string get_fingerprint() {
+        string path_to_pem = GLib.Path.build_filename(GLib.Environment.get_user_config_dir(), "nuntius/nuntius.pem");
+        string[] spawn_args = {"openssl", "x509", "-in", path_to_pem, "-fingerprint", "-sha1"};
+        string result = spawn_command(spawn_args);
+        string[] splitted = result.split("=");
+        splitted = splitted[1].split("\n");
+        string fingerprint = splitted[0];
+        return fingerprint;
+    }
+
+    private void show_qrcode() {
+        var dialog = new Gtk.Dialog.with_buttons(_("Certificate Fingerprint"),
+                                                 window,
+                                                 Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
+                                                 _("_OK"),
+                                                 Gtk.ResponseType.OK);
+        dialog.border_width = 30;
+        dialog.set_default_size(300, 300);
+
+        dialog.response.connect(i => {
+            window.destroy();
+        });
+
+        var qr = new Nuntius.QRImage();
+        qr.text = get_fingerprint() + "-" + GLib.Environment.get_host_name();
+        qr.show();
+
+        dialog.get_content_area().pack_end(qr, true, true, 0);
+        dialog.show();
+    }
+
     protected override void activate() {
         // We want it to start as a daemon and not showing the window from
         // the beginning
         if (!first_activation) {
             ensure_window();
             window.present();
+            if (cert_created) {
+                show_qrcode();
+            }
         }
 
         first_activation = false;
 
+        if (tcp_status == TcpConnectionStatus.DISCONNECTED && connect_host != null && cert != null) {
+            var host = connect_host;
+            var client = new SocketClient();
+
+            tcp_status = TcpConnectionStatus.CONNECTING;
+
+            client.tls = true;
+            client.event.connect(on_socket_client_event);
+            client.connect_to_host_async.begin(connect_host, 12233, cancellable, (obj, res) => {
+                try {
+                    var connection = client.connect_to_host_async.end(res);
+                    tcp_status = TcpConnectionStatus.CONNECTED;
+                    connections.add_connection(new Connection(host, connection));
+                } catch (Error e) {
+                    tcp_status = TcpConnectionStatus.DISCONNECTED;
+                    warning("Could not connect to server: %s", connect_host);
+                }
+            });
+        }
+
         base.activate();
     }
 
+    private void on_socket_client_event(SocketClientEvent event, SocketConnectable? connectable, IOStream? ios) {
+        if (event == SocketClientEvent.TLS_HANDSHAKING) {
+            var tls = (TlsConnection) ios;
+            tls.accept_certificate.connect((cert, err) => {
+                return true;
+            });
+            tls.set_certificate(cert);
+        }
+    }
+
+    protected override int command_line(ApplicationCommandLine cl) {
+        var dict = cl.get_options_dict();
+
+        dict.lookup("connect", "s", out connect_host);
+        activate();
+
+        return 0;
+    }
+
     private async void connect_interface(DBusObject object, DBusInterface iface, bool dump) {
         if (!(iface is DBusProxy)) {
             return;
@@ -217,7 +385,7 @@ public class Application : Gtk.Applicati
         }
 
         // try to get the device
-        if (name == "org.bluez.Device1" && !profile.get_device_connected(path)) {
+        if (name == "org.bluez.Device1" && !connections.get_connected(path)) {
             try {
                 BluezDeviceBus device = Bus.get_proxy_sync(BusType.SYSTEM, "org.bluez", path);
 
@@ -253,7 +421,7 @@ public class Application : Gtk.Applicati
             }
         }
 
-        if (!profile.has_any_device_connected()) {
+        if (!connections.is_connected()) {
             // try to connect to the paired device every few seconds
             connect_devices_id = Timeout.add_seconds(5, on_try_to_connect_devices);
         }
@@ -266,6 +434,66 @@ public class Application : Gtk.Applicati
         return false;
     }
 
+    public void on_open_notifications_view_activate(GLib.SimpleAction action, GLib.Variant? parameter) {
+        string id, package_name;
+        parameter.get("(ss)", out id, out package_name);
+
+        Notification? notification = null;
+        notification = get_notification(id, package_name);
+        if (notification == null) {
+            return;
+        }
+
+        /* FIXME: just temporary until we add actions to the main UI */
+        if (notification.actions != null) {
+            var view = new TestView(notification);
+            view.show_all();
+            return;
+        }
+
+        /* FIXME for now just raise the main window */
+        activate();
+    }
+
+    private void on_about_activate() {
+        const string copyright = "Copyright \xc2\xa9 2015 Holy Lobster Team";
+
+        const string authors[] = {
+            "Andrea Curtoni <andrea.curtoni@gmail.com>",
+            "Ignacio Casal Quinteiro <icq@gnome.org>",
+            "Paolo Borelli <pborelli@gnome.org>",
+            null
+        };
+
+        Gtk.show_about_dialog(window,
+                              "program-name", _("Nuntius"),
+                              "logo-icon-name", "nuntius",
+                              "version", Config.VERSION,
+                              "comments", _("Deliver notifications from your phone or tablet to your computer over Bluetooth."),
+                              "copyright", copyright,
+                              "authors", authors,
+                              "license-type", Gtk.License.GPL_2_0,
+                              "wrap-license", false,
+                              "translator-credits", _("translator-credits"),
+                              null);
+    }
+
+    private void on_show_qrcode_activate() {
+        show_qrcode();
+    }
+
+    public Notification? get_notification(string id, string package_name) {
+        foreach (var napp in notification_apps) {
+            if (napp.id == package_name) {
+                var notification = napp.get_notification(id);
+                if (notification != null) {
+                    return notification;
+                }
+            }
+        }
+        return null;
+    }
+
     public void add_notification(Notification notification) {
         bool found = false;
 
@@ -278,7 +506,7 @@ public class Application : Gtk.Applicati
         }
 
         if (!found) {
-            var napp = new NotificationApp(notification.package_name);
+            var napp = new NotificationApp(notification.package_name, notification.connection);
             napp.add_notification(notification);
             _notification_apps.prepend(napp);
 
@@ -292,18 +520,45 @@ public class Application : Gtk.Applicati
     public void mark_notification_read(string id, string package_name) {
         Notification? notification = null;
 
-        foreach (var napp in _notification_apps) {
+        notification = get_notification(id, package_name);
+
+        if (notification != null) {
+            withdraw_notification(notification.id);
+            notification.read = true;
+        }
+    }
+
+    public void blacklist_application(string package_name) {
+        foreach (var napp in notification_apps) {
             if (napp.id == package_name) {
-                notification = napp.get_notification(id);
-                break;
+                napp.blacklist();
             }
         }
+    }
 
-        if (notification != null) {
-            withdraw_notification(notification.id);
+    public SmsNotification? get_sms_notification(string id) {
+        foreach (var sms_notification in sms_notifications) {
+            if (sms_notification.id == id) {
+                return sms_notification;
+            }
+        }
+        return null;
+    }
+
+    public void add_sms_notification(SmsNotification sms_notification) {
+        sms_notifications.prepend(sms_notification);
+        send_notification(sms_notification.id, sms_notification.to_gnotification());
+    }
+
+    public void on_send_sms_activate(GLib.SimpleAction action, GLib.Variant? parameter) {
+        string id, text;
+        parameter.get("(ss)", out id, out text);
+
+        if (id != null && text != null) {
+            var sms_notification = get_sms_notification(id);
 
-            if (!notification.read) {
-                notification.read = true;
+            if (sms_notification != null) {
+                sms_notification.send_sms_message(text);
             }
         }
     }
--- nuntius-linux-0.2.0.orig/src/appslist.vala
+++ nuntius-linux-0.2.0/src/appslist.vala
@@ -25,9 +25,8 @@ public class AppsList : Gtk.ListBox {
         [GtkChild]
         private Gtk.Label label;
         [GtkChild]
-        private Gtk.Frame notifications_unread_frame;
-        [GtkChild]
-        private Gtk.Label notifications_unread_label;
+        private NotificationCounter notification_counter;
+        private Gtk.Menu menu;
 
         private NotificationApp _notification_app;
 
@@ -40,9 +39,13 @@ public class AppsList : Gtk.ListBox {
             Object(notification_app: notification_app);
 
             image.set_from_gicon(notification_app.icon, Gtk.IconSize.BUTTON);
-            notifications_unread_label.set_label(notification_app.unread_notifications.to_string());
+            notification_app.bind_property("unread-notifications",
+                                           notification_counter,
+                                           "counter",
+                                           BindingFlags.SYNC_CREATE);
+
             if (notification_app.unread_notifications > 0) {
-                notifications_unread_frame.show();
+                notification_counter.show();
                 label.set_markup("<b>" + notification_app.app_name + "</b>");
             } else {
                 label.set_label(notification_app.app_name);
@@ -57,8 +60,7 @@ public class AppsList : Gtk.ListBox {
             });
 
             notification_app.notify["unread-notifications"].connect(() => {
-                notifications_unread_frame.set_visible(notification_app.unread_notifications > 0);
-                notifications_unread_label.set_label(notification_app.unread_notifications.to_string());
+                notification_counter.set_visible(notification_app.unread_notifications > 0);
 
                 if (notification_app.unread_notifications > 0) {
                     label.set_markup("<b>" + notification_app.app_name + "</b>");
@@ -67,6 +69,17 @@ public class AppsList : Gtk.ListBox {
                 }
             });
         }
+
+        public void show_popup_menu(Gdk.EventButton event) {
+            menu = new Gtk.Menu();
+            var item = new Gtk.MenuItem.with_label (_("Blacklist this application"));
+            item.activate.connect(() => {
+                notification_app.blacklist();
+            });
+            menu.append(item);
+            menu.show_all();
+            menu.popup(null, null, null, event.button, event.get_time());
+        }
     }
 
     private string? filter_text;
@@ -89,6 +102,24 @@ public class AppsList : Gtk.ListBox {
             var row = new AppRow(napp);
             add(row);
         });
+
+        button_press_event.connect((event) => {
+            if (event.type == Gdk.EventType.BUTTON_PRESS &&
+                event.button == Gdk.BUTTON_SECONDARY) {
+                print("button press right click\n");
+                unselect_all();
+
+                var row = get_row_at_y((int) event.y) as AppRow;
+                if (row != null) {
+                    select_row(get_row_at_y((int) event.y));
+                    row.show_popup_menu(event);
+                }
+
+                return true;
+            }
+
+            return false;
+        });
     }
 
     private void update_header(Gtk.ListBoxRow row, Gtk.ListBoxRow? before) {
--- nuntius-linux-0.2.0.orig/src/config.vapi
+++ nuntius-linux-0.2.0/src/config.vapi
@@ -4,5 +4,6 @@ namespace Config {
     public const string DATADIR;
     public const string GETTEXT_PACKAGE;
     public const string GNOMELOCALEDIR;
+    public const string TOOLSDIR;
 }
 
--- nuntius-linux-0.2.0.orig/src/connection.vala
+++ nuntius-linux-0.2.0/src/connection.vala
@@ -17,40 +17,48 @@
 
 namespace Nuntius {
 
-public class DeviceConnection : Object {
-    Cancellable cancellable;
-    Socket socket;
-    SocketConnection? connection;
-    DataInputStream? input;
-    bool _connected;
-    ObjectPath _device;
+public class Connection : Object {
+    private Cancellable cancellable;
+    private SocketConnection? _connection;
+    private DataInputStream? input;
+    private DataOutputStream? output;
+    private bool _connected;
+    private string _server_name;
 
     public bool connected {
         get { return _connected; }
         set { _connected = value; }
     }
 
-    public ObjectPath device {
-        get { return _device; }
+    public string server_name {
+        get { return _server_name; }
+        set construct { _server_name = value; }
+    }
+
+    public SocketConnection? connection {
+        get { return _connection; }
+        set construct { _connection = value; }
     }
 
     public signal void notification_posted(Notification notification);
 
+    public signal void sms_received(SmsNotification notification);
+
     public signal void notification_removed(string id, string package_name);
 
-    public DeviceConnection(ObjectPath device, Socket socket) {
-        cancellable = new Cancellable();
-        this.socket = socket;
-        _connected = true;
-        _device = device;
+    public Connection(string server_name, SocketConnection connection) {
+        Object(connected: true, server_name: server_name, connection: connection);
 
-        connection = SocketConnection.factory_create_connection(socket);
-        input = new DataInputStream(connection.get_input_stream());
+        input = new DataInputStream(_connection.get_input_stream());
         input.set_newline_type(DataStreamNewlineType.CR_LF);
-
+        output = new DataOutputStream(_connection.get_output_stream());
         read_message();
     }
 
+    construct {
+        cancellable = new Cancellable();
+    }
+
     protected override void dispose() {
         if (cancellable != null) {
             cancellable.cancel();
@@ -63,6 +71,15 @@ public class DeviceConnection : Object {
         base.dispose();
     }
 
+    public void send_message(string msg) {
+        try {
+            output.put_string(msg + "\n");
+        } catch (Error e) {
+            print("Couldn't send message to " + _server_name);
+        }
+        print(msg);
+    }
+
     void read_message() {
         input.read_line_async.begin(Priority.DEFAULT, cancellable, (obj, res) => {
             try {
@@ -94,6 +111,7 @@ public class DeviceConnection : Object {
                 case "notificationPosted":
                     foreach (var i in eventItems) {
                         Notification? notification = null;
+                        string? key = null;
 
                         var object = i.get_object();
                         var id = object.get_int_member("id").to_string();
@@ -105,16 +123,36 @@ public class DeviceConnection : Object {
                             icon = new BytesIcon(new Bytes(Base64.decode(object.get_string_member("icon"))));
                         }
 
+                        if (object.has_member("key")) {
+                            key = object.get_string_member("key");
+                        }
+
                         var notification_object = object.get_object_member("notification");
                         if (notification_object.has_member("title")) {
                             var title = notification_object.get_string_member("title");
                             string? text = null;
+                            string? flags = null;
+                            string[]? actions_string = null;
+
+                            if (notification_object.has_member("flags")) {
+                                flags = notification_object.get_string_member("flags");
+                            }
 
                             if (notification_object.has_member("text")) {
                                 text = notification_object.get_string_member("text");
                             }
 
-                            notification = new Notification(id, package_name, app_name, title, text, icon);
+                            if (notification_object.has_member("actions")) {
+                                var actions = notification_object.get_array_member("actions").get_elements();
+                                var number_of_actions = notification_object.get_array_member("actions").get_length();
+                                actions_string = new string[number_of_actions];
+                                var count = 0;
+                                foreach (var action in actions) {
+                                    actions_string[count] = action.get_object().get_string_member("title");
+                                    count++;
+                                }
+                            }
+                            notification = new Notification(this, id, package_name, app_name, title, flags, key, text, icon, actions_string);
 
                             notification_posted(notification);
                         }
@@ -125,12 +163,43 @@ public class DeviceConnection : Object {
                         var object = i.get_object();
                         var id = object.get_int_member("id").to_string();
                         var package_name = object.get_string_member("packageName");
-
                         notification_removed(id, package_name);
                     }
                     break;
                 case "listNotifications":
                     break;
+                case "sms":
+                    foreach (var i in eventItems) {
+                        var object = i.get_object();
+                        string? id = null;
+                        string? sender = null;
+                        string? sender_num = null;
+                        string? msg = null;
+                        BytesIcon? icon = null;
+
+                        if (object.has_member("id")) {
+                            id = object.get_string_member("id");
+                        }
+
+                        if (object.has_member("sender")) {
+                            sender = object.get_string_member("sender");
+                        }
+
+                        if (object.has_member("sender_num")) {
+                            sender_num = object.get_string_member("sender_num");
+                        }
+
+                        if (object.has_member("message")) {
+                            msg = object.get_string_member("message");
+                        }
+
+                        if (object.has_member("icon")) {
+                            icon = new BytesIcon(new Bytes(Base64.decode(object.get_string_member("icon"))));
+                        }
+                        SmsNotification notification = new SmsNotification(this, id, sender, sender_num, msg, icon);
+                        sms_received(notification);
+                    }
+                    break;
                 default:
                     warning("Unknown event: %s", event);
                     break;
--- nuntius-linux-0.2.0.orig/src/main.vala
+++ nuntius-linux-0.2.0/src/main.vala
@@ -29,9 +29,9 @@ public static int main(string[] args) {
 
     app = new Nuntius.Application();
 
-    Unix.signal_add(Posix.SIGINT, on_terminate_app);
-    Unix.signal_add(Posix.SIGHUP, on_terminate_app);
-    Unix.signal_add(Posix.SIGTERM, on_terminate_app);
+    Unix.signal_add(Posix.Signal.INT, on_terminate_app);
+    Unix.signal_add(Posix.Signal.HUP, on_terminate_app);
+    Unix.signal_add(Posix.Signal.TERM, on_terminate_app);
 
     return app.run(args);
 }
--- nuntius-linux-0.2.0.orig/src/notification.vala
+++ nuntius-linux-0.2.0/src/notification.vala
@@ -18,52 +18,86 @@
 namespace Nuntius {
 
 public class Notification : Object {
-    private string _id;
-    private string _package_name;
-    private string _app_name;
-    private string _title;
-    private string _body;
-    private BytesIcon _icon;
-    private bool _read;
-
-    public string id {
-        get { return _id; }
-        set construct { _id = value; }
-    }
-
-    public string package_name {
-        get { return _package_name; }
-        set construct { _package_name = value; }
-    }
+    public string id { get; construct set; }
+    public string package_name { get; construct set; }
+    public string app_name { get; construct set; }
+    public string title { get; construct set; }
+    public string body { get; construct set; }
+    public string? flag { get; construct set; }
+    public string? key { get; construct set; }
+    public BytesIcon icon { get; construct set; }
+    public string[]? actions { get; construct set; }
+    public Connection connection { get; construct set; }
 
-    public string app_name {
-        get { return _app_name; }
-        set construct { _app_name = value; }
-    }
+    private bool _read = false;
 
-    public string title {
-        get { return _title; }
-        set construct { _title = value; }
-    }
-
-    public string body {
-        get { return _body; }
-        set construct { _body = value; }
+    [CCode (notify = false)]
+    public bool read {
+        get {
+            return _read;
+        }
+        set {
+            if (_read != value) {
+                _read = value;
+                notify_property("read");
+            }
+        }
     }
 
-    public BytesIcon icon {
-        get { return _icon; }
-        set construct { _icon = value; }
+    public Notification(Connection connection, string id, string package_name, string app_name, string title, string? flag, string? key, string? body, BytesIcon? icon, string[]? actions) {
+        Object(connection: connection, id: id, package_name: package_name, app_name: app_name, title: title, flag: flag, key: key, body: body, icon: icon, actions: actions);
     }
 
-    public bool read {
-        get { return _read; }
-        set { _read = value; }
-        default = false;
-    }
+    public void send_dismiss_message() {
+        Json.Builder builder = new Json.Builder();
+        builder.begin_object();
+        builder.set_member_name("event");
+        builder.add_string_value("dismiss");
+        builder.set_member_name("notification");
+        builder.begin_object();
+
+        if (key != null){
+            builder.set_member_name("key");
+            builder.add_string_value(_key);
+        } else {
+            builder.set_member_name("packageName");
+            builder.add_string_value(_package_name);
+            builder.set_member_name("flag");
+            builder.add_string_value(_flag);
+            builder.set_member_name("id");
+            builder.add_string_value(_id);
+        }
+        builder.end_object();
+        builder.end_object();
 
-    public Notification(string id, string package_name, string app_name, string title, string? body, BytesIcon? icon) {
-        Object(id: id, package_name: package_name, app_name: app_name, title: title, body: body, icon: icon);
+        Json.Generator generator = new Json.Generator();
+        Json.Node root = builder.get_root();
+        generator.set_root(root);
+        string dismiss_message = generator.to_data(null);
+        connection.send_message(dismiss_message);
+    }
+
+    public void send_action_message(string s) {
+        Json.Builder builder = new Json.Builder();
+        builder.begin_object();
+        builder.set_member_name("event");
+        builder.add_string_value("action");
+        builder.set_member_name("action");
+        builder.begin_object();
+
+        builder.set_member_name("key");
+        builder.add_string_value(_key);
+        builder.set_member_name("actionName");
+        builder.add_string_value(s);
+
+        builder.end_object();
+        builder.end_object();
+
+        Json.Generator generator = new Json.Generator();
+        Json.Node root = builder.get_root();
+        generator.set_root(root);
+        string action_message = generator.to_data(null);
+        connection.send_message(action_message);
     }
 
     public GLib.Notification to_gnotification() {
@@ -77,6 +111,9 @@ public class Notification : Object {
             notification.set_icon(icon);
         }
 
+        var variant = new Variant("(ss)", id, package_name);
+        notification.set_default_action_and_target_value("app.open-notifications-view", variant);
+
         return notification;
     }
 }
--- nuntius-linux-0.2.0.orig/src/notificationapp.vala
+++ nuntius-linux-0.2.0/src/notificationapp.vala
@@ -18,16 +18,12 @@
 namespace Nuntius {
 
 public class NotificationApp : Object {
-    private string _id;
+    public string id { get; construct set; }
+    public Connection connection { get; construct set; }
     private string _app_name;
     private BytesIcon _icon;
     private uint _unread_notifications;
-    List<Notification> _notifications;
-
-    public string id {
-        get { return _id; }
-        set construct { _id = value; }
-    }
+    private List<Notification> _notifications;
 
     public string app_name {
         get { return _app_name; }
@@ -45,8 +41,8 @@ public class NotificationApp : Object {
         get { return _notifications; }
     }
 
-    public NotificationApp(string id) {
-        Object(id: id);
+    public NotificationApp(string id, Connection connection) {
+        Object(id: id, connection: connection);
     }
 
     construct {
@@ -95,6 +91,28 @@ public class NotificationApp : Object {
 
         return n;
     }
+
+    public void blacklist() {
+        Json.Builder builder = new Json.Builder();
+        builder.begin_object();
+        builder.set_member_name("event");
+        builder.add_string_value("blacklist");
+        builder.set_member_name("app");
+        builder.begin_object();
+
+        builder.set_member_name("packageName");
+        builder.add_string_value(id);
+
+        builder.end_object();
+        builder.end_object();
+
+        Json.Generator generator = new Json.Generator();
+        Json.Node root = builder.get_root();
+        generator.set_root(root);
+
+        string blacklist_message = generator.to_data(null);
+        connection.send_message(blacklist_message);
+    }
 }
 
 } // namespace Nuntius
--- /dev/null
+++ nuntius-linux-0.2.0/src/notificationcounter.vala
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 - Holy Lobster
+ *
+ * Nuntius 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Nuntius 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 Nuntius. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Nuntius {
+
+[GtkTemplate (ui = "/org/holylobster/nuntius/ui/notificationcounter.ui")]
+public class NotificationCounter : Gtk.Frame {
+    private uint _counter;
+
+    [GtkChild]
+    private Gtk.Label label_counter;
+
+    public uint counter {
+        get { return _counter; }
+        set {
+            _counter = value;
+            label_counter.set_label(_counter.to_string());
+        }
+    }
+}
+
+} // namespace Nuntius
+
+/* ex:set ts=4 et: */
--- nuntius-linux-0.2.0.orig/src/notificationsview.vala
+++ nuntius-linux-0.2.0/src/notificationsview.vala
@@ -132,12 +132,21 @@ public class NotificationsView : Gtk.Tex
             buf.insert(ref it, "\n\n", -1);
         }
 
+#if VALA_0_28
         buf.insert_with_tags(ref it, notification.title, -1, notification_tag, title_tag, null);
 
         if (notification.body != null) {
             buf.insert_with_tags(ref it, "\n\n", -1, notification_tag, null);
             buf.insert_with_tags(ref it, notification.body, -1, notification_tag, null);
         }
+#else
+        buf.insert_with_tags(it, notification.title, -1, notification_tag, title_tag, null);
+
+        if (notification.body != null) {
+            buf.insert_with_tags(it, "\n\n", -1, notification_tag, null);
+            buf.insert_with_tags(it, notification.body, -1, notification_tag, null);
+        }
+#endif
 
         buf.insert(ref it, "\n\n\n", -1);
 
--- /dev/null
+++ nuntius-linux-0.2.0/src/qrencode.vapi
@@ -0,0 +1,45 @@
+
+/*
+ * Minimal VAPI file for LIBQRENCODE Barcode library.
+ */
+namespace Qrencode {
+
+    [CCode (cheader_filename = "qrencode.h", cname = "QRcode", unref_function = "QRcode_free")]
+    public class QRcode {
+        [CCode (cname = "QRcode_encodeString")]
+        public QRcode.encodeString(string digits, int version, EcLevel level, Mode hint, int casesensitive);
+
+        public int version;
+        public int width;
+        [CCode (array_length = false)]
+        public uint8[] data;
+    }
+
+    [CCode (cheader_filename = "qrencode.h", cname="QRencLevel")]
+    public enum EcLevel {
+        [CCode (cname="QR_ECLEVEL_L")]
+        L,
+        [CCode (cname="QR_ECLEVEL_M")]
+        M,
+        [CCode (cname="QR_ECLEVEL_Q")]
+        Q,
+        [CCode (cname="QR_ECLEVEL_H")]
+        H
+    }
+
+    [CCode (cheader_filename = "qrencode.h", cname="QRencodeMode")]
+    public enum Mode {
+        [CCode (cname="QR_MODE_NUL")]
+        NUL,
+        [CCode (cname="QR_MODE_NUM")]
+        NUM,
+        [CCode (cname="QR_MODE_AN")]
+        AN,
+        [CCode (cname="QR_MODE_8")]
+        B8,
+        [CCode (cname="QR_MODE_KANJI")]
+        KANJI,
+        [CCode (cname="QR_MODE_STRUCTURE")]
+        STRUCTURE
+    }
+}
--- /dev/null
+++ nuntius-linux-0.2.0/src/qrimage.vala
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2015 - Holy Lobster
+ *
+ * Nuntius 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Nuntius 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 Nuntius. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Nuntius {
+
+public class QRImage : Gtk.DrawingArea {
+    private string _text;
+    private Qrencode.QRcode? qrcode;
+    private const double MIN_SQUARE_SIZE = 1.0;
+
+    [CCode (notify = false)]
+    public string text {
+        get { return _text; }
+        set {
+            if (_text != value) {
+                _text = value;
+                qrcode = new Qrencode.QRcode.encodeString(_text, 0,
+                                                          Qrencode.EcLevel.M,
+                                                          Qrencode.Mode.B8, 1);
+                notify_property("text");
+
+                queue_draw();
+            }
+        }
+    }
+
+    protected override bool draw(Cairo.Context cr) {
+        if (qrcode != null) {
+            uint width, height;
+
+            width = get_allocated_width();
+            height = get_allocated_height();
+
+            /* make it square */
+            if (height < width) {
+                width = height;
+            }
+
+            double square_size = width / qrcode.width;
+            if (square_size < MIN_SQUARE_SIZE) {
+                square_size = MIN_SQUARE_SIZE;
+            }
+
+            cr.save();
+
+            cr.set_source_rgb(0, 0, 0);
+
+            for (int iy = 0; iy < qrcode.width; iy++) {
+                for (int ix = 0; ix < qrcode.width; ix++) {
+                    /* Symbol data is represented as an array contains
+                     * width*width uchars. Each uchar represents a module
+                     * (dot). If the less significant bit of the uchar
+                     * is 1, the corresponding module is black. The other
+                     * bits are meaningless for us.
+                     */
+                    if ((qrcode.data[iy * qrcode.width + ix] & 1) != 0) {
+                        cr.rectangle(ix * square_size, iy * square_size, square_size, square_size);
+                        cr.fill();
+                    }
+                }
+            }
+
+            cr.restore();
+        }
+
+        return false;
+    }
+}
+
+} // namespace Nuntius
+
+/* ex:set ts=4 et: */
--- nuntius-linux-0.2.0.orig/src/resources/css/nuntius-style.css
+++ nuntius-linux-0.2.0/src/resources/css/nuntius-style.css
@@ -39,7 +39,7 @@ NuntiusAppsListPanel.frame:dir(rtl) {
   background-color: transparent;
 }
 
-.nuntius-notifications-unread {
+NuntiusNotificationCounter {
   border-style: none;
   border-radius: 10px;
   background-color: darker(@theme_selected_bg_color);
--- /dev/null
+++ nuntius-linux-0.2.0/src/resources/gtk/menus.ui
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <menu id="app-menu">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">Show _QR Code</attribute>
+        <attribute name="action">app.show-qrcode</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">_About</attribute>
+        <attribute name="action">app.about</attribute>
+      </item>
+    </section>
+  </menu>
+</interface>
--- nuntius-linux-0.2.0.orig/src/resources/nuntius.gresource.xml
+++ nuntius-linux-0.2.0/src/resources/nuntius.gresource.xml
@@ -4,6 +4,8 @@
     <file preprocess="xml-stripblanks">ui/window.ui</file>
     <file preprocess="xml-stripblanks">ui/appslistpanel.ui</file>
     <file preprocess="xml-stripblanks">ui/approw.ui</file>
+    <file preprocess="xml-stripblanks">ui/notificationcounter.ui</file>
+    <file preprocess="xml-stripblanks">gtk/menus.ui</file>
     <file>css/nuntius-style.css</file>
   </gresource>
 </gresources>
--- nuntius-linux-0.2.0.orig/src/resources/ui/approw.ui
+++ nuntius-linux-0.2.0/src/resources/ui/approw.ui
@@ -38,24 +38,11 @@
           </packing>
         </child>
         <child>
-          <object class="GtkFrame" id="notifications_unread_frame">
+          <object class="NuntiusNotificationCounter" id="notification_counter">
             <property name="visible">False</property>
             <property name="can_focus">False</property>
             <property name="halign">end</property>
             <property name="valign">center</property>
-            <style>
-              <class name="nuntius-notifications-unread"/>
-            </style>
-            <child>
-              <object class="GtkLabel" id="notifications_unread_label">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="halign">start</property>
-                <property name="valign">center</property>
-                <property name="ellipsize">end</property>
-                <property name="label">50</property>
-              </object>
-            </child>
           </object>
           <packing>
             <property name="left_attach">2</property>
--- /dev/null
+++ nuntius-linux-0.2.0/src/resources/ui/notificationcounter.ui
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.1 -->
+<interface>
+  <template class="NuntiusNotificationCounter" parent="GtkFrame">
+    <property name="can_focus">False</property>
+    <property name="shadow_type">none</property>
+    <child>
+      <object class="GtkLabel" id="label_counter">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">center</property>
+        <property name="valign">center</property>
+        <property name="ellipsize">end</property>
+      </object>
+    </child>
+  </template>
+</interface>
--- /dev/null
+++ nuntius-linux-0.2.0/src/smsnotification.vala
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2015 - Holy Lobster
+ *
+ * Nuntius 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Nuntius 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 Nuntius. If not, see <http://www.gnu.org/licenses/>.
+ */
+namespace Nuntius {
+
+public class SmsNotification : Object {
+    public string id { get; construct set; }
+    public string sender { get; construct set; }
+    public string sender_num { get; construct set; }
+    public string message { get; construct set; }
+    public BytesIcon icon { get; construct set; }
+    public Connection connection { get; construct set; }
+
+    public SmsNotification(Connection connection, string id, string sender, string sender_num, string message, BytesIcon icon) {
+        Object(connection: connection, id: id, sender: sender, sender_num: sender_num, message: message, icon: icon);
+    }
+
+    public void send_sms_message(string message) {
+        Json.Builder builder = new Json.Builder();
+        builder.begin_object();
+        builder.set_member_name("event");
+        builder.add_string_value("sms");
+        builder.set_member_name("sms");
+        builder.begin_object();
+
+        builder.set_member_name("senderNum");
+        builder.add_string_value(_sender_num);
+
+        builder.set_member_name("msg");
+        builder.add_string_value(message);
+
+        builder.end_object();
+        builder.end_object();
+
+        Json.Generator generator = new Json.Generator();
+        Json.Node root = builder.get_root();
+        generator.set_root(root);
+        string sms_message = generator.to_data(null);
+        connection.send_message(sms_message);
+    }
+
+    public GLib.Notification to_gnotification() {
+        GLib.Notification notification = new GLib.Notification(sender);
+
+        notification.set_body(message);
+        notification.set_icon(icon);
+
+        // FIXME: just a test message until we have UI to type the reply
+        var variant = new Variant("(ss)", id, "Sent by Nuntius");
+        notification.add_button_with_target_value(_("Reply"),"app.send-sms", variant);
+
+        return notification;
+    }
+}
+
+}
--- /dev/null
+++ nuntius-linux-0.2.0/src/testview.vala
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2015 - Holy Lobster
+ *
+ * Nuntius 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Nuntius 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 Nuntius. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Nuntius {
+
+/* Just a temporary UI to send actions, this should go in the main UI */
+public class TestView : Gtk.Window {
+
+    Notification notification;
+
+    public TestView(Notification notification) {
+        this.notification = notification;
+
+        // Sets the title of the Window:
+        this.title = notification.title;
+
+        // Center window at startup:
+        this.window_position = Gtk.WindowPosition.CENTER;
+
+        // Sets the default size of a window:
+        this.set_default_size(500,150);
+
+        // Whether the titlebar should be hidden during maximization.
+        this.hide_titlebar_when_maximized = false;
+
+        // Method called on pressing [X]
+        this.destroy.connect(() => {
+            stdout.printf("Bye!\n");
+        });
+
+        Gtk.Box vertical_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
+        vertical_box.set_margin_left(20);
+        vertical_box.set_margin_right(20);
+        this.add(vertical_box);
+
+        Gtk.Box notification_area = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 10);
+        vertical_box.pack_start(notification_area);
+
+        Gtk.Image icon = new Gtk.Image();
+        icon.set_from_gicon(notification.icon, Gtk.IconSize.DIALOG);
+        notification_area.pack_start(icon);
+
+        var label = new Gtk.Label(notification.body);
+        notification_area.pack_start(label);
+
+        Gtk.Box button_area = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 10);
+        vertical_box.pack_start(button_area, false, false, 10);
+        var dismiss_button = new Gtk.Button.with_label("Dismiss");
+
+        dismiss_button.clicked.connect(() => {
+            notification.send_dismiss_message();
+        });
+
+        button_area.pack_start(dismiss_button);
+
+        if (notification.actions != null) {
+            var actions = notification.actions;
+            foreach(string s in actions) {
+                var action_button = new Gtk.Button.with_label(s);
+                button_area.pack_start(action_button);
+                action_button.clicked.connect(() => {
+                    notification.send_action_message(s);
+                });
+            }
+        }
+
+        var blacklist_button = new Gtk.Button.with_label("Blacklist this app");
+
+        blacklist_button.clicked.connect(() => {
+            var app = (Application) GLib.Application.get_default();
+            app.blacklist_application(notification.package_name);
+        });
+
+        button_area.pack_start(blacklist_button);
+    }
+}
+
+}
--- nuntius-linux-0.2.0.orig/src/window.vala
+++ nuntius-linux-0.2.0/src/window.vala
@@ -26,14 +26,50 @@ public class Window : Gtk.ApplicationWin
     [GtkChild]
     private Gtk.HeaderBar titlebar_right;
 
+    private GLib.Settings settings;
+
     public Window(Application app) {
         Object(application: app);
     }
 
     construct {
+        settings = new Settings("org.holylobster.nuntius.state.window");
+        settings.delay ();
+
+        destroy.connect(() => {
+            settings.apply();
+        });
+
+        // Setup window geometry saving
+        Gdk.WindowState window_state = (Gdk.WindowState)settings.get_int("state");
+        if (Gdk.WindowState.MAXIMIZED in window_state) {
+            maximize();
+        }
+
+        int width, height;
+        settings.get ("size", "(ii)", out width, out height);
+        resize(width, height);
+
         apps_list_panel.selection_changed.connect(on_selection_changed);
     }
 
+    protected override bool configure_event(Gdk.EventConfigure event) {
+        if (get_realized() && !(Gdk.WindowState.MAXIMIZED in get_window ().get_state())) {
+            settings.set("size", "(ii)", event.width, event.height);
+        }
+
+        return base.configure_event(event);
+    }
+
+    protected override bool window_state_event(Gdk.EventWindowState event) {
+        settings.set_int("state", event.new_window_state);
+        return base.window_state_event(event);
+    }
+
+    protected override bool delete_event(Gdk.EventAny event) {
+        return base.hide_on_delete();
+    }
+
     private void on_selection_changed(NotificationApp? notification_app) {
         if (notification_app == null) {
             titlebar_right.title = null;
--- /dev/null
+++ nuntius-linux-0.2.0/tests/qrtest.vala
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 - Holy Lobster
+ *
+ * Nuntius 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Nuntius 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 Nuntius. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+public static int main(string[] args) {
+    Gtk.init(ref args);
+
+    var window = new Gtk.Window();
+    window.title = "QR Test";
+    window.border_width = 10;
+    window.set_default_size(350, 70);
+    window.destroy.connect(Gtk.main_quit);
+
+    var qr = new Nuntius.QRImage();
+    qr.text = "This is a test";
+
+    window.add(qr);
+    window.show_all();
+
+    Gtk.main();
+
+    return 0;
+}
+
+/* ex:set ts=4 et: */
