mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-30 07:42:23 +02:00
Export playlist to file with Ctrl+E
This commit is contained in:
@@ -2,6 +2,7 @@ const Dialogs = imports.src.dialogs;
|
||||
|
||||
var actions = {
|
||||
open_local: ['<Ctrl>O'],
|
||||
export_playlist: ['<Ctrl>E'],
|
||||
open_uri: ['<Ctrl>U'],
|
||||
prefs: null,
|
||||
about: null,
|
||||
@@ -30,7 +31,8 @@ function handleAction(action, window)
|
||||
|
||||
switch(action.name) {
|
||||
case 'open_local':
|
||||
new Dialogs.FileChooser(window);
|
||||
case 'export_playlist':
|
||||
new Dialogs.FileChooser(window, action.name);
|
||||
break;
|
||||
case 'open_uri':
|
||||
new Dialogs.UriDialog(window);
|
||||
|
109
src/dialogs.js
109
src/dialogs.js
@@ -1,6 +1,7 @@
|
||||
const { Gio, GObject, Gtk, Gst } = imports.gi;
|
||||
const System = imports.system;
|
||||
const Debug = imports.src.debug;
|
||||
const FileOps = imports.src.fileOps;
|
||||
const Misc = imports.src.misc;
|
||||
const Prefs = imports.src.prefs;
|
||||
const PrefsBase = imports.src.prefsBase;
|
||||
@@ -10,14 +11,37 @@ const { debug } = Debug;
|
||||
var FileChooser = GObject.registerClass(
|
||||
class ClapperFileChooser extends Gtk.FileChooserNative
|
||||
{
|
||||
_init(window)
|
||||
_init(window, purpose)
|
||||
{
|
||||
super._init({
|
||||
transient_for: window,
|
||||
modal: true,
|
||||
select_multiple: true,
|
||||
});
|
||||
|
||||
switch(purpose) {
|
||||
case 'open_local':
|
||||
this._prepareOpenLocal();
|
||||
break;
|
||||
case 'export_playlist':
|
||||
this._prepareExportPlaylist();
|
||||
break;
|
||||
default:
|
||||
debug(new Error(`unknown file chooser purpose: ${purpose}`));
|
||||
break;
|
||||
}
|
||||
|
||||
this.chooserPurpose = purpose;
|
||||
this.responseSignal = this.connect('response', this._onResponse.bind(this));
|
||||
|
||||
/* File chooser closes itself when nobody is holding its ref */
|
||||
this.ref();
|
||||
this.show();
|
||||
}
|
||||
|
||||
_prepareOpenLocal()
|
||||
{
|
||||
this.select_multiple = true;
|
||||
|
||||
const filter = new Gtk.FileFilter({
|
||||
name: 'Media Files',
|
||||
});
|
||||
@@ -26,12 +50,18 @@ class ClapperFileChooser extends Gtk.FileChooserNative
|
||||
filter.add_mime_type('application/claps');
|
||||
Misc.subsMimes.forEach(mime => filter.add_mime_type(mime));
|
||||
this.add_filter(filter);
|
||||
}
|
||||
|
||||
this.responseSignal = this.connect('response', this._onResponse.bind(this));
|
||||
_prepareExportPlaylist()
|
||||
{
|
||||
this.action = Gtk.FileChooserAction.SAVE;
|
||||
this.set_current_name('playlist.claps');
|
||||
|
||||
/* File chooser closes itself when nobody is holding its ref */
|
||||
this.ref();
|
||||
this.show();
|
||||
const filter = new Gtk.FileFilter({
|
||||
name: 'Playlist Files',
|
||||
});
|
||||
filter.add_mime_type('application/claps');
|
||||
this.add_filter(filter);
|
||||
}
|
||||
|
||||
_onResponse(filechooser, response)
|
||||
@@ -42,31 +72,58 @@ class ClapperFileChooser extends Gtk.FileChooserNative
|
||||
this.responseSignal = null;
|
||||
|
||||
if(response === Gtk.ResponseType.ACCEPT) {
|
||||
const files = this.get_files();
|
||||
const filesArray = [];
|
||||
|
||||
let index = 0;
|
||||
let file;
|
||||
|
||||
while((file = files.get_item(index))) {
|
||||
filesArray.push(file);
|
||||
index++;
|
||||
switch(this.chooserPurpose) {
|
||||
case 'open_local':
|
||||
this._handleOpenLocal();
|
||||
break;
|
||||
case 'export_playlist':
|
||||
this._handleExportPlaylist();
|
||||
break;
|
||||
}
|
||||
|
||||
const { application } = this.transient_for;
|
||||
const isHandlesOpen = Boolean(
|
||||
application.flags & Gio.ApplicationFlags.HANDLES_OPEN
|
||||
);
|
||||
|
||||
/* Remote app does not handle open */
|
||||
if(isHandlesOpen)
|
||||
application.open(filesArray, "");
|
||||
else
|
||||
application._openFilesAsync(filesArray);
|
||||
}
|
||||
|
||||
this.unref();
|
||||
}
|
||||
|
||||
_handleOpenLocal()
|
||||
{
|
||||
const files = this.get_files();
|
||||
const filesArray = [];
|
||||
|
||||
let index = 0;
|
||||
let file;
|
||||
|
||||
while((file = files.get_item(index))) {
|
||||
filesArray.push(file);
|
||||
index++;
|
||||
}
|
||||
|
||||
const { application } = this.transient_for;
|
||||
const isHandlesOpen = Boolean(
|
||||
application.flags & Gio.ApplicationFlags.HANDLES_OPEN
|
||||
);
|
||||
|
||||
/* Remote app does not handle open */
|
||||
if(isHandlesOpen)
|
||||
application.open(filesArray, "");
|
||||
else
|
||||
application._openFilesAsync(filesArray);
|
||||
}
|
||||
|
||||
_handleExportPlaylist()
|
||||
{
|
||||
const file = this.get_file();
|
||||
const { playlistWidget } = this.transient_for.child.player;
|
||||
const playlist = playlistWidget.getPlaylist(true);
|
||||
|
||||
FileOps.saveFileSimplePromise(file, playlist.join('\n'))
|
||||
.then(() => {
|
||||
debug(`exported playlist to file: ${file.get_path()}`);
|
||||
})
|
||||
.catch(err => {
|
||||
debug(err);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var UriDialog = GObject.registerClass(
|
||||
|
@@ -57,6 +57,18 @@ function createDirPromise(dir)
|
||||
});
|
||||
}
|
||||
|
||||
/* Simple save data to GioFile */
|
||||
function saveFileSimplePromise(file, data)
|
||||
{
|
||||
return file.replace_contents_bytes_async(
|
||||
GLib.Bytes.new_take(data),
|
||||
null,
|
||||
false,
|
||||
Gio.FileCreateFlags.NONE,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
/* Saves file in optional subdirectory and resolves with it */
|
||||
function saveFilePromise(place, subdirName, fileName, data)
|
||||
{
|
||||
@@ -82,18 +94,12 @@ function saveFilePromise(place, subdirName, fileName, data)
|
||||
}
|
||||
|
||||
const destFile = destDir.get_child(fileName);
|
||||
destFile.replace_contents_bytes_async(
|
||||
GLib.Bytes.new_take(data),
|
||||
null,
|
||||
false,
|
||||
Gio.FileCreateFlags.NONE,
|
||||
null
|
||||
)
|
||||
.then(() => {
|
||||
debug(`saved file: ${destPath}`);
|
||||
resolve(destFile);
|
||||
})
|
||||
.catch(err => reject(err));
|
||||
saveFileSimplePromise(destFile, data)
|
||||
.then(() => {
|
||||
debug(`saved file: ${destPath}`);
|
||||
resolve(destFile);
|
||||
})
|
||||
.catch(err => reject(err));
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -76,6 +76,24 @@ class ClapperPlaylistWidget extends Gtk.ListBox
|
||||
return this.get_row_at_index(this.activeRowId);
|
||||
}
|
||||
|
||||
getPlaylist(useFilePaths)
|
||||
{
|
||||
const playlist = [];
|
||||
let index = 0;
|
||||
let item;
|
||||
|
||||
while((item = this.get_row_at_index(index))) {
|
||||
const path = (useFilePaths && item.isLocalFile)
|
||||
? GLib.filename_from_uri(item.uri)[0]
|
||||
: item.uri;
|
||||
|
||||
playlist.push(path);
|
||||
index++;
|
||||
}
|
||||
|
||||
return playlist;
|
||||
}
|
||||
|
||||
getActiveFilename()
|
||||
{
|
||||
const row = this.getActiveRow();
|
||||
|
Reference in New Issue
Block a user