-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwriting_manager.py
More file actions
236 lines (200 loc) · 9.01 KB
/
writing_manager.py
File metadata and controls
236 lines (200 loc) · 9.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
import tkinter as tk
import os
import configparser
import csv
from datetime import datetime
from pathlib import Path
# Read the root directory from the config file
config = configparser.ConfigParser()
config_dir = Path.home() / Path('.writing_manager')
config_file = config_dir / Path('config.ini')
print(f"Config file path: {config_file}")
if not config_file.exists():
# Create the config directory if it doesn't exist
config_file.parent.mkdir(parents=True, exist_ok=True)
# Create a default config file
with open(config_file, 'w') as f:
f.write("[files]\n")
# TODO: project_dir needs to be selected by the user
f.write("project_dir = /path/to/your/files\n")
# f.write("file_order_csv = /path/to/your/files/file_order.csv\n")
config.read(str(config_file))
project_dir = config.get('files', 'project_dir')
# file_order_csv = config.get('files', 'file_order_csv')
file_order_csv = config_dir / 'file_order.csv'
def read_file_order_from_csv(file_order_csv):
with open(file_order_csv, 'r') as csvfile:
reader = csv.reader(csvfile)
data = list(reader)
last_row = data[-1]
file_order = last_row[1].split('|')
return {file_order[i]: i for i in range(len(file_order))}
# file_order = read_file_order_from_csv(file_order_csv)
class DragDropListbox(tk.Listbox):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
# self.bind("<Button-1>", self.start_drag)
# self.bind("<B1-Motion>", self.do_drag)
# self.bind("<ButtonRelease-1>", self.stop_drag)
self.drag_data = {"index": None}
def list_files_numerically(self, file_order):
self.delete(0, tk.END)
for file, i in file_order.items():
self.insert(tk.END, f"{i+1}: {file}")
def get_filename_without_number(self, list_item):
return list_item.split(": ", 1)[1] if ": " in list_item else list_item
def get_ordered_file_list(self):
items = list(self.get(0, tk.END))
filenames = [self.get_filename_without_number(item) for item in items]
return filenames
def start_drag(self, event):
# Get the index of the clicked item
self.drag_data["index"] = self.nearest(event.y)
def do_drag(self, event):
# Highlight the item being dragged
self.selection_clear(0, tk.END)
self.selection_set(self.drag_data["index"])
def stop_drag(self, event):
# Get the target index where the item is dropped
target_index = self.nearest(event.y)
source_index = self.drag_data["index"]
if source_index != target_index:
# Rearrange items in the listbox
items = list(self.get(0, tk.END))
item = items.pop(source_index)
items.insert(target_index, item)
# Update the listbox with the new order
self.delete(0, tk.END)
for i in items:
self.insert(tk.END, i)
# Clear drag data
self.drag_data["index"] = None
class FileListApp:
def __init__(self, root):
self.root = root
self.root.title("File List App")
self.file_list = DragDropListbox(self.root, activestyle="dotbox")
self.file_list.pack(padx=10, pady=10,
# ipadx=10, ipady=10,
)
# Populate the listbox with files in the desired order
# self.file_list.list_files_numerically(read_file_order_from_csv(file_order_csv))
self.list_files_in_order()
# for file in file_order:
# self.file_list.insert(tk.END, file)
# Bind double-click event to open the file
self.file_list.bind('<Double-1>', self.open_file)
# Bind Enter key press to open the selected file
self.file_list.bind('<Return>', self.open_selected_file)
# Create reorder button
self.reorder_button = tk.Button(self.root, text="Reorder", command=self.toggle_reorder)
self.reorder_button.pack(padx=10, pady=10)
# Create reorder cancel button
self.cancel_button = tk.Button(self.root, text="Cancel", command=self.cancel_reorder)
self.cancel_button.pack_forget()
def open_file(self, event):
# Get the selected file
selected_index = self.file_list.nearest(event.y)
selected_file = self.file_list.get(selected_index)
# Construct the full path to the file
file_path = os.path.join(project_dir, selected_file)
# Open the file using the default application
os.startfile(file_path)
def open_selected_file(self, event):
# Get the selected file
selected_index = self.file_list.curselection()
if selected_index:
selected_file = self.file_list.get(selected_index)
# Construct the full path to the file
file_path = os.path.join(project_dir, selected_file)
# Open the file using the default application
os.startfile(file_path)
def move_up(self, event):
# Get the selected file
selected_index = self.file_list.curselection()
if selected_index and selected_index[0] > 0:
# Move the file up
items = list(self.file_list.get(0, tk.END))
item = items.pop(selected_index[0])
items.insert(selected_index[0] - 1, item)
self.file_list.delete(0, tk.END)
for i in items:
self.file_list.insert(tk.END, i)
self.file_list.selection_clear(0, tk.END)
new_index = selected_index[0] - 1
self.file_list.activate(selected_index[0])
self.file_list.see(new_index)
def move_down(self, event):
# Get the selected file
selected_index = self.file_list.curselection()
if selected_index and selected_index[0] < self.file_list.size() - 1:
# Move the file down
items = list(self.file_list.get(0, tk.END))
item = items.pop(selected_index[0])
items.insert(selected_index[0] + 1, item)
self.file_list.delete(0, tk.END)
for i in items:
self.file_list.insert(tk.END, i)
self.file_list.selection_clear(0, tk.END)
new_index = selected_index[0] + 1
self.file_list.selection_set(new_index)
self.file_list.activate(selected_index[0])
self.file_list.see(new_index)
def enable_reordering(self):
print("Enabling reordering")
# allow dragging and dropping to reorder files
self.file_list.bind("<Button-1>", self.file_list.start_drag)
self.file_list.bind("<B1-Motion>", self.file_list.do_drag)
self.file_list.bind("<ButtonRelease-1>", self.file_list.stop_drag)
self.file_list.bind("<Alt-Up>", self.move_up)
self.file_list.bind("<Alt-Down>", self.move_down)
def save_new_order(self):
print("Saving file order")
# Get the current order of files
filenames = self.file_list.get_ordered_file_list()
# Write the order at the end of the CSV file
with open(file_order_csv, 'a') as out:
# get date in the format YYYY-MM-DDTH:MM:SS
date = datetime.now().strftime("%Y-%m-%dT%H:%M:%S")
out.write(f"{date},{'|'.join(filenames)}\n")
# relist files with numbers corresponding to the new order
self.list_files_in_order()
def cancel_reorder(self):
self.reorder_button['text'] = "Reorder"
# self.reorder_button['command'] = self.toggle_reorder
self.file_list.unbind("<Button-1>")
self.file_list.unbind("<B1-Motion>")
self.file_list.unbind("<ButtonRelease-1>")
self.file_list.unbind('<Alt-Up>')
self.file_list.unbind('<Alt-Down>')
self.cancel_button.pack_forget()
# Readjust to show the current order of files
# file_order = read_file_order_from_csv(file_order_csv)
# self.file_list.delete(0, tk.END)
# self.file_list.list_files_numerically(file_order)
self.list_files_in_order()
# items = list(self.file_list.get(0, tk.END))
# # Sort the items based on the predefined order
# sorted_items = sorted(items, key=lambda x: file_order.get(x, float('inf')))
# # Update the listbox with the new order
# for item in sorted_items:
# self.file_list.insert(tk.END, item)
def list_files_in_order(self):
file_order = read_file_order_from_csv(file_order_csv)
self.file_list.list_files_numerically(file_order)
def toggle_reorder(self):
if self.reorder_button['text'] == "Reorder":
print("changing button to save")
self.reorder_button['text'] = "Save"
self.enable_reordering()
self.cancel_button.pack(side=tk.LEFT, padx=10)
else:
print("changing button to reorder")
self.reorder_button['text'] = "Reorder"
self.save_new_order()
print("removing cancel button")
self.cancel_button.pack_forget()
if __name__ == "__main__":
root = tk.Tk()
app = FileListApp(root)
root.mainloop()