mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-30 19:00:09 +00:00 
			
		
		
		
	more refactoring, fixed a bug in toggleMark event handling and added bookmark indicator to global info...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									a20cda9ed3
								
							
						
					
					
						commit
						2bd9c98011
					
				
							
								
								
									
										100
									
								
								ui/data.js
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								ui/data.js
									
									
									
									
									
								
							| @ -1806,17 +1806,6 @@ function openImageWith(prog){ | |||||||
| * Experimental & utility | * Experimental & utility | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| // The idea here is to add markers as first-class image-like elements...
 |  | ||||||
| //
 |  | ||||||
| // 	+ can be ordered
 |  | ||||||
| // 	- re-sorting via metadata will mess things up
 |  | ||||||
| //
 |  | ||||||
| // XXX this is not persistent...
 |  | ||||||
| function appendMarker(){ |  | ||||||
| 	return $('<div class="marker"/>').insertAfter(getImage()) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // NOTE: if cmp is explicitly false then no sorting will be done.
 | // NOTE: if cmp is explicitly false then no sorting will be done.
 | ||||||
| function loadRibbonsFromPath(path, cmp, reverse, dir_name){ | function loadRibbonsFromPath(path, cmp, reverse, dir_name){ | ||||||
| 	path = path == null ? BASE_URL : path | 	path = path == null ? BASE_URL : path | ||||||
| @ -1838,95 +1827,6 @@ function loadRibbonsFromPath(path, cmp, reverse, dir_name){ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| function readImageDate(gid, images){ |  | ||||||
| 	images = images == null ? IMAGES : images |  | ||||||
| 	var img = images[gid] |  | ||||||
| 	return getEXIFDate(normalizePath(img.path)) |  | ||||||
| 		.done(function(date){ |  | ||||||
| 			img.ctime = Date.fromTimeStamp(date).getTime()/1000 |  | ||||||
| 		}) |  | ||||||
| } |  | ||||||
| function readImagesDates(images){ |  | ||||||
| 	images = images == null ? IMAGES : images |  | ||||||
| 
 |  | ||||||
| 	return $.when.apply(null, $.map(images, function(_, gid){ |  | ||||||
| 		return readImageDate(gid, images) |  | ||||||
| 			.done(function(){ |  | ||||||
| 				IMAGES_UPDATED.push(gid) |  | ||||||
| 			}) |  | ||||||
| 	})) |  | ||||||
| } |  | ||||||
| function readImagesDatesQ(images){ |  | ||||||
| 	images = images == null ? IMAGES : images |  | ||||||
| 
 |  | ||||||
| 	var queue = getWorkerQueue('date_reader') |  | ||||||
| 
 |  | ||||||
| 	$.each(images, function(gid, img){ |  | ||||||
| 		queue.enqueue(readImageDate, gid, images) |  | ||||||
| 			.always(function(){  |  | ||||||
| 				IMAGES_UPDATED.push(gid) |  | ||||||
| 				queue.notify(gid, 'done')  |  | ||||||
| 			}) |  | ||||||
| 	}) |  | ||||||
| 
 |  | ||||||
| 	return queue |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // XXX deleting images is not sported, we need to explicitly re-save...
 |  | ||||||
| // XXX need to reload the viewer...
 |  | ||||||
| // XXX not tested...
 |  | ||||||
| function updateImageGID(gid, images, data){ |  | ||||||
| 	images = images == null ? IMAGES : images |  | ||||||
| 	var img = images[gid] |  | ||||||
| 	return getEXIFGID(normalizePath(img.path)) |  | ||||||
| 		.done(function(gid){ |  | ||||||
| 			img.id = gid |  | ||||||
| 			// images...
 |  | ||||||
| 			images[gid] = images[key] |  | ||||||
| 			delete images[key] |  | ||||||
| 			IMAGES_UPDATED.push(gid) |  | ||||||
| 
 |  | ||||||
| 			// data...
 |  | ||||||
| 			if(data != null){ |  | ||||||
| 				// replace current...
 |  | ||||||
| 				if(data.current == key){ |  | ||||||
| 					data.current = gid |  | ||||||
| 				} |  | ||||||
| 				// replace in order...
 |  | ||||||
| 				data.order[data.order.indexOf(key)] = gid |  | ||||||
| 				// replace in ribbons...
 |  | ||||||
| 				for(var i=0; i < data.ribbons; i++){ |  | ||||||
| 					var r = data.ribbons[i] |  | ||||||
| 					var k = r.indexOf(key) |  | ||||||
| 					if(k >= 0){ |  | ||||||
| 						r[k] = gid |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		}) |  | ||||||
| } |  | ||||||
| function updateImagesGIDs(images, data){ |  | ||||||
| 	images = images == null ? IMAGES : images |  | ||||||
| 
 |  | ||||||
| 	return $.when.apply(null, $.map(images, function(_, key){ |  | ||||||
| 		return updateImageGID(key, images, data) |  | ||||||
| 	})) |  | ||||||
| } |  | ||||||
| function updateImagesGIDsQ(images, data){ |  | ||||||
| 	images = images == null ? IMAGES : images |  | ||||||
| 
 |  | ||||||
| 	var queue = getWorkerQueue('gid_updater') |  | ||||||
| 
 |  | ||||||
| 	$.each(images, function(_, key){ |  | ||||||
| 		queue.enqueue(updateImageGID, key, images, data) |  | ||||||
| 			.always(function(){ queue.notify(key, 'done') }) |  | ||||||
| 	}) |  | ||||||
| 
 |  | ||||||
| 	return queue |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| /********************************************************************** | /********************************************************************** | ||||||
| * vim:set ts=4 sw=4 spell :                                          */ | * vim:set ts=4 sw=4 spell :                                          */ | ||||||
|  | |||||||
							
								
								
									
										166
									
								
								ui/files.js
									
									
									
									
									
								
							
							
						
						
									
										166
									
								
								ui/files.js
									
									
									
									
									
								
							| @ -83,19 +83,6 @@ function bubbleProgress(prefix, from, to, only_progress){ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| function runFileLoaders(prefix, res){ |  | ||||||
| 	return $.when.apply(null, FILE_LOADERS.map(function(load){ |  | ||||||
| 		return bubbleProgress(prefix, load(), res, true) |  | ||||||
| 	})) |  | ||||||
| } |  | ||||||
| // XXX do we need bubbleProgress(..) here???
 |  | ||||||
| function runFileSavers(name){ |  | ||||||
| 	FILE_SAVERS.map(function(save){ |  | ||||||
| 		return save(name) |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // Semi-generic deferred file loader
 | // Semi-generic deferred file loader
 | ||||||
| //
 | //
 | ||||||
| // if pattern is given, then search for the latest (ordered last) file 
 | // if pattern is given, then search for the latest (ordered last) file 
 | ||||||
| @ -234,8 +221,8 @@ function makeFileLoader(title, file_dfl, file_pattern, data_set){ | |||||||
| 		return res | 		return res | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | // XXX make this check for updates -- no need to re-save if nothing 
 | ||||||
| 
 | // 		changed...
 | ||||||
| function makeFileSaver(file_dfl, data_get){ | function makeFileSaver(file_dfl, data_get){ | ||||||
| 	return function(name){ | 	return function(name){ | ||||||
| 		name = name == null  | 		name = name == null  | ||||||
| @ -247,6 +234,19 @@ function makeFileSaver(file_dfl, data_get){ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | function runFileLoaders(prefix, res){ | ||||||
|  | 	return $.when.apply(null, FILE_LOADERS.map(function(load){ | ||||||
|  | 		return bubbleProgress(prefix, load(), res, true) | ||||||
|  | 	})) | ||||||
|  | } | ||||||
|  | // XXX do we need bubbleProgress(..) here???
 | ||||||
|  | function runFileSavers(name){ | ||||||
|  | 	FILE_SAVERS.map(function(save){ | ||||||
|  | 		return save(name) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /*********************************************************************/ | /*********************************************************************/ | ||||||
| 
 | 
 | ||||||
| @ -354,7 +354,7 @@ function loadFileImages(path, no_load_diffs){ | |||||||
| 
 | 
 | ||||||
| // Save current images list to file
 | // Save current images list to file
 | ||||||
| //
 | //
 | ||||||
| // If not name is given this will merge all the diffs and save a "clean"
 | // If no name is given this will merge all the diffs and save a "clean"
 | ||||||
| // (full) images.json file. Also removing the diff files.
 | // (full) images.json file. Also removing the diff files.
 | ||||||
| //
 | //
 | ||||||
| // NOTE: if an explicit name is given then this will not remove anything.
 | // NOTE: if an explicit name is given then this will not remove anything.
 | ||||||
| @ -385,7 +385,7 @@ function saveFileImages(name){ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| // Load images, ribbons and marks from cache
 | // Load images, ribbons and run registered load callbacks...
 | ||||||
| //
 | //
 | ||||||
| // XXX add support for explicit filenames...
 | // XXX add support for explicit filenames...
 | ||||||
| function loadFileState(path, prefix){ | function loadFileState(path, prefix){ | ||||||
| @ -431,14 +431,8 @@ function loadFileState(path, prefix){ | |||||||
| 							//loadFileImages(DATA.image_file != null ?
 | 							//loadFileImages(DATA.image_file != null ?
 | ||||||
| 							//		normalizePath(DATA.image_file, base) 
 | 							//		normalizePath(DATA.image_file, base) 
 | ||||||
| 							//		: null), res, true),
 | 							//		: null), res, true),
 | ||||||
| 						// load marks if available...
 | 						// run registered loaders...
 | ||||||
| 						runFileLoaders(prefix, res)) | 						runFileLoaders(prefix, res)) | ||||||
| 						/* |  | ||||||
| 						bubbleProgress(prefix, |  | ||||||
| 							loadFileMarks(), res, true), |  | ||||||
| 						bubbleProgress(prefix, |  | ||||||
| 							loadFileBookmarks(), res, true)) |  | ||||||
| 						*/ |  | ||||||
| 					.done(function(){ | 					.done(function(){ | ||||||
| 						reloadViewer() | 						reloadViewer() | ||||||
| 						res.resolve() | 						res.resolve() | ||||||
| @ -458,7 +452,7 @@ function loadFileState(path, prefix){ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| // Save, ribbons and marks to cache
 | // Save, ribbons and run registered save callbacks...
 | ||||||
| //
 | //
 | ||||||
| // NOTE: this will NOT save images, that operation must be explicitly 
 | // NOTE: this will NOT save images, that operation must be explicitly 
 | ||||||
| // 		performed by saveFileImages(...)
 | // 		performed by saveFileImages(...)
 | ||||||
| @ -480,8 +474,6 @@ function saveFileState(name, no_normalize_path){ | |||||||
| 	data.current = DATA.current | 	data.current = DATA.current | ||||||
| 
 | 
 | ||||||
| 	dumpJSON(name + '-data.json', data) | 	dumpJSON(name + '-data.json', data) | ||||||
| 	// XXX do we need to do this???
 |  | ||||||
| 	runFileSavers(name) |  | ||||||
| 
 | 
 | ||||||
| 	// save the updated images...
 | 	// save the updated images...
 | ||||||
| 	if(IMAGES_UPDATED.length > 0){ | 	if(IMAGES_UPDATED.length > 0){ | ||||||
| @ -492,6 +484,8 @@ function saveFileState(name, no_normalize_path){ | |||||||
| 		dumpJSON(name + '-images-diff.json', updated) | 		dumpJSON(name + '-images-diff.json', updated) | ||||||
| 		IMAGES_UPDATED = [] | 		IMAGES_UPDATED = [] | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	runFileSavers(name) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -536,10 +530,13 @@ function loadRawDir(path, no_preview_processing, prefix){ | |||||||
| 	reloadViewer() | 	reloadViewer() | ||||||
| 
 | 
 | ||||||
| 	// read orientation form files...
 | 	// read orientation form files...
 | ||||||
| 	res.notify(prefix, 'Loading', 'Images orientation.') | 	res.notify(prefix, 'Loading', 'Images metadata.') | ||||||
| 	var o = updateImagesOrientationQ() | 	var o = $.when( | ||||||
|  | 			readImagesOrientationQ(), | ||||||
|  | 			readImagesDatesQ() | ||||||
|  | 		) | ||||||
| 		.done(function(){ | 		.done(function(){ | ||||||
| 			res.notify(prefix, 'Loaded', 'Images orientation.') | 			res.notify(prefix, 'Loaded', 'Images metadata.') | ||||||
| 		}) | 		}) | ||||||
| 
 | 
 | ||||||
| 	// load/generate previews...
 | 	// load/generate previews...
 | ||||||
| @ -728,12 +725,14 @@ function exportImagesTo(path, im_name, dir_name, size){ | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /*********************************************************************/ | /********************************************************************** | ||||||
|  | * Metadata readers... | ||||||
|  | */ | ||||||
| 
 | 
 | ||||||
| // NOTE: this will overwrite current image orientation...
 | // NOTE: this will overwrite current image orientation...
 | ||||||
| //
 | //
 | ||||||
| // XXX this depends on getImageOrientation(...)
 | // XXX this depends on getImageOrientation(...)
 | ||||||
| function updateImageOrientation(gid, no_update_loaded){ | function readImageOrientation(gid, no_update_loaded){ | ||||||
| 	gid = gid == null ? getImageGID() : gid | 	gid = gid == null ? getImageGID() : gid | ||||||
| 	var img = IMAGES[gid] | 	var img = IMAGES[gid] | ||||||
| 
 | 
 | ||||||
| @ -764,23 +763,19 @@ function updateImageOrientation(gid, no_update_loaded){ | |||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
| } | } | ||||||
| 
 | function readImagesOrientation(gids, no_update_loaded){ | ||||||
| 
 |  | ||||||
| function updateImagesOrientation(gids, no_update_loaded){ |  | ||||||
| 	gids = gids == null ? getClosestGIDs() : gids | 	gids = gids == null ? getClosestGIDs() : gids | ||||||
| 	var res = [] | 	var res = [] | ||||||
| 
 | 
 | ||||||
| 	$.each(gids, function(_, gid){ | 	$.each(gids, function(_, gid){ | ||||||
| 		res.push(updateImageOrientation(gid, no_update_loaded)) | 		res.push(readImageOrientation(gid, no_update_loaded)) | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	return $.when.apply(null, res) | 	return $.when.apply(null, res) | ||||||
| } | } | ||||||
| 
 | // queued version of readImagesOrientation(...)
 | ||||||
| 
 |  | ||||||
| // queued version of updateImagesOrientation(...)
 |  | ||||||
| //
 | //
 | ||||||
| function updateImagesOrientationQ(gids, no_update_loaded){ | function readImagesOrientationQ(gids, no_update_loaded){ | ||||||
| 	gids = gids == null ? getClosestGIDs() : gids | 	gids = gids == null ? getClosestGIDs() : gids | ||||||
| 
 | 
 | ||||||
| 	var queue = getWorkerQueue('image_orientation_reader') | 	var queue = getWorkerQueue('image_orientation_reader') | ||||||
| @ -789,7 +784,7 @@ function updateImagesOrientationQ(gids, no_update_loaded){ | |||||||
| 
 | 
 | ||||||
| 	// attach workers to queue...
 | 	// attach workers to queue...
 | ||||||
| 	$.each(gids, function(_, gid){ | 	$.each(gids, function(_, gid){ | ||||||
| 		last = queue.enqueue(updateImageOrientation, gid, no_update_loaded) | 		last = queue.enqueue(readImageOrientation, gid, no_update_loaded) | ||||||
| 			.done(function(){ queue.notify(gid, 'done') }) | 			.done(function(){ queue.notify(gid, 'done') }) | ||||||
| 			.fail(function(){ queue.notify(gid, 'fail') }) | 			.fail(function(){ queue.notify(gid, 'fail') }) | ||||||
| 	}) | 	}) | ||||||
| @ -798,6 +793,95 @@ function updateImagesOrientationQ(gids, no_update_loaded){ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | function readImageDate(gid, images){ | ||||||
|  | 	images = images == null ? IMAGES : images | ||||||
|  | 	var img = images[gid] | ||||||
|  | 	return getEXIFDate(normalizePath(img.path)) | ||||||
|  | 		.done(function(date){ | ||||||
|  | 			img.ctime = Date.fromTimeStamp(date).getTime()/1000 | ||||||
|  | 		}) | ||||||
|  | } | ||||||
|  | function readImagesDates(images){ | ||||||
|  | 	images = images == null ? IMAGES : images | ||||||
|  | 
 | ||||||
|  | 	return $.when.apply(null, $.map(images, function(_, gid){ | ||||||
|  | 		return readImageDate(gid, images) | ||||||
|  | 			.done(function(){ | ||||||
|  | 				IMAGES_UPDATED.push(gid) | ||||||
|  | 			}) | ||||||
|  | 	})) | ||||||
|  | } | ||||||
|  | function readImagesDatesQ(images){ | ||||||
|  | 	images = images == null ? IMAGES : images | ||||||
|  | 
 | ||||||
|  | 	var queue = getWorkerQueue('date_reader') | ||||||
|  | 
 | ||||||
|  | 	$.each(images, function(gid, img){ | ||||||
|  | 		queue.enqueue(readImageDate, gid, images) | ||||||
|  | 			.always(function(){  | ||||||
|  | 				IMAGES_UPDATED.push(gid) | ||||||
|  | 				queue.notify(gid, 'done')  | ||||||
|  | 			}) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	return queue | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // XXX deleting images is not sported, we need to explicitly re-save...
 | ||||||
|  | // XXX need to reload the viewer...
 | ||||||
|  | // XXX not tested...
 | ||||||
|  | function updateImageGID(gid, images, data){ | ||||||
|  | 	images = images == null ? IMAGES : images | ||||||
|  | 	var img = images[gid] | ||||||
|  | 	return getEXIFGID(normalizePath(img.path)) | ||||||
|  | 		.done(function(gid){ | ||||||
|  | 			img.id = gid | ||||||
|  | 			// images...
 | ||||||
|  | 			images[gid] = images[key] | ||||||
|  | 			delete images[key] | ||||||
|  | 			IMAGES_UPDATED.push(gid) | ||||||
|  | 
 | ||||||
|  | 			// data...
 | ||||||
|  | 			if(data != null){ | ||||||
|  | 				// replace current...
 | ||||||
|  | 				if(data.current == key){ | ||||||
|  | 					data.current = gid | ||||||
|  | 				} | ||||||
|  | 				// replace in order...
 | ||||||
|  | 				data.order[data.order.indexOf(key)] = gid | ||||||
|  | 				// replace in ribbons...
 | ||||||
|  | 				for(var i=0; i < data.ribbons; i++){ | ||||||
|  | 					var r = data.ribbons[i] | ||||||
|  | 					var k = r.indexOf(key) | ||||||
|  | 					if(k >= 0){ | ||||||
|  | 						r[k] = gid | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | } | ||||||
|  | function updateImagesGIDs(images, data){ | ||||||
|  | 	images = images == null ? IMAGES : images | ||||||
|  | 
 | ||||||
|  | 	return $.when.apply(null, $.map(images, function(_, key){ | ||||||
|  | 		return updateImageGID(key, images, data) | ||||||
|  | 	})) | ||||||
|  | } | ||||||
|  | function updateImagesGIDsQ(images, data){ | ||||||
|  | 	images = images == null ? IMAGES : images | ||||||
|  | 
 | ||||||
|  | 	var queue = getWorkerQueue('gid_updater') | ||||||
|  | 
 | ||||||
|  | 	$.each(images, function(_, key){ | ||||||
|  | 		queue.enqueue(updateImageGID, key, images, data) | ||||||
|  | 			.always(function(){ queue.notify(key, 'done') }) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	return queue | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /********************************************************************** | /********************************************************************** | ||||||
| * vim:set ts=4 sw=4 :                                                */ | * vim:set ts=4 sw=4 :                                                */ | ||||||
|  | |||||||
| @ -32,6 +32,10 @@ function updateGlobalImageInfo(image){ | |||||||
| 
 | 
 | ||||||
| 	var meta = [] | 	var meta = [] | ||||||
| 
 | 
 | ||||||
|  | 	image.hasClass('bookmarked') ? meta.push( | ||||||
|  | 			'<span class="shown">B</span>'+ | ||||||
|  | 			'<span class="hidden"><b>B</b>ookmarked</span>') : '' | ||||||
|  | 
 | ||||||
| 	image.hasClass('marked') ? meta.push( | 	image.hasClass('marked') ? meta.push( | ||||||
| 			'<span class="shown">M</span>'+ | 			'<span class="shown">M</span>'+ | ||||||
| 			'<span class="hidden"><b>M</b>arked</span>') : '' | 			'<span class="hidden"><b>M</b>arked</span>') : '' | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								ui/setup.js
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								ui/setup.js
									
									
									
									
									
								
							| @ -348,15 +348,6 @@ function setupDataBindings(viewer){ | |||||||
| 					flashRibbonIndicator() | 					flashRibbonIndicator() | ||||||
| 				} | 				} | ||||||
| 			}) | 			}) | ||||||
| 		.on([ |  | ||||||
| 				'focusingImage', |  | ||||||
| 				'togglingMark' |  | ||||||
| 			].join(' '), |  | ||||||
| 			function(evt, image){ |  | ||||||
| 				image = $(image) |  | ||||||
| 				updateGlobalImageInfo(image) |  | ||||||
| 				updateContextIndicators(image) |  | ||||||
| 			}) |  | ||||||
| 		.on([ | 		.on([ | ||||||
| 				'rotatingLeft', | 				'rotatingLeft', | ||||||
| 				'rotateingRight', | 				'rotateingRight', | ||||||
| @ -367,6 +358,8 @@ function setupDataBindings(viewer){ | |||||||
| 				updateGlobalImageInfo($(image)) | 				updateGlobalImageInfo($(image)) | ||||||
| 			}) | 			}) | ||||||
| 		.on([ | 		.on([ | ||||||
|  | 				'focusingImage', | ||||||
|  | 				'togglingMark', | ||||||
| 				'removeingAllMarks', | 				'removeingAllMarks', | ||||||
| 				'removeingRibbonMarks', | 				'removeingRibbonMarks', | ||||||
| 				'markingAll', | 				'markingAll', | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user