[gnome-sound-recorder] edit recording name



commit 03a82ae947e074cb3bc554381019405a7faaf6e3
Author: Kavan Mevada <kavanmevada gmail com>
Date:   Thu Jun 18 00:35:50 2020 +0530

    edit recording name

 data/application.css |   4 ++
 data/ui/row.ui       | 187 ++++++++++++++++++++++++++++++++++++++-------------
 src/recorder.js      |   3 +-
 src/recording.js     |  16 ++++-
 src/row.js           |  45 +++++++++++--
 src/window.js        |   1 +
 6 files changed, 201 insertions(+), 55 deletions(-)
---
diff --git a/data/application.css b/data/application.css
index b6d807e..961c753 100644
--- a/data/application.css
+++ b/data/application.css
@@ -11,3 +11,7 @@
 .large-button {
   padding: 12px 12px;
 }
+
+row label.subtitle {
+  font-size: smaller;
+}
\ No newline at end of file
diff --git a/data/ui/row.ui b/data/ui/row.ui
index fb193c8..fa04ea5 100644
--- a/data/ui/row.ui
+++ b/data/ui/row.ui
@@ -2,94 +2,191 @@
 <!-- Generated with glade 3.22.2 -->
 <interface>
   <requires lib="gtk+" version="3.20"/>
-  <requires lib="libhandy" version="0.0"/>
-  <template class="Gjs_Row" parent="HdyPreferencesRow">
+  <template class="Gjs_Row" parent="GtkListBoxRow">
     <property name="visible">True</property>
     <property name="can_focus">True</property>
     <child>
-      <object class="GtkBox">
+      <object class="GtkStack" id="mainStack">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
-        <property name="no_show_all">True</property>
+        <property name="margin_top">12</property>
+        <property name="margin_bottom">12</property>
         <child>
-          <object class="GtkStack" id="playbackStack">
+          <object class="GtkBox">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="margin_start">12</property>
+            <property name="no_show_all">True</property>
             <child>
-              <object class="GtkButton" id="playButton">
-                <property name="name">playButton</property>
+              <object class="GtkStack" id="playbackStack">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="halign">center</property>
-                <property name="valign">center</property>
-                <property name="vexpand">True</property>
-                <property name="always_show_image">True</property>
+                <property name="can_focus">False</property>
+                <property name="margin_left">12</property>
+                <property name="margin_start">12</property>
                 <child>
-                  <object class="GtkImage" id="playIcon">
+                  <object class="GtkButton" id="playButton">
+                    <property name="name">playButton</property>
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="icon_name">media-playback-start-symbolic</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="halign">center</property>
+                    <property name="valign">center</property>
+                    <property name="always_show_image">True</property>
+                    <child>
+                      <object class="GtkImage" id="playIcon">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">media-playback-start-symbolic</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="name">play</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="pauseButton">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="halign">center</property>
+                    <property name="valign">center</property>
+                    <property name="always_show_image">True</property>
+                    <child>
+                      <object class="GtkImage" id="pauseIcon">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">media-playback-pause-symbolic</property>
+                      </object>
+                    </child>
                   </object>
+                  <packing>
+                    <property name="name">pause</property>
+                    <property name="position">1</property>
+                  </packing>
                 </child>
               </object>
               <packing>
-                <property name="name">play</property>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
               </packing>
             </child>
             <child>
-              <object class="GtkButton" id="pauseButton">
+              <object class="GtkBox">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="halign">center</property>
+                <property name="can_focus">False</property>
                 <property name="valign">center</property>
-                <property name="vexpand">True</property>
-                <property name="always_show_image">True</property>
+                <property name="margin_left">12</property>
+                <property name="hexpand">True</property>
+                <child>
+                  <object class="GtkLabel" id="duration">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="halign">end</property>
+                    <property name="margin_right">12</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="pack_type">end</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
                 <child>
-                  <object class="GtkImage" id="pauseIcon">
+                  <object class="GtkBox">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="icon_name">media-playback-pause-symbolic</property>
+                    <property name="margin_right">12</property>
+                    <property name="orientation">vertical</property>
+                    <child>
+                      <object class="GtkLabel" id="name">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="date">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <style>
+                          <class name="subtitle"/>
+                        </style>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
                   </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">2</property>
+                  </packing>
                 </child>
               </object>
               <packing>
-                <property name="name">pause</property>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
                 <property name="position">1</property>
               </packing>
             </child>
           </object>
           <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
+            <property name="name">display</property>
           </packing>
         </child>
         <child>
-          <object class="HdyActionRow" id="action_row">
+          <object class="GtkBox">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="hexpand">True</property>
+            <property name="can_focus">False</property>
             <child>
-              <object class="GtkLabel" id="duration">
+              <object class="GtkEntry" id="entry">
                 <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="valign">start</property>
-                <property name="margin_top">8</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
+                <property name="can_focus">True</property>
+                <property name="valign">center</property>
+                <property name="margin_left">12</property>
+                <property name="activates_default">True</property>
               </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="saveBtn">
+                <property name="label" translatable="yes">Save</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="valign">center</property>
+                <property name="margin_left">12</property>
+                <property name="margin_right">12</property>
+                <signal name="clicked" handler="onSaveRecording" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">1</property>
+              </packing>
             </child>
-            <style>
-              <class name="header"/>
-            </style>
           </object>
           <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
+            <property name="name">edit</property>
             <property name="position">1</property>
           </packing>
         </child>
diff --git a/src/recorder.js b/src/recorder.js
index 6ec9d5f..6d9f329 100644
--- a/src/recorder.js
+++ b/src/recorder.js
@@ -155,7 +155,8 @@ var Recorder = new GObject.registerClass({
             this.recordBus = null;
         }
 
-        return this.file ? new Recording(this.file) : null;
+        return this.file && this.file.query_exists(null)
+            ? new Recording(this.file) : null;
     }
 
     _onMessageReceived(message) {
diff --git a/src/recording.js b/src/recording.js
index d4c358a..bad742a 100644
--- a/src/recording.js
+++ b/src/recording.js
@@ -8,14 +8,17 @@ var Recording = new GObject.registerClass({
             'Recording Duration', 'Recording duration in seconds',
             GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT,
             0, GLib.MAXINT16, 0),
+        'name': GObject.ParamSpec.string(
+            'name',
+            'Recording Name', 'Recording name in string',
+            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT,
+            null),
     },
 }, class Recording extends GObject.Object {
     _init(file) {
         super._init({});
         this._file = file;
 
-        this._name = file.get_basename();
-
         let info = file.query_info('time::created,time::modified', 0, null);
 
         let timeModified = info.get_attribute_uint64('time::modified');
@@ -34,7 +37,14 @@ var Recording = new GObject.registerClass({
     }
 
     get name() {
-        return this._name;
+        return this._file.get_basename();
+    }
+
+    set name(filename) {
+        if (filename && filename !== this.name) {
+            this._file = this._file.set_display_name(filename, null);
+            this.notify('name');
+        }
     }
 
     get timeModified() {
diff --git a/src/row.js b/src/row.js
index 4610a85..ebbc534 100644
--- a/src/row.js
+++ b/src/row.js
@@ -1,5 +1,5 @@
 /* exported Row RowState */
-const { GObject, Handy } = imports.gi;
+const { Gdk, GObject, Gtk } = imports.gi;
 const { displayDateTime, formatTime } = imports.utils;
 
 const RowState = {
@@ -9,22 +9,34 @@ const RowState = {
 
 var Row = GObject.registerClass({
     Template: 'resource:///org/gnome/SoundRecorder/ui/row.ui',
-    InternalChildren: ['playbackStack', 'action_row', 'playButton', 'pauseButton', 'duration'],
+    InternalChildren: ['playbackStack', 'mainStack', 'playButton', 'pauseButton', 'name', 'entry', 'date', 
'duration', 'saveBtn'],
     Signals: {
         'play': { param_types: [GObject.TYPE_STRING] },
         'pause': {},
         'deleted': {},
     },
-}, class Row extends Handy.PreferencesRow {
+}, class Row extends Gtk.ListBoxRow {
     _init(recording) {
         super._init({});
+        this._recording = recording;
 
-        this._action_row.title = recording.name;
+        recording.bind_property('name', this._name, 'label', GObject.BindingFlags.SYNC_CREATE | 
GObject.BindingFlags.DEFAULT);
+        recording.bind_property('name', this._entry, 'text', GObject.BindingFlags.SYNC_CREATE | 
GObject.BindingFlags.DEFAULT);
+
+        this._editMode = false;
+
+        this._entry.connect('key-press-event', (_, event) => {
+            const key = event.get_keyval()[1];
+            this._entry.get_style_context().remove_class('error');
+
+            if (key === Gdk.KEY_Escape)
+                this.editMode = false;
+        });
 
         if (recording.timeCreated > 0)
-            this._action_row.subtitle = displayDateTime(recording.timeCreated);
+            this._date.label = displayDateTime(recording.timeCreated);
         else
-            this._action_row.subtitle = displayDateTime(recording.timeModified);
+            this._date.label = displayDateTime(recording.timeModified);
 
         recording.connect('notify::duration', () => {
             this._duration.label = formatTime(recording.duration);
@@ -46,10 +58,31 @@ var Row = GObject.registerClass({
         // });
     }
 
+    onSaveRecording() {
+        try {
+            if (this._name.label !== this._entry.text)
+                this._recording.name = this._entry.text;
+
+            this.editMode = false;
+            this._entry.get_style_context().remove_class('error');
+        } catch (e) {
+            this._entry.get_style_context().add_class('error');
+        }
+    }
+
     setState(rowState) {
         if (rowState === RowState.PLAYING)
             this._playbackStack.visible_child_name = 'pause';
         else if (rowState === RowState.PAUSED)
             this._playbackStack.visible_child_name = 'play';
     }
+
+    set editMode(state) {
+        this._mainStack.visible_child_name = state ? 'edit' : 'display';
+
+        if (state) {
+            this._entry.grab_focus();
+            this._saveBtn.grab_default();
+        }
+    }
 });
diff --git a/src/window.js b/src/window.js
index 2146f17..e495799 100644
--- a/src/window.js
+++ b/src/window.js
@@ -109,6 +109,7 @@ var Window = GObject.registerClass({
     onRecorderStop() {
         const recording = this.recorder.stop();
         this._recordingList.insert(0, recording);
+        this._listBox.get_row_at_index(0).editMode = true;
         this._setMainView();
     }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]