added ribbon number and level dir to export path pattern + removed level dir field from export dialog (experiment)...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2019-05-16 05:00:15 +03:00
parent 17c6f64c86
commit a2a475cbad
2 changed files with 78 additions and 18 deletions

View File

@ -1950,6 +1950,7 @@ var FileSystemWriterActions = actions.Actions({
// XXX document data format... // XXX document data format...
// XXX should %T / %I be global or current crop??? // XXX should %T / %I be global or current crop???
// XXX add support of %(fav)l for level dir...
// XXX set length of %g in options... // XXX set length of %g in options...
formatImageName: ['- File/', formatImageName: ['- File/',
core.doc` core.doc`
@ -1963,6 +1964,9 @@ var FileSystemWriterActions = actions.Actions({
%i - image index in ribbon %i - image index in ribbon
%I - global image index %I - global image index
%r - ribbon number
%R - ribbon number counting from the bottom
%t - total number of images in ribbon %t - total number of images in ribbon
%T - total number of images %T - total number of images
@ -1977,6 +1981,15 @@ var FileSystemWriterActions = actions.Actions({
%c - number in set of conflicting names (default: 0). %c - number in set of conflicting names (default: 0).
NOTE: this is not stable and can change depending NOTE: this is not stable and can change depending
on image order. on image order.
%(...)l - image level path, level depth corresponds to ribbon
number counting from the bottom
NOTE: if level is 0 this resolves to '/'
Example: '%(x)lz.jop' will resolve to '/z.jpg' for bottom
ribbon and to 'x/x/x/z.jpg' for ribbon #3 from the
bottom.
%(...)L - image level path, level depth corresponds to ribbon
number counting from the top
NOTE: if level is 0 this resolves to '/'
NOTE: file extension is added automatically. NOTE: file extension is added automatically.
NOTE: all group patterns (i.e. '%(..)x') can include other patterns. NOTE: all group patterns (i.e. '%(..)x') can include other patterns.
@ -2002,13 +2015,18 @@ var FileSystemWriterActions = actions.Actions({
// XXX revise defaults... // XXX revise defaults...
var len = data.len || this.data.ribbons[ribbon].len var len = data.len || this.data.ribbons[ribbon].len
var total_len = data.total_len || this.data.length var total_len = data.total_len || this.data.length
var r_len = data.r_len || Object.keys(this.data.ribbons).length
var i = data.i || this.data.getImageOrder('ribbon', gid) var i = data.i || this.data.getImageOrder('ribbon', gid)
var I = data.I || this.data.getImageOrder('loaded', gid) var I = data.I || this.data.getImageOrder('loaded', gid)
var r = data.r || this.data.getRibbonOrder(gid)
var R = data.R || r_len - r - 1
// pad with zeros... // pad with zeros...
i = (i+'').padStart((len + '').length, '0') i = (i+'').padStart((len + '').length, '0')
I = (I+'').padStart((total_len + '').length, '0') I = (I+'').padStart((total_len + '').length, '0')
r = (r+'').padStart((r_len + '').length, '0')
R = (R+'').padStart((r_len + '').length, '0')
//i = ((('1e'+(len+'').length)*1 + i) + '').slice(1) //i = ((('1e'+(len+'').length)*1 + i) + '').slice(1)
//I = ((('1e'+(total_len+'').length)*1 + I) + '').slice(1) //I = ((('1e'+(total_len+'').length)*1 + I) + '').slice(1)
@ -2027,6 +2045,10 @@ var FileSystemWriterActions = actions.Actions({
.replace(/%i/, i) .replace(/%i/, i)
.replace(/%I/, I) .replace(/%I/, I)
// ribbon order...
.replace(/%r/, r)
.replace(/%r/, R)
// totals... // totals...
.replace(/%t/, len) .replace(/%t/, len)
.replace(/%T/, total_len) .replace(/%T/, total_len)
@ -2055,6 +2077,20 @@ var FileSystemWriterActions = actions.Actions({
.replace( .replace(
/%\(([^)]*)\)c/, (conflicts || {})[gid] ? '$1' : '') /%\(([^)]*)\)c/, (conflicts || {})[gid] ? '$1' : '')
// level...
.replace(
/%\(([^)]*)\)L/,
function(match, level, offset, str){
return (offset == 0 ? '' : '/')
+(new Array(r*1)).fill(level).join('/')
+(match.length + offset == str.length ? '' : '/') })
.replace(
/%\(([^)]*)\)l/,
function(match, level, offset, str){
return (offset == 0 ? '' : '/')
+(new Array(r_len - r*1 - 1)).fill(level).join('/')
+(match.length + offset == str.length ? '' : '/') })
+ to_ext + to_ext
}], }],
@ -2094,7 +2130,9 @@ var FileSystemWriterActions = actions.Actions({
// get/set the config data... // get/set the config data...
// XXX should this store the last set??? // XXX should this store the last set???
level_dir = level_dir || this.config['export-level-directory-name'] || 'fav' level_dir = level_dir === undefined ?
level_dir
: (level_dir || this.config['export-level-directory-name'] || 'fav')
size = size || this.config['export-preview-size'] || 1000 size = size || this.config['export-preview-size'] || 1000
pattern = pattern || this.config['export-preview-name-pattern'] || '%f' pattern = pattern || this.config['export-preview-name-pattern'] || '%f'
@ -2163,7 +2201,9 @@ var FileSystemWriterActions = actions.Actions({
}) })
}) })
to_dir += '/'+level_dir to_dir += level_dir != null ?
'/'+level_dir
: ''
return res return res
})) }))
@ -2258,7 +2298,8 @@ var FileSystemWriterUIActions = actions.Actions({
'size', 'size',
'base_path', 'base_path',
'target_dir', 'target_dir',
'level_dir', // XXX add option to disable this...
//'level_dir',
], ],
}, },
}, },
@ -2392,6 +2433,7 @@ var FileSystemWriterUIActions = actions.Actions({
return res return res
}, },
// XXX add option not to create level dirs...
'level_dir': function(actions, make, parent){ 'level_dir': function(actions, make, parent){
return make(['$Level directory: ', return make(['$Level directory: ',
function(){ function(){
@ -2401,8 +2443,7 @@ var FileSystemWriterUIActions = actions.Actions({
'export-level-directory-names', 'export-level-directory-names',
'export-level-directory-name', { 'export-level-directory-name', {
length_limit: 10, length_limit: 10,
})) })) },
},
// XXX should we merge this with 'size_limit'???? // XXX should we merge this with 'size_limit'????
'size': function(actions, make, parent){ 'size': function(actions, make, parent){
return make(['Image $size: ', return make(['Image $size: ',

View File

@ -199,7 +199,6 @@ Items.ListTitle = function(){}
// //
// XXX make the event object customizable... // XXX make the event object customizable...
// XXX STUB event object... // XXX STUB event object...
// XXX should this be simply a shorthand to .trigger(..) ???
var makeEventMethod = function(event, handler){ var makeEventMethod = function(event, handler){
return function(item){ return function(item){
// register handler... // register handler...
@ -217,7 +216,6 @@ var makeEventMethod = function(event, handler){
//}, //},
} }
// XXX handle more of the API???
handler handler
&& handler.call(this, evt, ...arguments) && handler.call(this, evt, ...arguments)
@ -226,6 +224,11 @@ var makeEventMethod = function(event, handler){
} }
} }
// Call item event handlers...
//
// callItemEventHandlers(item, event_name, event_object, ...)
// -> null
//
var callItemEventHandlers = function(item, event, evt, ...args){ var callItemEventHandlers = function(item, event, evt, ...args){
;(item[event] ? ;(item[event] ?
[item[event]] [item[event]]
@ -235,8 +238,23 @@ var callItemEventHandlers = function(item, event, evt, ...args){
// XXX revise call signature... // XXX revise call signature...
handler.call(item, evt, item, ...args) }) } handler.call(item, evt, item, ...args) }) }
// Generate item event method...
//
// This extends makeEventMethod(..) by adding an option to pass an item
// when triggering the event, the rest of the signature is identical.
//
// Trigger an event on item(s)...
// .event(item, ..)
// .event([item, ..], ..)
// -> this
//
// NOTE: item is compatible to .search(item, ..) spec, see that for more
// details...
var makeItemEventMethod = function(event, handler, options){ var makeItemEventMethod = function(event, handler, options){
options = Object.assign( options = Object.assign(
// NOTE: we need to be able to pass item objects, so we can not
// use queries at the same time as there is not way to
// distinguish one from the other...
{ noQueryCheck: true }, { noQueryCheck: true },
options || {}) options || {})
// NOTE: this is not returned directly as we need to query the items // NOTE: this is not returned directly as we need to query the items
@ -261,7 +279,7 @@ var makeItemEventMethod = function(event, handler, options){
return that.search(e, options) }) return that.search(e, options) })
.flat() .flat()
.unique() .unique()
// query... // explicit item or query...
: item != null ? : item != null ?
this.search(item, options) this.search(item, options)
: [], : [],
@ -302,7 +320,7 @@ var BaseBrowserPrototype = {
// //
// NOTE: this can't be a map/dict as we need both order manipulation // NOTE: this can't be a map/dict as we need both order manipulation
// and nested structures which would overcomplicate things, as // and nested structures which would overcomplicate things, as
// a compromise we use .item_key_index below for item identification. // a compromise we use .index below for item identification.
__items: null, __items: null,
get items(){ get items(){
this.__items this.__items
@ -328,15 +346,16 @@ var BaseBrowserPrototype = {
// XXX can we make the format here simpler with less level // XXX can we make the format here simpler with less level
// of indirection?? // of indirection??
// ...currently to go down a path we need to: // ...currently to go down a path we need to:
// this.item_key_index.A.children.item_key_index.B.children... // this.index.A.children.index.B.children...
// would be nice to be closer to: // would be nice to be closer to:
// this.A.B... // this.A.B...
__item_index: null, __item_index: null,
get item_key_index(){ get index(){
this.__item_index this.__item_index
|| this.make() || this.make()
return this.__item_index }, return this.__item_index },
set item_key_index(value){ // XXX should this exist???
set index(value){
this.__item_index = value }, this.__item_index = value },
@ -401,7 +420,7 @@ var BaseBrowserPrototype = {
// //
// The resulting item is stored in: // The resulting item is stored in:
// .items // .items
// .item_key_index (keyed via .id or JSONified .value) // .index (keyed via .id or JSONified .value)
// //
// Each of the above structures is reset on each call to .make(..) // Each of the above structures is reset on each call to .make(..)
// //
@ -1411,9 +1430,9 @@ var BaseBrowserPrototype = {
cur = e.children cur = e.children
} else { } else {
// XXX .item_key_index feels ugly... // XXX .index feels ugly...
delete cur.item_key_index[n].collapsed delete cur.index[n].collapsed
cur = cur.item_key_index[n].children cur = cur.index[n].children
} }
}) })
return e return e
@ -1429,7 +1448,7 @@ var BaseBrowserPrototype = {
// Make .items and .item_key_index... // Make .items and .index...
// //
// .make() // .make()
// .make(options) // .make(options)
@ -1441,7 +1460,7 @@ var BaseBrowserPrototype = {
// For more doc on item construction see: .__init__(..) // For more doc on item construction see: .__init__(..)
// //
// //
// NOTE: each call to this will reset both .items and .item_key_index // NOTE: each call to this will reset both .items and .index
// NOTE: for items with repeating values there is no way to correctly // NOTE: for items with repeating values there is no way to correctly
// identify an item thus no state is maintained between .make(..) // identify an item thus no state is maintained between .make(..)
// calls for such items... // calls for such items...