Make the TVRenamer preserve file extensions.
[armadillo.git] / web_frontend / file.js
1 //
2 // Armadillo File Manager
3 // Copyright (c) 2010, Robert Sesek <http://www.bluestatic.org>
4 //
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.
8 //
9
10 goog.provide('armadillo.File');
11
12 goog.require('armadillo.Actor');
13 goog.require('goog.Disposable');
14 goog.require('goog.dom');
15 goog.require('goog.ui.AnimatedZippy');
16
17 /**
18 * A file in a directory listing.
19 * @param {string} File name.
20 * @param {string} The path the file resides at.
21 * @constructor
22 */
23 armadillo.File = function(name, path) {
24 goog.Disposable.call(this);
25 this.name_ = name;
26 this.path_ = path;
27 this.highlight_ = '';
28 this.isDirectory_ = app.isDirectory(name);
29 this.actor_ = new armadillo.Actor(this);
30 this.zippy_ = null;
31 };
32 goog.inherits(armadillo.File, goog.Disposable);
33
34 armadillo.File.Highlight = {
35 NONE : '',
36 SELECTED : 'file-selected',
37 ACTIVE : 'file-active'
38 };
39
40 /**
41 * Disposer
42 * @protected
43 */
44 armadillo.File.prototype.disposeInternal = function() {
45 armadillo.File.superClass_.disposeInternal.call(this);
46 this.element_ = null;
47 this.link_ = null;
48 goog.events.unlistenByKey(this.linkListener_);
49 goog.events.unlistenByKey(this.actorListener_);
50 this.actor_.dispose();
51 if (this.zippy_)
52 this.zippy_.dispose();
53 };
54
55 /**
56 * Returns the name of the file.
57 * @returns string
58 */
59 armadillo.File.prototype.getName = function() {
60 return this.name_;
61 };
62
63 /**
64 * Returns the path the file without the name. This is equivalent to calling
65 * dirname on the absolute path.
66 * @returns string
67 */
68 armadillo.File.prototype.getParentPath = function() {
69 return this.path_;
70 };
71
72 /**
73 * Gets the fully qualified path of the file, from the root of the jail to the
74 * name of the file.
75 * @returns string
76 */
77 armadillo.File.prototype.getFullPath = function() {
78 return this.path_ + this.name_;
79 };
80
81 /**
82 * Returns whether or not this is a directory.
83 * @returns boolean
84 */
85 armadillo.File.prototype.isDirectory = function() {
86 return this.isDirectory_;
87 };
88
89 /**
90 * Returns the extension of the file, or an empty string if theh file is a
91 * directory or does not have an extension.
92 * @returns string
93 */
94 armadillo.File.prototype.getExtension = function() {
95 if (this.isDirectory())
96 return '';
97 var index = this.getName().lastIndexOf('.');
98 if (index == -1)
99 return '';
100 return this.getName().substring(index);
101 };
102
103 /**
104 * Sets the highlight state.
105 */
106 armadillo.File.prototype.setHighlight = function(h) {
107 /*
108 // TODO: enable.
109 goog.dom.classes.addRemove(this.element_, this.highlight_, h);
110 this.highlight_ = h;
111 */
112 };
113
114 /**
115 * Constructs the Elements that make up the UI.
116 * @returns {Element} An element ready for insertion into DOM.
117 */
118 armadillo.File.prototype.draw = function() {
119 // Create the element if it does not exist. If it does, remove all children.
120 if (!this.element_) {
121 this.element_ = goog.dom.createElement('li');
122 this.element_.representedObject = this;
123 var handler = (this.isSpecial_() ? this.clickHandler_ : this.actorHandler_);
124 }
125 goog.dom.removeChildren(this.element_);
126
127 // Set the name of the entry.
128 this.title_ = goog.dom.createDom('div', null);
129 if (this.isDirectory()) {
130 this.link_ = goog.dom.createDom('a', null, this.name_);
131 this.linkListener_ = goog.events.listen(this.link_,
132 goog.events.EventType.CLICK, this.clickHandler_, false, this);
133 goog.dom.appendChild(this.title_, this.link_);
134 } else {
135 goog.dom.setTextContent(this.title_, this.name_);
136 }
137 goog.dom.appendChild(this.element_, this.title_);
138 this.actorListener_ = goog.events.listen(this.title_,
139 goog.events.EventType.CLICK, handler, false, this);
140
141 return this.element_;
142 };
143
144 /**
145 * Deletes the given file in the backend by sending a request. On return, it
146 * will re-query the directory.
147 */
148 armadillo.File.prototype.remove = function() {
149 var file = this;
150 var callback = function(data) {
151 if (data['error']) {
152 app.showError(data['message']);
153 return;
154 } else {
155 app.clearError();
156 }
157 app.list(file.path_);
158 };
159 app.sendRequest('remove', {'path':this.path_ + this.name_}, callback);
160 };
161
162 /**
163 * Moves a file from one absolute path to another. On success, it will navigate
164 * to the new path.
165 * @param {string} dest The destination path.
166 */
167 armadillo.File.prototype.move = function(dest) {
168 var file = this;
169 var callback = function(data) {
170 if (data['error']) {
171 app.showError(data['message']);
172 } else {
173 app.clearError();
174 app.list(app.stripLastPathComponent(dest));
175 }
176 };
177 app.sendRequest('move', {'source':this.getFullPath(), 'target':dest}, callback);
178 };
179
180 /**
181 * Click handler for the link element; only for directories.
182 * @param {Event} e
183 */
184 armadillo.File.prototype.clickHandler_ = function(e) {
185 if (this.isDirectory_) {
186 app.navigate(this.name_);
187 }
188 e.stopPropagation();
189 };
190
191 /**
192 * Click handler for the row, which brings up the Actor interface.
193 * @param {Event} e
194 */
195 armadillo.File.prototype.actorHandler_ = function(e) {
196 e.stopPropagation();
197 if (!this.actor_.isInDocument())
198 this.actor_.render(this.element_);
199 if (!this.zippy_) {
200 this.zippy_ = new goog.ui.AnimatedZippy(this.title_,
201 this.actor_.getElement(), false);
202 this.zippy_.toggle();
203 }
204 };
205
206 /**
207 * Returns TRUE if this File is not a real file, but a special kind.
208 * @returns boolean
209 */
210 armadillo.File.prototype.isSpecial_ = function() {
211 return this.name_ == '../';
212 };