diff --git a/data/jorts.gschema.xml b/data/jorts.gschema.xml
index 3e07f6b..635aab1 100644
--- a/data/jorts.gschema.xml
+++ b/data/jorts.gschema.xml
@@ -11,5 +11,10 @@
Hide actionbar
Whether to hide the actionbar and its buttons
+
+ " - "
+ Hide actionbar
+ Whether to hide the actionbar and its buttons
+
diff --git a/data/jorts.metainfo.xml.in b/data/jorts.metainfo.xml.in
index bbe348e..fe90faf 100644
--- a/data/jorts.metainfo.xml.in
+++ b/data/jorts.metainfo.xml.in
@@ -99,6 +99,7 @@
š 4.0.0 Jorts of Hyperspace!
- Version 4 to align with Gtk version
+ - Added button to toggle lists, and ability to customize them
- Ctrl+Scroll to zoom-in, zoom-out
- More zoom options
- Keyboard shortcuts work from popover now
@@ -114,7 +115,8 @@
Fixed zoom impacting emojichooser and context menu
Fixed coloring bleeding into icons in emojichooser and context menu
- Fixed absence of Ctrl+scroll
+ Added Ctrl+scroll
+ Added list feature
diff --git a/src/Application.vala b/src/Application.vala
index 187aa56..0117ec7 100644
--- a/src/Application.vala
+++ b/src/Application.vala
@@ -100,6 +100,7 @@ public class Jorts.Application : Gtk.Application {
set_accels_for_action ("win.action_toggle_mono", {"m"});
set_accels_for_action ("win.action_focus_title", {"L"});
set_accels_for_action ("win.action_show_emoji", {"period"});
+ set_accels_for_action ("win.action_toggle_list", {"F12"});
set_accels_for_action ("win.action_show_menu", {"G", "O"});
set_accels_for_action ("win.action_theme_1", {"1"});
diff --git a/src/Services/Constants.vala b/src/Services/Constants.vala
index c506b13..98b1380 100644
--- a/src/Services/Constants.vala
+++ b/src/Services/Constants.vala
@@ -36,7 +36,7 @@ namespace Jorts.Constants {
// New preference window
const int DEFAULT_PREF_WIDTH = 550;
- const int DEFAULT_PREF_HEIGHT = 290;
+ const int DEFAULT_PREF_HEIGHT = 310;
/*************************************************/
// Shortcuts
diff --git a/src/Views/NoteView.vala b/src/Views/NoteView.vala
index 3db3b7a..c5e20c9 100644
--- a/src/Views/NoteView.vala
+++ b/src/Views/NoteView.vala
@@ -68,6 +68,8 @@
emojichooser_popover.show.connect (randomize_emote_button);
emojichooser_popover.emoji_picked.connect (on_emoji_picked);
//Application.gsettings.bind ("hide-bar", actionbar, "revealed", SettingsBindFlags.INVERT_BOOLEAN);
+
+ //textview.bind_property ("on_list_item", actionbar.list_button, "active", GLib.BindingFlags.DEFAULT);
}
// Randomize the button emoji when clicked
diff --git a/src/Views/PreferencesView.vala b/src/Views/PreferencesView.vala
index d628410..eb4e440 100644
--- a/src/Views/PreferencesView.vala
+++ b/src/Views/PreferencesView.vala
@@ -12,10 +12,10 @@
construct {
orientation = VERTICAL;
- margin_top = 12;
- margin_bottom = 12;
- margin_start = 12;
- margin_end = 12;
+ margin_top = 10;
+ margin_bottom = 10;
+ margin_start = 10;
+ margin_end = 10;
var overlay = new Gtk.Overlay ();
append (overlay);
@@ -24,15 +24,48 @@
overlay.add_overlay (toast);
// the box with all the settings
- var settingsbox = new Gtk.Box (VERTICAL, 24) {
- margin_top = 6,
- margin_start = 6,
- margin_end = 6,
+ var settingsbox = new Gtk.Box (VERTICAL, 20) {
+ margin_top = 5,
+ margin_start = 5,
+ margin_end = 5,
hexpand = true,
vexpand = true,
valign = Gtk.Align.START
};
+
+ /***************************************/
+ /* lists */
+ /***************************************/
+
+ var lists_box = new Gtk.Box (HORIZONTAL, 5);
+
+ var list_entry = new Gtk.Entry () {
+ halign = Gtk.Align.END,
+ hexpand = false,
+ valign = Gtk.Align.CENTER,
+ max_length = 5,
+ max_width_chars = 5
+ };
+
+ var list_label = new Granite.HeaderLabel (_("List item symbol")) {
+ mnemonic_widget = list_entry,
+ secondary_text = _("Prefix by which to begin each item in a list. If there is no prefix, the toggle list button will be hidden"),
+ hexpand = true
+ };
+
+ lists_box.append (list_label);
+ lists_box.append (list_entry);
+
+ Application.gsettings.bind (
+ "list-item-start",
+ list_entry, "text",
+ SettingsBindFlags.DEFAULT);
+
+
+ settingsbox.append (lists_box);
+
+
/*************************************************/
/* scribbly Toggle */
/*************************************************/
@@ -63,13 +96,13 @@
/* Autostart Request */
/****************************************************/
#if !WINDOWS
- var both_buttons = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6) {
+ var both_buttons = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 5) {
halign = Gtk.Align.FILL
};
///TRANSLATORS: Button to autostart the application
var set_autostart = new Gtk.Button () {
- label = _("Set autostart"),
+ label = _("Autostart"),
valign = Gtk.Align.CENTER
};
@@ -94,7 +127,7 @@
both_buttons.append (set_autostart);
both_buttons.append (remove_autostart);
- var autostart_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
+ var autostart_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 5);
var autostart_label = new Granite.HeaderLabel (_("Allow to start at login")) {
mnemonic_widget = both_buttons,
@@ -109,12 +142,12 @@
/*************************************************/
// Bar at the bottom
var actionbar = new Gtk.CenterBox () {
- margin_start = 6,
- margin_end = 6,
- valign = Gtk.Align.END
+ margin_start = 5,
+ margin_end = 5,
+ valign = Gtk.Align.END,
+ hexpand = true,
+ vexpand = false
};
- actionbar.set_hexpand (true);
- actionbar.set_vexpand (false);
// Monies?
var support_button = new Gtk.LinkButton.with_label (
@@ -123,12 +156,6 @@
);
actionbar.start_widget = support_button;
- // Reset
- //reset_button = new Gtk.Button ();
- //reset_button.set_label ( _("Reset to Default"));
- //reset_button.tooltip_markup = (_("Reset all settings to defaults"));
- //actionbar.pack_end (reset_button);
-
close_button = new Gtk.Button () {
width_request = 96,
label = _("Close"),
@@ -137,9 +164,33 @@
_("Close preferences")
)
};
- actionbar.end_widget = close_button;
+
+ var reset = new Gtk.Button.from_icon_name ("system-reboot-symbolic") {
+ tooltip_markup = _("Reset all settings to defaults"),
+ valign = Gtk.Align.CENTER
+ };
+ reset.clicked.connect (on_reset);
+
+ var end_box = new Gtk.Box (HORIZONTAL, 5);
+ end_box.append (reset);
+ end_box.append (close_button);
+ actionbar.end_widget = end_box;
append (settingsbox);
append (actionbar);
}
+
+ private void on_reset () {
+ debug ("Resetting settingsā¦");
+
+ string[] keys = {"scribbly-mode-active", "hide-bar", "list-item-start"};
+ foreach (var key in keys) {
+ Application.gsettings.reset (key);
+ }
+
+#if !WINDOWS
+ Jorts.Utils.autostart_remove ();
+ toast.send_notification ();
+#endif
+ }
}
diff --git a/src/Widgets/ActionBar.vala b/src/Widgets/ActionBar.vala
index 0c06e27..5a7dba4 100644
--- a/src/Widgets/ActionBar.vala
+++ b/src/Widgets/ActionBar.vala
@@ -12,6 +12,7 @@
public class Jorts.ActionBar : Granite.Bin {
public Gtk.ActionBar actionbar;
+ public Gtk.Button list_button;
public Gtk.MenuButton emoji_button;
public Gtk.EmojiChooser emojichooser_popover;
public Gtk.MenuButton menu_button;
@@ -45,6 +46,18 @@
delete_item.action_name = StickyNoteWindow.ACTION_PREFIX + StickyNoteWindow.ACTION_DELETE;
/* **** RIGHT **** */
+ list_button = new Gtk.Button () {
+ icon_name = "view-list-symbolic",
+ width_request = 32,
+ height_request = 32,
+ tooltip_markup = Granite.markup_accel_tooltip (
+ {"F12"},
+ _("Toggle list")
+ )
+ };
+ list_button.add_css_class ("themedbutton");
+ list_button.action_name = StickyNoteWindow.ACTION_PREFIX + StickyNoteWindow.ACTION_TOGGLE_LIST;
+
emojichooser_popover = new Gtk.EmojiChooser ();
emoji_button = new Gtk.MenuButton () {
@@ -80,6 +93,7 @@
actionbar.pack_start (delete_item);
actionbar.pack_end (menu_button);
actionbar.pack_end (emoji_button);
+ actionbar.pack_end (list_button);
handle = new Gtk.WindowHandle () {
child = actionbar
@@ -89,6 +103,11 @@
// Randomize-skip emoji icon
emojichooser_popover.show.connect (on_emoji_popover);
+
+ // Hide the list button if user has specified no list item symbol
+ on_prefix_changed ();
+ Application.gsettings.changed["list-item-start"].connect (on_prefix_changed);
+
}
/**
@@ -109,4 +128,8 @@
)
);
}
+
+ private void on_prefix_changed () {
+ list_button.visible = (Application.gsettings.get_string ("list-item-start") != "");
+ }
}
diff --git a/src/Widgets/PreferencesWidgets/SettingsSwitch.vala b/src/Widgets/PreferencesWidgets/SettingsSwitch.vala
index 84a3692..25d1d97 100644
--- a/src/Widgets/PreferencesWidgets/SettingsSwitch.vala
+++ b/src/Widgets/PreferencesWidgets/SettingsSwitch.vala
@@ -12,7 +12,7 @@ public class Jorts.SettingsSwitch : Gtk.Box {
public SettingsSwitch (string name, string explanation, string key) {
orientation = Gtk.Orientation.HORIZONTAL;
- spacing = 6;
+ spacing = 5;
var toggle = new Gtk.Switch () {
halign = Gtk.Align.END,
diff --git a/src/Widgets/TextView.vala b/src/Widgets/TextView.vala
index 8566234..f4cef51 100644
--- a/src/Widgets/TextView.vala
+++ b/src/Widgets/TextView.vala
@@ -11,6 +11,10 @@
*/
public class Jorts.TextView : Granite.HyperTextView {
+ private Gtk.EventControllerKey keyboard;
+ private string list_item_start;
+ public bool on_list_item {public get; private set;}
+
public string text {
owned get {return buffer.text;}
set {buffer.text = value;}
@@ -27,7 +31,17 @@ public class Jorts.TextView : Granite.HyperTextView {
set_vexpand (true);
set_wrap_mode (Gtk.WrapMode.WORD_CHAR);
- //Application.gsettings.bind ("scribbly-mode-active", this, "scribbly", SettingsBindFlags.DEFAULT);
+ list_item_start = Application.gsettings.get_string ("list-item-start");
+ Application.gsettings.changed["list-item-start"].connect (on_prefix_changed);
+
+ keyboard = new Gtk.EventControllerKey ();
+ add_controller (keyboard);
+ keyboard.key_pressed.connect (on_key_pressed);
+
+ //TODO: Buggy. Clicking anywhere brings it out of whack
+ // on_cursor_changed ();
+ // move_cursor.connect_after (on_cursor_changed);
+
}
public void paste () {
@@ -43,4 +57,159 @@ public class Jorts.TextView : Granite.HyperTextView {
}
});
}
+
+ public void toggle_list () {
+ Gtk.TextIter start, end;
+ buffer.get_selection_bounds (out start, out end);
+
+ var first_line = (uint8)start.get_line ();
+ var last_line = (uint8)end.get_line ();
+ debug ("got " + first_line.to_string () + " to " + last_line.to_string ());
+
+ var selected_is_list = this.is_list (first_line, last_line, list_item_start);
+
+ buffer.begin_user_action ();
+ if (selected_is_list)
+ {
+ this.remove_list (first_line, last_line);
+
+ } else {
+ this.set_list (first_line, last_line);
+ }
+ buffer.end_user_action ();
+ }
+
+ /**
+ * Add the list prefix only to lines who hasnt it already
+ */
+ private bool has_prefix (uint8 line_number) {
+ Gtk.TextIter start, end;
+ buffer.get_iter_at_line_offset (out start, line_number, 0);
+
+ end = start.copy ();
+ end.forward_to_line_end ();
+
+ var text_in_line = buffer.get_slice (start, end, false);
+
+ return text_in_line.has_prefix (list_item_start);
+ }
+
+ /**
+ * Checks whether Line x to Line y are all bulleted.
+ */
+ private bool is_list (uint8 first_line, uint8 last_line, string list_item_start) {
+
+ for (uint8 line_number = first_line; line_number <= last_line; line_number++) {
+ debug ("doing line " + line_number.to_string ());
+
+ if (!this.has_prefix (line_number)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Add the list prefix only to lines who hasnt it already
+ */
+ private void set_list (uint8 first_line, uint8 last_line) {
+ Gtk.TextIter line_start;
+ for (uint8 line_number = first_line; line_number <= last_line; line_number++) {
+
+ debug ("doing line " + line_number.to_string ());
+ if (!this.has_prefix (line_number)) {
+ buffer.get_iter_at_line_offset (out line_start, line_number, 0);
+ buffer.insert (ref line_start, list_item_start, -1);
+ }
+ }
+ }
+
+ /**
+ * Remove list prefix from line x to line y. Presuppose it is there
+ */
+ private void remove_list (uint8 first_line, uint8 last_line) {
+ for (uint8 line_number = first_line; line_number <= last_line; line_number++) {
+ remove_prefix (line_number);
+ }
+ }
+
+ /**
+ * Remove list prefix from line x to line y. Presuppose it is there
+ */
+ private void remove_prefix (uint8 line_number) {
+ Gtk.TextIter line_start, prefix_end;
+ var remove_range = list_item_start.length;
+
+ debug ("doing line " + line_number.to_string ());
+ buffer.get_iter_at_line_offset (out line_start, line_number, 0);
+ buffer.get_iter_at_line_offset (out prefix_end, line_number, remove_range);
+ buffer.delete (ref line_start, ref prefix_end);
+ }
+
+ /**
+ * Handler whenever a key is pressed, to see if user needs something and get ahead
+ * Some local stuff is deduplicated in the Ifs, because i do not like the idea of getting computation done not needed 98% of the time
+ */
+ private bool on_key_pressed (uint keyval, uint keycode, Gdk.ModifierType state) {
+ print ("char typed");
+
+ // If backspace on a prefix: Delete the prefix.
+ if (keyval == Gdk.Key.BackSpace) {
+ print ("backspace");
+
+ Gtk.TextIter start, end;
+ buffer.get_selection_bounds (out start, out end);
+
+ var line_number = (uint8)start.get_line ();
+
+ if (has_prefix (line_number)) {
+
+ buffer.get_iter_at_line_offset (out start, line_number, 0);
+ var text_in_line = buffer.get_slice (start, end, false);
+
+ if (text_in_line == list_item_start) {
+
+ buffer.begin_user_action ();
+ buffer.delete (ref start, ref end);
+ buffer.insert_at_cursor ("\n", -1);
+ buffer.end_user_action ();
+ }
+ }
+
+ return false;
+
+ // If Enter on a list item, add a list prefix on the new line
+ } else if (keyval == Gdk.Key.Return) {
+ Gtk.TextIter start, end;
+ buffer.get_selection_bounds (out start, out end);
+ var line_number = (uint8)start.get_line ();
+
+ if (this.has_prefix (line_number)) {
+
+ buffer.begin_user_action ();
+ buffer.insert_at_cursor ("\n" + list_item_start, -1);
+ buffer.end_user_action ();
+
+ return true;
+ }
+ }
+
+ // Nothing, carry on
+ return false;
+ }
+
+ private void on_prefix_changed () {
+ list_item_start = Application.gsettings.get_string ("list-item-start");
+ }
+
+ private void on_cursor_changed () {
+ Gtk.TextIter start, end;
+ buffer.get_selection_bounds (out start, out end);
+ var line_number = (uint8)start.get_line ();
+
+ on_list_item = this.has_prefix (line_number);
+
+ print ("THIS IS LIST. HAS " + on_list_item.to_string () + "ON LINE " + line_number.to_string ());
+ }
}
diff --git a/src/Windows/PreferenceWindow.vala b/src/Windows/PreferenceWindow.vala
index 16fee33..b2a53f2 100644
--- a/src/Windows/PreferenceWindow.vala
+++ b/src/Windows/PreferenceWindow.vala
@@ -69,13 +69,4 @@ public class Jorts.PreferenceWindow : Gtk.Window {
//prefview.reset_button.clicked.connect (on_reset);
prefview.close_button.clicked.connect (() => {close ();});
}
-
-/* private void on_reset () {
- debug ("Resetting settingsā¦");
-
- string[] keys = {"scribbly-mode-active", "hide-bar"};
- foreach (var key in keys) {
- Application.gsettings.reset (key);
- }
- } */
}
diff --git a/src/Windows/StickyNoteWindow.vala b/src/Windows/StickyNoteWindow.vala
index 4db4f3d..a795136 100644
--- a/src/Windows/StickyNoteWindow.vala
+++ b/src/Windows/StickyNoteWindow.vala
@@ -41,6 +41,7 @@ public class Jorts.StickyNoteWindow : Gtk.Window {
public const string ACTION_ZOOM_IN = "action_zoom_in";
public const string ACTION_TOGGLE_MONO = "action_toggle_mono";
public const string ACTION_DELETE = "action_delete";
+ public const string ACTION_TOGGLE_LIST = "action_toggle_list";
public const string ACTION_THEME_1 = "action_theme_1";
public const string ACTION_THEME_2 = "action_theme_2";
@@ -63,6 +64,7 @@ public class Jorts.StickyNoteWindow : Gtk.Window {
{ ACTION_ZOOM_OUT, action_zoom_out},
{ ACTION_ZOOM_DEFAULT, action_zoom_default},
{ ACTION_TOGGLE_MONO, action_toggle_mono},
+ { ACTION_TOGGLE_LIST, action_toggle_list},
{ ACTION_ZOOM_IN, action_zoom_in},
{ ACTION_THEME_1, action_theme_1},
{ ACTION_THEME_2, action_theme_2},
@@ -242,11 +244,13 @@ public class Jorts.StickyNoteWindow : Gtk.Window {
private void action_show_menu () {view.menu_button.activate ();}
private void action_delete () {((Jorts.Application)this.application).manager.delete_note (this);}
private void action_toggle_mono () {popover.monospace = !popover.monospace;}
+ private void action_toggle_list () {view.textview.toggle_list ();}
private void action_zoom_out () {zoomcontroller.zoom_out ();}
private void action_zoom_default () {zoomcontroller.zoom_default ();}
private void action_zoom_in () {zoomcontroller.zoom_in ();}
+ // Careful! The keyboard counts from 1 to 10 (0), but the themes are from 0 to 9
private void action_theme_1 () {popover.color = (Jorts.Themes.all ())[0];}
private void action_theme_2 () {popover.color = (Jorts.Themes.all ())[1];}
private void action_theme_3 () {popover.color = (Jorts.Themes.all ())[2];}