[gnome-documents] properties: first implementation of a Properties dialog



commit 655a2201a984ef9f62bb06236d95f5cdd0879ac0
Author: Meg Ford <meg387 gmail com>
Date:   Tue Jul 31 11:30:23 2012 +0200

    properties: first implementation of a Properties dialog

 src/Makefile-js.am  |    1 +
 src/documents.js    |    9 +++
 src/properties.js   |  195 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/query.js        |    4 +-
 src/selections.js   |   25 ++++++-
 src/trackerUtils.js |   17 +++++
 6 files changed, 249 insertions(+), 2 deletions(-)
---
diff --git a/src/Makefile-js.am b/src/Makefile-js.am
index 725c7ba..7afe581 100644
--- a/src/Makefile-js.am
+++ b/src/Makefile-js.am
@@ -14,6 +14,7 @@ dist_js_DATA = \
     notifications.js \
     offsetController.js \
     preview.js \
+    properties.js\
     query.js \
     searchbar.js \
     selections.js \
diff --git a/src/documents.js b/src/documents.js
index ca3c1b7..783ba56 100644
--- a/src/documents.js
+++ b/src/documents.js
@@ -282,6 +282,7 @@ const DocCommon = new Lang.Class({
 
         this.mimeType = null;
         this.rdfType = null;
+        this.dateCreated = null;
         this.typeDescription = null;
         this.sourceName = null;
 
@@ -339,6 +340,14 @@ const DocCommon = new Lang.Class({
         this.rdfType = cursor.get_string(Query.QueryColumns.RDFTYPE)[0];
         this._updateInfoFromType();
 
+        let dateCreated = cursor.get_string(Query.QueryColumns.DATE_CREATED)[0];
+        if (dateCreated) {
+            let timeVal = GLib.time_val_from_iso8601(dateCreated)[1];
+            this.dateCreated = timeVal.tv_sec;
+        } else {
+            this.dateCreated = -1;
+        }
+
         // sanitize
         if (!this.uri)
             this.uri = '';
diff --git a/src/properties.js b/src/properties.js
new file mode 100644
index 0000000..51f0f74
--- /dev/null
+++ b/src/properties.js
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2012 Meg Ford
+ *
+ * Gnome Documents 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.
+ *
+ * Gnome Documents 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 Gnome Documents; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Meg Ford <megford gnome org>
+ *
+ */
+
+const Gd = imports.gi.Gd;
+const Gdk = imports.gi.Gdk;
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
+const Gtk = imports.gi.Gtk;
+const GtkClutter = imports.gi.GtkClutter;
+const _ = imports.gettext.gettext;
+
+const Documents = imports.documents;
+const Global = imports.global;
+const Mainloop = imports.mainloop;
+const Manager = imports.manager;
+const Notifications = imports.notifications;
+const Query = imports.query;
+const Selections = imports.selections;
+const TrackerUtils = imports.trackerUtils;
+const Utils = imports.utils;
+
+const Lang = imports.lang;
+const Signals = imports.signals;
+
+const _TITLE_ENTRY_TIMEOUT = 200;
+
+const PropertiesDialog = new Lang.Class({
+    Name: 'PropertiesDialog',
+ 	
+    _init: function(urn) {
+        this._urn = urn; 
+        let doc = Global.documentManager.getItemById(this._urn);
+
+        if (doc instanceof Documents.LocalDocument ){
+            this._sourceLink = Gio.file_new_for_uri(doc.uri).get_parent();
+            this._sourcePath = this._sourceLink.get_path();
+        } 
+
+        let _dateModified = GLib.DateTime.new_from_unix_local(doc.mtime);
+        this._dateModifiedString = _dateModified.format('%c');
+
+        if (doc.dateCreated != -1) {
+            let _dateCreated = GLib.DateTime.new_from_unix_local(doc.dateCreated);
+            this._dateCreatedString = _dateCreated.format('%c');
+        } else {
+            this._dateCreatedString = null;
+        }
+        this.docId = doc.id;
+        this._titleEntryTimeout = 0;
+
+        let toplevel = Global.application.get_windows()[0];
+        this.widget = new Gtk.Dialog ({ resizable: false, 
+                                        transient_for: toplevel,
+                                        modal: true,
+                                        destroy_with_parent: true,
+                                        default_width: 400, 
+                                        hexpand: true });
+       
+        let grid = new Gtk.Grid ({ orientation: Gtk.Orientation.VERTICAL, 
+                                   column_homogeneous: true,
+                                   halign: Gtk.Align.CENTER,
+                        	       row_spacing: 12,
+                                   column_spacing: 24,
+                                   margin_left: 24,
+                                   margin_right: 24,
+				                   margin_bottom: 12 });
+
+        let contentArea = this.widget.get_content_area();
+
+        this._done = new Gtk.Button({label: "Done"}); //Label for Done button in Properties dialog
+        this.widget.add_button('Done', Gtk.ResponseType.OK); 
+
+        this._message = new Gtk.Label ({ label: '<span size="large"><b>' + _("Properties") + '</b></span>', //Label for Properties dialog
+                	                     halign: Gtk.Align.CENTER,
+                                         use_markup: true, 
+                                         hexpand: false });
+        grid.attach (this._message, 1, 0, 1, 1);
+        
+        this._title = new Gtk.Label({ label: _("Title"), //Label for Title item in Properties dialog
+       	                              halign: Gtk.Align.END });
+        this._title.get_style_context ().add_class('dim-label')
+        grid.add(this._title);
+
+        this._author = new Gtk.Label({ label: _("Author"), //Label for Author item in Properties dialog
+       	                               halign: Gtk.Align.END });
+        this._author.get_style_context ().add_class('dim-label')
+        grid.add(this._author);
+     
+        this._source = new Gtk.Label({ label: _("Source"), //Label for Source item in Properties dialog
+                                       halign: Gtk.Align.END });
+        this._source.get_style_context ().add_class('dim-label')
+        grid.add (this._source);
+
+        this._dateModified = new Gtk.Label({ label: _("Date Modified"), //Label for Date Modified item in Properties dialog
+                                             halign: Gtk.Align.END });
+        this._dateModified.get_style_context ().add_class('dim-label')
+        grid.add (this._dateModified);
+
+        if (this._dateCreated) {
+            this._dateCreated = new Gtk.Label({ label: _("Date Created"), //Label for Date Created item in Properties dialog
+                                                halign: Gtk.Align.END });
+            this._dateCreated.get_style_context ().add_class('dim-label') 
+            grid.add (this._dateCreated);
+        }
+
+        this._docType = new Gtk.Label({ label: _("Type"), //Label for document Type in Properties dialog
+ 				       halign: Gtk.Align.END });
+        this._docType.get_style_context ().add_class('dim-label')
+        grid.add (this._docType);
+
+        if (doc instanceof Documents.LocalDocument) {
+	        this._titleEntry = new Gtk.Entry({ text: doc.name,
+                                               editable: true,
+					                           hexpand: true,
+					                           halign: Gtk.Align.START });
+        grid.attach_next_to (this._titleEntry, this._title, 1, 2, 1);
+	    this._titleEntry.connect("changed", Lang.bind (this, 
+            function(newTitle, docId) { 
+                if (this._titleEntryTimeout != 0) {
+                    Mainloop.source_remove(this._titleEntryTimeout);
+                    this._titleEntryTimeout = 0;
+                }
+
+                this._titleEntryTimeout = Mainloop.timeout_add(_TITLE_ENTRY_TIMEOUT, Lang.bind(this,
+                    function() {
+                        this._titleEntryTimeout = 0;
+                        this.newTitle = this._titleEntry.get_text();
+                        TrackerUtils.setEditedName(this.newTitle, this.docId, null);}));
+            }));
+        } else {
+	        this._titleEntry = new Gtk.Label({ label: doc.name,
+	         			                       halign: Gtk.Align.START });
+	    grid.attach_next_to (this._titleEntry, this._title, 1, 2, 1);
+        }
+
+        this._authorData = new Gtk.Label({ label: doc.author,
+					                       halign: Gtk.Align.START });
+	    grid.attach_next_to (this._authorData, this._author, 1, 2, 1);
+
+	    if (doc instanceof Documents.LocalDocument ){
+	        this._sourceData = new Gtk.LinkButton({ label: this._sourcePath,
+						                            uri: this._sourceLink.get_uri(),
+					                                halign: Gtk.Align.START });
+	    } else if (doc instanceof Documents.GoogleDocument) {
+	        this._sourceData = new Gtk.LinkButton({ label: doc.sourceName,
+                                                    uri: "http://docs.google.com/";,
+					                                halign: Gtk.Align.START });
+        } else if (doc instanceof Documents.SkydriveDocument) {
+	        this._sourceData = new Gtk.LinkButton({ label: doc.sourceName,
+                                                    uri: "https://skydrive.live.com";,
+					                                halign: Gtk.Align.START });
+        }
+
+	    grid.attach_next_to (this._sourceData, this._source, 1, 2, 1);
+
+	    this._dateModifiedData = new Gtk.Label({ label: this._dateModifiedString,
+						                         halign: Gtk.Align.START });
+	    grid.attach_next_to (this._dateModifiedData, this._dateModified, 1, 2, 1);
+
+	    if (this._dateCreated) {
+            this._dateCreatedString = new Gtk.Label({ label: this._dateCreated,
+						                            halign: Gtk.Align.START });
+	    grid.attach_next_to (this._dateCreatedData, this._dateCreated, 1, 2, 1);
+	    }
+
+	    this._documentTypeData = new Gtk.Label({ label: doc.typeDescription,
+	       					                     halign: Gtk.Align.START });
+	    grid.attach_next_to (this._documentTypeData, this._docType, 1, 2, 1);
+
+        contentArea.pack_start(grid, true, true, 2);
+	    this.widget.show_all();
+    },
+
+
+});
+
diff --git a/src/query.js b/src/query.js
index 1f4df54..c5a7509 100644
--- a/src/query.js
+++ b/src/query.js
@@ -38,7 +38,8 @@ const QueryColumns = {
     RDFTYPE: 8,
     RESOURCE_URN: 9,
     FAVORITE: 10,
-    SHARED: 11
+    SHARED: 11,
+    DATE_CREATED: 12
 };
 
 const QueryFlags = {
@@ -198,6 +199,7 @@ const QueryBuilder = new Lang.Class({
             'nie:dataSource(?urn) ' + // resource URN
             '( EXISTS { ?urn nao:hasTag nao:predefined-tag-favorite } ) ' + // favorite
             '( EXISTS { ?urn nco:contributor ?contributor FILTER ( ?contributor != ?creator ) } ) ' + // shared
+            'tracker:coalesce(nfo:fileCreated(?urn), nie:contentCreated(?urn)) ' + // date created
             whereSparql + tailSparql;
 
         return sparql;
diff --git a/src/selections.js b/src/selections.js
index 2309a6c..d02bf49 100644
--- a/src/selections.js
+++ b/src/selections.js
@@ -34,6 +34,7 @@ const Documents = imports.documents;
 const Global = imports.global;
 const Manager = imports.manager;
 const Notifications = imports.notifications;
+const Properties = imports.properties;
 const Query = imports.query;
 const Tweener = imports.util.tweener;
 const Utils = imports.utils;
@@ -768,6 +769,12 @@ const SelectionToolbar = new Lang.Class({
         this._leftBox.add(this._toolbarFavorite);
         this._toolbarFavorite.connect('clicked', Lang.bind(this, this._onToolbarFavorite));
 
+        this._toolbarProperties = new Gtk.Button({ child: new Gtk.Image ({ icon_name: 'document-properties-symbolic',
+                                                                           pixel_size: 32 })});
+        this._toolbarProperties.set_tooltip_text(_("Properties"));
+        this._leftBox.add(this._toolbarProperties);
+        this._toolbarProperties.connect('clicked', Lang.bind(this, this._onToolbarProperties));
+
         this._toolbarPrint = new Gtk.Button({ child: new Gtk.Image ({ icon_name: 'printer-symbolic',
                                                                       pixel_size: 32 })});
         this._toolbarPrint.set_tooltip_text(_("Print"));
@@ -852,6 +859,7 @@ const SelectionToolbar = new Lang.Class({
         let showFavorite = true;
         let showTrash = true;
         let showPrint = true;
+        let showProperties = true;
         let showOpen = true;
 
         this._insideRefresh = true;
@@ -875,8 +883,10 @@ const SelectionToolbar = new Lang.Class({
         showFavorite &= ((favCount == 0) || (favCount == selection.length));
         showOpen = (apps.length > 0);
 
-        if (selection.length > 1)
+        if (selection.length > 1) {
             showPrint = false;
+            showProperties = false;
+        }
 
         let openLabel = null;
         if (apps.length == 1) {
@@ -907,6 +917,7 @@ const SelectionToolbar = new Lang.Class({
         }
 
         this._toolbarPrint.set_visible(showPrint);
+        this._toolbarProperties.set_visible(showProperties);
         this._toolbarTrash.set_visible(showTrash);
         this._toolbarOpen.set_visible(showOpen);
         this._toolbarFavorite.set_visible(showFavorite);
@@ -964,6 +975,18 @@ const SelectionToolbar = new Lang.Class({
             }));
     },
 
+    _onToolbarProperties: function(widget) {
+        let selection = Global.selectionController.getSelection();
+        let dialog = new Properties.PropertiesDialog(selection[0]);
+        this._fadeOut();
+
+        dialog.widget.connect('response', Lang.bind(this,
+            function(widget, response) {
+                dialog.widget.destroy();
+                this._fadeIn();
+            }));
+    },
+
     _onToolbarPrint: function(widget) {
         let selection = Global.selectionController.getSelection();
 
diff --git a/src/trackerUtils.js b/src/trackerUtils.js
index 73e43a1..d667da6 100644
--- a/src/trackerUtils.js
+++ b/src/trackerUtils.js
@@ -38,3 +38,20 @@ function setFavorite(urn, isFavorite, callback) {
                 callback();
         });
 }
+
+function setEditedName(newTitle, docId, callback) {
+    let sparql = ('INSERT OR REPLACE { <%s> nfo:fileName\"%s\" }'.format(docId, newTitle));
+
+    Global.connectionQueue.update(sparql, null,
+        function(object, res) {
+            try {
+                object.update_finish(res);
+            } catch (e) {
+                log('Unable to set the new title on ' + docId + ' to : ' + e.toString());
+            }
+
+            if (callback)
+                callback();
+        });
+
+}



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