2 // Armadillo File Manager
3 // Copyright (c) 2010, Robert Sesek <http://www.bluestatic.org>
5 // This program is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free Software
7 // Foundation, either version 3 of the License, or any later version.
10 goog
.provide('armadillo.PathControl');
12 goog
.require('goog.array');
13 goog
.require('goog.ui.Control');
14 goog
.require('goog.ui.FilteredMenu');
15 goog
.require('goog.ui.LabelInput');
16 goog
.require('goog.ui.MenuButton');
17 goog
.require('goog.ui.MenuItem');
20 * Creates a new path editing control for a given path.
21 * @param {string} path The path to create an editor for
22 * @param {bool} editLastComponent Whether the last component should be shown as an edit box
23 * @param {DomHelper} opt_domHelper Optional DOM helper
26 armadillo
.PathControl
= function(path
, editLastComponent
, opt_domHelper
) {
27 goog
.ui
.Control
.call(this, opt_domHelper
);
30 * Full path of the control.
36 * The name of the file at the |path_|.
43 * Whether or not the last component is editable.
46 this.editableLastComponent_
= editLastComponent
;
49 * Control UI for the name component of the path.
50 * @type {goog.ui.Control}
52 this.nameControl_
= null;
56 * @type {goog.events.EventHandler}
58 this.eh_
= new goog
.events
.EventHandler();
60 goog
.inherits(armadillo
.PathControl
, goog
.ui
.Control
);
66 armadillo
.PathControl
.prototype.disposeInternal
= function() {
67 armadillo
.PathControl
.superClass_
.disposeInternal
.call(this);
68 this.nameControl_
= null;
76 * @param {string} path
78 armadillo
.PathControl
.prototype.setPath
= function(path
) {
79 this.path_
= app
.stripLastPathComponent(path
);
80 this.name_
= path
.substr(this.path_
.length
);
87 armadillo
.PathControl
.prototype.getPath
= function() {
88 return app
.joinPath(this.path_
, this.name_
);
92 * Gets the name control.
93 * @returns {goog.ui.Control}
95 armadillo
.PathControl
.prototype.getNameControl
= function() {
96 return this.nameControl_
;
100 * Creates a new path control object.
102 armadillo
.PathControl
.prototype.createDom
= function() {
103 this.decorateInternal($.createDom('div'));
104 return this.element_
;
108 * Decorates the given element into a path control.
109 * @param {Element} element
111 armadillo
.PathControl
.prototype.decorateInternal
= function(element
) {
112 this.element_
= element
;
113 var components
= this.path_
.split('/');
115 // If this is an item that lives at the root, generate a special node for
116 // moving between items at the top level.
119 // If the last component is emtpy, do not use it because it means a directory
121 if (components
[components
.length
- 1] == '') {
122 goog
.array
.removeAt(components
, components
.length
- 1);
126 $.each(components
, function (i
, part
) {
127 this.element_
.append(this.createComponentNode_(path
, part
), true);
128 path
= app
.joinPath(path
, part
);
131 if (this.editableLastComponent_
) {
132 this.nameControl_
= $.createDom('input');
133 this.nameControl_
.attr({
139 this.nameControl_
.bind('change keydown', this.nameChanged_
.bind(this));
141 this.nameControl_
= $.createDom('span').text(this.name_
);
144 this.element_
.append(this.nameControl_
);
150 armadillo
.PathControl
.prototype.enterDocument
= function() {
151 armadillo
.PathControl
.superClass_
.enterDocument
.call(this);
152 this.nameControl_
.getElement().focus();
156 * Creates a node for a single path component.
157 * @param {string} path The path up to this point.
158 * @param {string} name The current component after |path|.
160 armadillo
.PathControl
.prototype.createComponentNode_
= function(path
, name
) {
161 var menu
= new goog
.ui
.FilteredMenu();
162 menu
.setFilterLabel(name
);
163 menu
.setAllowMultiple(false);
164 menu
.setOpenFollowsHighlight(true);
165 goog
.events
.listen(menu
, goog
.ui
.Component
.EventType
.ACTION
,
166 this.componentChanged_
, false, this);
167 this.fetchMenuContents_(path
, name
, menu
);
169 var button
= new goog
.ui
.MenuButton(name
, menu
, null, this.dom_
);
170 button
.setFocusablePopupMenu(true);
171 button
.setScrollOnOverflow(true);
172 button
.setVisible(true);
177 * Queries the back-end for all the items at a given path and attaches them to
179 * @param {string} path The path to get a list of items in
180 * @param {string} name The name to select
181 * @param {goog.ui.Menu} The menu to attach items to
183 armadillo
.PathControl
.prototype.fetchMenuContents_
= function(path
, name
, menu
) {
184 var callback
= function(e
) {
185 var data
= e
.target
.getResponseJson();
187 app
.showError(data
['message']);
191 // If this is the root path element, make sure the root is accessible for
193 goog
.array
.insertAt(data
, '/', 0);
195 $.each(data
, function (i
, caption
) {
196 // It only makes sense to be able to move into directories.
197 if (!app
.isDirectory(caption
)) {
200 var item
= new goog
.ui
.MenuItem(caption
);
201 item
.setValue(app
.joinPath(path
, name
, caption
));
203 if (caption
== name
) {
204 menu
.setHighlighted(item
);
208 app
.sendRequest('list', {'path' : app
.joinPath(path
, name
)}, callback
);
212 * Handler for changing a component of the control.
215 armadillo
.PathControl
.prototype.componentChanged_
= function(e
) {
216 this.path_
= e
.target
.getValue();
217 this.element_
.clear();
218 this.decorateInternal(this.element_
);
222 * Handler for changing the editable name component.
225 armadillo
.PathControl
.prototype.nameChanged_
= function(e
) {
227 // TODO: assert(this.editableLastComponent_)
228 this.name_
= e
.target
.value
;