├── .gitignore ├── css ├── places.css ├── finder.css.combine ├── fonts.css ├── statusbar.css ├── contextmenu.css ├── common.css ├── navbar.css ├── quicklook.css ├── commands.css ├── toolbar.css ├── dialog.css └── cwd.css ├── files └── .gitignore ├── .easymin ├── noshrink_paths ├── ignore_types └── ignore_prefixes ├── img ├── crop.gif ├── dialogs.png ├── resize.png ├── toolbar.png ├── icons-big.png ├── progress.gif ├── _src │ ├── dialogs.pxm │ ├── toolbar.pxm │ ├── icons-big.psd │ ├── icons-big.pxm │ ├── icons-small.psd │ ├── icons-small.pxm │ ├── icons-small copy.pxm │ └── quicklook-icons.pxm ├── icons-small.png ├── quicklook-bg.png ├── spinner-mini.gif ├── arrows-active.png ├── arrows-normal.png └── quicklook-icons.png ├── js ├── Finder.version.js ├── finder.js.combine ├── commands │ ├── forward.js │ ├── back.js │ ├── home.js │ ├── mkfile.js │ ├── up.js │ ├── mkdir.js │ ├── view.js │ ├── sort.js │ ├── reload.js │ ├── copy.js │ ├── unmount.js │ ├── search.js │ ├── cut.js │ ├── duplicate.js │ ├── archive.js │ ├── download.js │ ├── extract.js │ ├── rm.js │ ├── open.js │ ├── netmount.js │ ├── getfile.js │ ├── rename.js │ ├── upload.js │ ├── help.js │ ├── edit.js │ ├── paste.js │ ├── info.js │ └── quicklook.plugins.js ├── ui │ ├── panel.js │ ├── viewbutton.js │ ├── uploadButton.js │ ├── workzone.js │ ├── navbar.js │ ├── path.js │ ├── overlay.js │ ├── toolbar.js │ ├── stat.js │ ├── searchbutton.js │ ├── button.js │ ├── sortbutton.js │ ├── contextmenu.js │ ├── dialog.js │ └── places.js ├── jquery.finder.js ├── Finder.history.js ├── jquery.dialogfinder.js ├── Finder.resources.js ├── Finder.command.js └── Finder.mime.js ├── jquery └── ui-themes │ └── smoothness │ └── images │ ├── ui-icons_222222_256x240.png │ ├── ui-icons_2e83ff_256x240.png │ ├── ui-icons_454545_256x240.png │ ├── ui-icons_888888_256x240.png │ ├── ui-icons_cd0a0a_256x240.png │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ ├── ui-bg_flat_75_ffffff_40x100.png │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ ├── ui-bg_glass_65_ffffff_1x400.png │ ├── ui-bg_glass_75_dadada_1x400.png │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ ├── ui-bg_glass_95_fef1ec_1x400.png │ └── ui-bg_highlight-soft_75_cccccc_1x100.png ├── php ├── MySQLStorage.sql ├── connector.php ├── Archive.php └── connector.src.php ├── finder.html ├── themes └── MacOS.css ├── Changelog └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /css/places.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/.gitignore: -------------------------------------------------------------------------------- 1 | * -------------------------------------------------------------------------------- /css/finder.css.combine: -------------------------------------------------------------------------------- 1 | ./ -------------------------------------------------------------------------------- /.easymin/noshrink_paths: -------------------------------------------------------------------------------- 1 | jquery -------------------------------------------------------------------------------- /.easymin/ignore_types: -------------------------------------------------------------------------------- 1 | .svn 2 | .psd 3 | .xcf 4 | .exe 5 | .pxm -------------------------------------------------------------------------------- /img/crop.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/crop.gif -------------------------------------------------------------------------------- /img/dialogs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/dialogs.png -------------------------------------------------------------------------------- /img/resize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/resize.png -------------------------------------------------------------------------------- /img/toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/toolbar.png -------------------------------------------------------------------------------- /img/icons-big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/icons-big.png -------------------------------------------------------------------------------- /img/progress.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/progress.gif -------------------------------------------------------------------------------- /img/_src/dialogs.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/_src/dialogs.pxm -------------------------------------------------------------------------------- /img/_src/toolbar.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/_src/toolbar.pxm -------------------------------------------------------------------------------- /img/icons-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/icons-small.png -------------------------------------------------------------------------------- /img/quicklook-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/quicklook-bg.png -------------------------------------------------------------------------------- /img/spinner-mini.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/spinner-mini.gif -------------------------------------------------------------------------------- /img/_src/icons-big.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/_src/icons-big.psd -------------------------------------------------------------------------------- /img/_src/icons-big.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/_src/icons-big.pxm -------------------------------------------------------------------------------- /img/arrows-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/arrows-active.png -------------------------------------------------------------------------------- /img/arrows-normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/arrows-normal.png -------------------------------------------------------------------------------- /img/_src/icons-small.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/_src/icons-small.psd -------------------------------------------------------------------------------- /img/_src/icons-small.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/_src/icons-small.pxm -------------------------------------------------------------------------------- /img/quicklook-icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/quicklook-icons.png -------------------------------------------------------------------------------- /img/_src/icons-small copy.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/_src/icons-small copy.pxm -------------------------------------------------------------------------------- /img/_src/quicklook-icons.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/img/_src/quicklook-icons.pxm -------------------------------------------------------------------------------- /js/Finder.version.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Application version 3 | * 4 | * @type String 5 | **/ 6 | Finder.prototype.version = '2.2.1'; 7 | 8 | -------------------------------------------------------------------------------- /.easymin/ignore_prefixes: -------------------------------------------------------------------------------- 1 | x_ 2 | X_ 3 | _ 4 | .git 5 | temp 6 | chars-test 7 | .tmb 8 | .quarantine 9 | .easymin 10 | finder.src.html 11 | connector.src.php -------------------------------------------------------------------------------- /jquery/ui-themes/smoothness/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/jquery/ui-themes/smoothness/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /jquery/ui-themes/smoothness/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/jquery/ui-themes/smoothness/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /jquery/ui-themes/smoothness/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/jquery/ui-themes/smoothness/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /jquery/ui-themes/smoothness/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/jquery/ui-themes/smoothness/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /jquery/ui-themes/smoothness/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/jquery/ui-themes/smoothness/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /jquery/ui-themes/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/jquery/ui-themes/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /jquery/ui-themes/smoothness/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/jquery/ui-themes/smoothness/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /jquery/ui-themes/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/jquery/ui-themes/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /jquery/ui-themes/smoothness/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/jquery/ui-themes/smoothness/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /jquery/ui-themes/smoothness/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/jquery/ui-themes/smoothness/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /jquery/ui-themes/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/jquery/ui-themes/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /jquery/ui-themes/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/jquery/ui-themes/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /jquery/ui-themes/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oyejorge/gpFinder/HEAD/jquery/ui-themes/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /js/finder.js.combine: -------------------------------------------------------------------------------- 1 | 2 | ./Finder.js 3 | ./Finder.version.js 4 | ./jquery.finder.js 5 | ./Finder.options.js 6 | ./Finder.history.js 7 | ./Finder.command.js 8 | ./Finder.resources.js 9 | ./Finder.mime.js 10 | ./jquery.dialogfinder.js 11 | ./i18n/en.js 12 | ./ui 13 | ./commands 14 | -------------------------------------------------------------------------------- /js/commands/forward.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class Finder command "forward" 3 | * Open next visited folder 4 | * 5 | * @author Dmitry (dio) Levashov 6 | **/ 7 | Finder.prototype.commands.forward = function() { 8 | this.alwaysEnabled = true; 9 | this.updateOnSelect = true; 10 | this.shortcuts = [{ 11 | pattern : 'ctrl+right' 12 | }]; 13 | 14 | this.getstate = function() { 15 | return this.fm.history.canForward() ? 0 : -1; 16 | } 17 | 18 | this.exec = function() { 19 | return this.fm.history.forward(); 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /js/ui/panel.js: -------------------------------------------------------------------------------- 1 | $.fn.finderpanel = function(fm) { 2 | 3 | return this.each(function() { 4 | var panel = $(this).addClass('finder-panel ui-state-default ui-corner-all'), 5 | margin = 'margin-'+(fm.direction == 'ltr' ? 'left' : 'right'); 6 | 7 | fm.one('load', function(e) { 8 | var navbar = fm.getUI('navbar'); 9 | 10 | panel.css(margin, parseInt(navbar.outerWidth(true))); 11 | navbar.bind('resize', function() { 12 | panel.is(':visible') && panel.css(margin, parseInt(navbar.outerWidth(true))) 13 | }) 14 | }) 15 | }) 16 | } -------------------------------------------------------------------------------- /js/commands/back.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * @class Finder command "back" 4 | * Open last visited folder 5 | * 6 | * @author Dmitry (dio) Levashov 7 | **/ 8 | Finder.prototype.commands.back = function() { 9 | this.alwaysEnabled = true; 10 | this.updateOnSelect = false; 11 | this.shortcuts = [{ 12 | pattern : 'ctrl+left backspace' 13 | }]; 14 | 15 | this.getstate = function() { 16 | return this.fm.history.canBack() ? 0 : -1; 17 | } 18 | 19 | this.exec = function() { 20 | return this.fm.history.back(); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /js/commands/home.js: -------------------------------------------------------------------------------- 1 | 2 | Finder.prototype.commands.home = function() { 3 | this.title = 'Home'; 4 | this.alwaysEnabled = true; 5 | this.updateOnSelect = false; 6 | this.shortcuts = [{ 7 | pattern : 'ctrl+home ctrl+shift+up', 8 | description : 'Home' 9 | }]; 10 | 11 | this.getstate = function() { 12 | var root = this.fm.root(), 13 | cwd = this.fm.cwd().hash; 14 | 15 | return root && cwd && root != cwd ? 0: -1; 16 | } 17 | 18 | this.exec = function() { 19 | return this.fm.exec('open', this.fm.root()); 20 | } 21 | 22 | 23 | } -------------------------------------------------------------------------------- /js/commands/mkfile.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * @class Finder command "mkfile" 4 | * Create new empty file 5 | * 6 | * @author Dmitry (dio) Levashov 7 | **/ 8 | Finder.prototype.commands.mkfile = function() { 9 | this.disableOnSearch = true; 10 | this.updateOnSelect = false; 11 | this.mime = 'text/plain'; 12 | this.prefix = 'untitled file.txt'; 13 | this.exec = $.proxy(this.fm.res('mixin', 'make'), this); 14 | 15 | this.getstate = function() { 16 | return !this._disabled && this.fm.cwd().write ? 0 : -1; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /js/commands/up.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * @class Finder command "up" 4 | * Go into parent directory 5 | * 6 | * @author Dmitry (dio) Levashov 7 | **/ 8 | Finder.prototype.commands.up = function() { 9 | this.alwaysEnabled = true; 10 | this.updateOnSelect = false; 11 | 12 | this.shortcuts = [{ 13 | pattern : 'ctrl+up' 14 | }]; 15 | 16 | this.getstate = function() { 17 | return this.fm.cwd().phash ? 0 : -1; 18 | } 19 | 20 | this.exec = function() { 21 | return this.fm.cwd().phash ? this.fm.exec('open', this.fm.cwd().phash) : $.Deferred().reject(); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /js/ui/viewbutton.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | /** 3 | * @class Finder toolbar button to switch current directory view. 4 | * 5 | * @author Dmitry (dio) Levashov 6 | **/ 7 | $.fn.finderviewbutton = function(cmd) { 8 | return this.each(function() { 9 | var button = $(this).finderbutton(cmd), 10 | icon = button.children('.finder-button-icon'); 11 | 12 | cmd.change(function() { 13 | var icons = cmd.value == 'icons'; 14 | 15 | icon.toggleClass('finder-button-icon-view-list', icons); 16 | button.attr('title', cmd.fm.i18n(icons ? 'viewlist' : 'viewicons')); 17 | }); 18 | }); 19 | } -------------------------------------------------------------------------------- /js/commands/mkdir.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * @class Finder command "mkdir" 4 | * Create new folder 5 | * 6 | * @author Dmitry (dio) Levashov 7 | **/ 8 | Finder.prototype.commands.mkdir = function() { 9 | this.disableOnSearch = true; 10 | this.updateOnSelect = false; 11 | this.mime = 'directory'; 12 | this.prefix = 'untitled folder'; 13 | this.exec = $.proxy(this.fm.res('mixin', 'make'), this); 14 | 15 | this.shortcuts = [{ 16 | pattern : 'ctrl+shift+n' 17 | }]; 18 | 19 | this.getstate = function() { 20 | return !this._disabled && this.fm.cwd().write ? 0 : -1; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /js/commands/view.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * @class Finder command "view" 4 | * Change current directory view (icons/list) 5 | * 6 | * @author Dmitry (dio) Levashov 7 | **/ 8 | Finder.prototype.commands.view = function() { 9 | this.value = this.fm.viewType; 10 | this.alwaysEnabled = true; 11 | this.updateOnSelect = false; 12 | 13 | this.options = { ui : 'viewbutton'}; 14 | 15 | this.getstate = function() { 16 | return 0; 17 | } 18 | 19 | this.exec = function() { 20 | var value = this.fm.storage('view', this.value == 'list' ? 'icons' : 'list'); 21 | this.fm.viewchange(); 22 | this.update(void(0), value); 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /js/commands/sort.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | /** 3 | * @class Finder command "sort" 4 | * Change sort files rule 5 | * 6 | * @author Dmitry (dio) Levashov 7 | **/ 8 | Finder.prototype.commands.sort = function() { 9 | /** 10 | * Command options 11 | * 12 | * @type Object 13 | */ 14 | this.options = {ui : 'sortbutton'}; 15 | 16 | this.getstate = function() { 17 | return 0; 18 | } 19 | 20 | this.exec = function(hashes, sort) { 21 | var fm = this.fm, 22 | sort = $.extend({ 23 | type : fm.sortType, 24 | order : fm.sortOrder, 25 | stick : fm.sortStickFolders 26 | }, sort); 27 | 28 | this.fm.setSort(sort.type, sort.order, sort.stick); 29 | return $.Deferred().resolve(); 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /js/ui/uploadButton.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * @class Finder toolbar's button tor upload file 4 | * 5 | * @author Dmitry (dio) Levashov 6 | **/ 7 | $.fn.finderuploadbutton = function(cmd) { 8 | return this.each(function() { 9 | var button = $(this).finderbutton(cmd) 10 | .unbind('click'), 11 | form = $('
').appendTo(button), 12 | input = $('') 13 | .change(function() { 14 | var _input = $(this); 15 | if (_input.val()) { 16 | cmd.exec({input : _input.remove()[0]}); 17 | input.clone(true).appendTo(form); 18 | } 19 | }); 20 | 21 | form.append(input.clone(true)); 22 | 23 | cmd.change(function() { 24 | form[cmd.disabled() ? 'hide' : 'show'](); 25 | }) 26 | .change(); 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /js/ui/workzone.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * @class finderworkzone - Finder container for nav and current directory 4 | * @author Dmitry (dio) Levashov 5 | **/ 6 | $.fn.finderworkzone = function(fm) { 7 | var cl = 'finder-workzone'; 8 | 9 | this.not('.'+cl).each(function() { 10 | var wz = $(this).addClass(cl), 11 | wdelta = wz.outerHeight(true) - wz.height(), 12 | parent = wz.parent(); 13 | 14 | parent.add(window).bind('resize', function() { 15 | var height = parent.height(); 16 | 17 | parent.children(':visible:not(.'+cl+')').each(function() { 18 | var ch = $(this); 19 | 20 | if (ch.css('position') != 'absolute') { 21 | height -= ch.outerHeight(true); 22 | } 23 | }); 24 | 25 | wz.height(height - wdelta); 26 | }); 27 | }); 28 | return this; 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /js/jquery.finder.js: -------------------------------------------------------------------------------- 1 | $.fn.finder = function(o) { 2 | 3 | if (o == 'instance') { 4 | return this.getFinder(); 5 | } 6 | 7 | return this.each(function() { 8 | 9 | var cmd = typeof(o) == 'string' ? o : ''; 10 | if (!this.finder) { 11 | new Finder(this, typeof(o) == 'object' ? o : {}) 12 | } 13 | 14 | switch(cmd) { 15 | case 'close': 16 | case 'hide': 17 | this.finder.hide(); 18 | break; 19 | 20 | case 'open': 21 | case 'show': 22 | this.finder.show(); 23 | break; 24 | 25 | case 'destroy': 26 | this.finder.destroy(); 27 | break; 28 | } 29 | 30 | }) 31 | } 32 | 33 | $.fn.getFinder = function() { 34 | var instance; 35 | 36 | this.each(function() { 37 | if (this.finder) { 38 | instance = this.finder; 39 | return false; 40 | } 41 | }); 42 | 43 | return instance; 44 | } 45 | -------------------------------------------------------------------------------- /js/ui/navbar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class findernav - Finder container for diretories tree and places 3 | * 4 | * @author Dmitry (dio) Levashov 5 | **/ 6 | $.fn.findernavbar = function(fm, opts) { 7 | 8 | this.not('.finder-navbar').each(function() { 9 | var nav = $(this).addClass('ui-state-default finder-navbar'), 10 | handle; 11 | 12 | nav.siblings('.finder-workzone').append(nav); 13 | 14 | if ($.fn.resizable) { 15 | handle = nav.resizable({ 16 | handles : (fm.direction == 'ltr') ? 'e' : 'w', 17 | minWidth : opts.minWidth || 150, 18 | maxWidth : opts.maxWidth || 500 19 | }) 20 | .bind('resize scroll', function() { 21 | handle.css({ 22 | top : parseInt(nav.scrollTop()) 23 | }) 24 | }) 25 | .find('.ui-resizable-handle').zIndex(nav.zIndex() + 10); 26 | 27 | fm.one('open', function() { 28 | setTimeout(function() { 29 | nav.trigger('resize'); 30 | }, 150); 31 | }); 32 | } 33 | }); 34 | 35 | return this; 36 | } 37 | -------------------------------------------------------------------------------- /js/commands/reload.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class Finder command "reload" 3 | * Sync files and folders 4 | * 5 | * @author Dmitry (dio) Levashov 6 | **/ 7 | Finder.prototype.commands.reload = function() { 8 | 9 | this.alwaysEnabled = true; 10 | this.updateOnSelect = true; 11 | 12 | this.shortcuts = [{ 13 | pattern : 'ctrl+shift+r f5' 14 | }]; 15 | 16 | this.getstate = function() { 17 | return 0; 18 | } 19 | 20 | this.exec = function() { 21 | 22 | // this would reload the contents of the folder, but wouldn't update the tree 23 | // return this.fm.exec('open', this.fm.cwd().hash ); 24 | 25 | var fm = this.fm, 26 | dfrd = fm.sync(), 27 | 28 | timeout = setTimeout(function() { 29 | fm.notify({type : 'reload', cnt : 1, hideCnt : true}); 30 | dfrd.always(function() { fm.notify({type : 'reload', cnt : -1}); }); 31 | }, fm.notifyDelay); 32 | 33 | return dfrd.always(function() { 34 | clearTimeout(timeout); 35 | fm.trigger('reload'); 36 | }); 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /js/ui/path.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * @class Finder ui 4 | * Display current folder path in statusbar. 5 | * Click on folder name in path - open folder 6 | * 7 | * @author Dmitry (dio) Levashov 8 | **/ 9 | $.fn.finderpath = function(fm) { 10 | return this.each(function() { 11 | var path = $(this).addClass('finder-path').html(' ') 12 | .delegate('a', 'click', function(e) { 13 | var hash = $(this).attr('href').substr(1); 14 | 15 | e.preventDefault(); 16 | hash != fm.cwd().hash && fm.exec('open', hash); 17 | }) 18 | .prependTo(fm.getUI('statusbar').show()) 19 | 20 | fm.bind('open searchend', function() { 21 | var dirs = []; 22 | 23 | $.each(fm.parents(fm.cwd().hash), function(i, hash) { 24 | dirs.push(''+fm.escape(fm.file(hash).name)+''); 25 | }); 26 | 27 | path.html(dirs.join(fm.option('separator'))); 28 | }) 29 | .bind('search', function() { 30 | path.html(fm.i18n('searcresult')); 31 | }); 32 | }); 33 | } -------------------------------------------------------------------------------- /js/commands/copy.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * @class Finder command "copy". 4 | * Put files in filemanager clipboard. 5 | * 6 | * @type Finder.command 7 | * @author Dmitry (dio) Levashov 8 | */ 9 | Finder.prototype.commands.copy = function() { 10 | 11 | this.shortcuts = [{ 12 | pattern : 'ctrl+c ctrl+insert' 13 | }]; 14 | 15 | this.getstate = function(sel) { 16 | var sel = this.files(sel), 17 | cnt = sel.length; 18 | 19 | return cnt && $.map(sel, function(f) { return f.phash && f.read ? f : null }).length == cnt ? 0 : -1; 20 | } 21 | 22 | this.exec = function(hashes) { 23 | var fm = this.fm, 24 | dfrd = $.Deferred() 25 | .fail(function(error) { 26 | fm.error(error); 27 | }); 28 | 29 | $.each(this.files(hashes), function(i, file) { 30 | if (!(file.read && file.phash)) { 31 | return !dfrd.reject(['errCopy', file.name, 'errPerm']); 32 | } 33 | }); 34 | 35 | 36 | return (dfrd.state() == 'rejected') ? dfrd : dfrd.resolve(fm.clipboard(this.hashes(hashes))); 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /css/fonts.css: -------------------------------------------------------------------------------- 1 | .finder-contextmenu .finder-contextmenu-item span { font-size:13px; } 2 | 3 | .finder-cwd-view-icons .finder-cwd-filename { font-size:.7em; } 4 | .finder-cwd-view-list td { font-size:.7em; } 5 | 6 | .std42-dialog .ui-dialog-titlebar { font-size:.82em; } 7 | .std42-dialog .ui-dialog-content { font-size:.72em; } 8 | .std42-dialog .ui-dialog-buttonpane { font-size:.76em; } 9 | .finder-info-tb { font-size:.9em; } 10 | .finder-upload-dropbox { font-size:1.2em; } 11 | .finder-upload-dialog-or { font-size:1.2em; } 12 | .dialogfinder .dialogfinder-drag { font-size:.9em; } 13 | .finder .finder-navbar { font-size:.72em; } 14 | .finder-place-drag .finder-navbar-dir { font-size:.9em;} 15 | .finder-quicklook-title { font-size:.7em; } 16 | .finder-quicklook-info-data { font-size:.72em; } 17 | .finder-quicklook-preview-text-wrapper { font-size:.9em; } 18 | .finder-button-menu-item { font-size:.72em; } 19 | .finder-button-search input { font-size:.8em; } 20 | .finder-statusbar div { font-size:.7em; } 21 | .finder-drag-num { font-size:12px; } 22 | 23 | -------------------------------------------------------------------------------- /js/commands/unmount.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @class Finder command "unmount" 4 | * un mount a network volume 5 | * 6 | */ 7 | Finder.prototype.commands.unmount = function() { 8 | var self = this, 9 | fm = this.fm; 10 | 11 | this.alwaysEnabled = true; 12 | this.updateOnSelect = false; 13 | 14 | this.getstate = function(target){ 15 | if( !target || target.length > 1 ) return -1; 16 | var file = fm.file(target[0]); 17 | if( file.net ){ 18 | return 0; 19 | } 20 | return -1; 21 | } 22 | 23 | this.exec = function(hashes){ 24 | var target = hashes[0], 25 | dfrd = $.Deferred(); 26 | 27 | return fm.request({ 28 | data : {cmd : 'unmount', target : target }, 29 | notify : {type : 'unmount', cnt : 1} 30 | }).fail(function(error){ 31 | dfrd.reject(error); 32 | }).done(function(error){ 33 | dfrd.resolve(); 34 | 35 | //remove the tree 36 | var span = $('#nav-'+target).closest('.finder-navbar-wrapper').detach(); 37 | 38 | //select different tree 39 | var $first = $('.finder-navbar-wrapper:first span:first').click(); 40 | 41 | }); 42 | } 43 | 44 | 45 | } -------------------------------------------------------------------------------- /js/ui/overlay.js: -------------------------------------------------------------------------------- 1 | 2 | $.fn.finderoverlay = function(opts) { 3 | 4 | this.filter(':not(.finder-overlay)').each(function() { 5 | opts = $.extend({}, opts); 6 | $(this).addClass('ui-widget-overlay finder-overlay') 7 | .hide() 8 | .mousedown(function(e) { 9 | e.preventDefault(); 10 | e.stopPropagation(); 11 | }) 12 | .data({ 13 | cnt : 0, 14 | show : typeof(opts.show) == 'function' ? opts.show : function() { }, 15 | hide : typeof(opts.hide) == 'function' ? opts.hide : function() { } 16 | }); 17 | }); 18 | 19 | if (opts == 'show') { 20 | var o = this.eq(0), 21 | cnt = o.data('cnt') + 1, 22 | show = o.data('show'); 23 | 24 | o.data('cnt', cnt); 25 | 26 | if (o.is(':hidden')) { 27 | o.zIndex(o.parent().zIndex()+1); 28 | o.show(); 29 | show(); 30 | } 31 | } 32 | 33 | if (opts == 'hide') { 34 | var o = this.eq(0), 35 | cnt = o.data('cnt') - 1, 36 | hide = o.data('hide'); 37 | 38 | o.data('cnt', cnt); 39 | 40 | if (cnt == 0 && o.is(':visible')) { 41 | o.hide(); 42 | hide(); 43 | } 44 | } 45 | 46 | return this; 47 | } -------------------------------------------------------------------------------- /css/statusbar.css: -------------------------------------------------------------------------------- 1 | /******************************************************************/ 2 | /* STATUSBAR STYLES */ 3 | /******************************************************************/ 4 | 5 | 6 | /* statusbar container */ 7 | .finder-statusbar { 8 | text-align:center; 9 | font-weight:normal; 10 | padding:.2em .5em; 11 | 12 | border-right:0 solid transparent; 13 | border-bottom:0 solid transparent; 14 | border-left:0 solid transparent; 15 | } 16 | 17 | .finder-statusbar a { text-decoration:none; } 18 | 19 | /* path in statusbar */ 20 | .finder-path { 21 | max-width:30%; 22 | white-space:nowrap; 23 | overflow:hidden; 24 | text-overflow:ellipsis; 25 | -o-text-overflow:ellipsis; 26 | } 27 | .finder-ltr .finder-path { float:left; } 28 | .finder-rtl .finder-path { float:right; } 29 | 30 | /* total/selected size in statusbar */ 31 | .finder-stat-size { white-space:nowrap; } 32 | .finder-ltr .finder-stat-size { float:right; } 33 | .finder-rtl .finder-stat-size { float:left; } 34 | 35 | .finder-stat-selected { white-space:nowrap; overflow:hidden; } 36 | -------------------------------------------------------------------------------- /js/commands/search.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | /** 3 | * @class Finder command "search" 4 | * Find files 5 | * 6 | * @author Dmitry (dio) Levashov 7 | **/ 8 | Finder.prototype.commands.search = function() { 9 | this.title = 'Find files'; 10 | this.options = {ui : 'searchbutton'} 11 | this.alwaysEnabled = true; 12 | this.updateOnSelect = false; 13 | 14 | /** 15 | * Return command status. 16 | * Search does not support old api. 17 | * 18 | * @return Number 19 | **/ 20 | this.getstate = function() { 21 | return 0; 22 | } 23 | 24 | /** 25 | * Send search request to backend. 26 | * 27 | * @param String search string 28 | * @return $.Deferred 29 | **/ 30 | this.exec = function(q) { 31 | var fm = this.fm; 32 | 33 | if (typeof(q) == 'string' && q) { 34 | fm.trigger('searchstart', {query : q}); 35 | 36 | return fm.request({ 37 | data : {cmd : 'search', q : q}, 38 | notify : {type : 'search', cnt : 1, hideCnt : true} 39 | }); 40 | } 41 | fm.getUI('toolbar').find('.'+fm.res('class', 'searchbtn')+' :text').focus(); 42 | return $.Deferred().reject(); 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /js/commands/cut.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * @class Finder command "copy". 4 | * Put files in filemanager clipboard. 5 | * 6 | * @type Finder.command 7 | * @author Dmitry (dio) Levashov 8 | */ 9 | Finder.prototype.commands.cut = function() { 10 | 11 | this.shortcuts = [{ 12 | pattern : 'ctrl+x shift+insert' 13 | }]; 14 | 15 | this.getstate = function(sel) { 16 | var sel = this.files(sel), 17 | cnt = sel.length; 18 | 19 | return cnt && $.map(sel, function(f) { return f.phash && f.read && !f.locked ? f : null }).length == cnt ? 0 : -1; 20 | } 21 | 22 | this.exec = function(hashes) { 23 | var fm = this.fm, 24 | dfrd = $.Deferred() 25 | .fail(function(error) { 26 | fm.error(error); 27 | }); 28 | 29 | $.each(this.files(hashes), function(i, file) { 30 | if( !(file.read && file.phash) ){ 31 | return !dfrd.reject(['errCopy', file.name, 'errPerm']); 32 | } 33 | if( file.locked ){ 34 | return !dfrd.reject(['errLocked', file.name]); 35 | } 36 | }); 37 | 38 | return (dfrd.state() == 'rejected') ? dfrd : dfrd.resolve(fm.clipboard(this.hashes(hashes), true)); 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /js/ui/toolbar.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * @class Finder toolbar 4 | * 5 | * @author Dmitry (dio) Levashov 6 | **/ 7 | $.fn.findertoolbar = function(fm, opts) { 8 | this.not('.finder-toolbar').each(function() { 9 | var commands = fm._commands, 10 | self = $(this).addClass('ui-helper-clearfix ui-widget-header ui-corner-top finder-toolbar'), 11 | panels = opts || [], 12 | l = panels.length, 13 | i, cmd, panel, button; 14 | 15 | self.prev().length && self.parent().prepend(this); 16 | 17 | while (l--) { 18 | if (panels[l]) { 19 | panel = $('
'); 20 | i = panels[l].length; 21 | while (i--) { 22 | if ((cmd = commands[panels[l][i]])) { 23 | button = 'finder'+cmd.options.ui; 24 | $.fn[button] && panel.prepend($('
')[button](cmd)); 25 | } 26 | } 27 | 28 | panel.children().length && self.prepend(panel); 29 | panel.children(':gt(0)').before(''); 30 | 31 | } 32 | } 33 | 34 | self.children().length && self.show(); 35 | }); 36 | 37 | return this; 38 | } 39 | -------------------------------------------------------------------------------- /php/MySQLStorage.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS `finder_file`; 2 | CREATE TABLE IF NOT EXISTS `finder_file` ( 3 | `id` int(7) unsigned NOT NULL auto_increment, 4 | `parent_id` int(7) unsigned NOT NULL, 5 | `name` varchar(256) NOT NULL, 6 | `content` longblob NOT NULL, 7 | `size` int(10) unsigned NOT NULL default '0', 8 | `mtime` int(10) unsigned NOT NULL, 9 | `mime` varchar(256) NOT NULL default 'unknown', 10 | `read` enum('1', '0') NOT NULL default '1', 11 | `write` enum('1', '0') NOT NULL default '1', 12 | `locked` enum('1', '0') NOT NULL default '0', 13 | `hidden` enum('1', '0') NOT NULL default '0', 14 | `width` int(5) NOT NULL, 15 | `height` int(5) NOT NULL, 16 | PRIMARY KEY (`id`), 17 | UNIQUE KEY `parent_name` (`parent_id`, `name`), 18 | KEY `parent_id` (`parent_id`) 19 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci; 20 | 21 | INSERT INTO `finder_file` 22 | (`id`, `parent_id`, `name`, `content`, `size`, `mtime`, `mime`, `read`, `write`, `locked`, `hidden`, `width`, `height`) VALUES 23 | ('1', '0', 'DATABASE', '', '0', '0', 'directory', '1', '1', '0', '0', '0', '0'); 24 | -------------------------------------------------------------------------------- /js/commands/duplicate.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * @class Finder command "duplicate" 4 | * Create file/folder copy with suffix "copy Number" 5 | * 6 | * @type Finder.command 7 | * @author Dmitry (dio) Levashov 8 | */ 9 | Finder.prototype.commands.duplicate = function() { 10 | var fm = this.fm; 11 | 12 | this.getstate = function(sel) { 13 | var sel = this.files(sel), 14 | cnt = sel.length; 15 | 16 | return !this._disabled && cnt && fm.cwd().write && $.map(sel, function(f) { return f.phash && f.read ? f : null }).length == cnt ? 0 : -1; 17 | } 18 | 19 | this.exec = function(hashes) { 20 | var fm = this.fm, 21 | files = this.files(hashes), 22 | cnt = files.length, 23 | dfrd = $.Deferred() 24 | .fail(function(error) { 25 | error && fm.error(error); 26 | }), 27 | args = []; 28 | 29 | if (!cnt || this._disabled) { 30 | return dfrd.reject(); 31 | } 32 | 33 | $.each(files, function(i, file) { 34 | if (!file.read || !fm.file(file.phash).write) { 35 | return !dfrd.reject(['errCopy', file.name, 'errPerm']); 36 | } 37 | }); 38 | 39 | if( dfrd.state() == 'rejected' ){ 40 | return dfrd; 41 | } 42 | 43 | return fm.request({ 44 | data : {cmd : 'duplicate', targets : this.hashes(hashes)}, 45 | notify : {type : 'copy', cnt : cnt} 46 | }); 47 | 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /finder.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | gpFinder 2.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 34 | 35 | 36 | 37 | 38 |
39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /js/ui/stat.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * @class Finder ui 4 | * Display number of files/selected files and its size in statusbar 5 | * 6 | * @author Dmitry (dio) Levashov 7 | **/ 8 | $.fn.finderstat = function(fm) { 9 | return this.each(function() { 10 | var size = $(this).addClass('finder-stat-size'), 11 | sel = $('
'), 12 | titlesize = fm.i18n('size').toLowerCase(), 13 | titleitems = fm.i18n('items').toLowerCase(), 14 | titlesel = fm.i18n('selected'), 15 | setstat = function(files, cwd) { 16 | var c = 0, 17 | s = 0; 18 | 19 | $.each(files, function(i, file) { 20 | if (!cwd || file.phash == cwd) { 21 | c++; 22 | s += parseInt(file.size)||0; 23 | } 24 | }) 25 | size.html(titleitems+': '+c+', '+titlesize+': '+fm.formatSize(s)); 26 | }; 27 | 28 | fm.getUI('statusbar').prepend(size).append(sel).show(); 29 | 30 | fm 31 | .bind('open reload add remove change searchend', function() { 32 | setstat(fm.files(), fm.cwd().hash) 33 | }) 34 | .search(function(e) { 35 | setstat(e.data.files); 36 | }) 37 | .select(function() { 38 | var s = 0, 39 | c = 0, 40 | files = fm.selectedFiles(); 41 | 42 | if (files.length == 1) { 43 | s = files[0].size; 44 | sel.html(fm.escape(files[0].name)+(s > 0 ? ', '+fm.formatSize(s) : '')); 45 | 46 | return; 47 | } 48 | 49 | $.each(files, function(i, file) { 50 | c++; 51 | s += parseInt(file.size)||0; 52 | }); 53 | 54 | sel.html(c ? titlesel+': '+c+', '+titlesize+': '+fm.formatSize(s) : ' '); 55 | }) 56 | 57 | ; 58 | }) 59 | } -------------------------------------------------------------------------------- /js/commands/archive.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | /** 3 | * @class Finder command "archive" 4 | * Archive selected files 5 | * 6 | * @author Dmitry (dio) Levashov 7 | **/ 8 | Finder.prototype.commands.archive = function() { 9 | var self = this, 10 | fm = self.fm, 11 | mimes = []; 12 | 13 | this.variants = []; 14 | 15 | this.disableOnSearch = true; 16 | 17 | /** 18 | * Update mimes on open/reload 19 | * 20 | * @return void 21 | **/ 22 | fm.bind('open reload', function() { 23 | self.variants = []; 24 | $.each((mimes = fm.option('archivers')['create'] || []), function(i, mime) { 25 | self.variants.push([mime, fm.mime2kind(mime)]) 26 | }); 27 | self.change(); 28 | }); 29 | 30 | this.getstate = function() { 31 | return !this._disabled && mimes.length && fm.selected().length && fm.cwd().write ? 0 : -1; 32 | } 33 | 34 | this.exec = function(hashes, type) { 35 | var files = this.files(hashes), 36 | cnt = files.length, 37 | mime = type || mimes[0], 38 | cwd = fm.cwd(), 39 | error = ['errArchive', 'errPerm'], 40 | dfrd = $.Deferred().fail(function(error) { 41 | error && fm.error(error); 42 | }), 43 | i; 44 | 45 | if (!(this.enabled() && cnt && mimes.length && $.inArray(mime, mimes) !== -1)) { 46 | return dfrd.reject(); 47 | } 48 | 49 | if (!cwd.write) { 50 | return dfrd.reject(error); 51 | } 52 | 53 | for (i = 0; i < cnt; i++) { 54 | if (!files[i].read) { 55 | return dfrd.reject(error); 56 | } 57 | } 58 | 59 | return fm.request({ 60 | data : {cmd : 'archive', targets : this.hashes(hashes), type : mime}, 61 | notify : {type : 'archive', cnt : 1}, 62 | syncOnFail : true 63 | }); 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /js/commands/download.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * @class Finder command "download". 4 | * Download selected files. 5 | * Only for new api 6 | * 7 | * @author Dmitry (dio) Levashov, dio@std42.ru 8 | **/ 9 | Finder.prototype.commands.download = function() { 10 | var self = this, 11 | fm = this.fm, 12 | filter = function(hashes) { 13 | return $.map(self.files(hashes), function(f) { return f.mime == 'directory' ? null : f }); 14 | }; 15 | 16 | this.shortcuts = [{ 17 | pattern : 'shift+enter' 18 | }]; 19 | 20 | this.getstate = function() { 21 | var sel = this.fm.selected(), 22 | cnt = sel.length; 23 | 24 | return !this._disabled && cnt && (!fm.UA.IE || cnt == 1) && cnt == filter(sel).length ? 0 : -1; 25 | } 26 | 27 | this.exec = function(hashes) { 28 | var fm = this.fm, 29 | base = fm.options.url, 30 | files = filter(hashes), 31 | dfrd = $.Deferred(), 32 | iframes = '', 33 | cdata = '', 34 | i, url; 35 | 36 | if (this.disabled()) { 37 | return dfrd.reject(); 38 | } 39 | 40 | $.each(fm.options.customData || {}, function(k, v) { 41 | cdata += '&'+k+'='+v; 42 | }); 43 | 44 | base += base.indexOf('?') === -1 ? '?' : '&'; 45 | 46 | for (i = 0; i < files.length; i++) { 47 | iframes += '