Hello community, here is the log from the commit of package spice-up for openSUSE:Factory checked in at 2018-10-02 19:48:30 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/spice-up (Old) and /work/SRC/openSUSE:Factory/.spice-up.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "spice-up" Tue Oct 2 19:48:30 2018 rev:12 rq:639447 version:1.6.0 Changes: -------- --- /work/SRC/openSUSE:Factory/spice-up/spice-up.changes 2018-09-18 11:47:01.203687035 +0200 +++ /work/SRC/openSUSE:Factory/.spice-up.new/spice-up.changes 2018-10-02 19:49:20.293711564 +0200 @@ -1,0 +2,17 @@ +Mon Sep 24 10:42:29 UTC 2018 - Alexei Podvalsky <avvi...@yandex.by> + +- Update to 1.6.0: + * Code cleanups + * Slide Transitions (#236) + * Add: PresenterNotes.vala + * Add option to set a slide as the File Preview + * SlideList: Right click actions + * Add presenter notes to main view + * Move button creation to function + * SlideList: Add separator and fix styles + * Add new slide after selected one + * Stick new slide button + * Fix: Empty slides not rendering in slide list + * Set accent color & use that on slide list + +------------------------------------------------------------------- Old: ---- Spice-up-1.5.2.tar.gz New: ---- Spice-up-1.6.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ spice-up.spec ++++++ --- /var/tmp/diff_new_pack.XQKTGo/_old 2018-10-02 19:49:22.125709656 +0200 +++ /var/tmp/diff_new_pack.XQKTGo/_new 2018-10-02 19:49:22.129709651 +0200 @@ -17,7 +17,7 @@ Name: spice-up -Version: 1.5.2 +Version: 1.6.0 Release: 0 Summary: Desktop presentation application License: GPL-3.0-only ++++++ Spice-up-1.5.2.tar.gz -> Spice-up-1.6.0.tar.gz ++++++ Binary files old/Spice-up-1.5.2/Screenshot.png and new/Spice-up-1.6.0/Screenshot.png differ Binary files old/Spice-up-1.5.2/Screenshot1.png and new/Spice-up-1.6.0/Screenshot1.png differ Binary files old/Spice-up-1.5.2/Screenshot2.png and new/Spice-up-1.6.0/Screenshot2.png differ Binary files old/Spice-up-1.5.2/Screenshot3.png and new/Spice-up-1.6.0/Screenshot3.png differ Binary files old/Spice-up-1.5.2/Screenshot4.png and new/Spice-up-1.6.0/Screenshot4.png differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/data/com.github.philip-scott.spice-up.appdata.xml new/Spice-up-1.6.0/data/com.github.philip-scott.spice-up.appdata.xml --- old/Spice-up-1.5.2/data/com.github.philip-scott.spice-up.appdata.xml 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/data/com.github.philip-scott.spice-up.appdata.xml 2018-09-24 06:56:52.000000000 +0200 @@ -26,7 +26,22 @@ <binary>spice-up</binary> </provides> <releases> - <release version="1.5.2" date="2018-8-23"> + <release version="1.6.0" date="2018-9-23"> + <description> + <p>Slide Transitions and the Slide List Redesign</p> + <ul> + <li>After so long, Slide Transitions are finally here! Use them to make your presentations more interesting</li> + <li>The New Slide Button will now always appear at the bottom, and new slides will now be added after the currently selected slide</li> + <li>You can right click the slide, and select from the actions there.</li> + <li>From that right click menu, you can now select which slide will be shown in the thumbnail!</li> + <li>Presenter notes has been moved to the main window. Toggle the editor from the new button on the headerbar!</li> + <li>Some color and Style changes!</li> + <li>Fixed the problem where empty slides would refuse to render on the Slide List!</li> + <li>Fixed: Non-editable items on the toolbar now show up properly</li> + </ul> + </description> + </release> + <release version="1.5.2" date="2018-8-23"> <description> <p>A Very Juno Update</p> <ul> @@ -173,7 +188,7 @@ <content_attribute id="language-humor">none</content_attribute> <content_attribute id="language-discrimination">none</content_attribute> <content_attribute id="social-chat">none</content_attribute> - <content_attribute id="social-info">none</content_attribute> + <content_attribute id="social-info">mild</content_attribute> <content_attribute id="social-audio">none</content_attribute> <content_attribute id="social-location">none</content_attribute> <content_attribute id="social-contacts">none</content_attribute> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/data/stylesheet.css new/Spice-up-1.6.0/data/stylesheet.css --- old/Spice-up-1.5.2/data/stylesheet.css 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/data/stylesheet.css 2018-09-24 06:56:52.000000000 +0200 @@ -1,4 +1,5 @@ -@define-color colorPrimary #2C2D2E; +@define-color colorPrimary #2c2d2e; +@define-color colorAccent @SLATE_100; .padding-none { padding: 0px; @@ -13,9 +14,12 @@ border-right: solid 1px rgba(0,0,0,0.75); } +.slide-list .list-row:selected:focus, .slide-list row:selected:focus { + background-color: @colorAccent; +} + .slide-list .list-row:selected, .slide-list row:selected { - box-shadow: inset 0px 24px 10px -6px rgba(0,0,0, 0.53); - background-color: shade(@bg_color, 0.5); + background-color: shade(@colorAccent, 0.7); } .new.slide { @@ -86,6 +90,14 @@ box-shadow: 0px 0px 1px 1px rgba (0,0,0, 0.1); } +.spice-dynamic-toolbar .spice .entry { + padding: 0px 3px; +} + +.spice-dynamic-toolbar .spice.padding-none { + padding: 0px; +} + .spice:active, .spice:checked, .spice:selected { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/src/CMakeLists.txt new/Spice-up-1.6.0/src/CMakeLists.txt --- old/Spice-up-1.5.2/src/CMakeLists.txt 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/src/CMakeLists.txt 2018-09-24 06:56:52.000000000 +0200 @@ -32,6 +32,7 @@ Widgets/Welcome.vala Widgets/SlideWidget.vala Widgets/PresenterView.vala + Widgets/PresenterNotes.vala Widgets/ColorPicker/ColorButton.vala Widgets/ColorPicker/ColorPicker.vala diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/src/Services/Slide.vala new/Spice-up-1.6.0/src/Services/Slide.vala --- old/Spice-up-1.5.2/src/Services/Slide.vala 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/src/Services/Slide.vala 2018-09-24 06:56:52.000000000 +0200 @@ -29,6 +29,7 @@ public string preview_data { get; private set; default = ""; } public string notes { get; set; default = ""; } + public Gtk.StackTransitionType transition { get; set; default = Gtk.StackTransitionType.NONE; } private bool visible_ = true; public bool visible { @@ -88,6 +89,12 @@ preview.set_from_pixbuf (pixbuf.scale_simple (SlideList.WIDTH, SlideList.HEIGHT, Gdk.InterpType.BILINEAR)); } + if (save_data.has_member ("transition")) { + transition = (Gtk.StackTransitionType) save_data.get_int_member ("transition"); + } else { + transition = Gtk.StackTransitionType.NONE; + } + var raw_notes = save_data.get_string_member ("notes"); if (raw_notes != null && raw_notes != "") { notes = (string) GLib.Base64.decode (raw_notes); @@ -154,7 +161,7 @@ } var raw_notes = (string) GLib.Base64.encode (notes.data); - return "{%s, \"items\": [%s], \"notes\": \"%s\", \"preview\": \"%s\"}\n".printf (canvas.serialise (), data, raw_notes, preview_data); + return "{%s, \"transition\": %d, \"items\": [%s], \"notes\": \"%s\", \"preview\": \"%s\"}\n".printf (canvas.serialise (), (int) transition, data, raw_notes, preview_data); } public void delete () { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/src/Services/SlideManager.vala new/Spice-up-1.6.0/src/Services/SlideManager.vala --- old/Spice-up-1.5.2/src/Services/SlideManager.vala 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/src/Services/SlideManager.vala 2018-09-24 06:56:52.000000000 +0200 @@ -46,6 +46,20 @@ } } + public Slide? preview_slide_ = null; + public Slide? preview_slide { + get { + if (preview_slide_ == null || preview_slide_.visible == false) { + return null; + } + + return preview_slide_; + } + set { + preview_slide_ = value; + } + } + public Slide? current_slide { get { return slide_; } set { @@ -57,16 +71,33 @@ current_slide.reload_preview_data (); } + if (window.is_fullscreen) { + slideshow.set_transition_duration (600); + slideshow.set_transition_type ((Gtk.StackTransitionType) value.transition); + + // Preload the next slide while presenting + Idle.add (() => { + var next_slide = get_next_slide (this.current_slide); + if (next_slide != null) { + next_slide.load_slide (); + } + return false; + }); + } else { + slideshow.set_transition_type (Gtk.StackTransitionType.NONE); + slideshow.set_transition_duration (0); + } + if (slides.contains (value)) { slide_ = value; current_item = null; + value.load_slide (); slideshow.set_visible_child (value.canvas); current_slide_changed (value); - value.load_slide (); } else if (value == end_presentation_slide) { + value.load_slide (); slideshow.set_visible_child (value.canvas); current_slide_changed (value); - value.load_slide (); slide_ = value; } } @@ -86,6 +117,7 @@ public void reset () { slide_ = null; + preview_slide_ = null; foreach (var slide in slides) { slideshow.remove (slide.canvas); @@ -120,7 +152,9 @@ } var current_slide_index = current_slide != null ? slides.index_of (current_slide) : 0; - return """{"current-slide":%d, "aspect-ratio":%d, "slides": [%s]}""".printf (current_slide_index, current_ratio, data); + var preview_slide_index = preview_slide != null ? slides.index_of (preview_slide) : 0; + + return """{"current-slide":%d, "preview-slide":%d, "aspect-ratio":%d, "slides": [%s]}""".printf (current_slide_index, preview_slide_index, current_ratio, data); } public void load_data (string data) { @@ -152,6 +186,15 @@ } else { current_slide = slides[0]; } + + if (root_object.has_member ("preview-slide")) { + position = (int) root_object.get_int_member ("preview-slide"); + if (slides.size > position && position >= 0) { + preview_slide = slides[position]; + } else { + preview_slide = slides[0]; + } + } } catch (Error e) { error ("Error loading file: %s", e.message); } @@ -164,7 +207,6 @@ if (next_slide != null) { var next_index = slides.index_of (next_slide); - slides.set (next_index, slide); slides.set (index, next_slide); @@ -336,7 +378,13 @@ slide.visible = true; } - slides.add (slide); + if (current_slide != null) { + var index = slides.index_of (current_slide); + slides.insert (index + 1, slide); + } else { + slides.add (slide); + } + slideshow.add (slide.canvas); slideshow.show_all (); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/src/Services/Utils.vala new/Spice-up-1.6.0/src/Services/Utils.vala --- old/Spice-up-1.5.2/src/Services/Utils.vala 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/src/Services/Utils.vala 2018-09-24 06:56:52.000000000 +0200 @@ -32,10 +32,18 @@ public static string get_thumbnail_data (string raw_json) { var root_object = get_json_object (raw_json); var slides_array = root_object.get_array_member ("slides"); + var preview_index = 0; + + if (root_object.has_member ("preview-slide")) { + preview_index = (int) root_object.get_int_member ("preview-slide"); + } var slides = slides_array.get_elements (); + if (preview_index > slides.length ()) preview_index = 0; + if (slides.length () > 0) { - var preview_data = slides.nth_data (0).get_object ().get_string_member ("preview"); + + var preview_data = slides.nth_data (preview_index).get_object ().get_string_member ("preview"); if (preview_data != null) { return preview_data; @@ -148,6 +156,93 @@ var cursor = new Gdk.Cursor.from_name (Gdk.Display.get_default (), cursor_type); window.get_screen ().get_active_window ().set_cursor (cursor); } + + public static void copy (Object object) { + if (object == null) return; + Gtk.Clipboard clipboard = Gtk.Clipboard.get (Gdk.Atom.intern_static_string ("SPICE_UP")); + + if (object is Spice.CanvasItem) { + clipboard.set_text ((object as Spice.CanvasItem).serialise (), -1); + } else if (object is Spice.Slide){ + clipboard.set_text ((object as Slide).serialise (), -1); + } + } + public static void paste (Spice.SlideManager manager) { + Gtk.Clipboard clipboard = Gtk.Clipboard.get (Gdk.Atom.intern_static_string ("SPICE_UP")); + var data = clipboard.wait_for_text (); + + if (data == null) return; + + try { + var parser = new Json.Parser (); + parser.load_from_data (data); + + var root_object = parser.get_root ().get_object (); + + if (root_object.has_member ("preview")) { + manager.new_slide (root_object, true); + } else { + manager.current_slide.add_item_from_data (root_object, true, true); + } + } catch (Error e) { + warning ("Cloning didn't work: %s", e.message); + } + } + + public static void cut (Object object) { + if (object == null) return; + Utils.copy (object); + Utils.delete (object); + } + + public static void delete (Object object) { + if (object == null) return; + + if (object is Spice.CanvasItem) { + (object as Spice.CanvasItem).delete (); + } else if (object is Spice.Slide) { + (object as Slide).delete (); + } + } + + public static void duplicate (Object object, Spice.SlideManager manager) { + if (object == null) return; + + string data; + + if (object is Spice.CanvasItem) { + data = (object as Spice.CanvasItem).serialise (); + } else if (object is Spice.Slide){ + data = (object as Slide).serialise (); + } else { + return; + } + + try { + var parser = new Json.Parser (); + parser.load_from_data (data); + + var root_object = parser.get_root ().get_object (); + + if (object is Spice.CanvasItem) { + manager.current_slide.add_item_from_data (root_object, true, true); + } else { + manager.new_slide (root_object, true); + } + } catch (Error e) { + warning ("Cloning didn't work: %s", e.message); + } + } + + public static void new_slide (Spice.SlideManager manager) { + manager.making_new_slide = true; + + var slide = manager.new_slide (null, true); + slide.reload_preview_data (); + manager.current_slide = slide; + + manager.making_new_slide = false; + } } public enum Spice.AspectRatio { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/src/Widgets/Canvas.vala new/Spice-up-1.6.0/src/Widgets/Canvas.vala --- old/Spice-up-1.5.2/src/Widgets/Canvas.vala 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/src/Widgets/Canvas.vala 2018-09-24 06:56:52.000000000 +0200 @@ -72,6 +72,10 @@ get_style_context ().add_class ("canvas"); add (grid); + // Hacky fix to prevent empty slides + // from not rendering in the sidebar + add_overlay (new Gtk.Label ("")); + calculate_ratio (); load_data (); style (); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/src/Widgets/ColorPicker/ColorButton.vala new/Spice-up-1.6.0/src/Widgets/ColorPicker/ColorButton.vala --- old/Spice-up-1.5.2/src/Widgets/ColorPicker/ColorButton.vala 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/src/Widgets/ColorPicker/ColorButton.vala 2018-09-24 06:56:52.000000000 +0200 @@ -21,6 +21,7 @@ protected class Spice.ColorButton : Gtk.Button { protected Gtk.EventBox surface; + protected Gtk.EventBox checkered_bg; public string _color = "none"; public string color { @@ -45,13 +46,13 @@ get_style_context ().add_class ("color-button"); Utils.set_style (this, STYLE_CSS); - var background = new Gtk.EventBox (); - background.get_style_context ().add_class ("checkered"); - Utils.set_style (background, CHECKERED_CSS); + checkered_bg = new Gtk.EventBox (); + checkered_bg.get_style_context ().add_class ("checkered"); + Utils.set_style (checkered_bg, CHECKERED_CSS); can_focus = false; - add (background); - background.add (surface); + add (checkered_bg); + checkered_bg.add (surface); } public void set_size (int x, int y) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/src/Widgets/ColorPicker/ColorPicker.vala new/Spice-up-1.6.0/src/Widgets/ColorPicker/ColorPicker.vala --- old/Spice-up-1.5.2/src/Widgets/ColorPicker/ColorPicker.vala 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/src/Widgets/ColorPicker/ColorPicker.vala 2018-09-24 06:56:52.000000000 +0200 @@ -84,6 +84,12 @@ } construct { + get_style_context ().add_class ("spice"); + surface.halign = Gtk.Align.CENTER; + surface.valign = Gtk.Align.CENTER; + checkered_bg.halign = Gtk.Align.CENTER; + checkered_bg.valign = Gtk.Align.CENTER; + var main_grid = new Gtk.Grid (); main_grid.margin = 6; @@ -290,8 +296,8 @@ private void attach_color (string color, int x, int y) { var color_button = new ColorButton (color); - color_button.set_size (14, 84); color_button.get_style_context ().add_class ("flat"); + color_button.set_size (14, 84); color_button.can_focus = true; color_button.margin_end = 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/src/Widgets/EntryCombo.vala new/Spice-up-1.6.0/src/Widgets/EntryCombo.vala --- old/Spice-up-1.5.2/src/Widgets/EntryCombo.vala 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/src/Widgets/EntryCombo.vala 2018-09-24 06:56:52.000000000 +0200 @@ -90,6 +90,8 @@ // If strict_signal == true, it will only send activated if the entry is the same as a value on the list public EntryCombo (bool strict_signal = false, bool alphabetize = false, bool searchable = false) { this.strict_signal = strict_signal; + get_style_context ().add_class ("spice"); + get_style_context ().add_class ("padding-none"); row_map = new Gee.HashMap<string, Gtk.ListBoxRow> (); keys = new Gee.HashMap<string, string> (); @@ -107,7 +109,7 @@ substitute_label.halign = Gtk.Align.START; var entry_substitute = new Gtk.Button (); - entry_substitute.get_style_context ().add_class ("entry"); + entry_substitute.get_style_context ().add_class ("flat"); entry_substitute.add (substitute_label); entry_substitute.can_focus = false; @@ -121,7 +123,7 @@ scroll.vscrollbar_policy = Gtk.PolicyType.NEVER; scroll.add (listbox); - popover = new Gtk.Popover (button); + popover = new Gtk.Popover (this); popover.position = Gtk.PositionType.BOTTOM; orientation = Gtk.Orientation.HORIZONTAL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/src/Widgets/Headerbar.vala new/Spice-up-1.6.0/src/Widgets/Headerbar.vala --- old/Spice-up-1.5.2/src/Widgets/Headerbar.vala 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/src/Widgets/Headerbar.vala 2018-09-24 06:56:52.000000000 +0200 @@ -25,7 +25,8 @@ TEXT, IMAGE, SHAPE, - RETURN; + RETURN, + NOTES; } public class Spice.Headerbar : Gtk.HeaderBar { @@ -38,9 +39,10 @@ private HeaderbarButton shape; private HeaderbarButton export; private HeaderbarButton show_welcome; - private HeaderbarButton present; + private Gtk.ToggleButton show_notes; + private Spice.SlideManager slide_manager; public new bool sensitive { @@ -56,6 +58,7 @@ export.sensitive = value; present.sensitive = value; show_welcome.sensitive = value; + show_notes.sensitive = value; } } @@ -86,6 +89,19 @@ present = new HeaderbarButton ("media-playback-start-symbolic",_("Start Presentation"), null); present.get_style_context ().add_class ("suggested-action"); + show_notes = new Gtk.ToggleButton (); + show_notes.can_focus = false; + + Gtk.Image show_notes_image = new Gtk.Image.from_icon_name ("accessories-text-editor-symbolic", Gtk.IconSize.BUTTON); + show_notes_image.margin = 3; + + show_notes.get_style_context ().add_class ("spice"); + show_notes.set_tooltip_text (_("Presenter Notes")); + show_notes.add (show_notes_image); + show_notes.clicked.connect (() => { + button_clicked (Spice.HeaderButton.NOTES); + }); + var undo_redo_box = new Gtk.Grid (); var object_box = new Gtk.Grid (); @@ -105,6 +121,7 @@ pack_end (present); pack_end (export); pack_end (show_welcome); + pack_end (show_notes); } private void connect_signals () { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/src/Widgets/PresenterNotes.vala new/Spice-up-1.6.0/src/Widgets/PresenterNotes.vala --- old/Spice-up-1.5.2/src/Widgets/PresenterNotes.vala 1970-01-01 01:00:00.000000000 +0100 +++ new/Spice-up-1.6.0/src/Widgets/PresenterNotes.vala 2018-09-24 06:56:52.000000000 +0200 @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2018 Felipe Escoto (https://github.com/Philip-Scott/Spice-up) +* +* 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 2 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, write to the +* Free Software Foundation, Inc., 59 Temple Place - Suite 330, +* Boston, MA 02111-1307, USA. +* +* Authored by: Felipe Escoto <felescot...@hotmail.com> +*/ + +public class Spice.PresenterNotes : Gtk.Revealer { + public signal void text_changed (string text); + + public Gtk.TextView notes_area { get; construct set; } + + private bool setting_text = false; + + construct { + var grid = new Gtk.Grid (); + grid.orientation = Gtk.Orientation.VERTICAL; + + notes_area = new Gtk.TextView (); + notes_area.set_wrap_mode (Gtk.WrapMode.WORD); + notes_area.left_margin = 6; + notes_area.get_style_context ().add_class ("h3"); + notes_area.get_style_context ().add_class ("h4"); + + notes_area.buffer.changed.connect (() => { + if (!setting_text) { + text_changed (notes_area.buffer.text); + } + }); + + var notes_scrolled = new Gtk.ScrolledWindow (null, null); + notes_scrolled.min_content_height = 150; + notes_scrolled.hexpand = true; + notes_scrolled.add (notes_area); + + grid.add (new Gtk.Separator (Gtk.Orientation.HORIZONTAL)); + grid.add (notes_scrolled); + + add (grid); + show_all (); + } + + public void set_text (string text) { + setting_text = true; + notes_area.buffer.text = text; + setting_text = false; + } +} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/src/Widgets/SlideList.vala new/Spice-up-1.6.0/src/Widgets/SlideList.vala --- old/Spice-up-1.5.2/src/Widgets/SlideList.vala 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/src/Widgets/SlideList.vala 2018-09-24 06:56:52.000000000 +0200 @@ -18,31 +18,31 @@ * * Authored by: Felipe Escoto <felescot...@hotmail.com> */ -using Cairo; -public class Spice.SlideList : Gtk.ScrolledWindow { - private Gtk.Grid slides_grid; - private Gtk.ListBox slides_list; - private SlideManager manager; +public class Spice.SlideList : Gtk.Grid { + public static int WIDTH = 200; + public static int HEIGHT = 150; - private Gtk.Button new_slide_button; + private Gtk.ListBox slides_list; + private unowned SlideManager manager; public SlideList (SlideManager manager) { - this.manager = manager; + orientation = Gtk.Orientation.VERTICAL; + get_style_context ().add_class ("slide-list"); - hscrollbar_policy = Gtk.PolicyType.NEVER; - vexpand = true; + this.manager = manager; - slides_grid = new Gtk.Grid (); - slides_grid.orientation = Gtk.Orientation.VERTICAL; - slides_grid.get_style_context ().add_class ("slide-list"); + var scrollbox = new Gtk.ScrolledWindow (null, null); + scrollbox.hscrollbar_policy = Gtk.PolicyType.NEVER; + scrollbox.vexpand = true; slides_list = new Gtk.ListBox (); - slides_list.get_style_context ().add_class ("slide-list"); slides_list.get_style_context ().add_class ("linked"); + slides_list.get_style_context ().add_class ("slide-list"); + slides_list.vexpand = true; - slides_grid.add (slides_list); - this.add (slides_grid); + scrollbox.add (slides_list); + add (scrollbox); slides_list.row_selected.connect ((row) => { if (row is SlideListRow) { @@ -86,26 +86,34 @@ else return 0; }); - new_slide_button = add_new_slide (); - slides_grid.add (new_slide_button); + add (new Gtk.Separator (Gtk.Orientation.HORIZONTAL)); - new_slide_button.clicked.connect (() => { - manager.making_new_slide = true; + var plus_icon = new Gtk.Image.from_icon_name ("list-add-symbolic", Gtk.IconSize.LARGE_TOOLBAR); + plus_icon.margin = 3; + + var new_slide_button = new Gtk.Button (); - var slide = manager.new_slide (null, true); - slide.reload_preview_data (); - manager.current_slide = slide; + new_slide_button.set_tooltip_text (_("Add a Slide")); + new_slide_button.get_style_context ().add_class ("new"); + new_slide_button.add (plus_icon); + new_slide_button.set_size_request (WIDTH, 0); + new_slide_button.margin = 0; + new_slide_button.can_focus = false; - manager.making_new_slide = false; + new_slide_button.clicked.connect (() => { + Utils.new_slide (manager); }); + + add (new_slide_button); + foreach (var slide in manager.slides) { add_slide (slide); } } private SlideListRow add_slide (Slide slide) { - var slide_row = new SlideListRow (slide); + var slide_row = new SlideListRow (slide, manager); slide_row.get_style_context ().add_class ("slide"); @@ -115,37 +123,20 @@ return slide_row; } - public static int WIDTH = 200; - public static int HEIGHT = 150; - - public Gtk.Button add_new_slide () { - var button = new Gtk.Button (); - var plus_icon = new Gtk.Image.from_icon_name ("list-add-symbolic", Gtk.IconSize.DIALOG); - plus_icon.margin = 24; - - button.get_style_context ().add_class ("slide"); - button.get_style_context ().add_class ("new"); - button.add (plus_icon); - button.set_size_request (WIDTH, HEIGHT); - button.margin = 9; - button.can_focus = false; - - return button; - } - private class SlideListRow : Gtk.ListBoxRow { public unowned Spice.Slide slide; + private unowned SlideManager manager; + private SlideWidget slide_widget; - public SlideListRow (Slide slide) { + public SlideListRow (Slide slide, SlideManager manager) { this.slide = slide; + this.manager = manager; slide_widget = new SlideWidget.from_slide (slide); + slide_widget.settings_requested.connect (() => { - var popover = SlideSettingsPopover.get_instance (); - popover.set_relative_to (slide_widget.settings_revealer); - popover.slide = this.slide; - popover.show_all (); + show_rightclick_menu (); }); add (slide_widget); @@ -172,67 +163,76 @@ } """; - private class SlideSettingsPopover : Gtk.Popover { - private static SlideSettingsPopover? instance = null; + public void show_rightclick_menu () { + var menu = new Gtk.Menu (); - private unowned Slide _slide; - public Slide slide { - get { - return _slide; - } set { - changing = true; - _slide = value; - notes.buffer.text = slide.notes; - changing = false; - } - } + var cut = new Gtk.MenuItem.with_label (_("Cut")); + var copy = new Gtk.MenuItem.with_label (_("Copy")); + var paste = new Gtk.MenuItem.with_label (_("Paste")); + var delete_slide = new Gtk.MenuItem.with_label (_("Delete")); + + var new_slide = new Gtk.MenuItem.with_label (_("New Slide")); + // var new_item = new Gtk.MenuItem.with_label (_("Skip Slide")); + var duplicate_slide = new Gtk.MenuItem.with_label (_("Duplicate Slide")); + var set_as_preview = new Gtk.MenuItem.with_label (_("Set as File Preview")); - private bool changing = false; - private Gtk.TextView notes; + cut.activate.connect (() => { + Utils.cut (this.slide); + }); - public static SlideSettingsPopover get_instance () { - if (instance == null) { - instance = new SlideSettingsPopover (); - } + copy.activate.connect (() => { + Utils.copy (this.slide); + }); - return instance; - } + paste.activate.connect (() => { + Utils.paste (this.manager); + }); - construct { - position = Gtk.PositionType.RIGHT; + delete_slide.activate.connect (() => { + Utils.delete (this.slide); + }); - notes = new Gtk.TextView (); - notes.get_style_context ().add_class ("h3"); - notes.wrap_mode = Gtk.WrapMode.WORD_CHAR; - notes.halign = Gtk.Align.FILL; - notes.indent = 6; - - notes.buffer.changed.connect (() => { - if (!this.changing) { - this.slide.notes = notes.buffer.text; - } - }); + new_slide.activate.connect (() => { + Utils.new_slide (manager); + }); + + duplicate_slide.activate.connect (() => { + Utils.duplicate (this.slide, this.manager); + }); + + set_as_preview.activate.connect (() => { + this.manager.preview_slide = this.slide; + }); - var notes_scrolled = new Gtk.ScrolledWindow (null, null); - notes_scrolled.hscrollbar_policy = Gtk.PolicyType.NEVER; - notes_scrolled.height_request = 150; - notes_scrolled.width_request = 290; - notes_scrolled.add (notes); - - var frame = new Gtk.Frame (null); - frame.add (notes_scrolled); - - var notes_label = new Granite.HeaderLabel (_("Presenter Notes:")); - notes_label.margin_start = 1; - - var grid = new Gtk.Grid (); - grid.orientation = Gtk.Orientation.VERTICAL; - grid.add (notes_label); - grid.add (frame); - grid.margin = 6; + menu.add (cut); + menu.add (copy); + menu.add (paste); + menu.add (delete_slide); + menu.add (new Gtk.SeparatorMenuItem ()); + menu.add (new_slide); + menu.add (duplicate_slide); + menu.add (new Gtk.SeparatorMenuItem ()); + menu.add (set_as_preview); + + menu.attach_to_widget (this, null); + menu.show_all (); + + menu.selection_done.connect (() => { + menu.detach (); + menu.destroy (); + }); + + menu.popup_at_widget (this, Gdk.Gravity.CENTER, Gdk.Gravity.CENTER, null); + } - add (grid); + public override bool button_press_event (Gdk.EventButton event) { + activate (); + + if (event.button == 3) { + show_rightclick_menu (); } + + return false; } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/src/Widgets/Toolbars/CanvasBar.vala new/Spice-up-1.6.0/src/Widgets/Toolbars/CanvasBar.vala --- old/Spice-up-1.5.2/src/Widgets/Toolbars/CanvasBar.vala 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/src/Widgets/Toolbars/CanvasBar.vala 2018-09-24 06:56:52.000000000 +0200 @@ -24,6 +24,7 @@ private Spice.ColorPicker canvas_gradient_background; private Spice.EntryCombo canvas_pattern; + private Spice.EntryCombo transition; private SlideManager manager; public CanvasToolbar (SlideManager slide_manager) { @@ -71,8 +72,34 @@ update_properties (); }); + transition = new Spice.EntryCombo (true, false); + transition.set_tooltip_text (_("Transition")); + transition.editable = false; + + transition.add_entry (((int) Gtk.StackTransitionType.NONE).to_string (), _("No Transition")); + transition.add_entry (((int) Gtk.StackTransitionType.CROSSFADE).to_string (), _("Crossfade")); + transition.add_entry (((int) Gtk.StackTransitionType.SLIDE_RIGHT).to_string (), _("Slide right")); + transition.add_entry (((int) Gtk.StackTransitionType.SLIDE_LEFT).to_string (), _("Slide left")); + transition.add_entry (((int) Gtk.StackTransitionType.SLIDE_UP).to_string (), _("Slide up")); + transition.add_entry (((int) Gtk.StackTransitionType.SLIDE_DOWN).to_string (), _("Slide down")); + transition.add_entry (((int) Gtk.StackTransitionType.OVER_UP).to_string (), _("Cover up")); + transition.add_entry (((int) Gtk.StackTransitionType.OVER_DOWN).to_string (), _("Cover down")); + transition.add_entry (((int) Gtk.StackTransitionType.OVER_LEFT).to_string (), _("Cover left")); + transition.add_entry (((int) Gtk.StackTransitionType.OVER_RIGHT).to_string (), _("Cover right")); + transition.add_entry (((int) Gtk.StackTransitionType.UNDER_UP).to_string (), _("Uncover up")); + transition.add_entry (((int) Gtk.StackTransitionType.UNDER_DOWN).to_string (), _("Uncover down")); + transition.add_entry (((int) Gtk.StackTransitionType.UNDER_LEFT).to_string (), _("Uncover left")); + transition.add_entry (((int) Gtk.StackTransitionType.UNDER_RIGHT).to_string (), _("Uncover right")); + + transition.activated.connect (() => { + var action = new Spice.Services.HistoryManager.HistoryAction<Slide, Gtk.StackTransitionType>.canvas_changed (this.manager.current_slide, "transition"); + Spice.Services.HistoryManager.get_instance ().add_undoable_action (action); + update_properties (); + }); + add (canvas_gradient_background); add (canvas_pattern); + add (transition); } protected override void item_selected (Spice.CanvasItem? item, bool new_item = false) { @@ -81,11 +108,13 @@ return; } + transition.text = ((int) manager.current_slide.transition).to_string (); canvas_gradient_background.color = manager.current_slide.canvas.background_color; canvas_pattern.text = manager.current_slide.canvas.background_pattern; } public override void update_properties () { + manager.current_slide.transition = (Gtk.StackTransitionType) int.parse (transition.text); manager.current_slide.canvas.background_pattern = canvas_pattern.text; manager.current_slide.canvas.background_color = canvas_gradient_background.color; manager.current_slide.canvas.style (); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/src/Widgets/Toolbars/CommonBar.vala new/Spice-up-1.6.0/src/Widgets/Toolbars/CommonBar.vala --- old/Spice-up-1.5.2/src/Widgets/Toolbars/CommonBar.vala 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/src/Widgets/Toolbars/CommonBar.vala 2018-09-24 06:56:52.000000000 +0200 @@ -54,35 +54,18 @@ clone_button.set_tooltip_text (_("Clone")); clone_button.clicked.connect (() => { - string data; - if (this.item != null) { - data = this.item.serialise (); + Utils.duplicate (this.item, this.manager); } else { - data = this.manager.current_slide.serialise (); - } - - try { - var parser = new Json.Parser (); - parser.load_from_data (data); - - var root_object = parser.get_root ().get_object (); - - if (this.item != null) { - this.manager.current_slide.add_item_from_data (root_object, true, true); - } else { - this.manager.new_slide (root_object, true); - } - } catch (Error e) { - warning ("Cloning didn't work: %s", e.message); + Utils.duplicate (this.manager.current_slide, this.manager); } }); - to_top = new Gtk.Button.from_icon_name ("go-up-symbolic", Gtk.IconSize.MENU); + to_top = new Gtk.Button.from_icon_name ("selection-raise-symbolic", Gtk.IconSize.MENU); to_top.get_style_context ().add_class ("spice"); to_top.set_tooltip_text (_("Bring forward")); - to_bottom = new Gtk.Button.from_icon_name ("go-down-symbolic", Gtk.IconSize.MENU); + to_bottom = new Gtk.Button.from_icon_name ("selection-lower-symbolic", Gtk.IconSize.MENU); to_bottom.get_style_context ().add_class ("spice"); to_bottom.set_tooltip_text (_("Send backward")); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Spice-up-1.5.2/src/Window.vala new/Spice-up-1.6.0/src/Window.vala --- old/Spice-up-1.5.2/src/Window.vala 2018-09-08 23:10:15.000000000 +0200 +++ new/Spice-up-1.6.0/src/Window.vala 2018-09-24 06:56:52.000000000 +0200 @@ -49,6 +49,7 @@ private Gtk.Revealer toolbar_revealer; private Gtk.AspectFrame? aspect_frame = null; private Gtk.Overlay app_overlay; + private Spice.PresenterNotes presenter_notes; private Gtk.Stack app_stack; private Spice.Welcome? welcome = null; @@ -103,6 +104,8 @@ sidebar_revealer = new Gtk.Revealer (); toolbar_revealer = new Gtk.Revealer (); + presenter_notes = new Spice.PresenterNotes (); + sidebar_revealer.add (slide_list); sidebar_revealer.reveal_child = true; @@ -117,9 +120,10 @@ var grid = new Gtk.Grid (); grid.get_style_context ().add_class ("app-back"); - grid.attach (toolbar_revealer, 1, 0, 2, 1); - grid.attach (sidebar_revealer, 0, 0, 1, 2); + grid.attach (toolbar_revealer, 1, 0, 1, 1); + grid.attach (sidebar_revealer, 0, 0, 1, 3); grid.attach (aspect_frame, 1, 1, 1, 1); + grid.attach (presenter_notes, 1, 2, 1, 1); app_stack.add_named (grid, "application"); @@ -149,6 +153,11 @@ return; } + if (button == Spice.HeaderButton.NOTES) { + presenter_notes.reveal_child = !presenter_notes.reveal_child; + return; + } + var item = slide_manager.request_new_item (button); if (item != null) { @@ -171,6 +180,7 @@ sidebar_revealer.visible = !is_fullscreen; sidebar_revealer.reveal_child = !is_fullscreen; toolbar_revealer.reveal_child = !is_fullscreen; + presenter_notes.visible =!is_fullscreen; slide_manager.checkpoint = null; if (toast != null && notification_shown) { @@ -185,6 +195,14 @@ return false; }); + slide_manager.current_slide_changed.connect ((current_slide) => { + presenter_notes.set_text (current_slide.notes); + }); + + presenter_notes.text_changed.connect ((text) => { + slide_manager.current_slide.notes = text; + }); + var undo_action = new SimpleAction ("undo-action", null); add_action (undo_action); app.set_accels_for_action ("win.undo-action", {"<Ctrl>Z"}); @@ -220,6 +238,7 @@ private bool on_key_pressed (Gtk.Widget source, Gdk.EventKey key) { debug ("Key: %s %u", key.str, key.keyval); + if (presenter_notes.notes_area.has_focus) return false; switch (key.keyval) { // Next Slide @@ -268,42 +287,19 @@ } private bool copy () { - Gtk.Clipboard clipboard = Gtk.Clipboard.get (Gdk.Atom.intern_static_string ("SPICE_UP")); - var current_item = slide_manager.current_item; if (current_item != null) { - clipboard.set_text (current_item.serialise (), -1); + Utils.copy (current_item); } else { - if (slide_manager.current_slide != null) { - clipboard.set_text (slide_manager.current_slide.serialise (), -1); - } + Utils.copy (slide_manager.current_slide); } return true; } private bool paste () { - Gtk.Clipboard clipboard = Gtk.Clipboard.get (Gdk.Atom.intern_static_string ("SPICE_UP")); - var data = clipboard.wait_for_text (); - - if (data == null) return false; - - try { - var parser = new Json.Parser (); - parser.load_from_data (data); - - var root_object = parser.get_root ().get_object (); - - if (root_object.has_member ("preview")) { - slide_manager.new_slide (root_object, true); - } else { - slide_manager.current_slide.add_item_from_data (root_object, true, true); - } - } catch (Error e) { - warning ("Cloning didn't work: %s", e.message); - } - + Utils.paste (slide_manager); return true; } @@ -311,11 +307,9 @@ var current_item = slide_manager.current_item; if (current_item != null) { - current_item.delete (); - } else { - if (slide_manager.current_slide != null) { - slide_manager.current_slide.delete (); - } + Utils.delete (current_item); + } else if (slide_manager.current_slide != null) { + Utils.delete (slide_manager.current_slide); } return true;