/* XOWA: the XOWA Offline Wiki Application Copyright (C) 2012 gnosygnu@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.gfui.ipts; import gplx.*; import gplx.gfui.*; public class IptArg_ { public static final IptArg[] Ary_empty = new IptArg[0]; public static final IptArg Null = null; public static final String Wildcard_key = "wildcard"; public static IptArg Wildcard = new IptKey(Int_.Max_value, Wildcard_key); public static boolean Is_null_or_none(IptArg arg) {return arg == Null || arg == IptKey_.None;} public static IptArg[] Ary(IptArg... v) {return v;} public static IptArg[] parse_ary_or_empty(String v) { IptArg[] rv = IptArg_.parse_ary_(v); int len = rv.length; for (int i = 0; i < len; i++) if (rv[i] == null) return Ary_empty;// indicates failed parse return rv; } public static IptArg[] parse_ary_(String raw) { String[] args = String_.Split(raw, "|"); int args_len = args.length; if (args_len == 0) return Ary_empty; IptArg[] rv = new IptArg[args_len]; for (int i = 0; i < args_len; i++) rv[i] = parse(String_.Trim(args[i])); return rv; } public static IptArg parse_chain_(String raw) {return IptKeyChain.parse(raw);} public static IptArg parse_or_none_(String raw) { try { return String_.Eq(raw, String_.Empty) ? IptKey_.None : parse(raw); } catch (Exception exc) { // as an "or" proc, handle errors; note that it may accept raw values from cfg files, so invalid input is possible; DATE:2014-06-04 Err_.Noop(exc); return IptKey_.None; } } public static IptArg parse(String raw) { if (String_.Has(raw, ",")) return IptKeyChain.parse(raw); String bgn = String_.GetStrBefore(raw, "."); if (String_.Eq(bgn, "wheel")) return IptMouseWheel_.parse(raw); else if (String_.Eq(bgn, "mouse")) return IptMouseBtn_.parse(raw); else if (String_.Eq(bgn, "key")) return IptKey_.parse(raw); else return IptMacro.Instance.parse(raw); } // NOTE: the following two methods should theoretically be interface methods, but since they are only used by two procs, they will be handled with if/else @gplx.Internal protected static IptEventType EventType_default(IptArg arg) { Class type = arg.getClass(); if ( type == IptKey.class || type == IptKeyChain.class) return IptEventType_.KeyDown; else if (type == IptMouseBtn.class) return IptEventType_.MouseUp; // changed from MouseDown; confirmed against Firefox, Eclipse; DATE:2014-05-16 else if (type == IptMouseWheel.class) return IptEventType_.MouseWheel; else if (type == IptMouseMove.class) return IptEventType_.MouseMove; else throw Err_.new_unhandled(type); } @gplx.Internal protected static boolean EventType_match(IptArg arg, IptEventType match) { Class type = arg.getClass(); if ( type == IptKey.class || type == IptKeyChain.class) return match == IptEventType_.KeyDown || match == IptEventType_.KeyUp || match == IptEventType_.KeyDown; else if (type == IptMouseBtn.class) return match == IptEventType_.MouseDown || match == IptEventType_.MouseUp || match == IptEventType_.MousePress; else if (type == IptMouseWheel.class) return match == IptEventType_.MouseWheel; else if (type == IptMouseMove.class) return match == IptEventType_.MouseMove; else throw Err_.new_unhandled(type); } } class IptMacro { public void Reg(String prefix, String alias, IptArg arg) { if (regy == null) Init(); Ordered_hash list = (Ordered_hash)regy.Get_by(prefix); if (list == null) { list = Ordered_hash_.New(); regy.Add(prefix, list); } list.Add_if_dupe_use_nth(alias, arg); } void Init() { regy = Ordered_hash_.New(); Reg("mod", "c", IptKey_.add_(IptKey_.Ctrl)); Reg("mod", "a", IptKey_.add_(IptKey_.Alt)); Reg("mod", "s", IptKey_.add_(IptKey_.Shift)); Reg("mod", "ca", IptKey_.add_(IptKey_.Ctrl, IptKey_.Alt)); Reg("mod", "cs", IptKey_.add_(IptKey_.Ctrl, IptKey_.Shift)); Reg("mod", "as", IptKey_.add_(IptKey_.Alt, IptKey_.Shift)); Reg("mod", "cas", IptKey_.add_(IptKey_.Ctrl, IptKey_.Alt, IptKey_.Shift)); } public IptArg parse(String raw) { if (regy == null) Init(); String[] plusAry = String_.Split(raw, "+"); String[] dotAry = String_.Split(plusAry[0], "."); String bgn = dotAry[0], end = dotAry[1]; Ordered_hash list = (Ordered_hash)regy.Get_by(bgn); if (list == null) throw parse_err(raw, "list not found").Args_add("list", bgn); IptKey rv = (IptKey)list.Get_by(end); if (rv == null) throw parse_err(raw, "arg not found").Args_add("arg", end); for (int i = 1; i < plusAry.length; i++) { rv = rv.Add((IptKey)IptKey_.parse(plusAry[i])); } return rv; } Ordered_hash regy; static Err parse_err(String raw, String loc) {return Err_.new_("gfui", "could not parse IptArg", "raw", raw, "loc", loc).Trace_ignore_add_1_();} public static final IptMacro Instance = new IptMacro(); IptMacro() {} }