summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--NEWS1
-rw-r--r--NEWS.xml1
-rw-r--r--content/fireflix-panel.xul1
-rw-r--r--content/fireflix.js12
-rw-r--r--content/flickr.js4
5 files changed, 15 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index b44ece1..219a07f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,20 +1,21 @@
10.0.5 () 10.0.5 ()
2 - Added toolbar button 2 - Added toolbar button
3 - Enter or double click on photo in set now opens photo in flickr 3 - Enter or double click on photo in set now opens photo in flickr
4 - Double click on photoset opens photoset in flickr
40.0.4 (November 13th, 2006) 50.0.4 (November 13th, 2006)
5 - Added button to remove linebreaks from generated HTML 6 - Added button to remove linebreaks from generated HTML
6 - Added the word 'sidebar' to the extension name so that you don't have to look hard for it 7 - Added the word 'sidebar' to the extension name so that you don't have to look hard for it
7 - UI polishing, including making it more boring 8 - UI polishing, including making it more boring
8 - code cosmetics 9 - code cosmetics
90.0.3 (November 6th, 2006) 100.0.3 (November 6th, 2006)
10 - Firefox 2.0 compatibility 11 - Firefox 2.0 compatibility
110.0.2 (October 17th, 2006) 120.0.2 (October 17th, 2006)
12 - Added brief help file 13 - Added brief help file
13 - Fixed HTML generation code 14 - Fixed HTML generation code
14 - Fixed a mistyped flickr url so that the 'Flickr' button works now 15 - Fixed a mistyped flickr url so that the 'Flickr' button works now
150.0.1 (October 3rd, 2006) 160.0.1 (October 3rd, 2006)
16 - Added ability to paginate through search results 17 - Added ability to paginate through search results
17 - Fixed packaging bug that omitted packaging license dialog 18 - Fixed packaging bug that omitted packaging license dialog
18 - A lot of code cleanup and UI polishing 19 - A lot of code cleanup and UI polishing
190.0 (September 26th, 2006) 200.0 (September 26th, 2006)
20 - Initial release 21 - Initial release
diff --git a/NEWS.xml b/NEWS.xml
index 79ccf1a..b8f1cf4 100644
--- a/NEWS.xml
+++ b/NEWS.xml
@@ -1,29 +1,30 @@
1<?xml version="1.0" encoding="us-ascii"?> 1<?xml version="1.0" encoding="us-ascii"?>
2<news> 2<news>
3 <version version="0.0.5"> 3 <version version="0.0.5">
4 <ni>Added toolbar button</ni> 4 <ni>Added toolbar button</ni>
5 <ni>Enter or double click on photo in set now opens photo in flickr</ni> 5 <ni>Enter or double click on photo in set now opens photo in flickr</ni>
6 <ni>Double click on photoset opens photoset in flickr</ni>
6 </version> 7 </version>
7 <version version="0.0.4" date="November 13th, 2006"> 8 <version version="0.0.4" date="November 13th, 2006">
8 <ni>Added button to remove linebreaks from generated HTML</ni> 9 <ni>Added button to remove linebreaks from generated HTML</ni>
9 <ni>Added the word 'sidebar' to the extension name so that you don't have to look hard for it</ni> 10 <ni>Added the word 'sidebar' to the extension name so that you don't have to look hard for it</ni>
10 <ni>UI polishing, including making it more boring</ni> 11 <ni>UI polishing, including making it more boring</ni>
11 <ni>code cosmetics</ni> 12 <ni>code cosmetics</ni>
12 </version> 13 </version>
13 <version version="0.0.3" date="November 6th, 2006"> 14 <version version="0.0.3" date="November 6th, 2006">
14 <ni>Firefox 2.0 compatibility</ni> 15 <ni>Firefox 2.0 compatibility</ni>
15 </version> 16 </version>
16 <version version="0.0.2" date="October 17th, 2006"> 17 <version version="0.0.2" date="October 17th, 2006">
17 <ni>Added brief help file</ni> 18 <ni>Added brief help file</ni>
18 <ni>Fixed HTML generation code</ni> 19 <ni>Fixed HTML generation code</ni>
19 <ni>Fixed a mistyped flickr url so that the 'Flickr' button works now</ni> 20 <ni>Fixed a mistyped flickr url so that the 'Flickr' button works now</ni>
20 </version> 21 </version>
21 <version version="0.0.1" date="October 3rd, 2006"> 22 <version version="0.0.1" date="October 3rd, 2006">
22 <ni>Added ability to paginate through search results</ni> 23 <ni>Added ability to paginate through search results</ni>
23 <ni>Fixed packaging bug that omitted packaging license dialog</ni> 24 <ni>Fixed packaging bug that omitted packaging license dialog</ni>
24 <ni>A lot of code cleanup and UI polishing</ni> 25 <ni>A lot of code cleanup and UI polishing</ni>
25 </version> 26 </version>
26 <version version="0.0" date="September 26th, 2006"> 27 <version version="0.0" date="September 26th, 2006">
27 <ni>Initial release</ni> 28 <ni>Initial release</ni>
28 </version> 29 </version>
29</news> 30</news>
diff --git a/content/fireflix-panel.xul b/content/fireflix-panel.xul
index b2ca7dc..af92d22 100644
--- a/content/fireflix-panel.xul
+++ b/content/fireflix-panel.xul
@@ -123,128 +123,129 @@
123 </tabs> 123 </tabs>
124 124
125 <tabpanels flex="1"> 125 <tabpanels flex="1">
126 126
127 <tabpanel id="tabpanel_search" flex="1"> 127 <tabpanel id="tabpanel_search" flex="1">
128 <vbox flex="1"> 128 <vbox flex="1">
129 <groupbox class="search_params" orient="vertical" onkeypress="if(event.keyCode==event.DOM_VK_RETURN) fireflix.foundphotos.search_photos()"> 129 <groupbox class="search_params" orient="vertical" onkeypress="if(event.keyCode==event.DOM_VK_RETURN) fireflix.foundphotos.search_photos()">
130 <hbox> 130 <hbox>
131 <vbox pack="center"> 131 <vbox pack="center">
132 <label control="search_for" value="&panel.search.search_for.label;" accesskey="s"/> 132 <label control="search_for" value="&panel.search.search_for.label;" accesskey="s"/>
133 </vbox> 133 </vbox>
134 <textbox id="search_for" flex="1"/> 134 <textbox id="search_for" flex="1"/>
135 </hbox> 135 </hbox>
136 <hbox> 136 <hbox>
137 <checkbox id="search_tags" label="&panel.search.mode.tagsonly.label;" 137 <checkbox id="search_tags" label="&panel.search.mode.tagsonly.label;"
138 tooltiptext="&panel.search.mode.tagsonly.tip;" checked="false" 138 tooltiptext="&panel.search.mode.tagsonly.tip;" checked="false"
139 accesskey="t" /> 139 accesskey="t" />
140 <checkbox id="search_mine" label="&panel.search.mode.mine.label;" checked="true" accesskey="m"/> 140 <checkbox id="search_mine" label="&panel.search.mode.mine.label;" checked="true" accesskey="m"/>
141 <spacer flex="1"/> 141 <spacer flex="1"/>
142 <button class="lean" command="cmd_search"/> 142 <button class="lean" command="cmd_search"/>
143 </hbox> 143 </hbox>
144 </groupbox> 144 </groupbox>
145 <hbox> 145 <hbox>
146 <button class="lean" command="cmd_search_prev_page"/> 146 <button class="lean" command="cmd_search_prev_page"/>
147 <spacer flex="1"/> 147 <spacer flex="1"/>
148 <label id="search_page" hidden="true"/> 148 <label id="search_page" hidden="true"/>
149 <spacer flex="1"/> 149 <spacer flex="1"/>
150 <button class="lean" command="cmd_search_next_page"/> 150 <button class="lean" command="cmd_search_next_page"/>
151 </hbox> 151 </hbox>
152 <tree id="searchresults" rows="2" flex="1" 152 <tree id="searchresults" rows="2" flex="1"
153 onselect="fireflix.foundphotos.on_select()" 153 onselect="fireflix.foundphotos.on_select()"
154 ondblclick="fireflix.foundphotos.on_cmd_open(event)" 154 ondblclick="fireflix.foundphotos.on_cmd_open(event)"
155 onkeypress="if(event.keyCode==event.DOM_VK_RETURN) fireflix.foundphotos.on_cmd_open(event)"> 155 onkeypress="if(event.keyCode==event.DOM_VK_RETURN) fireflix.foundphotos.on_cmd_open(event)">
156 <treecols> 156 <treecols>
157 <treecol id="sr_title" label="&panel.search.col.title.label;" flex="2" crop="end" align="start" /> 157 <treecol id="sr_title" label="&panel.search.col.title.label;" flex="2" crop="end" align="start" />
158 </treecols> 158 </treecols>
159 <treechildren/> 159 <treechildren/>
160 </tree> 160 </tree>
161 <groupbox id="searchresult_props" orient="horizontal" hidden="true"> 161 <groupbox id="searchresult_props" orient="horizontal" hidden="true">
162 <vbox width="100" pack="center"> 162 <vbox width="100" pack="center">
163 <hbox pack="center"> 163 <hbox pack="center">
164 <image id="search_photo" 164 <image id="search_photo"
165 ondblclick="fireflix.foundphotos.on_cmd_open(event)"/> 165 ondblclick="fireflix.foundphotos.on_cmd_open(event)"/>
166 </hbox> 166 </hbox>
167 </vbox> 167 </vbox>
168 <vbox flex="1"> 168 <vbox flex="1">
169 <label id="searchresult_title" crop="end"/> 169 <label id="searchresult_title" crop="end"/>
170 <hbox flex="1" pack="center"> 170 <hbox flex="1" pack="center">
171 <div flex="1" id="searchresult_description" xmlns="http://www.w3.org/1999/xhtml"/> 171 <div flex="1" id="searchresult_description" xmlns="http://www.w3.org/1999/xhtml"/>
172 </hbox> 172 </hbox>
173 <hbox pack="end"> 173 <hbox pack="end">
174 <button command="cmd_search_open"/> 174 <button command="cmd_search_open"/>
175 </hbox> 175 </hbox>
176 </vbox> 176 </vbox>
177 </groupbox> 177 </groupbox>
178 </vbox> 178 </vbox>
179 </tabpanel> 179 </tabpanel>
180 180
181 <tabpanel id="tabpanel_sets" flex="1" 181 <tabpanel id="tabpanel_sets" flex="1"
182 onkeypress="if(event.keyCode==event.DOM_VK_RETURN) 182 onkeypress="if(event.keyCode==event.DOM_VK_RETURN)
183 document.getElementById('setphotos').focus()"> 183 document.getElementById('setphotos').focus()">
184 <vbox flex="1"> 184 <vbox flex="1">
185 <tree id="setslist" rows="2" onselect="fireflix.photosets.on_select()" 185 <tree id="setslist" rows="2" onselect="fireflix.photosets.on_select()"
186 flex="1" context="sets_menu" 186 flex="1" context="sets_menu"
187 ondblclick="fireflix.photosets.on_cmd_open_in_flickr(event)"
187 > 188 >
188 <treecols> 189 <treecols>
189 <treecol id="sl_name" label="&panel.sets.name.label;" flex="4" crop="end" align="start" tooltiptext="&panel.sets.name.tip;"/> 190 <treecol id="sl_name" label="&panel.sets.name.label;" flex="4" crop="end" align="start" tooltiptext="&panel.sets.name.tip;"/>
190 <splitter class="tree-splitter" /> 191 <splitter class="tree-splitter" />
191 <treecol id="sl_photos" label="&panel.sets.photos.label;" flex="1" align="end" tooltiptext="&panel.sets.photos.tip;" /> 192 <treecol id="sl_photos" label="&panel.sets.photos.label;" flex="1" align="end" tooltiptext="&panel.sets.photos.tip;" />
192 </treecols> 193 </treecols>
193 <treechildren/> 194 <treechildren/>
194 </tree> 195 </tree>
195 <hbox> 196 <hbox>
196 <button command="cmd_refresh_sets" /> 197 <button command="cmd_refresh_sets" />
197 <button command="cmd_set_props" /> 198 <button command="cmd_set_props" />
198 </hbox> 199 </hbox>
199 <tree id="setphotos" rows="2" onselect="fireflix.photoset.on_select()" 200 <tree id="setphotos" rows="2" onselect="fireflix.photoset.on_select()"
200 flex="1" ondblclick="fireflix.photoset.on_cmd_open(event)" 201 flex="1" ondblclick="fireflix.photoset.on_cmd_open(event)"
201 onkeypress="if(event.keyCode==event.DOM_VK_RETURN) fireflix.photoset.on_cmd_open(event)"> 202 onkeypress="if(event.keyCode==event.DOM_VK_RETURN) fireflix.photoset.on_cmd_open(event)">
202 <treecols> 203 <treecols>
203 <treecol id="sp_title" label="&panel.setphotos.title.label;" flex="1" crop="end" align="start" tooltiptext="&panel.setphotos.title.tip;" /> 204 <treecol id="sp_title" label="&panel.setphotos.title.label;" flex="1" crop="end" align="start" tooltiptext="&panel.setphotos.title.tip;" />
204 <splitter class="tree-splitter" /> 205 <splitter class="tree-splitter" />
205 <treecol id="sp_taken" label="&panel.setphotos.taken.label;" crop="end" align="start" tooltiptext="&panel.setphotos.taken.tip;" hidden="true" /> 206 <treecol id="sp_taken" label="&panel.setphotos.taken.label;" crop="end" align="start" tooltiptext="&panel.setphotos.taken.tip;" hidden="true" />
206 <treecol id="sp_upload" label="&panel.setphotos.upload.label;" crop="end" align="start" tooltiptext="&panel.setphotos.upload.tip;" hidden="true" /> 207 <treecol id="sp_upload" label="&panel.setphotos.upload.label;" crop="end" align="start" tooltiptext="&panel.setphotos.upload.tip;" hidden="true" />
207 </treecols> 208 </treecols>
208 <treechildren/> 209 <treechildren/>
209 </tree> 210 </tree>
210 <groupbox id="set_photo_props" orient="horizontal"> 211 <groupbox id="set_photo_props" orient="horizontal">
211 <vbox width="100" pack="center"> 212 <vbox width="100" pack="center">
212 <hbox pack="center"> 213 <hbox pack="center">
213 <image id="set_photo" hidden="true" 214 <image id="set_photo" hidden="true"
214 ondblclick="fireflix.photoset.on_cmd_open(event)" /> 215 ondblclick="fireflix.photoset.on_cmd_open(event)" />
215 </hbox> 216 </hbox>
216 </vbox> 217 </vbox>
217 <spacer flex="1"/> 218 <spacer flex="1"/>
218 </groupbox> 219 </groupbox>
219 </vbox> 220 </vbox>
220 </tabpanel> 221 </tabpanel>
221 222
222 <tabpanel id="tabpanel_tags"> 223 <tabpanel id="tabpanel_tags">
223 <listbox id="tagslist" rows="8" flex="1"> 224 <listbox id="tagslist" rows="8" flex="1">
224 <listhead> 225 <listhead>
225 <listheader label="&panel.tagslist.tag.label;"/> 226 <listheader label="&panel.tagslist.tag.label;"/>
226 </listhead> 227 </listhead>
227 <listcols> 228 <listcols>
228 <listcol flex="1"/> 229 <listcol flex="1"/>
229 </listcols> 230 </listcols>
230 </listbox> 231 </listbox>
231 </tabpanel> 232 </tabpanel>
232 233
233 <tabpanel id="tabpanel_upload"> 234 <tabpanel id="tabpanel_upload">
234 <vbox flex="1"> 235 <vbox flex="1">
235 <tree id="uploadlist" rows="2" flex="1" 236 <tree id="uploadlist" rows="2" flex="1"
236 onselect="fireflix.uploads.selectionChanged()" 237 onselect="fireflix.uploads.selectionChanged()"
237 context="uploads_menu"> 238 context="uploads_menu">
238 <treecols> 239 <treecols>
239 <treecol id="up_file" label="&panel.uploadlist.file.label;" flex="4" crop="start" align="start"/> 240 <treecol id="up_file" label="&panel.uploadlist.file.label;" flex="4" crop="start" align="start"/>
240 <splitter class="tree-splitter" /> 241 <splitter class="tree-splitter" />
241 <treecol id="up_title" label="&panel.uploadlist.title.label;" flex="5" crop="end" align="start" /> 242 <treecol id="up_title" label="&panel.uploadlist.title.label;" flex="5" crop="end" align="start" />
242 <splitter class="tree-splitter" /> 243 <splitter class="tree-splitter" />
243 <treecol id="up_status" label="&panel.uploadlist.status.label;" flex="1" crop="end" align="start" /> 244 <treecol id="up_status" label="&panel.uploadlist.status.label;" flex="1" crop="end" align="start" />
244 </treecols> 245 </treecols>
245 <treechildren/> 246 <treechildren/>
246 </tree> 247 </tree>
247 <progressmeter id="upload_progress" mode="undetermined" hidden="true" /> 248 <progressmeter id="upload_progress" mode="undetermined" hidden="true" />
248 <groupbox id="upload_file_props" orient="horizontal" hidden="true"> 249 <groupbox id="upload_file_props" orient="horizontal" hidden="true">
249 <image id="upload_file_preview" width="100" height="100" /> 250 <image id="upload_file_preview" width="100" height="100" />
250 <grid flex="1"> 251 <grid flex="1">
diff --git a/content/fireflix.js b/content/fireflix.js
index 24894df..48053c5 100644
--- a/content/fireflix.js
+++ b/content/fireflix.js
@@ -103,200 +103,204 @@ var fireflix = {
103 if(c.id=='sp_taken') return p.datetaken; 103 if(c.id=='sp_taken') return p.datetaken;
104 if(c.id=='sp_upload') { 104 if(c.id=='sp_upload') {
105 var du = new Date(p.dateupload*1000); 105 var du = new Date(p.dateupload*1000);
106 var rv = du.getFullYear()+'-'+(du.getMonth()+1)+'-'+du.getDate() 106 var rv = du.getFullYear()+'-'+(du.getMonth()+1)+'-'+du.getDate()
107 +' '+ 107 +' '+
108 du.getHours()+':'+du.getMinutes()+':'+du.getSeconds(); 108 du.getHours()+':'+du.getMinutes()+':'+du.getSeconds();
109 return rv.replace(/(\D)(\d)(\D)/,'$10$2$3'); 109 return rv.replace(/(\D)(\d)(\D)/,'$10$2$3');
110 } 110 }
111 return c.id; 111 return c.id;
112 }, 112 },
113 setTree: function(t) { this.tree = t }, 113 setTree: function(t) { this.tree = t },
114 isContainer: function(r) { return false; }, 114 isContainer: function(r) { return false; },
115 isSeparator: function(r) { return false; }, 115 isSeparator: function(r) { return false; },
116 isSorted: function(r) { return false; }, 116 isSorted: function(r) { return false; },
117 getLevel: function(r) { return 0; }, 117 getLevel: function(r) { return 0; },
118 getImageSrc: function(r,c) { return null }, 118 getImageSrc: function(r,c) { return null },
119 getRowProperties: function(r,p) {}, 119 getRowProperties: function(r,p) {},
120 getCellProperties: function(cid,cel,p) {}, 120 getCellProperties: function(cid,cel,p) {},
121 getColumnProperties: function(cid,cel,p) { }, 121 getColumnProperties: function(cid,cel,p) { },
122 cycleHeader: function(cid,e) { }, 122 cycleHeader: function(cid,e) { },
123 getParentIndex: function(r) { return -1; }, 123 getParentIndex: function(r) { return -1; },
124 drop: function(r,o) { }, 124 drop: function(r,o) { },
125 canDropBeforeAfter: function(r,b) { return false }, 125 canDropBeforeAfter: function(r,b) { return false },
126 126
127 importXPR: function(xp) { 127 importXPR: function(xp) {
128 this.tree.beginUpdateBatch(); 128 this.tree.beginUpdateBatch();
129 this.photos = new Array(); 129 this.photos = new Array();
130 var n; while(n=xp.iterateNext()) { 130 var n; while(n=xp.iterateNext()) {
131 this.photos.push(new Photo(n)); 131 this.photos.push(new Photo(n));
132 } 132 }
133 this.rowCount = this.photos.length; 133 this.rowCount = this.photos.length;
134 this.tree.endUpdateBatch(); 134 this.tree.endUpdateBatch();
135 this.selection.clearSelection(); 135 this.selection.clearSelection();
136 }, 136 },
137 load_photos: function(psid) { 137 load_photos: function(psid) {
138 var _this = this; 138 var _this = this;
139 this.fireflix.flickr.api_call( 139 this.fireflix.flickr.api_call(
140 { 140 {
141 method: 'flickr.photosets.getPhotos', 141 method: 'flickr.photosets.getPhotos',
142 auth_token: 'default', 142 auth_token: 'default',
143 photoset_id: psid, 143 photoset_id: psid,
144 extras: 'license,date_upload,date_taken,owner_name,icon_server,original_format,last_update' 144 extras: 'license,date_upload,date_taken,owner_name,icon_server,original_format,last_update'
145 }, function(xr) { 145 }, function(xr) {
146 var x = xr.responseXML; 146 var x = xr.responseXML;
147 var xp = x.evaluate( 147 var xp = x.evaluate(
148 '/rsp/photoset/photo', x, null, 148 '/rsp/photoset/photo', x, null,
149 XPathResult.ORDERED_NODE_ITERATOR_TYPE, null ); 149 XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );
150 _this.importXPR(xp); 150 _this.importXPR(xp);
151 }, function(x,s,c,m) { 151 }, function(x,s,c,m) {
152 _this.fireflix.flickr_failure(x,s,c,m); 152 _this.fireflix.flickr_failure(x,s,c,m);
153 } 153 }
154 ); 154 );
155 }, 155 },
156 on_select: function() { 156 on_select: function() {
157 if(this.selection.count==1) { 157 if(this.selection.count==1) {
158 var p = this.photos[this.selection.currentIndex]; 158 var p = this.photos[this.selection.currentIndex];
159 this.set_photo.src = 159 this.set_photo.src =
160 this.fireflix.flickr.get_photo_url(p.server,p.id,p.secret,'t'); 160 this.fireflix.flickr.get_photo_url(p.server,p.id,p.secret,'t');
161 this.set_photo.hidden = false; 161 this.set_photo.hidden = false;
162 }else{ 162 }else{
163 this.set_photo.hidden = true; 163 this.set_photo.hidden = true;
164 } 164 }
165 }, 165 },
166 on_cmd_open: function(ev) { 166 on_cmd_open: function(ev) {
167 if(this.selection.currentIndex<0) 167 if(this.selection.currentIndex<0) return;
168 return;
169 var p = this.photos[this.selection.currentIndex]; 168 var p = this.photos[this.selection.currentIndex];
170 if(!p.id) 169 if(!p.id) return;
171 return;
172 this.fireflix.openTab(this.fireflix.flickr.make_photo_url(p,'p')); 170 this.fireflix.openTab(this.fireflix.flickr.make_photo_url(p,'p'));
173 } 171 }
174 }, 172 },
175 173
176 /* photosets treeview */ 174 /* photosets treeview */
177 photosets: { 175 photosets: {
178 sets: new Array(), 176 sets: new Array(),
179 fireflix: null, 177 fireflix: null,
180 init: function(f) { 178 init: function(f) {
181 this.fireflix = f; 179 this.fireflix = f;
182 document.getElementById('setslist').view = this; 180 document.getElementById('setslist').view = this;
183 }, 181 },
184 rowCount: 0, 182 rowCount: 0,
185 getCellText: function(r,c) { 183 getCellText: function(r,c) {
186 var s = this.sets[r]; 184 var s = this.sets[r];
187 if(c.id=='sl_name') return s.title; 185 if(c.id=='sl_name') return s.title;
188 if(c.id=='sl_photos') return s.photos; 186 if(c.id=='sl_photos') return s.photos;
189 return c.id; 187 return c.id;
190 }, 188 },
191 setTree: function(t) { this.tree = t }, 189 setTree: function(t) { this.tree = t },
192 isContainer: function(r) { return false; }, 190 isContainer: function(r) { return false; },
193 isSeparator: function(r) { return false; }, 191 isSeparator: function(r) { return false; },
194 isSorted: function() { return false; }, 192 isSorted: function() { return false; },
195 getLevel: function(r) { return 0; }, 193 getLevel: function(r) { return 0; },
196 getImageSrc: function(r,c) { return null }, 194 getImageSrc: function(r,c) { return null },
197 getRowProperties: function(r,p) {}, 195 getRowProperties: function(r,p) {},
198 getCellProperties: function(cid,cel,p) { }, 196 getCellProperties: function(cid,cel,p) { },
199 getColumnProperties: function(cid,cel,p) { }, 197 getColumnProperties: function(cid,cel,p) { },
200 cycleHeader: function(cid,e) { }, 198 cycleHeader: function(cid,e) { },
201 getParentIndex: function(r) { return -1; }, 199 getParentIndex: function(r) { return -1; },
202 drop: function(r,o) { }, 200 drop: function(r,o) { },
203 canDropBeforeAfter: function(r,b) { return false }, 201 canDropBeforeAfter: function(r,b) { return false },
204 202
205 importXPR: function(xp) { 203 importXPR: function(xp) {
206 this.tree.beginUpdateBatch(); 204 this.tree.beginUpdateBatch();
207 this.sets = new Array(); 205 this.sets = new Array();
208 var n; while(n=xp.iterateNext()) { 206 var n; while(n=xp.iterateNext()) {
209 this.sets.push(new Photoset(n)); 207 this.sets.push(new Photoset(n));
210 } 208 }
211 this.rowCount = this.sets.length; 209 this.rowCount = this.sets.length;
212 this.tree.endUpdateBatch(); 210 this.tree.endUpdateBatch();
213 }, 211 },
214 refresh_sets: function() { 212 refresh_sets: function() {
215 var _this = this; 213 var _this = this;
216 this.fireflix.flickr.api_call( 214 this.fireflix.flickr.api_call(
217 { 215 {
218 method: 'flickr.photosets.getList', 216 method: 'flickr.photosets.getList',
219 auth_token: 'default' 217 auth_token: 'default'
220 }, function(xr) { 218 }, function(xr) {
221 var x = xr.responseXML; 219 var x = xr.responseXML;
222 var xp = x.evaluate( 220 var xp = x.evaluate(
223 '/rsp/photosets/photoset', x, null, 221 '/rsp/photosets/photoset', x, null,
224 XPathResult.ORDERED_NODE_ITERATOR_TYPE, null ); 222 XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );
225 _this.importXPR(xp); 223 _this.importXPR(xp);
226 }, function(x,s,c,m) { 224 }, function(x,s,c,m) {
227 _this.fireflix.flickr_failure(x,s,c,m); 225 _this.fireflix.flickr_failure(x,s,c,m);
228 } 226 }
229 ); 227 );
230 }, 228 },
231 on_select: function() { 229 on_select: function() {
232 if(this.selection.count==1) { 230 if(this.selection.count==1) {
233 this.fireflix.cmd_set_props.setAttribute('disabled','false'); 231 this.fireflix.cmd_set_props.setAttribute('disabled','false');
234 var s = this.sets[this.selection.currentIndex]; 232 var s = this.sets[this.selection.currentIndex];
235 this.fireflix.photoset.load_photos(s.id); 233 this.fireflix.photoset.load_photos(s.id);
236 }else{ 234 }else{
237 this.fireflix.cmd_set_props.setAttribute('disabled','true'); 235 this.fireflix.cmd_set_props.setAttribute('disabled','true');
238 } 236 }
237 },
238 on_cmd_open_in_flickr: function(ev) {
239 if(this.selection.currentIndex<0) return;
240 var p = this.sets[this.selection.currentIndex];
241 if(!p.id) return;
242 this.fireflix.openTab(this.fireflix.flickr.make_photoset_url(p));
239 } 243 }
240 }, 244 },
241 245
242 refresh_user_tags: function() { 246 refresh_user_tags: function() {
243 var lb = document.getElementById('tagslist'); 247 var lb = document.getElementById('tagslist');
244 var _this = this; 248 var _this = this;
245 this.flickr.api_call( 249 this.flickr.api_call(
246 { 250 {
247 method: 'flickr.tags.getListUser', 251 method: 'flickr.tags.getListUser',
248 auth_token: 'default', 252 auth_token: 'default',
249 }, function(xr) { 253 }, function(xr) {
250 var x = xr.responseXML; 254 var x = xr.responseXML;
251 var xp = x.evaluate( 255 var xp = x.evaluate(
252 '/rsp/who/tags/tag', x, null, 256 '/rsp/who/tags/tag', x, null,
253 XPathResult.ORDERED_NODE_ITERATOR_TYPE, null ); 257 XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );
254 // TODO: clear list 258 // TODO: clear list
255 var n; while(n=xp.iterateNext()) { 259 var n; while(n=xp.iterateNext()) {
256 lb.appendItem(n.firstChild.nodeValue); 260 lb.appendItem(n.firstChild.nodeValue);
257 } 261 }
258 }, function(x,s,c,m) { 262 }, function(x,s,c,m) {
259 _this.flickr_failure(x,s,c,m); 263 _this.flickr_failure(x,s,c,m);
260 } 264 }
261 ); 265 );
262 }, 266 },
263 267
264 uploadObserver: { 268 uploadObserver: {
265 fireflix: null, 269 fireflix: null,
266 init: function(f) { 270 init: function(f) {
267 this.fireflix = f; 271 this.fireflix = f;
268 }, 272 },
269 getSupportedFlavours: function() { 273 getSupportedFlavours: function() {
270 var rv = new FlavourSet(); 274 var rv = new FlavourSet();
271 rv.appendFlavour('application/x-moz-file','nsIFile'); 275 rv.appendFlavour('application/x-moz-file','nsIFile');
272 rv.appendFlavour('application/x-moz-url'); 276 rv.appendFlavour('application/x-moz-url');
273 rv.appendFlavour('text/uri-list'); 277 rv.appendFlavour('text/uri-list');
274 rv.appendFlavour('text/unicode'); 278 rv.appendFlavour('text/unicode');
275 return rv; 279 return rv;
276 }, 280 },
277 canHandleMultipleItems: true, 281 canHandleMultipleItems: true,
278 onDragOver: function(ev,fl,sess) { 282 onDragOver: function(ev,fl,sess) {
279 return true; 283 return true;
280 }, 284 },
281 onDrop: function(ev,dd,s) { 285 onDrop: function(ev,dd,s) {
282 var ldf = null; 286 var ldf = null;
283 for(var i in dd.dataList) { 287 for(var i in dd.dataList) {
284 var di = dd.dataList[i]; 288 var di = dd.dataList[i];
285 var dif = di.first; 289 var dif = di.first;
286 if( 290 if(
287 ldf==null 291 ldf==null
288 || ldf.flavour.contentType!=dif.flavour.contentType 292 || ldf.flavour.contentType!=dif.flavour.contentType
289 || ldf.contentLength!=dif.contentLength 293 || ldf.contentLength!=dif.contentLength
290 || ldf.data!=dif.data ) 294 || ldf.data!=dif.data )
291 this.drop_item(ev,di,s); 295 this.drop_item(ev,di,s);
292 ldf = dif; 296 ldf = dif;
293 } 297 }
294 }, 298 },
295 drop_item: function(ev,di,s) { 299 drop_item: function(ev,di,s) {
296 var d = di.first; 300 var d = di.first;
297 switch(d.flavour.contentType) { 301 switch(d.flavour.contentType) {
298 case 'text/unicode': 302 case 'text/unicode':
299 this.drop_urilist(ev,d.data,s); 303 this.drop_urilist(ev,d.data,s);
300 break; 304 break;
301 case 'application/x-moz-file': 305 case 'application/x-moz-file':
302 this.fireflix.uploads.add(d.data.path); 306 this.fireflix.uploads.add(d.data.path);
diff --git a/content/flickr.js b/content/flickr.js
index 75d1a72..b8360c1 100644
--- a/content/flickr.js
+++ b/content/flickr.js
@@ -210,128 +210,132 @@ Flickr.prototype = {
210 this.prefs.clearUserPref(this.prefs_root+'.auth_user.fullname'); 210 this.prefs.clearUserPref(this.prefs_root+'.auth_user.fullname');
211 }, 211 },
212 _reset_token: function() { 212 _reset_token: function() {
213 this.token = null; this.perms = null; this.user = null; 213 this.token = null; this.perms = null; this.user = null;
214 return false; 214 return false;
215 }, 215 },
216 load_token: function() { 216 load_token: function() {
217 try { 217 try {
218 if(this.prefs.getPrefType(this.prefs_root+'.auth_token')!=this.prefs.PREF_STRING) 218 if(this.prefs.getPrefType(this.prefs_root+'.auth_token')!=this.prefs.PREF_STRING)
219 return this._reset_token(); 219 return this._reset_token();
220 this.token = this.prefs.getCharPref(this.prefs_root+'.auth_token'); 220 this.token = this.prefs.getCharPref(this.prefs_root+'.auth_token');
221 if(this.prefs.getPrefType(this.prefs_root+'.auth_perms')!=this.prefs.PREF_STRING) 221 if(this.prefs.getPrefType(this.prefs_root+'.auth_perms')!=this.prefs.PREF_STRING)
222 return this._reset_token(); 222 return this._reset_token();
223 this.perms = this.prefs.getCharPref(this.prefs_root+'.auth_perms'); 223 this.perms = this.prefs.getCharPref(this.prefs_root+'.auth_perms');
224 if(this.prefs.getPrefType(this.prefs_root+'.auth_user.nsid')!=this.prefs.PREF_STRING) 224 if(this.prefs.getPrefType(this.prefs_root+'.auth_user.nsid')!=this.prefs.PREF_STRING)
225 return this._reset_token(); 225 return this._reset_token();
226 this.user = new Object(); 226 this.user = new Object();
227 this.user.nsid = this.prefs.getCharPref(this.prefs_root+'.auth_user.nsid'); 227 this.user.nsid = this.prefs.getCharPref(this.prefs_root+'.auth_user.nsid');
228 if(this.prefs.getPrefType(this.prefs_root+'.auth_user.username')!=this.prefs.PREF_STRING) 228 if(this.prefs.getPrefType(this.prefs_root+'.auth_user.username')!=this.prefs.PREF_STRING)
229 return this._reset_token(); 229 return this._reset_token();
230 this.user.username = this.prefs.getCharPref(this.prefs_root+'.auth_user.username'); 230 this.user.username = this.prefs.getCharPref(this.prefs_root+'.auth_user.username');
231 if(this.prefs.getPrefType(this.prefs_root+'.auth_user.fullname')!=this.prefs.PREF_STRING) 231 if(this.prefs.getPrefType(this.prefs_root+'.auth_user.fullname')!=this.prefs.PREF_STRING)
232 return this._reset_token(); 232 return this._reset_token();
233 this.user.fullname = this.prefs.getCharPref(this.prefs_root+'.auth_user.fullname'); 233 this.user.fullname = this.prefs.getCharPref(this.prefs_root+'.auth_user.fullname');
234 }catch(e) { return this._reset_token(); } 234 }catch(e) { return this._reset_token(); }
235 return true; 235 return true;
236 }, 236 },
237 reset_token: function() { 237 reset_token: function() {
238 this._reset_token(); 238 this._reset_token();
239 this.save_token(); 239 this.save_token();
240 }, 240 },
241 241
242 get_photo_url: function(ser,id,sec,sfx,ext) { 242 get_photo_url: function(ser,id,sec,sfx,ext) {
243 var rv = this.photo_url + ser + '/' + id + '_' + sec; 243 var rv = this.photo_url + ser + '/' + id + '_' + sec;
244 if(sfx && sfx!='_') rv += '_'+sfx; 244 if(sfx && sfx!='_') rv += '_'+sfx;
245 rv += ext?'.'+ext:'.jpg'; 245 rv += ext?'.'+ext:'.jpg';
246 return rv; 246 return rv;
247 }, 247 },
248 get_image_url: function(o,sfx) { 248 get_image_url: function(o,sfx) {
249 return this.get_photo_url( 249 return this.get_photo_url(
250 o.server, 250 o.server,
251 (o instanceof Photoset)? o.primary : o.id, 251 (o instanceof Photoset)? o.primary : o.id,
252 o.secret, 252 o.secret,
253 sfx, 253 sfx,
254 (sfx=='o')?o.originalformat:null 254 (sfx=='o')?o.originalformat:null
255 ); 255 );
256 }, 256 },
257 get_photo_page_url: function(p) { 257 get_photo_page_url: function(p) {
258 if(p instanceof Photo) { 258 if(p instanceof Photo) {
259 // TODO: track photoset and user owner id from there? 259 // TODO: track photoset and user owner id from there?
260 // The approach below is sheerly wrong. 260 // The approach below is sheerly wrong.
261 var o = this.user.nsid; 261 var o = this.user.nsid;
262 if(p.owner && p.owner.nsid) o = p.owner.nsid; 262 if(p.owner && p.owner.nsid) o = p.owner.nsid;
263 var rv = this.photos_url + o +'/' + p.id; 263 var rv = this.photos_url + o +'/' + p.id;
264 return rv; 264 return rv;
265 }else // TODO: take owner into account? 265 }else // TODO: take owner into account?
266 return this.photos_url + this.user.nsid + '/' + p; 266 return this.photos_url + this.user.nsid + '/' + p;
267 }, 267 },
268 make_photo_url: function(p,sfx) { 268 make_photo_url: function(p,sfx) {
269 if(sfx=='p') 269 if(sfx=='p')
270 return this.get_photo_page_url(p); 270 return this.get_photo_page_url(p);
271 else 271 else
272 return this.get_image_url(p,sfx); 272 return this.get_image_url(p,sfx);
273 }, 273 },
274 make_photoset_url: function(ps) {
275 // TODO: allow for using someone else's photoset?
276 return this.photos_url+this.user.nsid+'/sets/'+ps.id;
277 },
274 278
275 upload_file: function(f,fa,on_success,on_failure) { 279 upload_file: function(f,fa,on_success,on_failure) {
276 try { 280 try {
277 var fi = Components.classes["@mozilla.org/file/local;1"] 281 var fi = Components.classes["@mozilla.org/file/local;1"]
278 .createInstance(Components.interfaces.nsILocalFile); 282 .createInstance(Components.interfaces.nsILocalFile);
279 fi.initWithPath( f ); 283 fi.initWithPath( f );
280 var st = Components.classes["@mozilla.org/network/file-input-stream;1"] 284 var st = Components.classes["@mozilla.org/network/file-input-stream;1"]
281 .createInstance(Components.interfaces.nsIFileInputStream); 285 .createInstance(Components.interfaces.nsIFileInputStream);
282 st.init(fi,0x01,00004,null); 286 st.init(fi,0x01,00004,null);
283 var bis = Components.classes["@mozilla.org/binaryinputstream;1"] 287 var bis = Components.classes["@mozilla.org/binaryinputstream;1"]
284 .createInstance(Components.interfaces.nsIBinaryInputStream); 288 .createInstance(Components.interfaces.nsIBinaryInputStream);
285 bis.setInputStream(st); 289 bis.setInputStream(st);
286 290
287 // allocate and initialize temp storage string 291 // allocate and initialize temp storage string
288 var pbs = Components.classes["@mozilla.org/storagestream;1"] 292 var pbs = Components.classes["@mozilla.org/storagestream;1"]
289 .createInstance(Components.interfaces.nsIStorageStream); 293 .createInstance(Components.interfaces.nsIStorageStream);
290 pbs.init(1024,10000000,null); 294 pbs.init(1024,10000000,null);
291 // create output stream 295 // create output stream
292 var pbos = pbs.getOutputStream(0); 296 var pbos = pbs.getOutputStream(0);
293 // and a binaryoutputstream interface 297 // and a binaryoutputstream interface
294 var pbbos = Components.classes["@mozilla.org/binaryoutputstream;1"] 298 var pbbos = Components.classes["@mozilla.org/binaryoutputstream;1"]
295 .createInstance(Components.interfaces.nsIBinaryOutputStream); 299 .createInstance(Components.interfaces.nsIBinaryOutputStream);
296 pbbos.setOutputStream(pbos); 300 pbbos.setOutputStream(pbos);
297 301
298 /* create POST body */ 302 /* create POST body */
299 var boundarytoken = 'kadaroloongazaduviaxamma'; 303 var boundarytoken = 'kadaroloongazaduviaxamma';
300 var boundary = '--'+boundarytoken; 304 var boundary = '--'+boundarytoken;
301 var b = ''; 305 var b = '';
302 306
303 var parms = { api_key: this.api_key, auth_token: this.token }; 307 var parms = { api_key: this.api_key, auth_token: this.token };
304 for(var p in fa) parms[p] = fa[p]; 308 for(var p in fa) parms[p] = fa[p];
305 var pns = new Array(); 309 var pns = new Array();
306 for(var p in parms) pns.push(p); 310 for(var p in parms) pns.push(p);
307 var pstr = ''; 311 var pstr = '';
308 for(var p in pns.sort()) { 312 for(var p in pns.sort()) {
309 var pn = pns[p]; 313 var pn = pns[p];
310 pstr += pn+parms[pn]; 314 pstr += pn+parms[pn];
311 b += boundary+'\nContent-Disposition: form-data; name="'+pn+'"\n\n'+toutf8(parms[pn])+'\n'; 315 b += boundary+'\nContent-Disposition: form-data; name="'+pn+'"\n\n'+toutf8(parms[pn])+'\n';
312 } 316 }
313 b += boundary+'\nContent-Disposition: form-data; name="api_sig"\n\n'+this.api_sig(pstr)+'\n'; 317 b += boundary+'\nContent-Disposition: form-data; name="api_sig"\n\n'+this.api_sig(pstr)+'\n';
314 b += boundary+'\nContent-Disposition: form-data; name="photo"; filename="'+f+'"\nContent-Type: image/jpeg\nContent-Transfer-Encoding: binary\n\n'; 318 b += boundary+'\nContent-Disposition: form-data; name="photo"; filename="'+f+'"\nContent-Type: image/jpeg\nContent-Transfer-Encoding: binary\n\n';
315 pbbos.writeBytes(b,b.length); 319 pbbos.writeBytes(b,b.length);
316 var bisbytes = bis.available(); 320 var bisbytes = bis.available();
317 pbbos.writeBytes(bis.readBytes(bisbytes),bisbytes); 321 pbbos.writeBytes(bis.readBytes(bisbytes),bisbytes);
318 pbbos.writeBytes('\n'+boundary+'--',3+boundary.length); bis.close(); st.close(); 322 pbbos.writeBytes('\n'+boundary+'--',3+boundary.length); bis.close(); st.close();
319 323
320 pbbos.close(); pbos.close(); 324 pbbos.close(); pbos.close();
321 325
322 var x = new XMLHttpRequest(); 326 var x = new XMLHttpRequest();
323 x.open("POST",this.upload_url); 327 x.open("POST",this.upload_url);
324 x.setRequestHeader('Content-Type', 'multipart/form-data; boundary="'+boundarytoken+'"'); 328 x.setRequestHeader('Content-Type', 'multipart/form-data; boundary="'+boundarytoken+'"');
325 x.setRequestHeader('Connection','close'); 329 x.setRequestHeader('Connection','close');
326 x.setRequestHeader('Content-Length',b.length); 330 x.setRequestHeader('Content-Length',b.length);
327 x.onreadystatechange=function() { 331 x.onreadystatechange=function() {
328 if(x.readyState!=4) return false; 332 if(x.readyState!=4) return false;
329 if(x.status==200) { 333 if(x.status==200) {
330 var stat = x.responseXML.firstChild.getAttribute('stat'); 334 var stat = x.responseXML.firstChild.getAttribute('stat');
331 if(stat=='ok') { 335 if(stat=='ok') {
332 var pid = xp_str('/rsp/photoid',x.responseXML); 336 var pid = xp_str('/rsp/photoid',x.responseXML);
333 if(on_success) on_success(x,pid); 337 if(on_success) on_success(x,pid);
334 }else{ 338 }else{
335 var e = x.responseXML.getElementsByTagName('err').item(0); 339 var e = x.responseXML.getElementsByTagName('err').item(0);
336 var ecode = e.getAttribute('code'); 340 var ecode = e.getAttribute('code');
337 var emsg = e.getAttribute('msg'); 341 var emsg = e.getAttribute('msg');