Compare commits

..

3 commits

Author SHA1 Message Date
j
b2368b9053 use native select folder dialog 2019-01-23 13:37:03 +05:30
j
1d52413618 pass parent to select folder/file dialog, set icon 2019-01-23 00:33:50 +05:30
j
7f05b08238 only create folder if target parent exists 2019-01-23 00:32:11 +05:30
7 changed files with 110 additions and 54 deletions

View file

@ -35,6 +35,8 @@ def selectFolder(data):
cmd = ['./ctl', 'ui', 'folder'] cmd = ['./ctl', 'ui', 'folder']
if sys.platform == 'win32': if sys.platform == 'win32':
cmd = win32_ui('folder') cmd = win32_ui('folder')
if 'base' in data:
cmd += [data['base']]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, close_fds=True) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, close_fds=True)
stdout, stderr = p.communicate() stdout, stderr = p.communicate()
path = stdout.decode('utf-8').strip() path = stdout.decode('utf-8').strip()
@ -53,6 +55,8 @@ def selectFile(data):
cmd = ['./ctl', 'ui', 'file'] cmd = ['./ctl', 'ui', 'file']
if sys.platform == 'win32': if sys.platform == 'win32':
cmd = win32_ui('file') cmd = win32_ui('file')
if 'base' in data:
cmd += [data['base']]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE) p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
stdout, stderr = p.communicate() stdout, stderr = p.communicate()
path = stdout.decode('utf-8').strip() path = stdout.decode('utf-8').strip()

View file

@ -129,12 +129,14 @@ def get_icons_db_path():
import settings import settings
import shutil import shutil
metadata = os.path.join(os.path.expanduser(settings.preferences['libraryPath']), 'Metadata') library = os.path.expanduser(settings.preferences['libraryPath'])
ox.makedirs(metadata) metadata = os.path.join(library, 'Metadata')
icons_db_path = os.path.join(metadata, 'icons.db') icons_db_path = os.path.join(metadata, 'icons.db')
old_icons_db_path = os.path.join(settings.data_path, 'icons.db') if os.path.exists(os.path.dirname(library)):
if not os.path.exists(icons_db_path) and os.path.exists(old_icons_db_path): ox.makedirs(metadata)
shutil.move(old_icons_db_path, icons_db_path) old_icons_db_path = os.path.join(settings.data_path, 'icons.db')
if not os.path.exists(icons_db_path) and os.path.exists(old_icons_db_path):
shutil.move(old_icons_db_path, icons_db_path)
return icons_db_path return icons_db_path
def get_icon_sync(id, type_, size): def get_icon_sync(id, type_, size):

View file

@ -1,24 +1,32 @@
# encoding: utf-8 # encoding: utf-8
# vi:si:et:sw=4:sts=4:ts=4 # vi:si:et:sw=4:sts=4:ts=4
import sys import sys
import os
try: try:
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject from gi.repository import Gtk, GObject
GObject.threads_init()
use_Gtk = True use_Gtk = True
except: except:
from tkinter import Tk from tkinter import Tk, PhotoImage
import tkinter.filedialog import tkinter.filedialog
use_Gtk = False use_Gtk = False
DEBUG = False DEBUG = False
def short_home(path):
home = os.path.expanduser('~')
if path and path.startswith(home):
path = path.replace(home, '~')
return path
class GtkUI: class GtkUI:
def selectFolder(self, data): def selectFolder(self, data):
dialog = Gtk.FileChooserDialog(data.get("title", "Select Folder"), dialog = Gtk.FileChooserDialog(title=data.get("title", "Select Folder"),
None, action=Gtk.FileChooserAction.SELECT_FOLDER)
Gtk.FileChooserAction.SELECT_FOLDER, dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
dialog.set_default_response(Gtk.ResponseType.OK) dialog.set_default_response(Gtk.ResponseType.OK)
response = dialog.run() response = dialog.run()
@ -35,14 +43,13 @@ class GtkUI:
Gtk.main_iteration() Gtk.main_iteration()
if DEBUG: if DEBUG:
print("done") print("done")
return filename return short_home(filename)
def selectFile(self, data): def selectFile(self, data):
dialog = Gtk.FileChooserDialog(data.get("title", "Select File"), dialog = Gtk.FileChooserDialog(title=data.get("title", "Select File"),
None, action=Gtk.FileChooserAction.OPEN)
Gtk.FileChooserAction.OPEN, dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
dialog.set_default_response(Gtk.ResponseType.OK) dialog.set_default_response(Gtk.ResponseType.OK)
response = dialog.run() response = dialog.run()
@ -59,23 +66,30 @@ class GtkUI:
Gtk.main_iteration() Gtk.main_iteration()
if DEBUG: if DEBUG:
print("done") print("done")
return filename return short_home(filename)
class TkUI: class TkUI:
def __init__(self): def __init__(self):
self.root = Tk() self.root = Tk(className="Open Media Library")
png = os.path.join(os.path.dirname(os.path.abspath('__file__')), 'static', 'png', 'oml.png')
icon = PhotoImage(file=png)
self.root.tk.call('wm', 'iconphoto', self.root._w, icon)
self.root.withdraw() # hiding tkinter window
if sys.platform == 'darwin': if sys.platform == 'darwin':
self.root.lift() self.root.lift()
self.root.call('wm', 'attributes', '.', '-topmost', True) self.root.call('wm', 'attributes', '.', '-topmost', True)
self.root.update() self.root.update()
self.root.after_idle(self.root.call, 'wm', 'attributes', '.', '-topmost', False) self.root.after_idle(self.root.call, 'wm', 'attributes', '.', '-topmost', False)
self.root.withdraw() # hiding tkinter window
def selectFolder(self, data): def selectFolder(self, data):
return tkinter.filedialog.askdirectory(title=data.get("title", "Select Folder")) folder = tkinter.filedialog.askdirectory(parent=self.root, title=data.get("title", "Select Folder"))
return short_home(folder)
def selectFile(self, data): def selectFile(self, data):
return tkinter.filedialog.askopenfilename(title=data.get("title", "Select File")) filename = tkinter.filedialog.askopenfilename(parent=self.root, title=data.get("title", "Select File"))
return short_home(filename)
if use_Gtk: if use_Gtk:
ui = GtkUI() ui = GtkUI()
@ -83,8 +97,12 @@ else:
ui = TkUI() ui = TkUI()
if __name__ == '__main__': if __name__ == '__main__':
import sys base = '~'
if len(sys.argv) == 2 and sys.argv[1] == 'folder': if len(sys.argv) >= 3:
base = sys.argv[2]
base = os.path.expanduser(base)
os.chdir(base)
if len(sys.argv) >= 2 and sys.argv[1] == 'folder':
print(ui.selectFolder({})) print(ui.selectFolder({}))
else: else:
print(ui.selectFile({})) print(ui.selectFile({}))

View file

@ -217,14 +217,7 @@ oml.ui.importExportDialog = function() {
var $element = Ox.Element(), var $element = Ox.Element(),
$form = Ox.Form({ $form = Ox.Form({
items: selected == 'import' ? [ items: selected == 'import' ? [
Ox.Input({ oml.ui.selectFolder({
autocomplete: function(value, callback) {
oml.api.autocompleteFolder({path: value}, function(result) {
callback(result.data.items);
});
},
autocompleteSelect: true,
changeOnKeypress: true,
id: 'path', id: 'path',
label: 'Source Path', label: 'Source Path',
labelWidth: 128, labelWidth: 128,
@ -256,14 +249,7 @@ oml.ui.importExportDialog = function() {
width: 480 width: 480
}) })
] : [ ] : [
Ox.Input({ oml.ui.selectFolder({
autocomplete: function(value, callback) {
oml.api.autocompleteFolder({path: value}, function(result) {
callback(result.data.items);
});
},
autocompleteSelect: true,
changeOnKeypress: true,
id: 'path', id: 'path',
label: 'Destination Path', label: 'Destination Path',
labelWidth: 128, labelWidth: 128,
@ -296,6 +282,7 @@ oml.ui.importExportDialog = function() {
.bindEvent({ .bindEvent({
change: function(data) { change: function(data) {
var values = $form.values(); var values = $form.values();
console.log(values)
$activityButton[selected].options({ $activityButton[selected].options({
disabled: !values.path disabled: !values.path
}); });

View file

@ -25,24 +25,14 @@ oml.ui.preferencesPanel = function() {
{ {
id: 'libraryPath', id: 'libraryPath',
title: 'Library Path', title: 'Library Path',
autocomplete: function(value, callback) { type: 'selectfolder',
oml.api.autocompleteFolder({path: value}, function(result) {
callback(result.data.items);
});
},
autocompleteSelect: true,
value: preferences.libraryPath, value: preferences.libraryPath,
help: 'The directory in which your "Books" folder is located. This is where your media files are stored. It can be on your local machine, but just as well on an external drive or networked volume.' help: 'The directory in which your "Books" folder is located. This is where your media files are stored. It can be on your local machine, but just as well on an external drive or networked volume.'
}, },
{ {
id: 'importPath', id: 'importPath',
title: 'Import Path', title: 'Import Path',
autocomplete: function(value, callback) { type: 'selectfolder',
oml.api.autocompleteFolder({path: value}, function(result) {
callback(result.data.items);
});
},
autocompleteSelect: true,
value: preferences.importPath, value: preferences.importPath,
help: 'Any media files that you put in this folder will be added to your library. Once added, they will be removed from this folder.' help: 'Any media files that you put in this folder will be added to your library. Once added, they will be removed from this folder.'
} }
@ -347,6 +337,15 @@ oml.ui.preferencesPanel = function() {
value: item.value, value: item.value,
width: 384 width: 384
}) })
: item.type == 'selectfolder'
? oml.ui.selectFolder({
label: Ox._(item.title),
labelWidth: 128,
placeholder: item.placeholder || '',
style: 'squared',
title: oml.user.preferences[item.id] || item.value || '',
width: 384 - !!item.unit * 48
})
: Ox.Input({ : Ox.Input({
autocomplete: item.autocomplete || null, autocomplete: item.autocomplete || null,
autocompleteSelect: item.autocompleteSelect || false, autocompleteSelect: item.autocompleteSelect || false,
@ -357,7 +356,6 @@ oml.ui.preferencesPanel = function() {
value: oml.user.preferences[item.id] || item.value || '', value: oml.user.preferences[item.id] || item.value || '',
width: 384 - !!item.unit * 48 width: 384 - !!item.unit * 48
}) })
].concat(item.unit ? [ ].concat(item.unit ? [
Ox.Label({ Ox.Label({
overlap: 'left', overlap: 'left',

46
static/js/selectFolder.js Normal file
View file

@ -0,0 +1,46 @@
'use strict';
oml.ui.selectFolder = function(options, self) {
options.width = options.width - options.labelWidth
options = Ox.extend({
title: '...',
textAlign: 'left'
}, options);
var $button = Ox.Button(options, self).bindEvent({
click: function(event) {
oml.api.selectFolder({
base: $button.value()
}, function(result) {
if (result.data.path) {
$button.value(result.data.path);
$button.options({
title: result.data.path
});
$button.triggerEvent('change', result.data.path);
}
})
}
}),
that = Ox.FormElementGroup({
id: options.id,
elements: [
Ox.Label({
style: options.style,
textAlign: 'right',
overlap: 'right',
title: options.label,
width: options.labelWidth
}),
$button
],
}, self);
that.value = function() {
return $button.value()
}
if (options.title && options.title != '...') {
$button.value(options.title)
}
return that;
}

View file

@ -58,6 +58,7 @@
"rightPanel.js", "rightPanel.js",
"sectionButtons.js", "sectionButtons.js",
"sectionbar.js", "sectionbar.js",
"selectFolder.js",
"sortElement.js", "sortElement.js",
"statusIcon.js", "statusIcon.js",
"statusbar.js", "statusbar.js",