* All App: get text selection in lists working with Alt/Cmd modifier and file drag-out with Shift+Alt/Cmd modifier

r49174: Apply Ctrl+Alt keys in order to be able to distinguish between content selection and dnd for draggable actions
r49176: * All Applications: Get all drag and drop action functionality working cross platform
-Fix drag Out to desktop functionality with Command+Shift keys (for Mac) or Alt+Shift keys (for other platforms)
-Fix content selection functionality with Command key (for Mac only) or Ctrl key (for other platforms)

r49177: text and German translations for drag-n-drop modifier hints
r49178: fix IDE warnings
This commit is contained in:
Ralf Becker 2014-10-24 12:57:16 +00:00
parent 7689e486ea
commit f5783649c1
5 changed files with 238 additions and 117 deletions

View File

@ -2152,6 +2152,35 @@ egwActionObject.prototype.getActionImplementationGroups = function(_test, _group
return _groups; return _groups;
}; };
/**
* Check if user tries to get dragOut action
*
* keys for dragOut:
* -Mac: Command + Shift
* -Others: Alt + Shift
*
* @param {event} _event
* @return {boolean} return true if Alt+Shift keys and left mouse click arre pressed, otherwise false
*/
egwActionObject.prototype.isDragOut = function (_event)
{
return (_event.altKey || _event.metaKey) && _event.shiftKey && _event.which == 1;
};
/**
* Check if user tries to get selection action
*
* Keys for selection:
* -Mac: Command key
* -Others: Ctrl key
*
* @param {type} _event
* @returns {Boolean} return true if left mouse click and Ctrl key are pressed, otherwise false
*/
egwActionObject.prototype.isSelection = function (_event)
{
return !(_event.shiftKey) && _event.which == 1 && (_event.metaKey || _event.ctrlKey);
};
/** egwActionObjectInterface Interface **/ /** egwActionObjectInterface Interface **/

View File

@ -15,6 +15,7 @@
egw_action_popup; egw_action_popup;
jquery.jquery; jquery.jquery;
jquery.jquery-ui; jquery.jquery-ui;
/phpgwapi/js/jquery/jquery-ui-touch-punch/touch.js;
*/ */
/** /**
@ -82,7 +83,7 @@ function egwDragActionImplementation()
ai.helper = null; ai.helper = null;
ai.ddTypes = []; ai.ddTypes = [];
ai.selected = []; ai.selected = [];
// Define default helper DOM // Define default helper DOM
// default helper also can be called later in application code in order to customization // default helper also can be called later in application code in order to customization
ai.defaultDDHelper = function (_selected) ai.defaultDDHelper = function (_selected)
@ -93,13 +94,13 @@ function egwDragActionImplementation()
var moreRow = $j(document.createElement('tr')).addClass('et2_egw_action_ddHelper_moreRow'); var moreRow = $j(document.createElement('tr')).addClass('et2_egw_action_ddHelper_moreRow');
// Main div helper container // Main div helper container
var div = $j(document.createElement("div")).append(table); var div = $j(document.createElement("div")).append(table);
var rows = []; var rows = [];
// Maximum number of rows to show // Maximum number of rows to show
var maxRows = 3; var maxRows = 3;
// item label // item label
var itemLabel = egw.lang(egw.link_get_registry(egw.app_name(),_selected.length > 1?'entries':'entry')||egw.app_name()); var itemLabel = egw.lang(egw.link_get_registry(egw.app_name(),_selected.length > 1?'entries':'entry')||egw.app_name());
var index = 0; var index = 0;
for (var i = 0; i < _selected.length;i++) for (var i = 0; i < _selected.length;i++)
{ {
@ -116,7 +117,7 @@ function egwDragActionImplementation()
var spanCnt = $j(document.createElement('span')) var spanCnt = $j(document.createElement('span'))
.addClass('et2_egw_action_ddHelper_itemsCnt') .addClass('et2_egw_action_ddHelper_itemsCnt')
.appendTo(div); .appendTo(div);
spanCnt.text(_selected.length +' '+ itemLabel); spanCnt.text(_selected.length +' '+ itemLabel);
// Number of not shown rows // Number of not shown rows
var restRows = _selected.length - maxRows; var restRows = _selected.length - maxRows;
@ -128,7 +129,7 @@ function egwDragActionImplementation()
break; break;
} }
} }
var text = $j(document.createElement('div')).addClass('et2_egw_action_ddHelper_tip'); var text = $j(document.createElement('div')).addClass('et2_egw_action_ddHelper_tip');
div.append(text); div.append(text);
@ -136,13 +137,14 @@ function egwDragActionImplementation()
if('draggable' in document.createElement('span') && if('draggable' in document.createElement('span') &&
navigator && navigator.userAgent.indexOf('Chrome') >= 0 && egw.app_name() == 'filemanager') // currently only filemanager supports drag out navigator && navigator.userAgent.indexOf('Chrome') >= 0 && egw.app_name() == 'filemanager') // currently only filemanager supports drag out
{ {
var key = ["Mac68K","MacPPC","MacIntel"].indexOf(window.navigator.platform) < 0 ? 'Ctrl' : 'Command'; var key = ["Mac68K","MacPPC","MacIntel"].indexOf(window.navigator.platform) < 0 ?
text.text(egw.lang('Hold %1 to drag %2 to your computer',key, itemLabel)); egw.lang('Alt') : egw.lang('Command ⌘');
text.text(egw.lang('Hold [%1] and [%2] key to drag %3 to your desktop', key, egw.lang('Shift ⇧'), itemLabel));
} }
// Final html DOM return as helper structor // Final html DOM return as helper structor
return div; return div;
} };
ai.doRegisterAction = function(_aoi, _callback, _context) ai.doRegisterAction = function(_aoi, _callback, _context)
{ {
var node = _aoi.getDOMNode(); var node = _aoi.getDOMNode();
@ -187,78 +189,121 @@ function egwDragActionImplementation()
* This way we can at least toggle which one is operating, so they * This way we can at least toggle which one is operating, so they
* both work alternately if not together. * both work alternately if not together.
*/ */
// Native DnD - Doesn't play nice with jQueryUI Sortable // Native DnD - Doesn't play nice with jQueryUI Sortable
// Tell jQuery to include this property // Tell jQuery to include this property
jQuery.event.props.push('dataTransfer'); jQuery.event.props.push('dataTransfer');
$j(node).off("mousedown") $j(node).off("mousedown")
.on("mousedown", function(event) { .on("mousedown", function(event) {
$j(node).draggable("option","disabled",event.ctrlKey || event.metaKey); var dragOut = _context.isDragOut(event);
$j(this).attr("draggable", event.ctrlKey || event.metaKey ? "true" : ""); $j(this).attr("draggable", dragOut? "true" : "");
$j(node).draggable("option","disabled",dragOut);
// Disabling draggable adds some UI classes, but we don't care so remove them if (dragOut)
$j(node).removeClass("ui-draggable-disabled ui-state-disabled");
if(!(event.ctrlKey || event.metaKey) || !this.addEventListener) return;
})
.on("dragstart", function(event) {
if(event.dataTransfer == null) {
return;
}
event.dataTransfer.effectAllowed="copy";
// Get all selected
// Multiples aren't supported by event.dataTransfer, yet, so
// select only the row they clicked on.
// var selected = _context.getSelectedLinks('drag');
var selected = [_context];
_context.parent.setAllSelected(false);
_context.setSelected(true);
// Set file data
for(var i = 0; i < selected.length; i++)
{
var data = selected[i].data || egw.dataGetUIDdata(selected[i].id).data || {};
if(data && data.mime && data.download_url)
{
var url = data.download_url;
// NEED an absolute URL
if (url[0] == '/') url = egw.link(url);
// egw.link adds the webserver, but that might not be an absolute URL - try again
if (url[0] == '/') url = window.location.origin+url;
// Unfortunately, dragging files is currently only supported by Chrome
if(navigator && navigator.userAgent.indexOf('Chrome'))
{ {
event.dataTransfer.setData("DownloadURL", data.mime+':'+data.name+':'+url); // Disabling draggable adds some UI classes, but we don't care so remove them
$j(node).removeClass("ui-draggable-disabled ui-state-disabled");
} }
else else
{ {
// Include URL as a fallback if (_context.isSelection(event))
event.dataTransfer.setData("text/uri-list", url); {
$j(node).draggable("disable");
// Disabling draggable adds some UI classes, but we don't care so remove them
$j(node).removeClass("ui-draggable-disabled ui-state-disabled");
}
else if(event.which != 3)
{
document.getSelection().removeAllRanges();
}
if(!(dragOut) || !this.addEventListener) return;
}
})
.on ("mouseup", function (event){
if (_context.isSelection(event))
$j(node).draggable("enable");
})
.on("dragstart", function(event) {
if(_context.isSelection(event)) return;
if(event.dataTransfer == null) {
return;
}
event.dataTransfer.effectAllowed="copy";
// Get all selected
// Multiples aren't supported by event.dataTransfer, yet, so
// select only the row they clicked on.
// var selected = _context.getSelectedLinks('drag');
var selected = [_context];
_context.parent.setAllSelected(false);
_context.setSelected(true);
// Set file data
for(var i = 0; i < selected.length; i++)
{
var data = selected[i].data || egw.dataGetUIDdata(selected[i].id).data || {};
if(data && data.mime && data.download_url)
{
var url = data.download_url;
// NEED an absolute URL
if (url[0] == '/') url = egw.link(url);
// egw.link adds the webserver, but that might not be an absolute URL - try again
if (url[0] == '/') url = window.location.origin+url;
// Unfortunately, dragging files is currently only supported by Chrome
if(navigator && navigator.userAgent.indexOf('Chrome'))
{
event.dataTransfer.setData("DownloadURL", data.mime+':'+data.name+':'+url);
}
else
{
// Include URL as a fallback
event.dataTransfer.setData("text/uri-list", url);
}
} }
} }
} if(event.dataTransfer.types.length == 0)
if(event.dataTransfer.types.length == 0) {
{ // No file data? Abort: drag does nothing
// No file data? Abort: drag does nothing event.preventDefault();
event.preventDefault(); return;
return; }
}
// Create drag icon // Create drag icon
_callback.call(_context, _context, ai); _callback.call(_context, _context, ai);
// Drag icon must be visible for setDragImage() - we'll remove it on drag // Drag icon must be visible for setDragImage() - we'll remove it on drag
$j("body").append(ai.helper); $j("body").append(ai.helper);
event.dataTransfer.setDragImage(ai.helper[0],-12,-12); event.dataTransfer.setDragImage(ai.helper[0],-12,-12);
}) })
.on("drag", function(e) { .on("drag", function(e) {
// Remove the helper, it has been copied into the dataTransfer object now // Remove the helper, it has been copied into the dataTransfer object now
// Hopefully user didn't notice it... // Hopefully user didn't notice it...
if(e.dataTransfer != null) if(e.dataTransfer != null)
{ {
ai.helper.remove(); ai.helper.remove();
} }
});
}
else
{
// Use Ctrl key in order to select content
$j(node).off("mousedown")
.on({
mousedown: function(event){
if (_context.isSelection(event)){
$j(node).draggable("disable");
// Disabling draggable adds some UI classes, but we don't care so remove them
$j(node).removeClass("ui-draggable-disabled ui-state-disabled");
}
else if(event.which != 3)
{
document.getSelection().removeAllRanges();
}
},
mouseup: function (){
$j(node).draggable("enable");
}
}); });
} }
$j(node).draggable( $j(node).draggable(
@ -283,7 +328,7 @@ function egwDragActionImplementation()
{ {
// Add a basic class to the helper in order to standardize the background layout // Add a basic class to the helper in order to standardize the background layout
ai.helper.addClass('et2_egw_action_ddHelper'); ai.helper.addClass('et2_egw_action_ddHelper');
// Append the helper object to the body element - this // Append the helper object to the body element - this
// fixes a bug in IE: If the element isn't inserted into // fixes a bug in IE: If the element isn't inserted into
// the DOM-tree jquery appends it to the parent node. // the DOM-tree jquery appends it to the parent node.
@ -307,13 +352,13 @@ function egwDragActionImplementation()
// to distinguish whether the action was intended for dragging or selecting content. // to distinguish whether the action was intended for dragging or selecting content.
var tipTelorance = 10; var tipTelorance = 10;
var helperTop = ai.helper.position().top; var helperTop = ai.helper.position().top;
if (helperTop >= dTarget.offset().top if (helperTop >= dTarget.offset().top
&& helperTop <= (dTarget.height() + dTarget.offset().top) + tipTelorance) && helperTop <= (dTarget.height() + dTarget.offset().top) + tipTelorance)
{ {
var key = ["Mac68K","MacPPC","MacIntel"].indexOf(window.navigator.platform) < 0 ? 'Ctrl' : 'Command'; var key = ["Mac68K","MacPPC","MacIntel"].indexOf(window.navigator.platform) < 0 ?
// Comment this out ATM till we get the ctrl and content selection functionality working egw.lang("Ctrl") : egw.lang("Command ⌘");
//egw.message(egw.lang('Hold %1 key to select content.', key),'info'); egw.message(egw.lang('Hold [%1] key to select text eg. to copy it', key), 'info');
} }
// Invalid target // Invalid target
return true; return true;

View File

@ -16,11 +16,11 @@
*/ */
if (typeof window._egwActionClasses == "undefined") if (typeof window._egwActionClasses == "undefined")
window._egwActionClasses = {} window._egwActionClasses = {};
_egwActionClasses["popup"] = { _egwActionClasses["popup"] = {
"actionConstructor": egwPopupAction, "actionConstructor": egwPopupAction,
"implementation": getPopupImplementation "implementation": getPopupImplementation
} };
function egwPopupAction(_id, _handler, _caption, _icon, _onExecute, _allowOnMultiple) function egwPopupAction(_id, _handler, _caption, _icon, _onExecute, _allowOnMultiple)
{ {
@ -38,34 +38,34 @@ function egwPopupAction(_id, _handler, _caption, _icon, _onExecute, _allowOnMult
action.set_default = function(_value) { action.set_default = function(_value) {
action["default"] = _value; action["default"] = _value;
} };
action.set_order = function(_value) { action.set_order = function(_value) {
action.order = _value; action.order = _value;
} };
action.set_group = function(_value) { action.set_group = function(_value) {
action.group = _value; action.group = _value;
} };
action.set_hint = function(_value) { action.set_hint = function(_value) {
action.hint = _value; action.hint = _value;
} };
// If true, the action will be rendered as checkbox // If true, the action will be rendered as checkbox
action.set_checkbox = function(_value) { action.set_checkbox = function(_value) {
action.checkbox = _value; action.checkbox = _value;
} };
action.set_checked = function(_value) { action.set_checked = function(_value) {
action.checked = _value; action.checked = _value;
} };
// If radioGroup is >0 and the element is a checkbox, radioGroup specifies // If radioGroup is >0 and the element is a checkbox, radioGroup specifies
// the group of radio buttons this one belongs to // the group of radio buttons this one belongs to
action.set_radioGroup = function(_value) { action.set_radioGroup = function(_value) {
action.radioGroup = _value; action.radioGroup = _value;
} };
action.set_shortcut = function(_value) { action.set_shortcut = function(_value) {
if (_value) if (_value)
@ -75,7 +75,7 @@ function egwPopupAction(_id, _handler, _caption, _icon, _onExecute, _allowOnMult
"shift": false, "shift": false,
"ctrl": false, "ctrl": false,
"alt": false "alt": false
} };
if (typeof _value == "object" && typeof _value.keyCode != "undefined" && if (typeof _value == "object" && typeof _value.keyCode != "undefined" &&
typeof _value.caption != "undefined") typeof _value.caption != "undefined")
@ -93,7 +93,7 @@ function egwPopupAction(_id, _handler, _caption, _icon, _onExecute, _allowOnMult
{ {
this.shortcut = false; this.shortcut = false;
} }
} };
return action; return action;
} }
@ -107,7 +107,7 @@ function getPopupImplementation()
{ {
_popupActionImpl = new egwPopupActionImplementation(); _popupActionImpl = new egwPopupActionImplementation();
} }
return _popupActionImpl return _popupActionImpl;
} }
function egwPopupActionImplementation() function egwPopupActionImplementation()
@ -118,8 +118,14 @@ function egwPopupActionImplementation()
/** /**
* Registers the handler for the default action * Registers the handler for the default action
*
* @param {DOMNode} _node
* @param {function} _callback
* @param {object} _context
* @returns {boolean}
*/ */
ai._registerDefault = function(_node, _callback, _context) { ai._registerDefault = function(_node, _callback, _context)
{
var defaultHandler = function(e) { var defaultHandler = function(e) {
if (typeof document.selection != "undefined" && typeof document.selection.empty != "undefined") if (typeof document.selection != "undefined" && typeof document.selection.empty != "undefined")
{ {
@ -134,14 +140,14 @@ function egwPopupActionImplementation()
_callback.call(_context, "default", ai); _callback.call(_context, "default", ai);
return false; return false;
} };
if (egwIsMobile()) { if (egwIsMobile()) {
$j(_node).bind('click', defaultHandler); $j(_node).bind('click', defaultHandler);
} else { } else {
_node.ondblclick = defaultHandler; _node.ondblclick = defaultHandler;
} }
} };
ai._getDefaultLink = function(_links) { ai._getDefaultLink = function(_links) {
var defaultAction = null; var defaultAction = null;
@ -155,7 +161,7 @@ function egwPopupActionImplementation()
} }
return defaultAction; return defaultAction;
} };
ai._searchShortcut = function (_key, _objs, _links) { ai._searchShortcut = function (_key, _objs, _links) {
for (var i = 0; i < _objs.length; i++) for (var i = 0; i < _objs.length; i++)
@ -174,7 +180,7 @@ function egwPopupActionImplementation()
return obj; return obj;
} }
} }
} };
ai._searchShortcutInLinks = function(_key, _links) { ai._searchShortcutInLinks = function(_key, _links) {
var objs = []; var objs = [];
@ -187,10 +193,16 @@ function egwPopupActionImplementation()
} }
return ai._searchShortcut(_key, objs, _links); return ai._searchShortcut(_key, objs, _links);
} };
/** /**
* Handles a key press * Handles a key press
*
* @param {object} _key
* @param {type} _selected
* @param {type} _links
* @param {type} _target
* @returns {Boolean}
*/ */
ai._handleKeyPress = function(_key, _selected, _links, _target) { ai._handleKeyPress = function(_key, _selected, _links, _target) {
// Handle the default // Handle the default
@ -208,7 +220,7 @@ function egwPopupActionImplementation()
{ {
return this.doExecuteImplementation({posx:0,posy:0}, _selected, _links, _target); return this.doExecuteImplementation({posx:0,posy:0}, _selected, _links, _target);
} }
// Check whether the given shortcut exists // Check whether the given shortcut exists
var obj = this._searchShortcutInLinks(_key, _links); var obj = this._searchShortcutInLinks(_key, _links);
@ -219,12 +231,18 @@ function egwPopupActionImplementation()
} }
return false; return false;
} };
/** /**
* Registers the handler for the context menu * Registers the handler for the context menu
*
* @param {DOMNode} _node
* @param {function} _callback
* @param {object} _context
* @returns {boolean}
*/ */
ai._registerContext = function(_node, _callback, _context) { ai._registerContext = function(_node, _callback, _context)
{
var contextHandler = function(e) { var contextHandler = function(e) {
//Obtain the event object //Obtain the event object
if (!e) if (!e)
@ -234,28 +252,28 @@ function egwPopupActionImplementation()
if (_egw_active_menu) if (_egw_active_menu)
{ {
_egw_active_menu.hide() _egw_active_menu.hide();
} }
else if (!e.ctrlKey) else if (!e.ctrlKey && e.which == 3)
{ {
_xy = ai._getPageXY(e); var _xy = ai._getPageXY(e);
_callback.call(_context, _xy, ai); _callback.call(_context, _xy, ai);
} }
e.cancelBubble = !e.ctrlKey; e.cancelBubble = !e.ctrlKey || e.which == 1;
if (e.stopPropagation && !e.ctrlKey) if (e.stopPropagation && e.cancelBubble)
{ {
e.stopPropagation(); e.stopPropagation();
} }
return e.ctrlKey; return !e.cancelBubble;
} };
if (egwIsMobile()) { if (egwIsMobile()) {
$j(_node).bind('taphold', contextHandler); $j(_node).bind('taphold', contextHandler);
} else { } else {
$j(_node).on('contextmenu', contextHandler); $j(_node).on('contextmenu', contextHandler);
} }
} };
ai.doRegisterAction = function(_aoi, _callback, _context) ai.doRegisterAction = function(_aoi, _callback, _context)
{ {
@ -268,15 +286,21 @@ function egwPopupActionImplementation()
return true; return true;
} }
return false; return false;
} };
ai.doUnregisterAction = function(_aoi) ai.doUnregisterAction = function(_aoi)
{ {
// //
} };
/** /**
* Builds the context menu and shows it at the given position/DOM-Node. * Builds the context menu and shows it at the given position/DOM-Node.
*
* @param {object} _context
* @param {type} _selected
* @param {type} _links
* @param {type} _target
* @returns {Boolean}
*/ */
ai.doExecuteImplementation = function(_context, _selected, _links, _target) ai.doExecuteImplementation = function(_context, _selected, _links, _target)
{ {
@ -301,7 +325,7 @@ function egwPopupActionImplementation()
x = $j(node).offset().left; x = $j(node).offset().left;
y = $j(node).offset().top; y = $j(node).offset().top;
_context = {"posx": x, "posy": y} _context = {"posx": x, "posy": y};
} }
var menu = ai._buildMenu(_links, _selected, _target); var menu = ai._buildMenu(_links, _selected, _target);
@ -319,10 +343,14 @@ function egwPopupActionImplementation()
} }
return false; return false;
} };
/** /**
* Groups and sorts the given action tree layer * Groups and sorts the given action tree layer
*
* @param {type} _layer
* @param {type} _links
* @param {type} _parentGroup
*/ */
ai._groupLayers = function(_layer, _links, _parentGroup) ai._groupLayers = function(_layer, _links, _parentGroup)
{ {
@ -407,10 +435,16 @@ function egwPopupActionImplementation()
} }
_parentGroup.groups = groups2; _parentGroup.groups = groups2;
} };
/** /**
* Build the menu layers * Build the menu layers
*
* @param {type} _menu
* @param {type} _groups
* @param {type} _selected
* @param {type} _enabled
* @param {type} _target
*/ */
ai._buildMenuLayer = function(_menu, _groups, _selected, _enabled, _target) ai._buildMenuLayer = function(_menu, _groups, _selected, _enabled, _target)
{ {
@ -487,10 +521,15 @@ function egwPopupActionImplementation()
firstGroup = firstGroup && firstElem; firstGroup = firstGroup && firstElem;
} }
} };
/** /**
* Builds the context menu from the given action links * Builds the context menu from the given action links
*
* @param {type} _links
* @param {type} _selected
* @param {type} _target
* @returns {egwMenu|egwActionImplementation._buildMenu.menu}
*/ */
ai._buildMenu = function(_links, _selected, _target) ai._buildMenu = function(_links, _selected, _target)
{ {
@ -502,7 +541,7 @@ function egwPopupActionImplementation()
_links[k].actionObj.appendToTree(tree); _links[k].actionObj.appendToTree(tree);
} }
// We need the dummy object container in order to pass the array by // We need the dummy object container in order to pass the array by
// reference // reference
var groups = { var groups = {
"groups": [] "groups": []
@ -520,7 +559,7 @@ function egwPopupActionImplementation()
this._buildMenuLayer(menu, groups.groups, _selected, true, _target); this._buildMenuLayer(menu, groups.groups, _selected, true, _target);
return menu; return menu;
} };
ai._getPageXY = function getPageXY(event) ai._getPageXY = function getPageXY(event)
{ {
@ -531,7 +570,7 @@ function egwPopupActionImplementation()
document.documentElement.scrollLeft; document.documentElement.scrollLeft;
return {'posx': (event.clientX + scrollLeft), 'posy': (event.clientY + scrollTop)}; return {'posx': (event.clientX + scrollLeft), 'posy': (event.clientY + scrollTop)};
} };
return ai; return ai;
} }

View File

@ -185,6 +185,7 @@ cocos (keeling) islands common de COCOS INSELN
collection empty. common de Collection ist leer collection empty. common de Collection ist leer
collection listing common de Auflistung der Collection collection listing common de Auflistung der Collection
colombia common de KOLUMBIEN colombia common de KOLUMBIEN
command ⌘ common de Cmd ⌘
common preferences common de Allgemeine Einstellungen common preferences common de Allgemeine Einstellungen
comoros common de KOMOREN comoros common de KOMOREN
company common de Unternehmen company common de Unternehmen
@ -373,6 +374,8 @@ height common de Höhe
help common de Hilfe help common de Hilfe
high common de Hoch high common de Hoch
highest common de Höchste highest common de Höchste
hold [%1] and [%2] key to drag %3 to your desktop common de [%1] und [%2] Tasten halten um %3 auf Ihren Schreibtisch (Desktop) zu ziehen
hold [%1] key to select text eg. to copy it common de [%1] Taste halten um Text zu markieren um ihn z.B. zu kopieren
holy see (vatican city state) common de VATICAN holy see (vatican city state) common de VATICAN
home common de Home home common de Home
home email common de private E-Mail home email common de private E-Mail
@ -730,6 +733,7 @@ setup common de Setup
setup main menu common de Setup Hauptmenü setup main menu common de Setup Hauptmenü
seychelles common de SEYCHELLEN seychelles common de SEYCHELLEN
shift common de Shift shift common de Shift
shift ⇧ common de Umschalten ⇧
show all common de alle anzeigen show all common de alle anzeigen
show all categorys common de Alle Kategorien anzeigen show all categorys common de Alle Kategorien anzeigen
show as topmenu common de Menü oben anzeigen show as topmenu common de Menü oben anzeigen

View File

@ -185,6 +185,7 @@ cocos (keeling) islands common en COCOS (KEELING) ISLANDS
collection empty. common en Collection empty. collection empty. common en Collection empty.
collection listing common en Collection listing collection listing common en Collection listing
colombia common en COLOMBIA colombia common en COLOMBIA
command ⌘ common en Command ⌘
common preferences common en Common preferences common preferences common en Common preferences
comoros common en COMOROS comoros common en COMOROS
company common en Company company common en Company
@ -373,6 +374,8 @@ height common en Height
help common en Help help common en Help
high common en High high common en High
highest common en Highest highest common en Highest
hold [%1] and [%2] key to drag %3 to your desktop common en Hold [%1] and [%2] key to drag %3 to your desktop
hold [%1] key to select text eg. to copy it common en Hold [%1] key to select text eg. to copy it
holy see (vatican city state) common en HOLY SEE (VATICAN CITY STATE) holy see (vatican city state) common en HOLY SEE (VATICAN CITY STATE)
home common en Home home common en Home
home email common en Home email home email common en Home email
@ -730,6 +733,7 @@ setup common en Setup
setup main menu common en Setup main menu setup main menu common en Setup main menu
seychelles common en SEYCHELLES seychelles common en SEYCHELLES
shift common en Shift shift common en Shift
shift ⇧ common en Shift ⇧
show all common en Show all show all common en Show all
show all categorys common en Show all categories show all categorys common en Show all categories
show as topmenu common en Show as top menu show as topmenu common en Show as top menu