Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to set Keywords #139

Merged
merged 1 commit into from
Feb 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ sources = files(
'src' / 'View' / 'EditView.vala',
'src' / 'View' / 'FilesView.vala',
'src' / 'Widget' / 'CategoryChooser.vala',
'src' / 'Widget' / 'KeywordsRow.vala',
'src' / 'Application.vala',
'src' / 'Define.vala',
'src' / 'MainWindow.vala'
Expand Down
1 change: 1 addition & 0 deletions po/POTFILES
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ src/MainWindow.vala
src/View/EditView.vala
src/View/FilesView.vala
src/Widget/CategoryChooser.vala
src/Widget/KeywordsRow.vala
15 changes: 15 additions & 0 deletions src/Define.vala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ namespace Define {
*/
public const string APP_NAME = "Pin It!";

/**
* A key under g_key_file_desktop_group, whose value is a list of strings giving the keywords which may be used in
* addition to other metadata to describe this entry.
*
* Using KeyFileDesktop.KEY_KEYWORDS will cause the cc failing with "‘G_KEY_FILE_DESKTOP_KEY_KEYWORDS’ undeclared"
* error. This constant does not seem to be defined in the original glib and defined in the following patch.
* (and maybe valac uses glibc with this patch and thus it does not complain any error.)
*
* https://sources.debian.org/patches/glib2.0/2.78.3-2/01_gettext-desktopfiles.patch/
*
* I just keep to borrow the definition of KEY_KEYWORDS here instead of applying the patch,
* since it might have side effect.
*/
public const string KEY_KEYWORDS = "Keywords";

/**
* Defines response IDs used in Adw.MessageDialog.
*/
Expand Down
13 changes: 13 additions & 0 deletions src/View/EditView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class View.EditView : Adw.NavigationPage {
private Adw.EntryRow generic_name_entry;
private Adw.EntryRow comment_entry;
private Widget.CategoryChooser categories_row;
private Widget.KeywordsRow keywords_row;
private Adw.EntryRow startup_wm_class_entry;
private Adw.SwitchRow terminal_row;

Expand Down Expand Up @@ -119,6 +120,9 @@ public class View.EditView : Adw.NavigationPage {
categories_row = new Widget.CategoryChooser ();
optional_group.add (categories_row);

keywords_row = new Widget.KeywordsRow ();
optional_group.add (keywords_row);

/*
* Content part - Advanced Entries
*/
Expand Down Expand Up @@ -331,6 +335,14 @@ public class View.EditView : Adw.NavigationPage {
desktop_file.set_string_list (KeyFileDesktop.KEY_CATEGORIES, categories_row.selected);
});

keywords_row.keywords_changed.connect (() => {
if (is_loading) {
return;
}

desktop_file.set_string_list (Define.KEY_KEYWORDS, keywords_row.keywords);
});

startup_wm_class_entry.notify["text"].connect (() => {
if (is_loading) {
return;
Expand Down Expand Up @@ -400,6 +412,7 @@ public class View.EditView : Adw.NavigationPage {
comment_entry.text = desktop_file.get_locale_string (KeyFileDesktop.KEY_COMMENT, locale, false);

categories_row.selected = desktop_file.get_string_list (KeyFileDesktop.KEY_CATEGORIES, false);
keywords_row.keywords = desktop_file.get_string_list (Define.KEY_KEYWORDS, false);
startup_wm_class_entry.text = desktop_file.get_string (KeyFileDesktop.KEY_STARTUP_WM_CLASS, false);
terminal_row.active = desktop_file.get_boolean (KeyFileDesktop.KEY_TERMINAL, false);

Expand Down
129 changes: 129 additions & 0 deletions src/Widget/KeywordsRow.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-FileCopyrightText: 2021-2024 Ryo Nakano <ryonakaknock3@gmail.com>
*/

/**
* List Keywords of the app.
*
* There are {@link Widget.KeywordsRow.KeywordRow} for each keyword.
*/
public class Widget.KeywordsRow : Adw.ExpanderRow {
/**
* A signal emitted when keywords are changed.
*/
public signal void keywords_changed ();

/**
* Set/get keywords.
*/
public string[] keywords {
owned get {
string[] _keywords = {};

rows.foreach ((row) => {
_keywords += row.text;
return true;
});

return _keywords;
}

set {
// Clear all of the currently added entries
rows.foreach ((row) => {
remove_row (row);
return true;
});

foreach (unowned string keyword in value) {
add_keyword (keyword);
}
}
}

/**
* Stores all of the rows in this expander row.
*/
private Gee.ArrayList<KeywordRow> rows;

public KeywordsRow () {
}

construct {
title = _("Keywords");
subtitle = _("These words can be used as search terms.");

rows = new Gee.ArrayList<KeywordRow> ();

var add_keyword_button = new Gtk.Button.from_icon_name ("list-add-symbolic") {
tooltip_text = _("Add a new keyword"),
valign = Gtk.Align.CENTER
};
add_keyword_button.add_css_class ("flat");
add_suffix (add_keyword_button);

add_keyword_button.clicked.connect (() => {
expanded = true;
add_keyword ();
});
}

/**
* Add new keyword.
*
* @param keyword The keyword.
*/
public void add_keyword (string keyword = "") {
var row = new KeywordRow (keyword);
((Gtk.Editable) row).changed.connect (() => {
keywords_changed ();
});
row.delete_clicked.connect (() => {
remove_row (row);
keywords_changed ();
});
rows.add (row);
add_row (row);
}

/**
* Remove row.
*
* @param row The {@link KeywordRow} to remove.
*/
private void remove_row (KeywordRow row) {
rows.remove (row);
remove (row);
}

private class KeywordRow : Adw.EntryRow {
/**
* A signal emitted when the delete button is clicked.
*/
public signal void delete_clicked ();

/**
* The constructor.
*
* Create a new KeywordRow and set its text to keyword.
*
* @param keyword The keyword to set to the text property.
*/
public KeywordRow (string keyword) {
title = _("Keyword");
text = keyword;

var delete_button = new Gtk.Button.from_icon_name ("edit-delete-symbolic") {
tooltip_text = _("Delete keyword"),
valign = Gtk.Align.CENTER
};
delete_button.add_css_class ("flat");
add_suffix (delete_button);

delete_button.clicked.connect (() => {
delete_clicked ();
});
}
}
}