Browse Source

Add bookmarks

tags/0.2.0
Julien Blanchard 1 year ago
parent
commit
79c1ee3df2
6 changed files with 154 additions and 24 deletions
  1. 1
    0
      .gitignore
  2. 1
    1
      Cargo.toml
  3. 34
    0
      src/bookmarks.rs
  4. 39
    5
      src/castor.glade
  5. 16
    18
      src/gui.rs
  6. 63
    0
      src/main.rs

+ 1
- 0
.gitignore View File

@@ -1,2 +1,3 @@
1 1
 /target
2 2
 **/*.rs.bk
3
+/src/castor.glade~

+ 1
- 1
Cargo.toml View File

@@ -24,4 +24,4 @@ lazy_static = "*"
24 24
 
25 25
 [dependencies.gtk]
26 26
 version = "0.8.0"
27
-features = ["v3_16"]
27
+features = ["v3_22"]

+ 34
- 0
src/bookmarks.rs View File

@@ -0,0 +1,34 @@
1
+extern crate dirs;
2
+use std::fs::File;
3
+use std::fs::OpenOptions;
4
+use std::io::{Read, Write};
5
+
6
+
7
+pub fn add(url: &str) {
8
+    let mut file = bookmarks_file();
9
+    let entry = format!("=> {}\n", url);
10
+    file.write_all(entry.as_bytes())
11
+        .expect("Unable to write file");
12
+}
13
+
14
+pub fn content() -> String {
15
+    let mut file = bookmarks_file();
16
+    let mut content = String::new();
17
+    file.read_to_string(&mut content)
18
+        .expect("Unable to read file");
19
+
20
+    content
21
+}
22
+
23
+fn bookmarks_file() -> File {
24
+    let mut bookmarks = dirs::data_local_dir().unwrap();
25
+    bookmarks.push("castor_bookmarks");
26
+    let file_path = bookmarks.into_os_string();
27
+
28
+    OpenOptions::new()
29
+        .create(true)
30
+        .append(true)
31
+        .read(true)
32
+        .open(file_path)
33
+        .expect("file not found")
34
+}

+ 39
- 5
src/castor.glade View File

@@ -4,6 +4,23 @@
4 4
   <requires lib="gtk+" version="3.16"/>
5 5
   <object class="GtkTextBuffer"/>
6 6
   <object class="GtkTextBuffer"/>
7
+  <object class="GtkImage" id="image1">
8
+    <property name="name">add_bookmark</property>
9
+    <property name="visible">True</property>
10
+    <property name="can_focus">False</property>
11
+    <property name="stock">gtk-add</property>
12
+  </object>
13
+  <object class="GtkImage" id="image2">
14
+    <property name="visible">True</property>
15
+    <property name="can_focus">False</property>
16
+    <property name="tooltip_text" translatable="yes">Show Bookmarks</property>
17
+    <property name="stock">gtk-justify-fill</property>
18
+  </object>
19
+  <object class="GtkImage" id="image3">
20
+    <property name="visible">True</property>
21
+    <property name="can_focus">False</property>
22
+    <property name="stock">gtk-go-back</property>
23
+  </object>
7 24
   <object class="GtkApplicationWindow" id="window">
8 25
     <property name="can_focus">False</property>
9 26
     <property name="title" translatable="yes">Castor - Gemini Browser</property>
@@ -25,11 +42,12 @@
25 42
             <property name="can_focus">False</property>
26 43
             <child>
27 44
               <object class="GtkButton" id="back_button">
28
-                <property name="label" translatable="yes">Back</property>
29 45
                 <property name="name">back_button</property>
30 46
                 <property name="visible">True</property>
31 47
                 <property name="can_focus">True</property>
32 48
                 <property name="receives_default">True</property>
49
+                <property name="tooltip_text" translatable="yes">Go back</property>
50
+                <property name="image">image3</property>
33 51
                 <property name="always_show_image">True</property>
34 52
               </object>
35 53
               <packing>
@@ -40,12 +58,13 @@
40 58
               </packing>
41 59
             </child>
42 60
             <child>
43
-              <object class="GtkButton" id="forward_button">
44
-                <property name="label" translatable="yes">Bookmarks</property>
45
-                <property name="name">forward_button</property>
61
+              <object class="GtkButton" id="add_bookmark_button">
62
+                <property name="name">add_bookmark_button</property>
46 63
                 <property name="visible">True</property>
47 64
                 <property name="can_focus">True</property>
48 65
                 <property name="receives_default">True</property>
66
+                <property name="tooltip_text" translatable="yes">Add to Bookmarks</property>
67
+                <property name="image">image1</property>
49 68
                 <property name="always_show_image">True</property>
50 69
               </object>
51 70
               <packing>
@@ -56,6 +75,21 @@
56 75
               </packing>
57 76
             </child>
58 77
             <child>
78
+              <object class="GtkButton" id="show_bookmarks_button">
79
+                <property name="name">show_bookmarks_button</property>
80
+                <property name="visible">True</property>
81
+                <property name="can_focus">True</property>
82
+                <property name="receives_default">True</property>
83
+                <property name="tooltip_text" translatable="yes">Show Bookmarks</property>
84
+                <property name="image">image2</property>
85
+              </object>
86
+              <packing>
87
+                <property name="expand">False</property>
88
+                <property name="fill">True</property>
89
+                <property name="position">2</property>
90
+              </packing>
91
+            </child>
92
+            <child>
59 93
               <object class="GtkEntry" id="url_bar">
60 94
                 <property name="name">url_bar</property>
61 95
                 <property name="visible">True</property>
@@ -67,7 +101,7 @@
67 101
                 <property name="expand">True</property>
68 102
                 <property name="fill">True</property>
69 103
                 <property name="padding">1</property>
70
-                <property name="position">2</property>
104
+                <property name="position">3</property>
71 105
               </packing>
72 106
             </child>
73 107
           </object>

+ 16
- 18
src/gui.rs View File

@@ -7,6 +7,8 @@ pub struct Gui {
7 7
     url_bar: Entry,
8 8
     content_view: TextView,
9 9
     back_button: Button,
10
+    add_bookmark_button: Button,
11
+    show_bookmarks_button: Button,
10 12
 }
11 13
 
12 14
 impl Gui {
@@ -20,38 +22,26 @@ impl Gui {
20 22
         let url_bar: Entry = builder.get_object("url_bar").expect("Couldn't get url_bar");
21 23
         let content_view: TextView = builder.get_object("content_view").expect("Couldn't get content_view");
22 24
         let back_button: Button = builder.get_object("back_button").expect("Couldn't get back_button");
25
+        let add_bookmark_button: Button = builder.get_object("add_bookmark_button").expect("Couldn't get add_bookmark_button");
26
+        let show_bookmarks_button: Button = builder.get_object("show_bookmarks_button").expect("Couldn't get show_bookmarks_button");
23 27
 
24 28
         Gui {
25 29
             window,
26 30
             url_bar,
27 31
             content_view,
28 32
             back_button,
33
+            add_bookmark_button,
34
+            show_bookmarks_button,
29 35
         }
30 36
     }
31 37
 
32
-    // Set up naming for the window and show it to the user.
33 38
     pub fn start(&self) {
34
-        glib::set_application_name("Castor");
35
-        self.window.set_wmclass("Castor", "Castor");
39
+        glib::set_application_name("Castor - Gemini Browser");
40
+        self.window.set_role("Castor - Gemini Browser");
36 41
         self.window.connect_delete_event(|_, _| { gtk::main_quit(); Inhibit(false) });
37 42
         self.window.show_all();
38 43
     }
39 44
 
40
-    // pub fn update_from(&self, state: &State) {
41
-    //     if let Some(ref err) = state.error {
42
-    //         self.error_label.set_text(
43
-    //             &format!("The dice expression entered is not valid:\n{}", err)
44
-    //         );
45
-    //         self.popover.show_all();
46
-    //     } else {
47
-    //         // The popover will hide itself anyway when the user clicks
48
-    //         // outside of it, but we shouldn't leave an error indicator in it.
49
-    //         self.error_label.set_text("");
50
-    //     }
51
-
52
-    //     self.result.set_text(&format!("{}", state.value));
53
-    // }
54
-
55 45
     pub fn window(&self) -> &ApplicationWindow {
56 46
         &self.window
57 47
     }
@@ -67,4 +57,12 @@ impl Gui {
67 57
     pub fn back_button(&self) -> &Button {
68 58
         &self.back_button
69 59
     }
60
+
61
+    pub fn add_bookmark_button(&self) -> &Button {
62
+        &self.add_bookmark_button
63
+    }
64
+
65
+    pub fn show_bookmarks_button(&self) -> &Button {
66
+        &self.show_bookmarks_button
67
+    }
70 68
 }

+ 63
- 0
src/main.rs View File

@@ -16,6 +16,7 @@ use url::{Position, Url};
16 16
 mod gui;
17 17
 use gui::Gui;
18 18
 mod absolute;
19
+mod bookmarks;
19 20
 mod content;
20 21
 mod history;
21 22
 mod link;
@@ -43,6 +44,24 @@ fn main() {
43 44
         });
44 45
     }
45 46
 
47
+    // Bind add_bookmark button
48
+    {
49
+        let button = gui.add_bookmark_button();
50
+        let gui = gui.clone();
51
+        button.connect_clicked(move |_| {
52
+            add_bookmark(&gui);
53
+        });
54
+    }
55
+
56
+    // Bind show_bookmarks button
57
+    {
58
+        let button = gui.show_bookmarks_button();
59
+        let gui = gui.clone();
60
+        button.connect_clicked(move |_| {
61
+            show_bookmarks(&gui);
62
+        });
63
+    }
64
+
46 65
     // Bind URL bar
47 66
     {
48 67
         let gui_clone = gui.clone();
@@ -78,10 +97,37 @@ fn update_url_field(gui: &Arc<Gui>, url: &str) {
78 97
     url_bar.get_buffer().set_text(url);
79 98
 }
80 99
 
100
+fn add_bookmark(gui: &Arc<Gui>) {
101
+    let current_url = history::get_current_url();
102
+    if let Some(url) = current_url {
103
+        bookmarks::add(&url);
104
+        info_dialog(&gui, "Bookmark added.");
105
+    }
106
+}
107
+
108
+fn show_bookmarks(gui: &Arc<Gui>) {
109
+    let content_view = gui.content_view();
110
+
111
+    let bookmarks_list = format!("# Bookmarks\n\n{}", bookmarks::content());
112
+    let parsed_content = parser::parse(bookmarks_list);
113
+
114
+    clear_buffer(&content_view);
115
+    draw_content(&gui, parsed_content);
116
+
117
+    update_url_field(&gui, "::bookmarks");
118
+
119
+    content_view.show_all();
120
+}
121
+
81 122
 fn visit_url(gui: &Arc<Gui>, url: String) {
82 123
     {
83 124
         let content_view = gui.content_view();
84 125
 
126
+        if url == String::from("gemini://::bookmarks") {
127
+            show_bookmarks(&gui);
128
+            return
129
+        }
130
+
85 131
         match absolute::make(url.as_str()) {
86 132
             Ok(url) => match content::get_data(&url) {
87 133
                 Ok((meta, new_content)) => {
@@ -272,6 +318,23 @@ fn insert_external_button(gui: &Arc<Gui>, url: Url, label: &str) {
272 318
     buffer.insert(&mut end_iter, "\n");
273 319
 }
274 320
 
321
+fn info_dialog(gui: &Arc<Gui>, message: &str) {
322
+    let dialog = gtk::Dialog::new_with_buttons(
323
+        Some("Info"),
324
+        Some(gui.window()),
325
+        gtk::DialogFlags::MODAL,
326
+        &[("Close", ResponseType::Close)],
327
+    );
328
+    dialog.set_default_response(ResponseType::Close);
329
+    dialog.connect_response(|dialog, _| dialog.destroy());
330
+
331
+    let content_area = dialog.get_content_area();
332
+    let message = gtk::Label::new(Some(message));
333
+    content_area.add(&message);
334
+
335
+    dialog.show_all();
336
+}
337
+
275 338
 fn error_dialog(gui: &Arc<Gui>, message: &str) {
276 339
     let dialog = gtk::Dialog::new_with_buttons(
277 340
         Some("Error"),

Loading…
Cancel
Save