Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
nerrons
purr-data
Commits
172416dd
Commit
172416dd
authored
Jan 19, 2017
by
Albert Gräf
Browse files
Add a Recent Files menu (fixes #124 and #221).
parent
eefbef29
Changes
8
Hide whitespace changes
Inline
Side-by-side
pd/nw/locales/de/translation.json
View file @
172416dd
...
...
@@ -99,6 +99,10 @@
"new_tt"
:
"Erzeuge einen leeren Pd-Patch"
,
"open"
:
"Öffnen"
,
"open_tt"
:
"Öffne eine oder mehrere Pd-Dateien"
,
"recent_files"
:
"Zuletzt geöffnete Dateien"
,
"recent_files_tt"
:
"Öffne eine der zuletzt geöffneten Pd-Dateien"
,
"clear_recent_files"
:
"Liste leeren"
,
"clear_recent_files_tt"
:
"Leere die Liste der zuletzt geöffneten Pd-Dateien"
,
"k12_demos"
:
"K12-Demos"
,
"k12_demos_tt"
:
"Demo-Patches zur Verwendung im K12-Modus"
,
"save"
:
"Speichern"
,
...
...
pd/nw/locales/en/translation.json
View file @
172416dd
...
...
@@ -99,6 +99,10 @@
"new_tt"
:
"Create an empty Pd patch"
,
"open"
:
"Open"
,
"open_tt"
:
"Open one or more Pd files"
,
"recent_files"
:
"Recent Files"
,
"recent_files_tt"
:
"Open a recently opened Pd file"
,
"clear_recent_files"
:
"Clear List"
,
"clear_recent_files_tt"
:
"Clear the recent files list"
,
"k12_demos"
:
"K12 Demos"
,
"k12_demos_tt"
:
"Demo patches for use with K12 Mode"
,
"save"
:
"Save"
,
...
...
pd/nw/pd_menus.js
View file @
172416dd
...
...
@@ -3,6 +3,7 @@
var
pdgui
=
require
(
"
./pdgui.js
"
);
var
l
=
pdgui
.
get_local_string
;
// For menu names
var
osx_menu
=
null
;
// OSX App menu -- a single one per running instance
var
recent_files_submenu
=
null
;
function
create_menu
(
gui
,
type
)
{
// On OSX we create a menu only once, and then enable/disable menuitems
...
...
@@ -26,6 +27,16 @@ function create_menu(gui, type) {
media_menu
,
help_menu
;
// We only maintain a single instance of the recent files submenu which
// gets updated in pdgui.js via a callback from the engine.
if
(
!
recent_files_submenu
)
{
recent_files_submenu
=
new
gui
.
Menu
();
// NOTE: Since we can't be sure whether the GUI or the engine runs
// first, make sure that we populate the submenu on the first run in
// either case.
pdgui
.
populate_recent_files
(
recent_files_submenu
);
}
// OSX just spawns a single canvas menu and then enables/disables
// the various menu items as needed.
canvas_menu
=
osx
||
(
type
!==
"
console
"
);
...
...
@@ -63,6 +74,11 @@ function create_menu(gui, type) {
modifiers
:
cmd_or_ctrl
,
tooltip
:
l
(
"
menu.open_tt
"
)
}));
file_menu
.
append
(
m
.
file
.
recent_files
=
new
gui
.
MenuItem
({
label
:
l
(
"
menu.recent_files
"
),
submenu
:
recent_files_submenu
,
tooltip
:
l
(
"
menu.recent_files_tt
"
)
}));
if
(
pdgui
.
k12_mode
==
1
)
{
file_menu
.
append
(
m
.
file
.
k12
=
new
gui
.
MenuItem
({
label
:
l
(
"
menu.k12_demos
"
),
...
...
pd/nw/pdgui.js
View file @
172416dd
...
...
@@ -741,6 +741,9 @@ function saveas_callback(cid, file, close_flag) {
}
pdsend
(
cid
,
"
savetofile
"
,
enquote
(
basename
),
enquote
(
directory
),
close_flag
);
// update the recent files list
var
norm_path
=
path
.
normalize
(
directory
);
pdsend
(
"
pd add-recent-file
"
,
enquote
(
path
.
join
(
norm_path
,
basename
)));
}
exports
.
saveas_callback
=
saveas_callback
;
...
...
@@ -976,6 +979,9 @@ function open_file(file) {
(
enquote
(
directory
)));
set_pd_opendir
(
directory
);
//::pd_guiprefs::update_recentfiles "$filename" 1
// update the recent files list
var
norm_path
=
path
.
normalize
(
directory
);
pdsend
(
"
pd add-recent-file
"
,
enquote
(
path
.
join
(
norm_path
,
basename
)));
}
}
...
...
@@ -4446,6 +4452,58 @@ function open_search() {
exports
.
open_search
=
open_search
;
// This is the same for all windows (initialization is in pd_menus.js).
var
recent_files_submenu
=
null
;
var
recent_files
=
null
;
// We need to jump through some hoops here since JS closures capture variables
// by reference, which causes trouble when closures are created within a
// loop.
function
recent_files_callback
(
i
)
{
return
function
()
{
var
fname
=
recent_files
[
i
];
//post("clicked recent file: "+fname);
open_file
(
fname
);
}
}
function
populate_recent_files
(
submenu
)
{
if
(
submenu
)
recent_files_submenu
=
submenu
;
if
(
recent_files
&&
recent_files_submenu
)
{
//post("recent files: " + recent_files.join(" "));
while
(
recent_files_submenu
.
items
.
length
>
0
)
recent_files_submenu
.
removeAt
(
0
);
for
(
var
i
=
0
;
i
<
recent_files
.
length
;
i
++
)
{
var
item
=
new
nw
.
MenuItem
({
label
:
path
.
basename
(
recent_files
[
i
]),
tooltip
:
recent_files
[
i
]
});
item
.
click
=
recent_files_callback
(
i
);
recent_files_submenu
.
append
(
item
);
}
if
(
recent_files_submenu
.
items
.
length
>
0
)
{
recent_files_submenu
.
append
(
new
nw
.
MenuItem
({
type
:
"
separator
"
}));
var
item
=
new
nw
.
MenuItem
({
label
:
lang
.
get_local_string
(
"
menu.clear_recent_files
"
),
tooltip
:
lang
.
get_local_string
(
"
menu.clear_recent_files_tt
"
)
});
item
.
click
=
function
()
{
pdsend
(
"
pd clear-recent-files
"
);
};
recent_files_submenu
.
append
(
item
);
}
}
}
exports
.
populate_recent_files
=
populate_recent_files
;
function
gui_recent_files
(
dummy
,
recent_files_array
)
{
recent_files
=
recent_files_array
;
populate_recent_files
(
recent_files_submenu
);
}
function
gui_audio_properties
(
gfxstub
,
sys_indevs
,
sys_outdevs
,
pd_indevs
,
pd_inchans
,
pd_outdevs
,
pd_outchans
,
audio_attrs
)
{
var
attrs
=
audio_attrs
.
concat
([
...
...
pd/src/m_glob.c
View file @
172416dd
...
...
@@ -37,6 +37,9 @@ void glob_ping(t_pd *dummy);
void
glob_watchdog
(
t_pd
*
dummy
);
void
glob_savepreferences
(
t_pd
*
dummy
);
void
glob_forward_files_from_secondary_instance
(
void
);
void
glob_recent_files
(
t_pd
*
dummy
);
void
glob_add_recent_file
(
t_pd
*
dummy
,
t_symbol
*
s
);
void
glob_clear_recent_files
(
t_pd
*
dummy
);
void
alsa_resync
(
void
);
...
...
@@ -168,6 +171,12 @@ void glob_init(void)
gensym
(
"gui-preset"
),
A_SYMBOL
,
0
);
class_addmethod
(
glob_pdobject
,
(
t_method
)
glob_gui_properties
,
gensym
(
"gui-properties"
),
0
);
class_addmethod
(
glob_pdobject
,
(
t_method
)
glob_recent_files
,
gensym
(
"recent-files"
),
0
);
class_addmethod
(
glob_pdobject
,
(
t_method
)
glob_add_recent_file
,
gensym
(
"add-recent-file"
),
A_SYMBOL
,
0
);
class_addmethod
(
glob_pdobject
,
(
t_method
)
glob_clear_recent_files
,
gensym
(
"clear-recent-files"
),
0
);
#ifdef UNIX
class_addmethod
(
glob_pdobject
,
(
t_method
)
glob_watchdog
,
gensym
(
"watchdog"
),
0
);
...
...
pd/src/s_file.c
View file @
172416dd
...
...
@@ -149,7 +149,7 @@ static void sys_initsavepreferences( void)
// user config dir doesn't exist yet, try to create it
if
(
mkdir
(
filenamebuf
,
0755
))
{
pd_error
(
0
,
"%s: %s"
,
filenamebuf
,
strerror
(
errno
));
return
;
return
;
}
}
snprintf
(
filenamebuf
,
FILENAME_MAX
,
"%s/.pd-l2ork/user.settings"
,
homedir
);
...
...
@@ -636,3 +636,165 @@ void glob_savepreferences(t_pd *dummy)
sys_donesavepreferences
();
}
/* AG: Recent files table */
int
sys_n_recent_files
=
0
;
char
*
sys_recent_files
[
MAX_RECENT_FILES
];
static
int
fexists
(
const
char
*
s
)
{
struct
stat
statbuf
;
return
stat
(
s
,
&
statbuf
)
==
0
;
}
void
sys_add_recent_file
(
const
char
*
s
)
{
int
i
;
// only add the file if it actually exists
if
(
!
fexists
(
s
))
return
;
for
(
i
=
0
;
i
<
sys_n_recent_files
&&
strcmp
(
sys_recent_files
[
i
],
s
);
i
++
)
;
if
(
i
<
sys_n_recent_files
)
{
// already got an existing entry, move it to the front
char
*
t
=
sys_recent_files
[
i
];
memmove
(
sys_recent_files
+
1
,
sys_recent_files
,
i
*
sizeof
(
char
*
));
sys_recent_files
[
0
]
=
t
;
}
else
{
char
*
t
=
strdup
(
s
);
if
(
!
t
)
return
;
if
(
sys_n_recent_files
==
MAX_RECENT_FILES
)
{
// kick out the oldest entry to make room for a new one
free
(
sys_recent_files
[
--
sys_n_recent_files
]);
}
// add a new entry at the beginning of the table
memmove
(
sys_recent_files
+
1
,
sys_recent_files
,
sys_n_recent_files
*
sizeof
(
char
*
));
sys_recent_files
[
0
]
=
t
;
sys_n_recent_files
++
;
}
}
void
sys_save_recent_files
(
void
)
{
int
i
;
#ifdef UNIX
// UNIX/Linux: save in recent_files file
FILE
*
fp
;
char
filenamebuf
[
FILENAME_MAX
],
*
homedir
=
getenv
(
"HOME"
);
struct
stat
statbuf
;
if
(
!
homedir
)
return
;
snprintf
(
filenamebuf
,
FILENAME_MAX
,
"%s/.pd-l2ork"
,
homedir
);
filenamebuf
[
FILENAME_MAX
-
1
]
=
0
;
if
(
stat
(
filenamebuf
,
&
statbuf
)
||
!
S_ISDIR
(
statbuf
.
st_mode
))
{
// user config dir doesn't exist yet, try to create it
if
(
mkdir
(
filenamebuf
,
0755
))
{
pd_error
(
0
,
"%s: %s"
,
filenamebuf
,
strerror
(
errno
));
return
;
}
}
snprintf
(
filenamebuf
,
FILENAME_MAX
,
"%s/.pd-l2ork/recent_files"
,
homedir
);
filenamebuf
[
FILENAME_MAX
-
1
]
=
0
;
if
((
fp
=
fopen
(
filenamebuf
,
"w"
))
==
NULL
)
{
pd_error
(
0
,
"%s: %s"
,
filenamebuf
,
strerror
(
errno
));
return
;
}
for
(
i
=
0
;
i
<
sys_n_recent_files
;
i
++
)
{
fprintf
(
fp
,
"%s
\n
"
,
sys_recent_files
[
i
]);
}
fclose
(
fp
);
#else
// Mac/Windows (use the defaults/registry)
char
buf
[
MAXPDSTRING
];
sys_initsavepreferences
();
for
(
i
=
0
;
i
<
sys_n_recent_files
;
i
++
)
{
sprintf
(
buf
,
"recent%d"
,
i
+
1
);
sys_putpreference
(
buf
,
sys_recent_files
[
i
]);
}
sprintf
(
buf
,
"%d"
,
i
);
sys_putpreference
(
"nrecent"
,
buf
);
sys_donesavepreferences
();
#endif
}
void
sys_load_recent_files
(
void
)
{
#ifdef UNIX
// UNIX/Linux: load from recent_files file
FILE
*
fp
;
char
filenamebuf
[
FILENAME_MAX
],
*
homedir
=
getenv
(
"HOME"
);
if
(
!
homedir
)
return
;
snprintf
(
filenamebuf
,
FILENAME_MAX
,
"%s/.pd-l2ork/recent_files"
,
homedir
);
filenamebuf
[
FILENAME_MAX
-
1
]
=
0
;
if
((
fp
=
fopen
(
filenamebuf
,
"r"
))
==
NULL
)
return
;
for
(
sys_n_recent_files
=
0
;
sys_n_recent_files
<
MAX_RECENT_FILES
&&
fgets
(
filenamebuf
,
FILENAME_MAX
,
fp
);
)
{
char
*
s
;
int
l
=
strlen
(
filenamebuf
);
if
(
l
>
0
&&
filenamebuf
[
l
-
1
]
==
'\n'
)
filenamebuf
[
--
l
]
=
0
;
// only add files which actually exist
if
(
l
==
0
||
!
fexists
(
filenamebuf
))
continue
;
s
=
strdup
(
filenamebuf
);
if
(
s
)
sys_recent_files
[
sys_n_recent_files
++
]
=
s
;
}
fclose
(
fp
);
#else
// Mac/Windows (use the defaults/registry)
char
prefbuf
[
MAXPDSTRING
],
keybuf
[
80
];
int
i
,
maxi
=
MAX_RECENT_FILES
;
sys_initloadpreferences
();
if
(
sys_getpreference
(
"nrecent"
,
prefbuf
,
MAXPDSTRING
))
sscanf
(
prefbuf
,
"%d"
,
&
maxi
);
for
(
i
=
0
;
i
<
maxi
;
i
++
)
{
int
l
;
char
*
s
;
sprintf
(
keybuf
,
"recent%d"
,
i
+
1
);
if
(
!
sys_getpreference
(
keybuf
,
prefbuf
,
MAXPDSTRING
))
break
;
l
=
strlen
(
prefbuf
);
if
(
l
==
0
||
!
fexists
(
prefbuf
))
continue
;
s
=
strdup
(
prefbuf
);
if
(
s
)
sys_recent_files
[
sys_n_recent_files
++
]
=
s
;
}
sys_doneloadpreferences
();
#endif
}
void
sys_clear_recent_files
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
sys_n_recent_files
;
i
++
)
{
free
(
sys_recent_files
[
i
]);
}
sys_n_recent_files
=
0
;
}
// send the recent files list back to the gui so that the Recent Files menu
// can be updated accordingly
void
glob_recent_files
(
t_pd
*
dummy
)
{
int
i
;
gui_start_vmess
(
"gui_recent_files"
,
"x"
,
dummy
);
gui_start_array
();
for
(
i
=
0
;
i
<
sys_n_recent_files
;
i
++
)
{
gui_s
(
sys_recent_files
[
i
]);
}
gui_end_array
();
gui_end_vmess
();
}
// add an entry to the recent files list, save the list and update the gui
void
glob_add_recent_file
(
t_pd
*
dummy
,
t_symbol
*
s
)
{
sys_add_recent_file
(
s
->
s_name
);
sys_save_recent_files
();
glob_recent_files
(
dummy
);
}
// clear the recent files list, save the list and update the gui
void
glob_clear_recent_files
(
t_pd
*
dummy
)
{
sys_clear_recent_files
();
sys_save_recent_files
();
glob_recent_files
(
dummy
);
}
pd/src/s_main.c
View file @
172416dd
...
...
@@ -301,6 +301,7 @@ int sys_main(int argc, char **argv)
noprefs
=
1
;
if
(
!
noprefs
)
sys_loadpreferences
();
/* load default settings */
sys_load_recent_files
();
/* load recent files table */
#ifndef MSW
if
(
!
noprefs
)
sys_rcfile
();
/* parse the startup file */
...
...
@@ -320,6 +321,8 @@ int sys_main(int argc, char **argv)
gui_vmess
(
"gui_set_lib_dir"
,
"s"
,
sys_libdir
->
s_name
);
/* send the name of the gui preset */
gui_vmess
(
"gui_set_gui_preset"
,
"s"
,
sys_gui_preset
->
s_name
);
/* send the recent files list */
glob_recent_files
(
0
);
if
(
sys_externalschedlib
)
return
(
sys_run_scheduler
(
sys_externalschedlibname
,
...
...
pd/src/s_stuff.h
View file @
172416dd
...
...
@@ -42,6 +42,14 @@ extern int sys_defeatrt;
extern
t_symbol
*
sys_gui_preset
;
extern
t_symbol
*
sys_flags
;
#define MAX_RECENT_FILES 8
void
sys_load_recent_files
(
void
);
void
sys_save_recent_files
(
void
);
void
sys_add_recent_file
(
const
char
*
s
);
void
sys_clear_recent_files
(
void
);
extern
int
sys_n_recent_files
;
extern
char
*
sys_recent_files
[];
/* s_main.c */
extern
int
sys_debuglevel
;
extern
int
sys_verbose
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment