Hello community,

here is the log from the commit of package reco for openSUSE:Factory checked in 
at 2019-09-17 13:39:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/reco (Old)
 and      /work/SRC/openSUSE:Factory/.reco.new.7948 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "reco"

Tue Sep 17 13:39:32 2019 rev:3 rq:731346 version:2.2.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/reco/reco.changes        2019-08-15 
12:29:44.242473634 +0200
+++ /work/SRC/openSUSE:Factory/.reco.new.7948/reco.changes      2019-09-17 
13:39:32.869822399 +0200
@@ -1,0 +2,17 @@
+Mon Sep  9 18:45:10 UTC 2019 - Alexei Podvalsky <[email protected]>
+
+- Update to 2.2.0:
+  * MainWindow: Remove a redundant comment
+  * MainWindow: Prevents position changes from being spammed
+  * Recorder refactoring (#38)
+  * Fix forgetting to remove the unnecessary string for debug
+  * Show successful mark when a recording is saved correctly
+  * Resume the pause icon on canceling recording
+  * MainWindow: Remove the unused 'app' property
+  * RecordView: Remove the unused 'app' property
+  * Omit the instruction that build the app to update .po files
+  * Revert "Add name-domain to .travis.yml"
+  * Add name-domain to .travis.yml
+  * Use more efficient way to get/set window positions
+
+-------------------------------------------------------------------

Old:
----
  reco-2.1.0.tar.gz

New:
----
  reco-2.2.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ reco.spec ++++++
--- /var/tmp/diff_new_pack.nOLojn/_old  2019-09-17 13:39:33.293822331 +0200
+++ /var/tmp/diff_new_pack.nOLojn/_new  2019-09-17 13:39:33.293822331 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           reco
-Version:        2.1.0
+Version:        2.2.0
 Release:        0
 Summary:        Audio Recording App
 License:        GPL-3.0-or-later

++++++ reco-2.1.0.tar.gz -> reco-2.2.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reco-2.1.0/README.md new/reco-2.2.0/README.md
--- old/reco-2.1.0/README.md    2019-08-03 02:36:52.000000000 +0200
+++ new/reco-2.2.0/README.md    2019-09-08 15:45:30.000000000 +0200
@@ -64,7 +64,7 @@
 
 ### Translating This App
 
-I accept translations through Pull Requests.
+I accept translations through Pull Requests. If you're not sure how to do, 
[the guideline I made](po/README.md) might be helpful.
 
 ## The Story Behind This App
 
Binary files old/reco-2.1.0/data/Screenshot.png and 
new/reco-2.2.0/data/Screenshot.png differ
Binary files old/reco-2.1.0/data/Screenshot2.png and 
new/reco-2.2.0/data/Screenshot2.png differ
Binary files old/reco-2.1.0/data/Screenshot3.png and 
new/reco-2.2.0/data/Screenshot3.png differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/reco-2.1.0/data/com.github.ryonakano.reco.appdata.xml.in 
new/reco-2.2.0/data/com.github.ryonakano.reco.appdata.xml.in
--- old/reco-2.1.0/data/com.github.ryonakano.reco.appdata.xml.in        
2019-08-03 02:36:52.000000000 +0200
+++ new/reco-2.2.0/data/com.github.ryonakano.reco.appdata.xml.in        
2019-09-08 15:45:30.000000000 +0200
@@ -76,12 +76,13 @@
   </content_rating>
 
   <releases>
-    <release version="2.1.0" date="2019-08-03">
+    <release version="2.2.0" date="2019-09-08">
       <description>
         <ul>
-          <li>Allow to cancel/pause countdown before recording</li>
-          <li>Save recordings when the app window is destroyed</li>
-          <li>Fix the app freezes on closing an error dialog</li>
+          <li>Getting/setting window positions gets more efficient</li>
+          <li>Fix the app does not resume the pause icon when you cancel 
recording while pausing it</li>
+          <li>Fix the app shows the successful mark even if a recording is not 
saved correctly</li>
+          <li>Save and restore values typed into the spin buttons</li>
         </ul>
       </description>
     </release>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/reco-2.1.0/data/com.github.ryonakano.reco.gschema.xml 
new/reco-2.2.0/data/com.github.ryonakano.reco.gschema.xml
--- old/reco-2.1.0/data/com.github.ryonakano.reco.gschema.xml   2019-08-03 
02:36:52.000000000 +0200
+++ new/reco-2.2.0/data/com.github.ryonakano.reco.gschema.xml   2019-09-08 
15:45:30.000000000 +0200
@@ -34,15 +34,10 @@
       <default>''</default>
       <summary>Default destination</summary>
     </key>
-    <key name="window-x" type="i">
-      <default>-1</default>
-      <summary>Window x position</summary>
-      <description>X position of last closed window</description>
-    </key>
-    <key name="window-y" type="i">
-      <default>-1</default>
-      <summary>Window y position</summary>
-      <description>Y position of last closed window</description>
+    <key name="window-position" type="(ii)">
+      <default>(-1, -1)</default>
+      <summary>Window position</summary>
+      <description>Position of last closed window</description>
     </key>
   </schema>
 </schemalist>
Binary files old/reco-2.1.0/data/screenshots/fr/Screenshot.png and 
new/reco-2.2.0/data/screenshots/fr/Screenshot.png differ
Binary files old/reco-2.1.0/data/screenshots/fr/Screenshot3.png and 
new/reco-2.2.0/data/screenshots/fr/Screenshot3.png differ
Binary files old/reco-2.1.0/data/screenshots/ja/Screenshot.png and 
new/reco-2.2.0/data/screenshots/ja/Screenshot.png differ
Binary files old/reco-2.1.0/data/screenshots/ja/Screenshot3.png and 
new/reco-2.2.0/data/screenshots/ja/Screenshot3.png differ
Binary files old/reco-2.1.0/data/screenshots/lt/Screenshot.png and 
new/reco-2.2.0/data/screenshots/lt/Screenshot.png differ
Binary files old/reco-2.1.0/data/screenshots/lt/Screenshot3.png and 
new/reco-2.2.0/data/screenshots/lt/Screenshot3.png differ
Binary files old/reco-2.1.0/data/screenshots/nl/Screenshot.png and 
new/reco-2.2.0/data/screenshots/nl/Screenshot.png differ
Binary files old/reco-2.1.0/data/screenshots/nl/Screenshot3.png and 
new/reco-2.2.0/data/screenshots/nl/Screenshot3.png differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reco-2.1.0/meson.build new/reco-2.2.0/meson.build
--- old/reco-2.1.0/meson.build  2019-08-03 02:36:52.000000000 +0200
+++ new/reco-2.2.0/meson.build  2019-09-08 15:45:30.000000000 +0200
@@ -1,4 +1,4 @@
-project('com.github.ryonakano.reco', 'vala', 'c', version: '2.1.0')
+project('com.github.ryonakano.reco', 'vala', 'c', version: '2.2.0')
 
 gnome = import('gnome')
 i18n = import('i18n')
@@ -18,6 +18,7 @@
 executable(
     meson.project_name(),
     asresources,
+    'src/Services/Recorder.vala',
     'src/Views/CountDownView.vala',
     'src/Views/WelcomeView.vala',
     'src/Views/RecordView.vala',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reco-2.1.0/po/README.md new/reco-2.2.0/po/README.md
--- old/reco-2.1.0/po/README.md 1970-01-01 01:00:00.000000000 +0100
+++ new/reco-2.2.0/po/README.md 2019-09-08 15:45:30.000000000 +0200
@@ -0,0 +1,56 @@
+# How to Add a Translation of This App
+
+## Fork and Clone the Repository
+
+First of all, fork this repository on GitHub. Next, clone the forked 
repository to local:
+
+    git clone https://github.com/your-username/reco.git
+
+## Add Your Language Code to LINGUAS Files
+
+Search for your language code (e.g. en = English, zh_CN = Chinese Simplified). 
See https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes if needed. Then add 
it to `po/LINGUAS` and `po/extra/LINGUAS`. Please make sure language codes sort 
alphabetically. For example, if a LINGUAS file contains `ko`, `mr` and `zh_TW`, 
its content should be sorted like this:
+
+    ko
+    mr
+    zh_TW
+
+## Translate .po Files
+
+Now what you've been waiting for! Copy `po/com.github.ryonakano.reco.pot` and 
name `po/<language_code>.po` and copy `po/extra/extra.pot` and name 
`po/extra/<language_code>.po`. Then translate these created .po files using a 
.po file editor of your choice (e.g. Poedit). The former file contains strings 
for the app itself and the latter is for metadata files (.appdata.xml and 
.desktop files).
+
+## Commit Your Translation Works
+
+After saving the .po files, open a terminal in the folder you've cloned this 
repository in and type:
+
+    git checkout -b add-translation
+
+Then add the .po files of your language and LINGUAS files. **Do not add other 
files!**
+
+    git add po/LINGUAS po/extra/LINGUAS po/<language_code>.po 
po/extra/<language_code>.po
+
+Next, create a commit and push it to your cloned repository on GitHub:
+
+    git commit -m "Add <Language Name> translation"
+    git push origin add-translation
+
+Type your GitHub username and password if asked.
+
+Finally, open your cloned repository on GitHub, select "Compare & Pull 
Request", and create a new pull request.
+
+And that's all! I'll check whether there is no problem in your pull request 
and if so I'll approve and merge your pull request! Your translation is 
released every time I release a new version of the app to AppCenter, so it is 
not always reflected when your pull request is merged. Please be patient.
+
+# How to Update an Existing Translation
+
+You can also create a pull request that updates existing translations. In this 
case, you don't have to edit LINGUAS files. Open existing .po files with any 
.po file editor and commit them when completed.
+
+# Note
+
+* **If you find some issue (e.g. typo) in the source strings, create another 
pull request that fixes it. Do NOT fix it in your translation pull request.** 
If you don't know how to fix it, create a new issue about it. I'll fix it.
+* **If you would like to translate the app into multiple languages, please 
make separated PRs per languages.** It's not a good thing to include 
translations of more than 2 languages in your one pull request.
+* Edit and commit only `po/LINGUAS`, `po/extra/LINGUAS`, 
`po/<language_code>.po` and `po/extra/<language_code>.po`. Do NOT include other 
files in your pull request.
+
+# References
+
+This file was created by referring the following reference:
+
+* https://github.com/lainsce/notejot/blob/master/po/README.md
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reco-2.1.0/po/com.github.ryonakano.reco.pot 
new/reco-2.2.0/po/com.github.ryonakano.reco.pot
--- old/reco-2.1.0/po/com.github.ryonakano.reco.pot     2019-08-03 
02:36:52.000000000 +0200
+++ new/reco-2.2.0/po/com.github.ryonakano.reco.pot     2019-09-08 
15:45:30.000000000 +0200
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: com.github.ryonakano.reco\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-08-03 09:32+0900\n"
+"POT-Creation-Date: 2019-09-08 22:39+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <[email protected]>\n"
@@ -78,51 +78,51 @@
 msgstr ""
 
 #. TRANSLATORS: The name of the folder which recordings are saved
-#: src/Views/WelcomeView.vala:147
+#: src/Views/WelcomeView.vala:136
 msgid "Recordings"
 msgstr ""
 
-#: src/Views/RecordView.vala:69
+#: src/Views/RecordView.vala:62
 msgid "Cancel recording"
 msgstr ""
 
-#: src/Views/RecordView.vala:75
+#: src/Views/RecordView.vala:68
 msgid "Finish recording"
 msgstr ""
 
-#: src/Views/RecordView.vala:83 src/Views/RecordView.vala:327
-#: src/Views/RecordView.vala:362
+#: src/Views/RecordView.vala:76 src/Views/RecordView.vala:98
+#: src/Views/RecordView.vala:129 src/Views/RecordView.vala:141
 msgid "Pause recording"
 msgstr ""
 
-#: src/Views/RecordView.vala:126
+#: src/Views/RecordView.vala:119
+msgid "Resume recording"
+msgstr ""
+
+#: src/MainWindow.vala:80
 msgid "Unable to Create an Audio File"
 msgstr ""
 
-#: src/Views/RecordView.vala:127
+#: src/MainWindow.vala:81
 msgid ""
 "A GStreamer error happened while recording, the following error message may "
 "be helpful:"
 msgstr ""
 
 #. TRANSLATORS: %s represents a timestamp here
-#: src/Views/RecordView.vala:154
+#: src/MainWindow.vala:94
 #, c-format
 msgid "Recording from %s"
 msgstr ""
 
-#: src/Views/RecordView.vala:169
+#: src/MainWindow.vala:112
 msgid "Save your recording"
 msgstr ""
 
-#: src/Views/RecordView.vala:170
+#: src/MainWindow.vala:113
 msgid "Save"
 msgstr ""
 
-#: src/Views/RecordView.vala:170
+#: src/MainWindow.vala:113
 msgid "Cancel"
 msgstr ""
-
-#: src/Views/RecordView.vala:351
-msgid "Resume recording"
-msgstr ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reco-2.1.0/po/fr.po new/reco-2.2.0/po/fr.po
--- old/reco-2.1.0/po/fr.po     2019-08-03 02:36:52.000000000 +0200
+++ new/reco-2.2.0/po/fr.po     2019-09-08 15:45:30.000000000 +0200
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: com.github.ryonakano.reco\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-08-03 09:32+0900\n"
+"POT-Creation-Date: 2019-09-08 22:39+0900\n"
 "PO-Revision-Date: 2019-01-16 22:17+0100\n"
 "Last-Translator: NathanBnm\n"
 "Language-Team: Français\n"
@@ -78,31 +78,36 @@
 msgstr "Démarrer l'enregistrement"
 
 #. TRANSLATORS: The name of the folder which recordings are saved
-#: src/Views/WelcomeView.vala:147
+#: src/Views/WelcomeView.vala:136
 msgid "Recordings"
 msgstr "Enregistrements"
 
-#: src/Views/RecordView.vala:69
+#: src/Views/RecordView.vala:62
 #, fuzzy
 msgid "Cancel recording"
 msgstr "Démarrer l'enregistrement"
 
-#: src/Views/RecordView.vala:75
+#: src/Views/RecordView.vala:68
 #, fuzzy
 msgid "Finish recording"
 msgstr "Arrêter l'enregistrement"
 
-#: src/Views/RecordView.vala:83 src/Views/RecordView.vala:327
-#: src/Views/RecordView.vala:362
+#: src/Views/RecordView.vala:76 src/Views/RecordView.vala:98
+#: src/Views/RecordView.vala:129 src/Views/RecordView.vala:141
 #, fuzzy
 msgid "Pause recording"
 msgstr "Démarrer l'enregistrement"
 
-#: src/Views/RecordView.vala:126
+#: src/Views/RecordView.vala:119
+#, fuzzy
+msgid "Resume recording"
+msgstr "Enregistrements"
+
+#: src/MainWindow.vala:80
 msgid "Unable to Create an Audio File"
 msgstr "Impossible de créer un fichier audio"
 
-#: src/Views/RecordView.vala:127
+#: src/MainWindow.vala:81
 #, fuzzy
 msgid ""
 "A GStreamer error happened while recording, the following error message may "
@@ -110,29 +115,24 @@
 msgstr "Une erreur GStreamer est survenue pendant l'enregistrement :"
 
 #. TRANSLATORS: %s represents a timestamp here
-#: src/Views/RecordView.vala:154
+#: src/MainWindow.vala:94
 #, c-format
 msgid "Recording from %s"
 msgstr "Enregistré depuis %s"
 
-#: src/Views/RecordView.vala:169
+#: src/MainWindow.vala:112
 #, fuzzy
 msgid "Save your recording"
 msgstr "Démarrer l'enregistrement"
 
-#: src/Views/RecordView.vala:170
+#: src/MainWindow.vala:113
 msgid "Save"
 msgstr ""
 
-#: src/Views/RecordView.vala:170
+#: src/MainWindow.vala:113
 msgid "Cancel"
 msgstr ""
 
-#: src/Views/RecordView.vala:351
-#, fuzzy
-msgid "Resume recording"
-msgstr "Enregistrements"
-
 #~ msgid "Wav"
 #~ msgstr "Wav"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reco-2.1.0/po/ja.po new/reco-2.2.0/po/ja.po
--- old/reco-2.1.0/po/ja.po     2019-08-03 02:36:52.000000000 +0200
+++ new/reco-2.2.0/po/ja.po     2019-09-08 15:45:30.000000000 +0200
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: com.github.ryonakano.reco\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-08-03 09:32+0900\n"
+"POT-Creation-Date: 2019-09-08 22:39+0900\n"
 "PO-Revision-Date: 2019-06-01 20:42+0900\n"
 "Last-Translator: Ryo Nakano <[email protected]>\n"
 "Language-Team: none\n"
@@ -79,28 +79,32 @@
 msgstr "録音を開始します"
 
 #. TRANSLATORS: The name of the folder which recordings are saved
-#: src/Views/WelcomeView.vala:147
+#: src/Views/WelcomeView.vala:136
 msgid "Recordings"
 msgstr "レコーディング"
 
-#: src/Views/RecordView.vala:69
+#: src/Views/RecordView.vala:62
 msgid "Cancel recording"
 msgstr "録音をキャンセルします"
 
-#: src/Views/RecordView.vala:75
+#: src/Views/RecordView.vala:68
 msgid "Finish recording"
 msgstr "録音を終了します"
 
-#: src/Views/RecordView.vala:83 src/Views/RecordView.vala:327
-#: src/Views/RecordView.vala:362
+#: src/Views/RecordView.vala:76 src/Views/RecordView.vala:98
+#: src/Views/RecordView.vala:129 src/Views/RecordView.vala:141
 msgid "Pause recording"
 msgstr "録音を一時停止します"
 
-#: src/Views/RecordView.vala:126
+#: src/Views/RecordView.vala:119
+msgid "Resume recording"
+msgstr "録音を再開します"
+
+#: src/MainWindow.vala:80
 msgid "Unable to Create an Audio File"
 msgstr "オーディオファイルを作成できません"
 
-#: src/Views/RecordView.vala:127
+#: src/MainWindow.vala:81
 msgid ""
 "A GStreamer error happened while recording, the following error message may "
 "be helpful:"
@@ -109,27 +113,23 @@
 "性があります:"
 
 #. TRANSLATORS: %s represents a timestamp here
-#: src/Views/RecordView.vala:154
+#: src/MainWindow.vala:94
 #, c-format
 msgid "Recording from %s"
 msgstr "録音 %s"
 
-#: src/Views/RecordView.vala:169
+#: src/MainWindow.vala:112
 msgid "Save your recording"
 msgstr "録音したものを保存"
 
-#: src/Views/RecordView.vala:170
+#: src/MainWindow.vala:113
 msgid "Save"
 msgstr "保存"
 
-#: src/Views/RecordView.vala:170
+#: src/MainWindow.vala:113
 msgid "Cancel"
 msgstr "キャンセル"
 
-#: src/Views/RecordView.vala:351
-msgid "Resume recording"
-msgstr "録音を再開します"
-
 #~ msgid "Are you sure you want to quit Reco?"
 #~ msgstr "Reco を終了してもよろしいですか?"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reco-2.1.0/po/lt.po new/reco-2.2.0/po/lt.po
--- old/reco-2.1.0/po/lt.po     2019-08-03 02:36:52.000000000 +0200
+++ new/reco-2.2.0/po/lt.po     2019-09-08 15:45:30.000000000 +0200
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: com.github.ryonakano.reco\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-08-03 09:32+0900\n"
+"POT-Creation-Date: 2019-09-08 22:39+0900\n"
 "PO-Revision-Date: 2019-02-18 14:35+0200\n"
 "Last-Translator: Moo\n"
 "Language-Team: \n"
@@ -80,31 +80,36 @@
 msgstr "Pradėti įrašinėjimą"
 
 #. TRANSLATORS: The name of the folder which recordings are saved
-#: src/Views/WelcomeView.vala:147
+#: src/Views/WelcomeView.vala:136
 msgid "Recordings"
 msgstr "Įrašinėjimai"
 
-#: src/Views/RecordView.vala:69
+#: src/Views/RecordView.vala:62
 #, fuzzy
 msgid "Cancel recording"
 msgstr "Pradėti įrašinėjimą"
 
-#: src/Views/RecordView.vala:75
+#: src/Views/RecordView.vala:68
 #, fuzzy
 msgid "Finish recording"
 msgstr "Stabdyti įrašinėjimą"
 
-#: src/Views/RecordView.vala:83 src/Views/RecordView.vala:327
-#: src/Views/RecordView.vala:362
+#: src/Views/RecordView.vala:76 src/Views/RecordView.vala:98
+#: src/Views/RecordView.vala:129 src/Views/RecordView.vala:141
 #, fuzzy
 msgid "Pause recording"
 msgstr "Pradėti įrašinėjimą"
 
-#: src/Views/RecordView.vala:126
+#: src/Views/RecordView.vala:119
+#, fuzzy
+msgid "Resume recording"
+msgstr "Įrašinėjimas"
+
+#: src/MainWindow.vala:80
 msgid "Unable to Create an Audio File"
 msgstr "Nepavyko sukurti garso failą"
 
-#: src/Views/RecordView.vala:127
+#: src/MainWindow.vala:81
 #, fuzzy
 msgid ""
 "A GStreamer error happened while recording, the following error message may "
@@ -112,28 +117,23 @@
 msgstr "Įrašanėjant, įvyko GStreamer klaida:"
 
 #. TRANSLATORS: %s represents a timestamp here
-#: src/Views/RecordView.vala:154
+#: src/MainWindow.vala:94
 #, c-format
 msgid "Recording from %s"
 msgstr "Įrašinėjimas iš %s"
 
-#: src/Views/RecordView.vala:169
+#: src/MainWindow.vala:112
 msgid "Save your recording"
 msgstr "Išsaugokite savo įrašinėjimą"
 
-#: src/Views/RecordView.vala:170
+#: src/MainWindow.vala:113
 msgid "Save"
 msgstr "Išsaugoti"
 
-#: src/Views/RecordView.vala:170
+#: src/MainWindow.vala:113
 msgid "Cancel"
 msgstr "Atsisakyti"
 
-#: src/Views/RecordView.vala:351
-#, fuzzy
-msgid "Resume recording"
-msgstr "Įrašinėjimas"
-
 #~ msgid "Are you sure you want to quit Reco?"
 #~ msgstr "Ar tikrai norite išeiti iš Reco?"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reco-2.1.0/po/nl.po new/reco-2.2.0/po/nl.po
--- old/reco-2.1.0/po/nl.po     2019-08-03 02:36:52.000000000 +0200
+++ new/reco-2.2.0/po/nl.po     2019-09-08 15:45:30.000000000 +0200
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: com.github.ryonakano.reco\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-08-03 09:32+0900\n"
+"POT-Creation-Date: 2019-09-08 22:39+0900\n"
 "PO-Revision-Date: 2019-03-29 14:04+0100\n"
 "Last-Translator: Heimen Stoffels <[email protected]>\n"
 "Language-Team: Dutch <[email protected]>\n"
@@ -79,28 +79,32 @@
 msgstr "Opname starten"
 
 #. TRANSLATORS: The name of the folder which recordings are saved
-#: src/Views/WelcomeView.vala:147
+#: src/Views/WelcomeView.vala:136
 msgid "Recordings"
 msgstr "Opnamen"
 
-#: src/Views/RecordView.vala:69
+#: src/Views/RecordView.vala:62
 msgid "Cancel recording"
 msgstr "Opname afbreken"
 
-#: src/Views/RecordView.vala:75
+#: src/Views/RecordView.vala:68
 msgid "Finish recording"
 msgstr "Opname afronden"
 
-#: src/Views/RecordView.vala:83 src/Views/RecordView.vala:327
-#: src/Views/RecordView.vala:362
+#: src/Views/RecordView.vala:76 src/Views/RecordView.vala:98
+#: src/Views/RecordView.vala:129 src/Views/RecordView.vala:141
 msgid "Pause recording"
 msgstr "Opname pauzeren"
 
-#: src/Views/RecordView.vala:126
+#: src/Views/RecordView.vala:119
+msgid "Resume recording"
+msgstr "Opname hervatten"
+
+#: src/MainWindow.vala:80
 msgid "Unable to Create an Audio File"
 msgstr "Kan geen audiobestand creëren"
 
-#: src/Views/RecordView.vala:127
+#: src/MainWindow.vala:81
 msgid ""
 "A GStreamer error happened while recording, the following error message may "
 "be helpful:"
@@ -109,27 +113,23 @@
 "foutmelding kan nuttig zijn:"
 
 #. TRANSLATORS: %s represents a timestamp here
-#: src/Views/RecordView.vala:154
+#: src/MainWindow.vala:94
 #, c-format
 msgid "Recording from %s"
 msgstr "Opnemen van %s"
 
-#: src/Views/RecordView.vala:169
+#: src/MainWindow.vala:112
 msgid "Save your recording"
 msgstr "Sla je opname op"
 
-#: src/Views/RecordView.vala:170
+#: src/MainWindow.vala:113
 msgid "Save"
 msgstr "Opslaan"
 
-#: src/Views/RecordView.vala:170
+#: src/MainWindow.vala:113
 msgid "Cancel"
 msgstr "Afbreken"
 
-#: src/Views/RecordView.vala:351
-msgid "Resume recording"
-msgstr "Opname hervatten"
-
 #~ msgid "Are you sure you want to quit Reco?"
 #~ msgstr "Weet je zeker dat je Reco wilt afsluiten?"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reco-2.1.0/src/Application.vala 
new/reco-2.2.0/src/Application.vala
--- old/reco-2.1.0/src/Application.vala 2019-08-03 02:36:52.000000000 +0200
+++ new/reco-2.2.0/src/Application.vala 2019-09-08 15:45:30.000000000 +0200
@@ -39,8 +39,8 @@
             return;
         }
 
-        var window_x = settings.get_int ("window-x");
-        var window_y = settings.get_int ("window-y");
+        int window_x, window_y;
+        settings.get ("window-position", "(ii)", out window_x, out window_y);
 
         window = new MainWindow (this);
 
@@ -56,9 +56,9 @@
         add_action (quit_action);
         set_accels_for_action ("app.quit", {"<Control>q"});
         quit_action.activate.connect (() => {
-            if (window.record_view.is_recording) {
+            if (window.recorder.is_recording) {
                 var loop = new MainLoop ();
-                window.record_view.stop_recording.begin ((obj, res) => {
+                window.record_view.trigger_stop_recording.begin ((obj, res) => 
{
                     loop.quit ();
                 });
                 loop.run ();
@@ -75,7 +75,7 @@
                 window.welcome_view.trigger_recording ();
             } else if (window.stack.visible_child_name == "record") {
                 var loop = new MainLoop ();
-                window.record_view.stop_recording.begin ((obj, res) => {
+                window.record_view.trigger_stop_recording.begin ((obj, res) => 
{
                     loop.quit ();
                 });
                 loop.run ();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reco-2.1.0/src/MainWindow.vala 
new/reco-2.2.0/src/MainWindow.vala
--- old/reco-2.1.0/src/MainWindow.vala  2019-08-03 02:36:52.000000000 +0200
+++ new/reco-2.2.0/src/MainWindow.vala  2019-09-08 15:45:30.000000000 +0200
@@ -16,17 +16,17 @@
 */
 
 public class MainWindow : Gtk.ApplicationWindow {
-    public Application app { get; construct; }
     public WelcomeView welcome_view { get; private set; }
     private CountDownView countdown_view;
     public RecordView record_view { get; private set; }
+    public Recorder recorder { get; private set; default = new Recorder (); }
     public Gtk.Stack stack { get; private set; }
+    private uint configure_id;
 
     public MainWindow (Application app) {
         Object (
             border_width: 6,
             application: app,
-            app: app,
             resizable: false,
             width_request: 400,
             height_request: 300
@@ -51,7 +51,7 @@
 
         welcome_view = new WelcomeView (this);
         countdown_view = new CountDownView (this);
-        record_view = new RecordView (this, app);
+        record_view = new RecordView (this);
 
         stack = new Gtk.Stack ();
         stack.add_named (welcome_view, "welcome");
@@ -64,9 +64,9 @@
         show_welcome ();
 
         delete_event.connect ((event) => {
-            if (record_view.is_recording) {
+            if (recorder.is_recording) {
                 var loop = new MainLoop ();
-                record_view.stop_recording.begin ((obj, res) => {
+                record_view.trigger_stop_recording.begin ((obj, res) => {
                     loop.quit ();
                 });
                 loop.run ();
@@ -74,6 +74,68 @@
 
             return false;
         });
+
+        recorder.handle_error.connect ((err, debug) => {
+            var error_dialog = new 
Granite.MessageDialog.with_image_from_icon_name (
+                _("Unable to Create an Audio File"),
+                _("A GStreamer error happened while recording, the following 
error message may be helpful:"),
+                "dialog-error", Gtk.ButtonsType.CLOSE);
+            error_dialog.transient_for = this;
+            error_dialog.show_error_details ("%s\n%s".printf (err.message, 
debug));
+            error_dialog.run ();
+            error_dialog.destroy ();
+
+            record_view.stop_count ();
+            show_welcome ();
+        });
+
+        recorder.handle_save_file.connect ((tmp_full_path, suffix) => {
+            ///TRANSLATORS: %s represents a timestamp here
+            string filename = _("Recording from %s").printf (new 
DateTime.now_local ().format ("%Y-%m-%d %H.%M.%S"));
+
+            var tmp_source = File.new_for_path (tmp_full_path);
+
+            string destination = Application.settings.get_string 
("destination");
+
+            if (Application.settings.get_boolean ("auto-save")) {
+                try {
+                    var uri = File.new_for_path (destination + "/" + filename 
+ suffix);
+
+                    if (tmp_source.move (uri, FileCopyFlags.OVERWRITE)) {
+                        welcome_view.show_success_button ();
+                    }
+                } catch (Error e) {
+                    warning (e.message);
+                }
+            } else {
+                var filechooser = new Gtk.FileChooserNative (
+                    _("Save your recording"), this, Gtk.FileChooserAction.SAVE,
+                    _("Save"), _("Cancel"));
+                filechooser.set_current_name (filename + suffix);
+                filechooser.set_filename (destination);
+                filechooser.do_overwrite_confirmation = true;
+
+                if (filechooser.run () == Gtk.ResponseType.ACCEPT) {
+                    try {
+                        var uri = File.new_for_path (filechooser.get_filename 
());
+
+                        if (tmp_source.move (uri, FileCopyFlags.OVERWRITE)) {
+                            welcome_view.show_success_button ();
+                        }
+                    } catch (Error e) {
+                        warning (e.message);
+                    }
+                } else {
+                    try {
+                        tmp_source.delete ();
+                    } catch (Error e) {
+                        warning (e.message);
+                    }
+                }
+
+                filechooser.destroy ();
+            }
+        });
     }
 
     public void show_welcome () {
@@ -86,16 +148,30 @@
     }
 
     public void show_record () {
+        recorder.start_recording ();
+
+        int record_length = Application.settings.get_int ("length");
+        if (record_length != 0) {
+            record_view.init_countdown (record_length);
+        }
+
+        record_view.init_count ();
         stack.visible_child_name = "record";
-        record_view.start_recording ();
     }
 
-    // Save window position when changed
     public override bool configure_event (Gdk.EventConfigure event) {
-        int x, y;
-        get_position (out x, out y);
-        Application.settings.set_int ("window-x", x);
-        Application.settings.set_int ("window-y", y);
+        if (configure_id != 0) {
+            GLib.Source.remove (configure_id);
+        }
+
+        configure_id = Timeout.add (100, () => {
+            configure_id = 0;
+            int x, y;
+            get_position (out x, out y);
+            Application.settings.set ("window-position", "(ii)", x, y);
+
+            return false;
+        });
 
         return base.configure_event (event);
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reco-2.1.0/src/Services/Recorder.vala 
new/reco-2.2.0/src/Services/Recorder.vala
--- old/reco-2.1.0/src/Services/Recorder.vala   1970-01-01 01:00:00.000000000 
+0100
+++ new/reco-2.2.0/src/Services/Recorder.vala   2019-09-08 15:45:30.000000000 
+0200
@@ -0,0 +1,168 @@
+/*
+* (C) 2019 Ryo Nakano
+*
+* 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/>.
+*
+* Gstreamer related codes are inspired from 
https://github.com/artemanufrij/screencast/blob/master/src/MainWindow.vala
+*/
+
+public class Recorder : Object {
+    public bool is_recording { get; private set; }
+    private string suffix;
+    private string tmp_full_path;
+    private Gst.Pipeline pipeline;
+
+    public signal void handle_error (Error err, string debug);
+    public signal void handle_save_file (string tmp_full_path, string suffix);
+
+    construct {
+    }
+
+    public void start_recording () {
+        pipeline = new Gst.Pipeline ("pipeline");
+        var audiobin = new Gst.Bin ("audio");
+        var sink = Gst.ElementFactory.make ("filesink", "sink");
+
+        if (pipeline == null) {
+            error ("Gstreamer sink was not created correctly!");
+        } else if (audiobin == null) {
+            error ("Gstreamer pipeline was not created correctly!");
+        } else if (sink == null) {
+            error ("Gstreamer audiobin was not created correctly!");
+        }
+
+        string command = Application.settings.get_boolean ("system-sound") ? 
"pacmd list-sinks" : "pacmd list-sources";
+        string default_device = "";
+        try {
+            string sound_devices = "";
+            Process.spawn_command_line_sync (command, out sound_devices);
+            var re = new Regex 
("(?<=\\*\\sindex:\\s\\d\\s\\sname:\\s<)[\\w\\.\\-]*");
+            MatchInfo mi;
+
+            if (re.match (sound_devices, 0, out mi)) {
+                default_device = mi.fetch (0);
+            }
+
+            if (Application.settings.get_boolean ("system-sound")) {
+                default_device += ".monitor";
+            }
+        } catch (Error e) {
+            warning (e.message);
+        }
+
+        assert (sink != null);
+        string tmp_destination = Environment.get_tmp_dir ();
+        string tmp_filename = "reco_" + new DateTime.now_local ().to_unix 
().to_string ();
+
+        string file_format = Application.settings.get_string ("format");
+
+        try {
+            switch (file_format) {
+                case "aac":
+                    audiobin = (Gst.Bin) Gst.parse_bin_from_description 
("pulsesrc device=" + default_device + " ! avenc_aac ! mp4mux", true);
+                    suffix = ".m4a";
+                    break;
+                case "flac":
+                    audiobin = (Gst.Bin) Gst.parse_bin_from_description 
("pulsesrc device=" + default_device + " ! flacenc", true);
+                    suffix = ".flac";
+                    break;
+                case "mp3":
+                    audiobin = (Gst.Bin) Gst.parse_bin_from_description 
("pulsesrc device=" + default_device + " ! lamemp3enc", true);
+                    suffix = ".mp3";
+                    break;
+                case "ogg":
+                    audiobin = (Gst.Bin) Gst.parse_bin_from_description 
("pulsesrc device=" + default_device + " ! vorbisenc ! oggmux", true);
+                    suffix = ".ogg";
+                    break;
+                case "opus":
+                    audiobin = (Gst.Bin) Gst.parse_bin_from_description 
("pulsesrc device=" + default_device + " ! opusenc ! oggmux", true);
+                    suffix = ".opus";
+                    break;
+                default:
+                    audiobin = (Gst.Bin) Gst.parse_bin_from_description 
("pulsesrc device=" + default_device + " ! wavenc", true);
+                    suffix = ".wav";
+                    break;
+            }
+        } catch (Error e) {
+            error ("Could not set the audio format correctly: %s", e.message);
+        }
+
+        tmp_full_path = tmp_destination + "/%s%s".printf (tmp_filename, 
suffix);
+        sink.set ("location", tmp_full_path);
+        debug ("The recording is stored at %s temporary".printf 
(tmp_full_path));
+
+        pipeline.add_many (audiobin, sink);
+        audiobin.link (sink);
+
+        pipeline.get_bus ().add_watch (Priority.DEFAULT, bus_message_cb);
+        set_recording_state (Gst.State.PLAYING);
+    }
+
+    private bool bus_message_cb (Gst.Bus bus, Gst.Message msg) {
+        switch (msg.type) {
+            case Gst.MessageType.ERROR:
+                set_recording_state (Gst.State.NULL);
+                pipeline.dispose ();
+
+                Error err;
+                string debug;
+                msg.parse_error (out err, out debug);
+
+                handle_error (err, debug);
+                break;
+            case Gst.MessageType.EOS:
+                set_recording_state (Gst.State.NULL);
+                pipeline.dispose ();
+
+                handle_save_file (tmp_full_path, suffix);
+                break;
+            default:
+                break;
+        }
+
+        return true;
+    }
+
+    public void cancel_recording () {
+        set_recording_state (Gst.State.NULL);
+        pipeline.dispose ();
+
+        // Remove canceled file in /tmp
+        try {
+            File.new_for_path (tmp_full_path).delete ();
+        } catch (Error e) {
+            warning (e.message);
+        }
+    }
+
+    public void stop_recording () {
+        pipeline.send_event (new Gst.Event.eos ());
+    }
+
+    public void set_recording_state (Gst.State state) {
+        pipeline.set_state (state);
+
+        switch (state) {
+            case Gst.State.PLAYING:
+                is_recording = true;
+                break;
+            case Gst.State.PAUSED:
+            case Gst.State.NULL:
+                is_recording = false;
+                break;
+            default:
+                assert_not_reached ();
+        }
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reco-2.1.0/src/Views/RecordView.vala 
new/reco-2.2.0/src/Views/RecordView.vala
--- old/reco-2.1.0/src/Views/RecordView.vala    2019-08-03 02:36:52.000000000 
+0200
+++ new/reco-2.2.0/src/Views/RecordView.vala    2019-09-08 15:45:30.000000000 
+0200
@@ -19,18 +19,12 @@
 
 public class RecordView : Gtk.Box {
     public MainWindow window { get; construct; }
-    public Application app { get; construct; }
     private Gtk.Label time_label;
     private Gtk.Label remaining_time_label;
     private Gtk.Button stop_button;
     private Gtk.Button pause_button;
-    public bool is_recording { get; private set; }
-    private string suffix;
-    private string tmp_full_path;
     private uint count;
     private uint countdown;
-    private Gst.Bin audiobin;
-    private Gst.Pipeline pipeline;
     private int past_minutes_10;
     private int past_minutes_1;
     private int past_seconds_10;
@@ -40,12 +34,11 @@
     private int remain_seconds_10;
     private int remain_seconds_1;
 
-    public RecordView (MainWindow window, Application app) {
+    public RecordView (MainWindow window) {
         Object (
             orientation: Gtk.Orientation.VERTICAL,
             spacing: 12,
             window: window,
-            app: app,
             margin: 6
         );
     }
@@ -97,273 +90,63 @@
         pack_end (buttons_grid, false, false);
 
         cancel_button.clicked.connect (() => {
-            cancel_recording ();
+            stop_count ();
+
+            // If a user tries to cancel recording while pausing, resume 
recording once and reset the button icon
+            if (!window.recorder.is_recording) {
+                pause_button.image = new Gtk.Image.from_icon_name 
("media-playback-pause-symbolic", Gtk.IconSize.BUTTON);
+                pause_button.tooltip_text = _("Pause recording");
+            }
+
+            window.recorder.cancel_recording ();
             window.show_welcome ();
-            is_recording = false;
         });
 
         stop_button.clicked.connect (() => {
             var loop = new MainLoop ();
-            window.record_view.stop_recording.begin ((obj, res) => {
+            trigger_stop_recording.begin ((obj, res) => {
                 loop.quit ();
             });
             loop.run ();
         });
 
         pause_button.clicked.connect (() => {
-            pause_recording ();
-        });
-    }
-
-    private bool bus_message_cb (Gst.Bus bus, Gst.Message msg) {
-        switch (msg.type) {
-            case Gst.MessageType.ERROR:
-                Error err;
-                string debug;
-                msg.parse_error (out err, out debug);
-
-                var error_dialog = new 
Granite.MessageDialog.with_image_from_icon_name (
-                    _("Unable to Create an Audio File"),
-                    _("A GStreamer error happened while recording, the 
following error message may be helpful:"),
-                    "dialog-error", Gtk.ButtonsType.CLOSE);
-                error_dialog.transient_for = window;
-                error_dialog.show_error_details ("%s\n%s".printf (err.message, 
debug));
-                error_dialog.run ();
-                error_dialog.destroy ();
-
-                if (count != 0) {
-                    count = 0;
-                }
-
-                if (countdown != 0) {
-                    countdown = 0;
-                    remaining_time_label.label = null;
-                }
-
-                window.show_welcome ();
-                is_recording = false;
+            if (window.recorder.is_recording) {
+                stop_count ();
 
-                pipeline.set_state (Gst.State.NULL);
-                break;
-            case Gst.MessageType.EOS:
-                pipeline.set_state (Gst.State.NULL);
-
-                is_recording = false;
-
-                ///TRANSLATORS: %s represents a timestamp here
-                string filename = _("Recording from %s").printf (new 
DateTime.now_local ().format ("%Y-%m-%d %H.%M.%S"));
-
-                var tmp_source = File.new_for_path (tmp_full_path);
-
-                string destination = Application.settings.get_string 
("destination");
-
-                if (Application.settings.get_boolean ("auto-save")) { // The 
app saved files automatically
-                    try {
-                        var uri = File.new_for_path (destination + "/" + 
filename + suffix);
-                        tmp_source.move (uri, FileCopyFlags.OVERWRITE);
-                    } catch (Error e) {
-                        warning (e.message);
-                    }
-                } else { // The app asks destination and filename each time
-                    var filechooser = new Gtk.FileChooserNative (
-                        _("Save your recording"), window, 
Gtk.FileChooserAction.SAVE,
-                        _("Save"), _("Cancel"));
-                    filechooser.set_current_name (filename + suffix);
-                    filechooser.set_filename (destination);
-                    filechooser.do_overwrite_confirmation = true;
-
-                    if (filechooser.run () == Gtk.ResponseType.ACCEPT) {
-                        try {
-                            var uri = File.new_for_path 
(filechooser.get_filename ());
-                            tmp_source.move (uri, FileCopyFlags.OVERWRITE);
-                        } catch (Error e) {
-                            warning (e.message);
-                        }
-                    } else {
-                        try {
-                            tmp_source.delete ();
-                        } catch (Error e) {
-                            warning (e.message);
-                        }
-                    }
+                window.recorder.set_recording_state (Gst.State.PAUSED);
+                pause_button.image = new Gtk.Image.from_icon_name 
("media-playback-start-symbolic", Gtk.IconSize.BUTTON);
+                pause_button.tooltip_text = _("Resume recording");
+            } else {
+                start_count ();
 
-                    filechooser.destroy ();
+                if (Application.settings.get_int ("length") != 0) {
+                    start_countdown ();
                 }
 
-                pipeline.dispose ();
-                pipeline = null;
-                break;
-            default:
-                break;
-        }
-
-        return true;
-    }
-
-    public void start_recording () {
-        init_count ();
-
-        pipeline = new Gst.Pipeline ("pipeline");
-        audiobin = new Gst.Bin ("audio");
-        var sink = Gst.ElementFactory.make ("filesink", "sink");
-
-        if (pipeline == null) {
-            error ("Gstreamer sink was not created correctly!");
-        } else if (audiobin == null) {
-            error ("Gstreamer pipeline was not created correctly!");
-        } else if (sink == null) {
-            error ("Gstreamer audiobin was not created correctly!");
-        }
-
-        string command = Application.settings.get_boolean ("system-sound") ? 
"pacmd list-sinks" : "pacmd list-sources";
-        string default_device = "";
-        try {
-            string sound_devices = "";
-            Process.spawn_command_line_sync (command, out sound_devices);
-            var re = new Regex 
("(?<=\\*\\sindex:\\s\\d\\s\\sname:\\s<)[\\w\\.\\-]*");
-            MatchInfo mi;
-
-            if (re.match (sound_devices, 0, out mi)) {
-                default_device = mi.fetch (0);
+                window.recorder.set_recording_state (Gst.State.PLAYING);
+                pause_button.image = new Gtk.Image.from_icon_name 
("media-playback-pause-symbolic", Gtk.IconSize.BUTTON);
+                pause_button.tooltip_text = _("Pause recording");
             }
-
-            if (Application.settings.get_boolean ("system-sound")) {
-                default_device += ".monitor";
-            }
-        } catch (Error e) {
-            warning (e.message);
-        }
-
-        assert (sink != null);
-        string tmp_destination = Environment.get_tmp_dir ();
-        string tmp_filename = "reco_" + new DateTime.now_local ().to_unix 
().to_string ();
-
-        string file_format = Application.settings.get_string ("format");
-
-        try {
-            switch (file_format) {
-                case "aac":
-                    audiobin = (Gst.Bin) Gst.parse_bin_from_description 
("pulsesrc device=" + default_device + " ! avenc_aac ! mp4mux", true);
-                    suffix = ".m4a";
-                    break;
-                case "flac":
-                    audiobin = (Gst.Bin) Gst.parse_bin_from_description 
("pulsesrc device=" + default_device + " ! flacenc", true);
-                    suffix = ".flac";
-                    break;
-                case "mp3":
-                    audiobin = (Gst.Bin) Gst.parse_bin_from_description 
("pulsesrc device=" + default_device + " ! lamemp3enc", true);
-                    suffix = ".mp3";
-                    break;
-                case "ogg":
-                    audiobin = (Gst.Bin) Gst.parse_bin_from_description 
("pulsesrc device=" + default_device + " ! vorbisenc ! oggmux", true);
-                    suffix = ".ogg";
-                    break;
-                case "opus":
-                    audiobin = (Gst.Bin) Gst.parse_bin_from_description 
("pulsesrc device=" + default_device + " ! opusenc ! oggmux", true);
-                    suffix = ".opus";
-                    break;
-                default:
-                    audiobin = (Gst.Bin) Gst.parse_bin_from_description 
("pulsesrc device=" + default_device + " ! wavenc", true);
-                    suffix = ".wav";
-                    break;
-            }
-        } catch (Error e) {
-            error ("Could not set the audio format correctly: %s", e.message);
-        }
-
-        tmp_full_path = tmp_destination + "/%s%s".printf (tmp_filename, 
suffix);
-        sink.set ("location", tmp_full_path);
-        debug ("The recording is stored at %s temporary".printf 
(tmp_full_path));
-
-        pipeline.add_many (audiobin, sink);
-        audiobin.link (sink);
-
-        pipeline.get_bus ().add_watch (Priority.DEFAULT, bus_message_cb);
-        pipeline.set_state (Gst.State.PLAYING);
-
-        int record_length = Application.settings.get_int ("length");
-        if (record_length != 0) {
-            init_countdown (record_length);
-        }
-    }
-
-    public void cancel_recording () {
-        if (count != 0) {
-            count = 0;
-        }
-
-        if (countdown != 0) {
-            countdown = 0;
-            remaining_time_label.label = null;
-        }
-
-        pipeline.set_state (Gst.State.NULL);
-        pipeline.dispose ();
-        pipeline = null;
-
-        // Remove canceled file in /tmp
-        try {
-            File.new_for_path (tmp_full_path).delete ();
-        } catch (Error e) {
-            warning (e.message);
-        }
+        });
     }
 
-    public async void stop_recording () {
-        if (count != 0) {
-            count = 0;
-        }
-
-        if (countdown != 0) {
-            countdown = 0;
-            remaining_time_label.label = null;
-        }
+    public async void trigger_stop_recording () {
+        stop_count ();
 
         // If a user tries to stop recording while pausing, resume recording 
once and reset the button icon
-        if (!is_recording) {
-            pipeline.set_state (Gst.State.PLAYING);
-            is_recording = true;
+        if (!window.recorder.is_recording) {
+            window.recorder.set_recording_state (Gst.State.PLAYING);
             pause_button.image = new Gtk.Image.from_icon_name 
("media-playback-pause-symbolic", Gtk.IconSize.BUTTON);
             pause_button.tooltip_text = _("Pause recording");
         }
 
-        if (pipeline.send_event (new Gst.Event.eos ())) {
-            window.welcome_view.show_success_button ();
-        }
-
+        window.recorder.stop_recording ();
         window.show_welcome ();
-        is_recording = false;
+        window.recorder.set_recording_state (Gst.State.PAUSED);
     }
 
-    private void pause_recording () {
-        if (is_recording) {
-            if (count != 0) {
-                count = 0;
-            }
-
-            if (countdown != 0) {
-                countdown = 0;
-            }
-
-            pipeline.set_state (Gst.State.PAUSED);
-            is_recording = false;
-            pause_button.image = new Gtk.Image.from_icon_name 
("media-playback-start-symbolic", Gtk.IconSize.BUTTON);
-            pause_button.tooltip_text = _("Resume recording");
-        } else {
-            start_count ();
-
-            if (Application.settings.get_int ("length") != 0) {
-                start_countdown ();
-            }
-
-            pipeline.set_state (Gst.State.PLAYING);
-            is_recording = true;
-            pause_button.image = new Gtk.Image.from_icon_name 
("media-playback-pause-symbolic", Gtk.IconSize.BUTTON);
-            pause_button.tooltip_text = _("Pause recording");
-        }
-    }
-
-    private void init_count () {
+    public void init_count () {
         past_minutes_10 = 0;
         past_minutes_1 = 0;
         past_seconds_10 = 0;
@@ -371,7 +154,6 @@
 
         // Show initial time (00:00)
         show_timer_label (time_label, past_minutes_10, past_minutes_1, 
past_seconds_10, past_seconds_1);
-        is_recording = true;
 
         start_count ();
     }
@@ -397,11 +179,21 @@
 
             show_timer_label (time_label, past_minutes_10, past_minutes_1, 
past_seconds_10, past_seconds_1);
 
-            return is_recording? true : false;
+            return window.recorder.is_recording? true : false;
         });
     }
 
-    private void init_countdown (int remaining_time) {
+    public void stop_count () {
+        if (count != 0) {
+            count = 0;
+        }
+
+        if (countdown != 0) {
+            countdown = 0;
+        }
+    }
+
+    public void init_countdown (int remaining_time) {
         int remain_minutes = remaining_time / 60;
         if (remain_minutes < 10) {
             remain_minutes_10 = 0;
@@ -422,7 +214,6 @@
 
         // Show initial time (00:00)
         show_timer_label (time_label, past_minutes_10, past_minutes_1, 
past_seconds_10, past_seconds_1);
-        is_recording = true;
 
         start_countdown ();
     }
@@ -455,14 +246,14 @@
 
             if (remain_minutes_10 == 0 && remain_minutes_1 == 0 && 
remain_seconds_10 == 0 && remain_seconds_1 == 0) {
                 var loop = new MainLoop ();
-                window.record_view.stop_recording.begin ((obj, res) => {
+                trigger_stop_recording.begin ((obj, res) => {
                     loop.quit ();
                 });
                 loop.run ();
                 return false;
             }
 
-            return is_recording? true : false;
+            return window.recorder.is_recording? true : false;
         });
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/reco-2.1.0/src/Views/WelcomeView.vala 
new/reco-2.2.0/src/Views/WelcomeView.vala
--- old/reco-2.1.0/src/Views/WelcomeView.vala   2019-08-03 02:36:52.000000000 
+0200
+++ new/reco-2.2.0/src/Views/WelcomeView.vala   2019-09-08 15:45:30.000000000 
+0200
@@ -109,21 +109,10 @@
         pack_start (settings_grid, false, false);
         pack_end (record_button, false, false);
 
-        delay_spin.changed.connect (() => {
-            Application.settings.set_int ("delay", delay_spin.get_value_as_int 
());
-        });
-
-        length_spin.changed.connect (() => {
-            Application.settings.set_int ("length", 
length_spin.get_value_as_int ());
-        });
-
-        system_sound_switch.notify["active"].connect (() => {
-            Application.settings.set_boolean ("system-sound", 
system_sound_switch.active);
-        });
-
-        format_combobox.changed.connect (() => {
-            Application.settings.set_enum ("format", format_combobox.active);
-        });
+        Application.settings.bind ("delay", delay_spin, "value", 
SettingsBindFlags.DEFAULT);
+        Application.settings.bind ("length", length_spin, "value", 
SettingsBindFlags.DEFAULT);
+        Application.settings.bind ("system-sound", system_sound_switch, 
"active", SettingsBindFlags.DEFAULT);
+        Application.settings.bind ("format", format_combobox, "active_id", 
SettingsBindFlags.DEFAULT);
 
         auto_save.notify["active"].connect (() => {
             destination_chooser.sensitive = auto_save.active;


Reply via email to