www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

relatedbox.xml (9416B)


      1 <?xml version="1.0"?>
      2 <!--
      3     ***** BEGIN LICENSE BLOCK *****
      4     
      5     Copyright © 2009 Center for History and New Media
      6                      George Mason University, Fairfax, Virginia, USA
      7                      http://zotero.org
      8     
      9     This file is part of Zotero.
     10     
     11     Zotero is free software: you can redistribute it and/or modify
     12     it under the terms of the GNU Affero General Public License as published by
     13     the Free Software Foundation, either version 3 of the License, or
     14     (at your option) any later version.
     15     
     16     Zotero is distributed in the hope that it will be useful,
     17     but WITHOUT ANY WARRANTY; without even the implied warranty of
     18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19     GNU Affero General Public License for more details.
     20     
     21     You should have received a copy of the GNU Affero General Public License
     22     along with Zotero.  If not, see <http://www.gnu.org/licenses/>.
     23     
     24     ***** END LICENSE BLOCK *****
     25 -->
     26 
     27 <!DOCTYPE bindings SYSTEM "chrome://zotero/locale/zotero.dtd">
     28 
     29 <bindings 	xmlns="http://www.mozilla.org/xbl"
     30 			xmlns:xbl="http://www.mozilla.org/xbl"
     31 			xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
     32 	<binding id="related-box">
     33 		<implementation>
     34 			<!-- Modes are predefined settings groups for particular tasks -->
     35 			<field name="_mode">"view"</field>
     36 			<property name="mode" onget="return this._mode;">
     37 				<setter>
     38 				<![CDATA[
     39 					this.clickable = false;
     40 					this.editable = false;
     41 					
     42 					switch (val) {
     43 						case 'view':
     44 						case 'merge':
     45 						case 'mergeedit':
     46 							break;
     47 						
     48 						case 'edit':
     49 							this.clickable = true;
     50 							this.editable = true;
     51 							//this.clickHandler = this.showEditor;
     52 							//this.blurHandler = this.hideEditor;
     53 							break;
     54 						
     55 						default:
     56 							throw ("Invalid mode '" + val + "' in relatedbox.xml");
     57 					}
     58 					
     59 					this._mode = val;
     60 					document.getAnonymousNodes(this)[0].setAttribute('mode', val);
     61 				]]>
     62 				</setter>
     63 			</property>
     64 			
     65 			<field name="itemRef"/>
     66 			<property name="item" onget="return this.itemRef;">
     67 				<setter>
     68 					<![CDATA[
     69 						this.itemRef = val;
     70 						this.refresh();
     71 					]]>
     72 				</setter>
     73 			</property>
     74 			<property name="summary">
     75 				<getter>
     76 				<![CDATA[
     77 					var r = "";
     78 					
     79 					if (this.item) {
     80 						var keys = this.item.relatedItems;
     81 						if (keys.length) {
     82 							for (let key of keys) {
     83 								let item = Zotero.Items.getByLibraryAndKey(this.item.libraryID, key);
     84 								if (!item) {
     85 									Zotero.debug(`Related item ${this.item.libraryID}/${key} not found `
     86 										+ `for item ${this.item.libraryKey}`, 2);
     87 									continue;
     88 								}
     89 								r = r + item.getDisplayTitle() + ", ";
     90 							}
     91 							r = r.substr(0,r.length-2);
     92 						}
     93 					}
     94 					
     95 					return r;
     96 				]]>
     97 				</getter>
     98 			</property>
     99 			
    100 			<constructor>
    101 			<![CDATA[
    102 				this._notifierID = Zotero.Notifier.registerObserver(this, ['item'], 'relatedbox');
    103 			]]>
    104 			</constructor>
    105 			
    106 			<destructor>
    107 			<![CDATA[
    108 				Zotero.Notifier.unregisterObserver(this._notifierID);
    109 			]]>
    110 			</destructor>
    111 			
    112 			<!-- TODO: Asyncify -->
    113 			<method name="notify">
    114 				<parameter name="event"/>
    115 				<parameter name="type"/>
    116 				<parameter name="ids"/>
    117 				<parameter name="extraData"/>
    118 				<body><![CDATA[
    119 					if (event != 'modify' || !this.item || !this.item.id) return;
    120 					for (let i = 0; i < ids.length; i++) {
    121 						let id = ids[i];
    122 						if (id != this.item.id) {
    123 							continue;
    124 						}
    125 						this.refresh();
    126 						break;
    127 					}
    128 				]]></body>
    129 			</method>
    130 			
    131 			<method name="refresh">
    132 				<body><![CDATA[
    133 					var addButton = this.id('addButton');
    134 					addButton.hidden = !this.editable;
    135 					
    136 					var rows = this.id('relatedRows');
    137 					while(rows.hasChildNodes())
    138 						rows.removeChild(rows.firstChild);
    139 					
    140 					if (this.item) {
    141 						var relatedKeys = this.item.relatedItems;
    142 						for (var i = 0; i < relatedKeys.length; i++) {
    143 							let key = relatedKeys[i];
    144 							let relatedItem = Zotero.Items.getByLibraryAndKey(
    145 								this.item.libraryID, key
    146 							);
    147 							if (!relatedItem) {
    148 								Zotero.debug(`Related item ${this.item.libraryID}/${key} not found `
    149 									+ `for item ${this.item.libraryKey}`, 2);
    150 								continue;
    151 							}
    152 							let id = relatedItem.id;
    153 							let icon = document.createElement("image");
    154 							icon.className = "zotero-box-icon";
    155 							icon.setAttribute('src', relatedItem.getImageSrc());
    156 					
    157 							var label = document.createElement("label");
    158 							label.className = "zotero-box-label";
    159 							label.setAttribute('value', relatedItem.getDisplayTitle());
    160 							label.setAttribute('crop','end');
    161 							label.setAttribute('flex','1');
    162 							
    163 							var box = document.createElement('box');
    164 							box.setAttribute('onclick',
    165 								"document.getBindingParent(this).showItem(" + id + ")");
    166 							box.setAttribute('class','zotero-clicky');
    167 							box.setAttribute('flex','1');
    168 							box.appendChild(icon);
    169 							box.appendChild(label);
    170 							
    171 							if (this.editable) {
    172 								var remove = document.createElement("label");
    173 								remove.setAttribute('value','-');
    174 								remove.setAttribute('onclick',
    175 									"document.getBindingParent(this).remove(" + id + ");");
    176 								remove.setAttribute('class','zotero-clicky zotero-clicky-minus');
    177 							}
    178 							
    179 							var row = document.createElement("row");
    180 							row.appendChild(box);
    181 							if (this.editable) {
    182 								row.appendChild(remove);
    183 							}
    184 							rows.appendChild(row);
    185 						}
    186 						this.updateCount(rows.childNodes.length);
    187 					}
    188 				]]></body>
    189 			</method>
    190 			<method name="add">
    191 				<body><![CDATA[
    192 					return Zotero.spawn(function* () {
    193 						var io = {dataIn: null, dataOut: null};
    194 						
    195 						window.openDialog('chrome://zotero/content/selectItemsDialog.xul', '',
    196 								'chrome,dialog=no,modal,centerscreen,resizable=yes', io);
    197 						
    198 						if (!io.dataOut || !io.dataOut.length) {
    199 							return;
    200 						}
    201 						var relItems = yield Zotero.Items.getAsync(io.dataOut);
    202 						if (!relItems.length) {
    203 							return;
    204 						}
    205 						
    206 						if (relItems[0].libraryID != this.item.libraryID) {
    207 							// FIXME
    208 							var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
    209 													.getService(Components.interfaces.nsIPromptService);
    210 							ps.alert(null, "", "You cannot relate items in different libraries.");
    211 							return;
    212 						}
    213 						yield Zotero.DB.executeTransaction(function* () {
    214 							for (let relItem of relItems) {
    215 								if (this.item.addRelatedItem(relItem)) {
    216 									yield this.item.save({
    217 										skipDateModifiedUpdate: true
    218 									});
    219 								}
    220 								if (relItem.addRelatedItem(this.item)) {
    221 									yield relItem.save({
    222 										skipDateModifiedUpdate: true
    223 									});
    224 								}
    225 							}
    226 						}.bind(this));
    227 					}, this);
    228 				]]></body>
    229 			</method>
    230 			<method name="remove">
    231 				<parameter name="id"/>
    232 				<body><![CDATA[
    233 					return Zotero.spawn(function* () {
    234 						var item = yield Zotero.Items.getAsync(id);
    235 						if (item) {
    236 							yield Zotero.DB.executeTransaction(function* () {
    237 								if (this.item.removeRelatedItem(item)) {
    238 									yield this.item.save({
    239 										skipDateModifiedUpdate: true
    240 									});
    241 								}
    242 								if (item.removeRelatedItem(this.item)) {
    243 									yield item.save({
    244 										skipDateModifiedUpdate: true
    245 									});
    246 								}
    247 							}.bind(this));
    248 						}
    249 					}, this);
    250 				]]></body>
    251 			</method>
    252 			<method name="showItem">
    253 				<parameter name="id"/>
    254 				<body>
    255 					<![CDATA[
    256 						if(id)
    257 						{
    258 							var p;
    259 							if(window.ZoteroPane_Local)
    260 							{
    261 								p = window.ZoteroPane_Local;
    262 							}
    263 							else
    264 							{
    265 								var win;
    266 														
    267 								if(window.opener && window.opener.ZoteroPane)
    268 								{
    269 									win = window.opener;
    270 								}
    271 								else
    272 								{
    273 									var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
    274 														.getService(Components.interfaces.nsIWindowMediator);
    275 									win = wm.getMostRecentWindow('navigator:browser');
    276 									if(!win)
    277 										return;
    278 								}
    279 								
    280 								p = win.ZoteroPane;
    281 							}
    282 								
    283 							p.selectItem(id);
    284 						}
    285 					]]>
    286 				</body>
    287 			</method>
    288 			<method name="updateCount">
    289 				<parameter name="count"/>
    290 				<body>
    291 					<![CDATA[
    292 						if (count == null) {
    293 							var count = this.item.relatedItems.length;
    294 						}
    295 						
    296 						var str = 'pane.item.related.count.';
    297 						switch (count){
    298 							case 0:
    299 								str += 'zero';
    300 								break;
    301 							case 1:
    302 								str += 'singular';
    303 								break;
    304 							default:
    305 								str += 'plural';
    306 								break;
    307 						}
    308 						this.id('relatedNum').value = Zotero.getString(str, [count]);
    309 					]]>
    310 				</body>
    311 			</method>
    312 			<method name="id">
    313 				<parameter name="id"/>
    314 				<body>
    315 					<![CDATA[
    316 						return document.getAnonymousNodes(this)[0].getElementsByAttribute('id',id)[0];
    317 					]]>
    318 				</body>
    319 			</method>
    320 		</implementation>
    321 		<content>
    322 			<xul:vbox xbl:inherits="flex" class="zotero-box">
    323 				<xul:hbox align="center">
    324 					<xul:label id="relatedNum"/>
    325 					<xul:button id="addButton" label="&zotero.item.add;"
    326 						oncommand="this.parentNode.parentNode.parentNode.add();"/>
    327 				</xul:hbox>
    328 				<xul:grid flex="1">
    329 					<xul:columns>
    330 						<xul:column flex="1"/>
    331 						<xul:column/>
    332 					</xul:columns>
    333 					<xul:rows id="relatedRows"/>
    334 				</xul:grid>
    335 			</xul:vbox>
    336 		</content>
    337 	</binding>
    338 </bindings>