Compare commits
No commits in common. "b2368b9053dd954bb473206aa2a44786753a0c2b" and "31e91d16bfab4f90980e1a77da6671a44312e631" have entirely different histories.
b2368b9053
...
31e91d16bf
7 changed files with 54 additions and 110 deletions
|
|
@ -35,8 +35,6 @@ 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()
|
||||||
|
|
@ -55,8 +53,6 @@ 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()
|
||||||
|
|
|
||||||
|
|
@ -129,14 +129,12 @@ def get_icons_db_path():
|
||||||
import settings
|
import settings
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
library = os.path.expanduser(settings.preferences['libraryPath'])
|
metadata = os.path.join(os.path.expanduser(settings.preferences['libraryPath']), 'Metadata')
|
||||||
metadata = os.path.join(library, 'Metadata')
|
ox.makedirs(metadata)
|
||||||
icons_db_path = os.path.join(metadata, 'icons.db')
|
icons_db_path = os.path.join(metadata, 'icons.db')
|
||||||
if os.path.exists(os.path.dirname(library)):
|
old_icons_db_path = os.path.join(settings.data_path, 'icons.db')
|
||||||
ox.makedirs(metadata)
|
if not os.path.exists(icons_db_path) and os.path.exists(old_icons_db_path):
|
||||||
old_icons_db_path = os.path.join(settings.data_path, 'icons.db')
|
shutil.move(old_icons_db_path, icons_db_path)
|
||||||
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):
|
||||||
|
|
|
||||||
58
oml/ui.py
58
oml/ui.py
|
|
@ -1,32 +1,24 @@
|
||||||
# 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, PhotoImage
|
from tkinter import Tk
|
||||||
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(title=data.get("title", "Select Folder"),
|
dialog = Gtk.FileChooserDialog(data.get("title", "Select Folder"),
|
||||||
action=Gtk.FileChooserAction.SELECT_FOLDER)
|
None,
|
||||||
dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
|
Gtk.FileChooserAction.SELECT_FOLDER,
|
||||||
Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
|
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
|
||||||
|
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()
|
||||||
|
|
@ -43,13 +35,14 @@ class GtkUI:
|
||||||
Gtk.main_iteration()
|
Gtk.main_iteration()
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
print("done")
|
print("done")
|
||||||
return short_home(filename)
|
return filename
|
||||||
|
|
||||||
def selectFile(self, data):
|
def selectFile(self, data):
|
||||||
dialog = Gtk.FileChooserDialog(title=data.get("title", "Select File"),
|
dialog = Gtk.FileChooserDialog(data.get("title", "Select File"),
|
||||||
action=Gtk.FileChooserAction.OPEN)
|
None,
|
||||||
dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
|
Gtk.FileChooserAction.OPEN,
|
||||||
Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
|
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
|
||||||
|
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()
|
||||||
|
|
@ -66,30 +59,23 @@ class GtkUI:
|
||||||
Gtk.main_iteration()
|
Gtk.main_iteration()
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
print("done")
|
print("done")
|
||||||
return short_home(filename)
|
return filename
|
||||||
|
|
||||||
|
|
||||||
class TkUI:
|
class TkUI:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.root = Tk(className="Open Media Library")
|
self.root = Tk()
|
||||||
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):
|
||||||
folder = tkinter.filedialog.askdirectory(parent=self.root, title=data.get("title", "Select Folder"))
|
return tkinter.filedialog.askdirectory(title=data.get("title", "Select Folder"))
|
||||||
return short_home(folder)
|
|
||||||
|
|
||||||
def selectFile(self, data):
|
def selectFile(self, data):
|
||||||
filename = tkinter.filedialog.askopenfilename(parent=self.root, title=data.get("title", "Select File"))
|
return tkinter.filedialog.askopenfilename(title=data.get("title", "Select File"))
|
||||||
return short_home(filename)
|
|
||||||
|
|
||||||
|
|
||||||
if use_Gtk:
|
if use_Gtk:
|
||||||
ui = GtkUI()
|
ui = GtkUI()
|
||||||
|
|
@ -97,12 +83,8 @@ else:
|
||||||
ui = TkUI()
|
ui = TkUI()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
base = '~'
|
import sys
|
||||||
if len(sys.argv) >= 3:
|
if len(sys.argv) == 2 and sys.argv[1] == 'folder':
|
||||||
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({}))
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,14 @@ oml.ui.importExportDialog = function() {
|
||||||
var $element = Ox.Element(),
|
var $element = Ox.Element(),
|
||||||
$form = Ox.Form({
|
$form = Ox.Form({
|
||||||
items: selected == 'import' ? [
|
items: selected == 'import' ? [
|
||||||
oml.ui.selectFolder({
|
Ox.Input({
|
||||||
|
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,
|
||||||
|
|
@ -249,7 +256,14 @@ oml.ui.importExportDialog = function() {
|
||||||
width: 480
|
width: 480
|
||||||
})
|
})
|
||||||
] : [
|
] : [
|
||||||
oml.ui.selectFolder({
|
Ox.Input({
|
||||||
|
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,
|
||||||
|
|
@ -282,7 +296,6 @@ 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
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -25,14 +25,24 @@ oml.ui.preferencesPanel = function() {
|
||||||
{
|
{
|
||||||
id: 'libraryPath',
|
id: 'libraryPath',
|
||||||
title: 'Library Path',
|
title: 'Library Path',
|
||||||
type: 'selectfolder',
|
autocomplete: function(value, callback) {
|
||||||
|
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',
|
||||||
type: 'selectfolder',
|
autocomplete: function(value, callback) {
|
||||||
|
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.'
|
||||||
}
|
}
|
||||||
|
|
@ -337,15 +347,6 @@ 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,
|
||||||
|
|
@ -356,6 +357,7 @@ 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',
|
||||||
|
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
'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;
|
|
||||||
}
|
|
||||||
|
|
@ -58,7 +58,6 @@
|
||||||
"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",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue