Skip to content

Commit

Permalink
- Add read-only support
Browse files Browse the repository at this point in the history
- Add code comments
- Finish export to markdown support
  • Loading branch information
Wemmy0 committed Dec 12, 2023
1 parent 8186ad6 commit 0c883ba
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 88 deletions.
2 changes: 1 addition & 1 deletion src/ChatGPT.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

class AiGUI(Gtk.Window):
def __init__(self):
# TODO: This (costs moolah)
super().__init__()
self.set_title("ChatGPT")
self.set_size_request(200, 300)


class AiConnector:
def __init__(self, api_key, model):
# TODO: This costs moolah
openai.api_key = api_key
28 changes: 23 additions & 5 deletions src/Export.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,37 @@
from NoteView import Title, Body, Image, List, Task
from gi.repository import Gtk


def export_to_markdown(content):
def export_to_markdown(content, path):
# Purpose: Given list of elements, export them to a markdown file
result = []
for element in content:
# TODO: Export images
if type(element.main) is Body:
result.append(element.main.save()["text"])
elif type(element.main) is Title:
result.append(f"### {element.main.save()['text']}")
elif type(element.main) is List:
result += element.main.save()["items"]
result += [f"- {item}" for item in element.main.save()["items"]]
elif type(element.main) is Task:
result += [f"- [{'x' if item[1] else ' '}] {item[0]}" for item in element.main.save()["items"]]
finalise(result)
finalise(result, path)


def finalise(data):
print(data)
def finalise(data, path):
# Purpose: Given a list of the content of every element,
# try and save the file to disk with each item being a new line
try:
with open(path[:path.rfind('.')] + ".md", "w+") as file:
for line in data:
file.write(line + "\n")
dialogue = Gtk.MessageDialog(text="File Successfully Exported",
secondary_text=path[:path.rfind('.')] + ".md",
message_type=Gtk.MessageType.INFO,
buttons=Gtk.ButtonsType.OK)
except:
dialogue = Gtk.MessageDialog(text="Unable to export file",
message_type=Gtk.MessageType.INFO,
buttons=Gtk.ButtonsType.OK)
dialogue.connect("response", lambda dialog, *args: dialog.destroy())
dialogue.present()
3 changes: 2 additions & 1 deletion src/FileView.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,10 @@ def add_note(self, *args):

def create_new_note(self, *args):
filename = self.path + "/" + self.file_viewer.get_last_child().get_last_child().get_first_child().get_text() + ".json"
print(f"Create new file {filename}")
self.file_viewer.json_data[filename] = self.file_viewer.palette[0]
self.file_viewer.remove(self.get_last_child().get_last_child())
initialise_json(filename)
self.file_viewer.validate_colours()
self.file_viewer.add_files([filename])
self.file_viewer.files.append(filename)
self.creating_new = False # Allows user to use create new note button again
Expand Down
135 changes: 72 additions & 63 deletions src/NoteView.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,20 @@ def edit_style(element, mode):


class NoteView(Gtk.Box):
def __init__(self, config, ai_config, header):
def __init__(self, config, ai_config, read_only, header):
super().__init__(orientation=Gtk.Orientation.VERTICAL)
self.config = config
self.ai_config = ai_config
self.read_only = read_only
# List of pointers to all children elements as GTK doesn't allow getting a specific
# child at index with a Gtk.Box
self.children = []
self.header_ui = header
self.editing = False
self.history = Stack()

def remove_all(self):
# Purpose: Removes all elements when changing a file
for i in self.children:
self.remove(i)
self.children = []
Expand All @@ -37,32 +41,23 @@ def change_file(self, filename):
self.filename = filename
self.remove_all()

# with open(filename, "w+") as file:
# data = file.readlines()
# print(data)
# if not data:
# print(f"{filename} is empty, re-initialising json")
# file.write("{}")

with open(filename, "r") as file:
# data = file.readlines()
# print(data)
# if data == "":
# print("Empty File")
# else:
self.objects = list(json.load(file).values())

for i in self.objects:
self.add_element(i, True)

def add_element(self, data, loading_file=False):
element = Element(data, self.config, self.ai_config)
element.del_btn.connect("clicked", self.remove_element)
element.up_btn.connect("clicked", self.move)
element.down_btn.connect("clicked", self.move)
# Purpose: Adds an element when giving json data
element = Element(data, self.config, self.ai_config, self.read_only)
if not self.read_only:
element.del_btn.connect("clicked", self.remove_element)
element.up_btn.connect("clicked", self.move)
element.down_btn.connect("clicked", self.move)
self.children.append(element)
self.append(element)
self.can_move()
if not self.read_only:
self.can_move()

if not loading_file:
self.header_ui.undo_btn.show()
Expand All @@ -79,38 +74,46 @@ def undo(self, *args):
self.header_ui.undo_btn.hide()

def save_file(self, *args):
# Purpose: Save all elements in dictionary. Because keys don't matter but have to be unique use a random number
# If number already exists, try again
print(f"Saving {self.filename}")
out = {}
with open(self.filename, "w") as file:
for i in self.children:
out[randint(0, 9999)] = i.export()
while True:
num = randint(0, 9999)
if num not in out.keys():
out[num] = i.export()
break
json.dump(out, file)

def edit(self, *args):
if not self.editing:
self.editing = True
for i in self.children:
edit_style(i, True)
# Purpose:
if not self.read_only:
if not self.editing:
self.editing = True
for i in self.children:
edit_style(i, True)
else:
self.editing = False
for i in self.children:
edit_style(i, False)
self.save_file()
self.toggle_edit_btn()

def toggle_edit_btn(self):
# Purpose: Flip the icon and tooltip of the edit button depending on mode
if self.editing:
# Toggle to view mode
self.header_ui.edit_btn.set_icon_name("ephy-reader-mode-symbolic")
self.header_ui.edit_btn.set_tooltip_text("Switch to view mode")
else:
self.editing = False
for i in self.children:
edit_style(i, False)
self.save_file()
self.change_view_mode()

def change_view_mode(self):
current_mode = self.header_ui.edit_btn.get_icon_name()
match current_mode:
case "ymuse-edit-symbolic":
# Toggle to view mode
self.header_ui.edit_btn.set_icon_name("ephy-reader-mode-symbolic")
self.header_ui.edit_btn.set_tooltip_text("Switch to view mode")
case "ephy-reader-mode-symbolic":
# Toggle to edit mode
self.header_ui.edit_btn.set_icon_name("ymuse-edit-symbolic")
self.header_ui.edit_btn.set_tooltip_text("Switch to edit mode")
# Toggle to edit mode
self.header_ui.edit_btn.set_icon_name("ymuse-edit-symbolic")
self.header_ui.edit_btn.set_tooltip_text("Switch to edit mode")

def remove_element(self, button):
# Purpose: Removes an element when the bin button is clicked
element = button.get_parent().get_parent().get_parent()
element.hide()
self.children.remove(element)
Expand All @@ -133,7 +136,7 @@ def move(self, button):
# Get all children to be affected
# If up: Gets all the children at one above the moved element and below
elements = self.children[row_no - 1:] if button.get_icon_name() == "go-up-symbolic" else self.children[row_no:]
# remove all children one up and the rest below
# Remove all children one up and the rest below
for i in elements:
self.remove(i)
self.children.remove(i)
Expand Down Expand Up @@ -162,33 +165,38 @@ def can_move(self):


class Element(Gtk.Box):
def __init__(self, data, config, ai_config):
def __init__(self, data, config, ai_config, read_only):
super().__init__()
self.container = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.data = data
self.config = config
self.ai_config = ai_config
self.create_controls()
self.read_only = read_only
if not read_only:
self.create_controls()
set_margins(self.container, 10)
self.append(self.container)
try:
match self.data["type"]:
case "title":
if config["title"]: self.main = Title(self.data)
print("Title")
if config["title"]: self.main = Title(self.data, read_only)
self.container.append(self.main)

case "body":
if config["body"]: self.main = Body(self.data)
if config["body"]: self.main = Body(self.data, read_only)
self.container.append(self.main)

case "image":
if config["image"]: self.main = Image(self.data)
if config["image"]: self.main = Image(self.data, read_only)
self.container.append(self.main)

case "list":
if config["list"]: self.main = List(self.data)
if config["list"]: self.main = List(self.data, read_only)
self.container.append(self.main)

case "task":
if config["task"]: self.main = Task(self.data)
if config["task"]: self.main = Task(self.data, read_only)
self.container.append(self.main)

case _:
Expand All @@ -210,6 +218,7 @@ def set_tooltip(self):
pass

def create_controls(self):
# Purpose: Created the UI elements for edit mode (hidden by default)
self.controls = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,
halign=Gtk.Align.END,
valign=Gtk.Align.CENTER,
Expand All @@ -222,6 +231,12 @@ def create_controls(self):
self.controls.append(self.del_btn)
self.controls.append(self.down_btn)

self.create_ai()

self.container.append(self.controls)

def create_ai(self):
# Purpose: Creates AI elements if AI is enabled in the config
if self.data["type"] == "body" and self.ai_config["enabled"]:
print(f"Adding AI magic with {self.ai_config['model']}")
self.ai_btn = Gtk.Button(icon_name="tool-magic-symbolic")
Expand All @@ -231,33 +246,28 @@ def create_controls(self):
self.ai_dialogue = AiGUI()
self.ai_btn.connect("clicked", self.new_ai_dialogue)

self.container.append(self.controls)
set_margins(self.container, 10)

self.append(self.container)

def new_ai_dialogue(self, *args):
self.ai_dialogue.present()
print("gue")
self.ai_container = AiGUI()


class Title(Gtk.Box):
def __init__(self, data):
def __init__(self, data, read_only):
super().__init__(margin_start=0)
self.main = Gtk.Entry(text=data["text"],
css_name="title",
halign=Gtk.Align.START,
width_request=400,
height_request=10)
height_request=10,
editable=not read_only)
self.append(self.main)

def save(self):
return {"type": "title", "text": self.main.get_text()}


class Body(Gtk.Box):
def __init__(self, data):
def __init__(self, data, read_only):
super().__init__(margin_start=5)
self.main = Gtk.TextView(width_request=100, height_request=16,
hexpand=True, css_classes=["list-item"],
Expand All @@ -272,7 +282,7 @@ def save(self):


class Image(Gtk.Box):
def __init__(self, data):
def __init__(self, data, read_only):
super().__init__()
if data["source"] == "url":
print(f"Has scale {data['scale']}")
Expand Down Expand Up @@ -314,7 +324,7 @@ def save(self):


class List(Gtk.Box):
def __init__(self, data):
def __init__(self, data, read_only):
super().__init__(css_name="item-list", margin_start=5)
self.children = []
self.main = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
Expand All @@ -333,14 +343,13 @@ def backspace_item(self, widget):

def add_item(self, widget: Gtk.Entry):
if widget.get_text(): # Prevents new tasks being added when last task is empty
item = ListItem("")
item.main.connect("activate", self.add_item)
# item.main.connect("backspace", self.backspace_item)
removed = []
while True:
next = self.main.get_last_child()
if next == widget.get_parent():
item = ListItem()
item = ListItem("")
item.main.connect("activate", self.add_item)
self.children.insert(self.children.index(widget.get_parent()) + 1, item)
self.main.append(item)
for i in removed[::-1]:
Expand Down Expand Up @@ -372,7 +381,7 @@ def save(self):


class Task(Gtk.Box):
def __init__(self, data):
def __init__(self, data, read_only):
super().__init__(css_name="item-list", margin_start=0)
self.children = []
self.main = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
Expand Down
2 changes: 2 additions & 0 deletions src/configuration-default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
path = "Folder"
# Enable or disable the ability to colour code notes
colour-support = true
# Enable or disable the ability to edit notes
read-only = false

[database]
enabled = true
Expand Down
2 changes: 1 addition & 1 deletion src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class MyApp(Adw.Application):
def __init__(self, **kwargs):
super().__init__(**kwargs)
load_configuration()
self.sync = Sync(config["database"], verbose)
self.sync = Sync(config, False)
self.connect('activate', self.on_activate)

def on_activate(self, app):
Expand Down
Loading

0 comments on commit 0c883ba

Please sign in to comment.