Skip to content

Commit 83f2ce2

Browse files
authored
v2.1
1 parent 3463ba9 commit 83f2ce2

File tree

8 files changed

+144
-39
lines changed

8 files changed

+144
-39
lines changed

README.md

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,35 +11,28 @@ on Windows
1111
For Windows you need to also install ```windows-curses``` or related program
1212
to provide the basic curses functionality
1313

14-
### System requirements
15-
16-
**A computer running any of the following OSes:**
17-
18-
Microsoft Windows 7
19-
Microsoft Windows 8
20-
Microsoft Windows 8.1
21-
Microsoft Windows 10
22-
Microsoft Windows 11
23-
Any modern distro of Linux that supports Python3
24-
25-
**Python Version 3.6 or newer**
26-
2714
## What's New?
2815

29-
### Version 2.0.5
16+
### Version 2.1: Files 'n' Folders
3017

31-
Fix small bug in Manjaro Konsole
18+
-Add openfolderdialog()
3219

33-
### Version 2.0.4
20+
-Change colours
3421

35-
More features added to filedialog
22+
-Performance improvements for all methods
3623

3724
### Version 2.0: Incompatible api changes
3825

3926
-askyesno now MUST be messagebox.askyesno
27+
4028
-Rewrite colour system. load_colours() is now nonexistent.
29+
4130
-Now use set_colour(background,foreground). A set of colour constants are defined in the cp class.
4231

4332
## Uses
4433

45-
curses-plus offers many utilities to make writing TUI applications easy. (TUI stands for Terminal User Interface)
34+
curses-plus offers many utilities to make writing TUI applications easy. (TUI stands for Terminal User Interface)
35+
36+
## Documentation
37+
38+
TODO
10.6 KB
Binary file not shown.

dist/cursesplus-2.1.tar.gz

9.82 KB
Binary file not shown.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ requires = ["setuptools>=61.0"]
33
build-backend = "setuptools.build_meta"
44
[project]
55
name = "cursesplus"
6-
version = "2.0.5"
6+
version = "2.1"
77
authors = [{name="Enderbyte Programs",email="[email protected]"},]
88
description = "An extension program to curses that offers option menus, message boxes, file dialogs and more"
99
readme = "README.md"

src/__cptest.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
from time import sleep
66

77
def __test__(stdscr):
8-
filedialog.openfilesdialog(stdscr)
9-
showcursor()
8+
displaymsg(stdscr,[filedialog.openfolderdialog(stdscr)])
109
if __name__ == "__main__":
1110
#Testing things
1211
curses.wrapper(__test__)

src/cursesplus.egg-info/PKG-INFO

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Metadata-Version: 2.1
22
Name: cursesplus
3-
Version: 2.0.5
3+
Version: 2.1
44
Summary: An extension program to curses that offers option menus, message boxes, file dialogs and more
55
Author-email: Enderbyte Programs <[email protected]>
66
Project-URL: Homepage, https://github.com/Enderbyte-Programs/Curses-Plus
@@ -25,35 +25,28 @@ on Windows
2525
For Windows you need to also install ```windows-curses``` or related program
2626
to provide the basic curses functionality
2727

28-
### System requirements
29-
30-
**A computer running any of the following OSes:**
31-
32-
Microsoft Windows 7
33-
Microsoft Windows 8
34-
Microsoft Windows 8.1
35-
Microsoft Windows 10
36-
Microsoft Windows 11
37-
Any modern distro of Linux that supports Python3
38-
39-
**Python Version 3.6 or newer**
40-
4128
## What's New?
4229

43-
### Version 2.0.5
30+
### Version 2.1: Files 'n' Folders
4431

45-
Fix small bug in Manjaro Konsole
32+
-Add openfolderdialog()
4633

47-
### Version 2.0.4
34+
-Change colours
4835

49-
More features added to filedialog
36+
-Performance improvements for all methods
5037

5138
### Version 2.0: Incompatible api changes
5239

5340
-askyesno now MUST be messagebox.askyesno
41+
5442
-Rewrite colour system. load_colours() is now nonexistent.
43+
5544
-Now use set_colour(background,foreground). A set of colour constants are defined in the cp class.
5645

5746
## Uses
5847

5948
curses-plus offers many utilities to make writing TUI applications easy. (TUI stands for Terminal User Interface)
49+
50+
## Documentation
51+
52+
TODO
7.35 KB
Binary file not shown.

src/cursesplus/filedialog.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ def openfiledialog(stdscr,title: str = "Please choose a file",filter: str = [["*
142142
selected = 0
143143
refresh = True
144144
yoffset = 0
145+
directory = directory.replace("//","/")
145146
else:
146147
return masterlist[selected].path
147148
elif ch == cp.curses.KEY_SLEFT or ch == 98:
@@ -151,6 +152,7 @@ def openfiledialog(stdscr,title: str = "Please choose a file",filter: str = [["*
151152
refresh = True
152153
if directory == "":
153154
directory = "/"
155+
directory = directory.replace("//","/")
154156
elif ch == 114:
155157
refresh = True#Refresh files list
156158
elif ch == 108:
@@ -167,6 +169,122 @@ def openfiledialog(stdscr,title: str = "Please choose a file",filter: str = [["*
167169

168170
#masterlist.clear()
169171

172+
def openfolderdialog(stdscr,title: str = "Please choose a folder",directory: str = os.getcwd()) -> str:
173+
"""Start a filedialog to open a file. title is the prompt the use recieves. filter is the file filter. The filter syntax is the same as TK syntax. The first
174+
filter provided is the main filter.
175+
Filter Syntax:
176+
[[GLOB,NAME],[GLOB,NAME]]
177+
Glob is a pattern to match for files (like *.txt)
178+
Name is a file type like (Text Files)
179+
180+
directory is the directory that the dialog opens to
181+
182+
RETURNS the full file path chosen
183+
"""
184+
xoffset: int = 0
185+
yoffset: int = 0
186+
selected: int = 0
187+
refresh: bool = False
188+
masterlist: list = list[Fileobj]
189+
directories = [directory+"/"+l for l in os.listdir(directory) if os.path.isdir(directory+"/"+l)]
190+
directories.sort()
191+
#displaymsg(stdscr,directories+files)
192+
masterlist = [Fileobj(f) for f in directories]
193+
while True:
194+
195+
mx,my = os.get_terminal_size()
196+
MAXNL = mx - 33
197+
stdscr.clear()
198+
cp.rectangle(stdscr,2,0,my-2,mx-1)
199+
cp.filline(stdscr,0,cp.set_color(cp.BLUE,cp.WHITE))
200+
cp.filline(stdscr,1,cp.set_color(cp.GREEN,cp.WHITE))
201+
cp.filline(stdscr,my-2,cp.set_color(cp.WHITE,cp.BLACK))
202+
cp.filline(stdscr,my-1,cp.set_color(cp.RED,cp.WHITE))
203+
topline = "Name"+" "*(MAXNL-4)+"|"+"Size "+"|Date Modified"
204+
topline = topline+(mx-2-len(topline))*" "
205+
if refresh:
206+
masterlist: list = list[Fileobj]
207+
directories = [directory+"/"+l for l in os.listdir(directory) if os.path.isdir(directory+"/"+l)]
208+
directories.sort()
209+
masterlist = [Fileobj(f) for f in directories]
210+
stdscr.addstr(0,0,title+"|H for Help|Press Shift-Left Arrow to move up directory"[0:mx],cp.set_colour(cp.BLUE,cp.WHITE))
211+
stdscr.addstr(1,0,directory[xoffset:xoffset+mx],cp.set_colour(cp.GREEN,cp.WHITE))
212+
stdscr.addstr(my-2,0,f"[{len(masterlist)} objects found]"[0:mx],cp.set_colour(cp.WHITE,cp.BLACK))
213+
stdscr.addstr(2,1,topline[0:mx-1])
214+
215+
try:
216+
stdscr.addstr(my-1,0,masterlist[selected].path[xoffset:xoffset+mx],cp.set_colour(cp.RED,cp.WHITE))
217+
except:
218+
pass
219+
ind = yoffset#Track position in list
220+
indx = 0#track position in iter
221+
for fileobjects in masterlist[yoffset:yoffset+my-5]:
222+
wstr = fileobjects.strippedpath[xoffset:xoffset+MAXNL]
223+
wstr += " "*(MAXNL-len(wstr)+1)
224+
wstr += fileobjects.sizestr
225+
wstr += " "*(10-len(fileobjects.sizestr))
226+
wstr += fileobjects.date
227+
if selected == ind:
228+
stdscr.addstr(3+indx,1,wstr,cp.set_colour(cp.BLACK,cp.GREEN))
229+
elif fileobjects.isdir:
230+
stdscr.addstr(3+indx,1,wstr,cp.set_colour(cp.BLACK,cp.YELLOW))
231+
else:
232+
stdscr.addstr(3+indx,1,wstr)
233+
ind += 1
234+
indx += 1#Inc both
235+
236+
237+
stdscr.refresh()
238+
ch = stdscr.getch()
239+
refresh = False
240+
if ch == cp.curses.KEY_LEFT and xoffset > 0:
241+
xoffset -= 1
242+
elif ch == cp.curses.KEY_RIGHT:
243+
xoffset += 1
244+
elif ch == cp.curses.KEY_UP and selected > 0:
245+
selected -= 1
246+
if selected < yoffset:
247+
yoffset -= 1
248+
elif ch == cp.curses.KEY_DOWN and selected < len(masterlist)-1:
249+
if selected - yoffset > my - 7:
250+
yoffset += 1
251+
selected += 1
252+
elif ch == cp.curses.KEY_ENTER or ch == 10 or ch == 13:
253+
if masterlist[selected].isdir:
254+
directory = masterlist[selected].path
255+
selected = 0
256+
refresh = True
257+
yoffset = 0
258+
directory = directory.replace("//","/")
259+
else:
260+
return masterlist[selected].path
261+
elif ch == 115:
262+
return masterlist[selected].path
263+
elif ch == cp.curses.KEY_SLEFT or ch == 98:
264+
directory = "/".join(directory.split("/")[0:-1])
265+
selected = 0
266+
yoffset = 0
267+
refresh = True
268+
if directory == "":
269+
directory = "/"
270+
271+
directory = directory.replace("//","/")
272+
elif ch == 114:
273+
refresh = True#Refresh files list
274+
elif ch == 108:
275+
npath = cp.cursesinput(stdscr,"Please enter new path").replace("\n","")
276+
if os.path.isdir(npath):
277+
directory = npath
278+
selected = 0
279+
yoffset = 0
280+
refresh = True
281+
else:
282+
messagebox.showwarning(stdscr,["Path does not exist"])
283+
elif ch == 104:
284+
cp.displaymsg(stdscr,["List of Keybinds","Down Arrow: Scroll down","Up Arrow: Scroll up","Left Arrow: Scroll left","Right Arrow: Scroll right","Shift-left arrow: Move up to parent Directory","Enter: Open","S: Choose folder","L: Change location"])
285+
286+
#masterlist.clear()
287+
170288
def openfilesdialog(stdscr,title: str = "Please choose a file",filter: str = [["*","All Files"]],directory: str = os.getcwd()) -> list:
171289
"""Start a filedialog to select multiple files. title is the prompt the user recieves. filter is the file filter. The filter syntax is the same as TK syntax. The first
172290
filter provided is the main filter.
@@ -269,6 +387,7 @@ def openfilesdialog(stdscr,title: str = "Please choose a file",filter: str = [["
269387
selected = 0
270388
yoffset = 0
271389
update = True
390+
directory = directory.replace("//","/")
272391
else:
273392
chosen.clear()
274393
chosen.append(masterlist[selected].path)
@@ -286,6 +405,7 @@ def openfilesdialog(stdscr,title: str = "Please choose a file",filter: str = [["
286405
update = True
287406
if directory == "":
288407
directory = "/"
408+
directory = directory.replace("//","/")
289409
elif ch == 114:
290410
update = True#Refresh files list
291411
elif ch == 100 or cp.curses.keyname(ch).decode() == "^X":

0 commit comments

Comments
 (0)