Create the TVRenamer class which as of now just parses the name.
[armadillo.git] / web_frontend / actor.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.Actor');
11 goog.provide('armadillo.Actor.TileControlRenderer_');
12
13 goog.require('armadillo.PathControl');
14 goog.require('armadillo.TVRenamer');
15 goog.require('goog.array');
16 goog.require('goog.dom');
17 goog.require('goog.events');
18 goog.require('goog.events.EventHandler');
19 goog.require('goog.style');
20 goog.require('goog.ui.Container');
21 goog.require('goog.ui.Dialog');
22
23 /**
24 * The Actor is a popup that displays the various actions that can be performed
25 * on a given File.
26 * @param {armadillo.File} file The file to act on.
27 * @param {goog.dom.DomHelper} opt_domHelper
28 * @constructor
29 */
30 armadillo.Actor = function(file, opt_domHelper) {
31 goog.ui.Container.call(this, null, null, opt_domHelper);
32
33 /**
34 * The file object on which this acts.
35 * @type {armadillo.File}
36 */
37 this.file_ = file;
38
39 /**
40 * Registrar for all the Actor's events.
41 * @type {goog.events.EventHandler}
42 */
43 this.eh_ = new goog.events.EventHandler();
44
45 /**
46 * The UI element used for a specific action.
47 * @type {goog.Disposable}
48 */
49 this.actionObject_ = null;
50 }
51 goog.inherits(armadillo.Actor, goog.ui.Container);
52
53 /**
54 * The different options that the Actor can perform.
55 */
56 armadillo.Actor.options_ = {
57 OPEN : 'open',
58 MOVE : 'move',
59 RENAME : 'rename',
60 DELETE : 'delete',
61 TV_RENAME : 'tv-rename',
62 };
63
64 /**
65 * String values for the options.
66 */
67 armadillo.Actor.optionStrings_ = {
68 'open' : 'Open',
69 'move' : 'Move',
70 'rename' : 'Rename',
71 'delete' : 'Delete',
72 'tv-rename' : 'Rename TV Episode',
73 };
74
75 /**
76 * Disposer
77 * @protected
78 */
79 armadillo.Actor.prototype.disposeInternal = function() {
80 armadillo.Actor.superClass_.disposeInternal.call(this);
81
82 this.eh_.dispose();
83
84 // Remove the actor display element.
85 goog.dom.removeNode(this.element_);
86 this.element_ = null;
87
88 if (this.actionObject_) {
89 this.actionObject_.dispose();
90 this.actionObject_ = null;
91 }
92
93 this.file_ = null;
94 };
95
96 armadillo.Actor.prototype.createDom = function() {
97 this.setElementInternal(this.dom_.createDom('div'));
98 this.decorate(this.getElement());
99 };
100
101 /**
102 * Decorates the given element into a path control.
103 * @param {Element} element
104 */
105 armadillo.Actor.prototype.decorateInternal = function(element) {
106 this.element_ = element;
107 goog.dom.classes.add(this.element_, 'actor');
108 this.dom_.removeChildren(this.element_);
109 for (var option in armadillo.Actor.options_) {
110 var tile = this.createTile_(option);
111 if (tile) {
112 this.addChild(tile, true);
113 }
114 }
115 };
116
117 /**
118 * Creates the DOM Element that is inserted into the popup.
119 * @param {armadillo.Actor.options_} Key of the option to create
120 * @returns {goog.ui.Control}
121 */
122 armadillo.Actor.prototype.createTile_ = function(option) {
123 var value = armadillo.Actor.options_[option];
124
125 // Create the title element.
126 var title = this.dom_.createDom('span', 'title',
127 armadillo.Actor.optionStrings_[value]);
128
129 var tile = new goog.ui.Control(title, new armadillo.Actor.TileControlRenderer_());
130 tile.actorOption = value;
131
132 // Cannot open non-directory files.
133 if (value == armadillo.Actor.options_.OPEN && !this.file_.isDirectory()) {
134 return null;
135 }
136
137 this.eh_.listen(tile, goog.ui.Component.EventType.ACTION,
138 this.tileClickHandler_, false, this);
139 return tile;
140 };
141
142 /**
143 * Click handler for individual tiles.
144 * @param {Event} e
145 */
146 armadillo.Actor.prototype.tileClickHandler_ = function(e) {
147 var option = e.target.actorOption;
148 if (option == armadillo.Actor.options_.OPEN) {
149 // TODO: assert that this.file_.isDirectory().
150 app.navigate(this.file_.getName());
151 } else if (option == armadillo.Actor.options_.MOVE ||
152 option == armadillo.Actor.options_.RENAME) {
153 this.performMove_();
154 } else if (option == armadillo.Actor.options_.DELETE) {
155 this.performDelete_();
156 } else if (option == armadillo.Actor.options_.TV_RENAME) {
157 this.performTVRename_();
158 }
159 };
160
161 /**
162 * Subroutine to handle bringing up the move confirmation UI.
163 * @private
164 */
165 armadillo.Actor.prototype.performMove_ = function() {
166 this.actionObject_ = this.createActionDialog_();
167 this.actionObject_.setTitle('Move File');
168
169 var editor = new armadillo.PathControl(this.file_.getFullPath(), true);
170 this.actionObject_.addChild(editor, true);
171
172 var closeCallback = function(e) {
173 if (e.key != goog.ui.Dialog.DefaultButtonKeys.CANCEL) {
174 var newPath = editor.getPath();
175 this.file_.move(newPath);
176 }
177 };
178 // Will be removed when the event source closes.
179 this.eh_.listen(this.actionObject_, goog.ui.Dialog.SELECT_EVENT,
180 closeCallback, false, this);
181
182 this.actionObject_.setVisible(true);
183 var position = goog.style.getPosition(this.actionObject_.getElement());
184 goog.style.setPosition(this.actionObject_.getElement(), position.x, '10%');
185 };
186
187 /**
188 * Subroutine to handle bringing up the delete confirmation UI.
189 * @private
190 */
191 armadillo.Actor.prototype.performDelete_ = function() {
192 this.actionObject_ = this.createActionDialog_();
193 this.actionObject_.setTitle('Confirm Delete');
194
195 var container = this.actionObject_.getContentElement();
196 var content = goog.dom.createDom('span', null,
197 'Are you sure you want to delete:',
198 goog.dom.createElement('br'),
199 goog.dom.createDom('strong', null, this.file_.getName()));
200 goog.dom.appendChild(container, content);
201
202 var closeCallback = function(e) {
203 if (e.key != goog.ui.Dialog.DefaultButtonKeys.CANCEL) {
204 this.file_.remove();
205 }
206 };
207 // Will be removed when the event source closes.
208 this.eh_.listen(this.actionObject_, goog.ui.Dialog.SELECT_EVENT,
209 closeCallback, false, this);
210
211 this.actionObject_.setVisible(true);
212 };
213
214 /**
215 * Subroutine that renames a file to it's title based on season and episode.
216 * @private
217 */
218 armadillo.Actor.prototype.performTVRename_ = function() {
219 var renamer = new armadillo.TVRenamer(this.file_);
220 renamer.run();
221 };
222
223 /**
224 * Creates a new instance of a Dialog that has some basic properties set that
225 * are common to performing actions.
226 * @private
227 */
228 armadillo.Actor.prototype.createActionDialog_ = function() {
229 var confirm = new goog.ui.Dialog();
230 confirm.setDisposeOnHide(true);
231 confirm.setEscapeToCancel(true);
232 confirm.setModal(true);
233 confirm.setDraggable(false);
234 confirm.setHasTitleCloseButton(false);
235 return confirm;
236 };
237
238 /**
239 * Tile Control Renderer
240 * @constructor
241 */
242 armadillo.Actor.TileControlRenderer_ = function() {
243 goog.ui.ControlRenderer.call(this);
244 };
245 goog.inherits(armadillo.Actor.TileControlRenderer_, goog.ui.ControlRenderer);
246
247 /**
248 * Returns the control's contents wrapped in a DIV, with the renderer's own
249 * CSS class and additional state-specific classes applied to it.
250 * @param {goog.ui.Control} control Control to render.
251 * @return {Element} Root element for the control.
252 */
253 armadillo.Actor.TileControlRenderer_.prototype.createDom = function(control) {
254 // Create and return DIV wrapping contents.
255 return control.getDomHelper().createDom('div', 'tile', control.getContent());
256 };