Skip to content

Commit 9903113

Browse files
authored
Merge branch 'alainm23:master' into master
2 parents 415199a + 2abe639 commit 9903113

20 files changed

+658
-19
lines changed

core/Objects/Attachment.vala

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright © 2023 Alain M. (https://github.com/alainm23/planify)
3+
*
4+
* This program is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 3 of the License, or (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public
15+
* License along with this program; if not, write to the
16+
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17+
* Boston, MA 02110-1301 USA
18+
*
19+
* Authored by: Alain M. <alainmh23@gmail.com>
20+
*/
21+
22+
public class Objects.Attachment : GLib.Object {
23+
public string id { get; set; default = ""; }
24+
public string item_id { get; set; default = ""; }
25+
public string file_type { get; set; default = ""; }
26+
public string file_name { get; set; default = ""; }
27+
public int64 file_size { get; set; default = 0; }
28+
public string file_path { get; set; default = ""; }
29+
30+
public signal void deleted ();
31+
32+
Objects.Item? _item;
33+
public Objects.Item item {
34+
get {
35+
_item = Services.Database.get_default ().get_item (item_id);
36+
return _item;
37+
}
38+
39+
set {
40+
_item = value;
41+
}
42+
}
43+
44+
construct {
45+
deleted.connect (() => {
46+
Services.Database.get_default ().attachment_deleted (this);
47+
});
48+
}
49+
50+
public string to_string () {
51+
return """
52+
_________________________________
53+
ID: %s
54+
ITEM ID: %s
55+
FILE TYPE: %s
56+
FILE NAME: %s
57+
FILE SIZE: %s
58+
FILE PATH: %s
59+
---------------------------------
60+
""".printf (
61+
id,
62+
item_id,
63+
file_type,
64+
file_name,
65+
file_size.to_string (),
66+
file_path
67+
);
68+
}
69+
70+
public void delete () {
71+
Services.Database.get_default ().delete_attachment (this);
72+
}
73+
}

core/Objects/Filters/FilterItem.vala

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ public class Objects.Filters.FilterItem : GLib.Object {
3535
return _id;
3636
}
3737
}
38-
}
38+
}

core/Objects/Item.vala

+41
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,14 @@ public class Objects.Item : Objects.BaseObject {
256256
}
257257
}
258258

259+
Gee.ArrayList<Objects.Attachment> _attachments;
260+
public Gee.ArrayList<Objects.Attachment> attachments {
261+
get {
262+
_attachments = Services.Database.get_default ().get_attachments_by_item (this);
263+
return _attachments;
264+
}
265+
}
266+
259267
public signal void item_label_added (Objects.Label label);
260268
public signal void item_label_deleted (Objects.Label label);
261269
public signal void item_added (Objects.Item item);
@@ -264,6 +272,8 @@ public class Objects.Item : Objects.BaseObject {
264272
public signal void loading_changed (bool value);
265273
public signal void show_item_changed ();
266274
public signal void collapsed_change ();
275+
public signal void attachment_added (Objects.Attachment attachment);
276+
public signal void attachment_deleted (Objects.Attachment attachment);
267277

268278
construct {
269279
deleted.connect (() => {
@@ -768,6 +778,37 @@ public class Objects.Item : Objects.BaseObject {
768778
_reminders.add (reminder);
769779
}
770780

781+
public Objects.Attachment? add_attachment_if_not_exists (Objects.Attachment attachment) {
782+
Objects.Attachment? return_value = null;
783+
lock (_attachments) {
784+
return_value = get_attachment (attachment);
785+
if (return_value == null) {
786+
Services.Database.get_default ().insert_attachment (attachment);
787+
add_attachment (attachment);
788+
}
789+
790+
return return_value;
791+
}
792+
}
793+
794+
private Objects.Attachment? get_attachment (Objects.Attachment attachment) {
795+
Objects.Attachment? return_value = null;
796+
lock (_attachments) {
797+
foreach (var _attachment in _attachments) {
798+
if (_attachment.file_path == attachment.file_path) {
799+
return_value = _attachment;
800+
break;
801+
}
802+
}
803+
}
804+
805+
return return_value;
806+
}
807+
808+
private void add_attachment (Objects.Attachment attachment) {
809+
_attachments.add (attachment);
810+
}
811+
771812
// Labels
772813
public Objects.Label add_label_if_not_exists (Objects.Label label) {
773814
Objects.Label? return_value = null;

core/Services/Database.vala

+131-8
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public class Services.Database : GLib.Object {
4949
public signal void reminder_added (Objects.Reminder reminder);
5050
public signal void reminder_deleted (Objects.Reminder reminder);
5151

52+
public signal void attachment_deleted (Objects.Attachment attachment);
53+
5254
private static Database? _instance;
5355
public static Database get_default () {
5456
if (_instance == null) {
@@ -109,6 +111,17 @@ public class Services.Database : GLib.Object {
109111
}
110112
}
111113

114+
Gee.ArrayList<Objects.Attachment> _attachments = null;
115+
public Gee.ArrayList<Objects.Attachment> attachments {
116+
get {
117+
if (_attachments == null) {
118+
_attachments = get_attachments_collection ();
119+
}
120+
121+
return _attachments;
122+
}
123+
}
124+
112125
construct {
113126
label_deleted.connect ((label) => {
114127
if (_labels.remove (label)) {
@@ -139,6 +152,12 @@ public class Services.Database : GLib.Object {
139152
debug ("Reminder Removed: %s", reminder.id.to_string ());
140153
}
141154
});
155+
156+
attachment_deleted.connect ((attachment) => {
157+
if (_attachments.remove (attachment)) {
158+
debug ("Attachment Removed: %s", attachment.id.to_string ());
159+
}
160+
});
142161
}
143162

144163
public void init_database () {
@@ -342,6 +361,22 @@ public class Services.Database : GLib.Object {
342361
);
343362
""";
344363

364+
if (db.exec (sql, null, out errormsg) != Sqlite.OK) {
365+
warning (errormsg);
366+
}
367+
368+
sql = """
369+
CREATE TABLE IF NOT EXISTS Attachments (
370+
id TEXT PRIMARY KEY,
371+
item_id TEXT,
372+
file_type TEXT,
373+
file_name TEXT,
374+
file_size TEXT,
375+
file_path TEXT,
376+
FOREIGN KEY (item_id) REFERENCES Items (id) ON DELETE CASCADE
377+
);
378+
""";
379+
345380
if (db.exec (sql, null, out errormsg) != Sqlite.OK) {
346381
warning (errormsg);
347382
}
@@ -1744,7 +1779,6 @@ public class Services.Database : GLib.Object {
17441779
}
17451780

17461781
// Reminders
1747-
17481782
public void insert_reminder (Objects.Reminder reminder) {
17491783
Sqlite.Statement stmt;
17501784
string sql;
@@ -1842,9 +1876,98 @@ public class Services.Database : GLib.Object {
18421876
stmt.reset ();
18431877
}
18441878

1845-
/*
1846-
Queue
1847-
*/
1879+
// Atrachments
1880+
public void insert_attachment (Objects.Attachment attachment) {
1881+
Sqlite.Statement stmt;
1882+
string sql;
1883+
1884+
sql = """
1885+
INSERT OR IGNORE INTO Attachments (id, item_id, file_type, file_name, file_size, file_path)
1886+
VALUES ($id, $item_id, $file_type, $file_name, $file_size, $file_path);
1887+
""";
1888+
1889+
db.prepare_v2 (sql, sql.length, out stmt);
1890+
set_parameter_str (stmt, "$id", attachment.id);
1891+
set_parameter_str (stmt, "$item_id", attachment.item_id);
1892+
set_parameter_str (stmt, "$file_type", attachment.file_type);
1893+
set_parameter_str (stmt, "$file_name", attachment.file_name);
1894+
set_parameter_int64 (stmt, "$file_size", attachment.file_size);
1895+
set_parameter_str (stmt, "$file_path", attachment.file_path);
1896+
1897+
if (stmt.step () != Sqlite.DONE) {
1898+
warning ("Error: %d: %s", db.errcode (), db.errmsg ());
1899+
} else {
1900+
attachments.add (attachment);
1901+
attachment.item.attachment_added (attachment);
1902+
}
1903+
1904+
stmt.reset ();
1905+
}
1906+
1907+
public Gee.ArrayList<Objects.Attachment> get_attachments_collection () {
1908+
Gee.ArrayList<Objects.Attachment> return_value = new Gee.ArrayList<Objects.Attachment> ();
1909+
Sqlite.Statement stmt;
1910+
1911+
sql = """
1912+
SELECT * FROM Attachments;
1913+
""";
1914+
1915+
db.prepare_v2 (sql, sql.length, out stmt);
1916+
1917+
while (stmt.step () == Sqlite.ROW) {
1918+
return_value.add (_fill_attachment (stmt));
1919+
}
1920+
stmt.reset ();
1921+
return return_value;
1922+
}
1923+
1924+
public Objects.Attachment _fill_attachment (Sqlite.Statement stmt) {
1925+
Objects.Attachment return_value = new Objects.Attachment ();
1926+
return_value.id = stmt.column_text (0);
1927+
return_value.item_id = stmt.column_text (1);
1928+
return_value.file_type = stmt.column_text (2);
1929+
return_value.file_name = stmt.column_text (3);
1930+
return_value.file_size = stmt.column_int64 (4);
1931+
return_value.file_path = stmt.column_text (5);
1932+
return return_value;
1933+
}
1934+
1935+
public Gee.ArrayList<Objects.Attachment> get_attachments_by_item (Objects.Item item) {
1936+
Gee.ArrayList<Objects.Attachment> return_value = new Gee.ArrayList<Objects.Attachment> ();
1937+
lock (_attachments) {
1938+
foreach (var attachment in attachments) {
1939+
if (attachment.item_id == item.id) {
1940+
return_value.add (attachment);
1941+
}
1942+
}
1943+
1944+
return return_value;
1945+
}
1946+
}
1947+
1948+
public void delete_attachment (Objects.Attachment attachment) {
1949+
Sqlite.Statement stmt;
1950+
1951+
sql = """
1952+
DELETE FROM Attachments WHERE id=$id;
1953+
""";
1954+
1955+
db.prepare_v2 (sql, sql.length, out stmt);
1956+
set_parameter_str (stmt, "$id", attachment.id);
1957+
1958+
if (stmt.step () == Sqlite.DONE) {
1959+
attachment.deleted ();
1960+
attachment.item.attachment_deleted (attachment);
1961+
} else {
1962+
warning ("Error: %d: %s", db.errcode (), db.errmsg ());
1963+
}
1964+
1965+
stmt.reset ();
1966+
}
1967+
1968+
/*
1969+
* Queue
1970+
*/
18481971

18491972
public void insert_queue (Objects.Queue queue) {
18501973
Sqlite.Statement stmt;
@@ -2170,10 +2293,10 @@ public class Services.Database : GLib.Object {
21702293
stmt.bind_int (par_position, val);
21712294
}
21722295

2173-
// private void set_parameter_int64 (Sqlite.Statement? stmt, string par, int64 val) {
2174-
// int par_position = stmt.bind_parameter_index (par);
2175-
// stmt.bind_int64 (par_position, val);
2176-
// }
2296+
private void set_parameter_int64 (Sqlite.Statement? stmt, string par, int64 val) {
2297+
int par_position = stmt.bind_parameter_index (par);
2298+
stmt.bind_int64 (par_position, val);
2299+
}
21772300

21782301
private void set_parameter_str (Sqlite.Statement? stmt, string par, string val) {
21792302
int par_position = stmt.bind_parameter_index (par);

core/Util/Util.vala

+9-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ public class Util : GLib.Object {
8888
}
8989

9090
// Providers
91-
9291
private Gee.HashMap<string, Gtk.CssProvider>? providers;
9392
public void set_widget_color (string color, Gtk.Widget widget) {
9493
if (providers == null) {
@@ -347,6 +346,15 @@ public class Util : GLib.Object {
347346
return Uri.escape_string (text, null, false);
348347
}
349348

349+
private Gtk.MediaFile soud_medida = null;
350+
public void play_audio () {
351+
if (soud_medida == null) {
352+
soud_medida = Gtk.MediaFile.for_resource ("/io/github/alainm23/planify/success.ogg");
353+
}
354+
355+
soud_medida.play ();
356+
}
357+
350358
/*
351359
DateTime
352360
*/

core/meson.build

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ core_files = files(
7676
'Objects/Reminder.vala',
7777
'Objects/Section.vala',
7878
'Objects/Promise.vala',
79+
'Objects/Attachment.vala',
7980

8081
'Objects/Filters/Pinboard.vala',
8182
'Objects/Filters/Scheduled.vala',

data/io.github.alainm23.planify.gresource.xml

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
<file alias="subprojects.webm" compressed="true">resources/videos/subprojects.webm</file>
2121
<file alias="magic-button.webm" compressed="true">resources/videos/magic-button.webm</file>
2222

23+
<!-- Audios -->
24+
<file alias="success.ogg" compressed="true">resources/sounds/success.ogg</file>
25+
2326
<!-- Icons -->
2427
<file alias="todoist.svg">resources/icons/todoist.svg</file>
2528
<file alias="cloud.svg">resources/icons/cloud.svg</file>
@@ -82,6 +85,7 @@
8285
<file alias="step-out-symbolic.svg">resources/icons/step-out-symbolic.svg</file>
8386
<file alias="playlist-repeat-symbolic.svg">resources/icons/playlist-repeat-symbolic.svg</file>
8487
<file alias="vertical-arrows-long-symbolic.svg">resources/icons/vertical-arrows-long-symbolic.svg</file>
88+
<file alias="mail-attachment-symbolic.svg">resources/icons/mail-attachment-symbolic.svg</file>
8589
</gresource>
8690

8791
<gresource prefix="/io/github/alainm23/planify/Devel/icons/scalable/actions">
@@ -141,6 +145,7 @@
141145
<file alias="step-out-symbolic.svg">resources/icons/step-out-symbolic.svg</file>
142146
<file alias="playlist-repeat-symbolic.svg">resources/icons/playlist-repeat-symbolic.svg</file>
143147
<file alias="vertical-arrows-long-symbolic.svg">resources/icons/vertical-arrows-long-symbolic.svg</file>
148+
<file alias="mail-attachment-symbolic.svg">resources/icons/mail-attachment-symbolic.svg</file>
144149
</gresource>
145150

146151
<gresource prefix="/io/github/alainm23/planify/quick-add/icons/scalable/actions">
@@ -200,5 +205,6 @@
200205
<file alias="step-out-symbolic.svg">resources/icons/step-out-symbolic.svg</file>
201206
<file alias="playlist-repeat-symbolic.svg">resources/icons/playlist-repeat-symbolic.svg</file>
202207
<file alias="vertical-arrows-long-symbolic.svg">resources/icons/vertical-arrows-long-symbolic.svg</file>
208+
<file alias="mail-attachment-symbolic.svg">resources/icons/mail-attachment-symbolic.svg</file>
203209
</gresource>
204210
</gresources>

0 commit comments

Comments
 (0)