aboutsummaryrefslogtreecommitdiffstats
path: root/3rdparty/QtPropertyBrowser/src/qteditorfactory.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/QtPropertyBrowser/src/qteditorfactory.cpp')
0 files changed, 0 insertions, 0 deletions
'#n18'>18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Matt Allen
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package org.sufficientlysecure.keychain.ui.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.Log;

/**
 * Created by Matt Allen
 * 01/07/14
 * http://www.mattallensoftware.co.uk
 * mattallen092@gmail.com
 * <p/>
 * https://github.com/matt-allen/android-password-strength-indicator
 * <p/>
 * <p>
 * This View is designed to indicate how secure a user-entered password is in a visual way to
 * relay to the user if they need to make it stronger. The strength of the password can be set
 * at creation (or after) which will decide whether their password is strong enough.
 * </p>
 * <p/>
 * <p>
 * The password strength is decided by an index of 20. The minimum score needed to pass is 10
 * which means the String has met the conditions imposed by the strength test, but can be improved.
 * If the password scores 10-19 it is considered weak, and only if it scores 20 will it be
 * considered strong.
 * </p>
 */
public class PasswordStrengthView extends View {

    protected int mMinWidth;
    protected int mMinHeight;

    protected Paint mIndicatorPaint;
    protected Paint mGuidePaint;

    protected int mIndicatorHeight;
    protected int mIndicatorWidth;
    protected int mCurrentScore;

    protected int mColorFail;
    protected int mColorWeak;
    protected int mColorStrong;

    protected boolean mShowGuides = true;

    /**
     * Used to define that the indicator should only be looking
     * for a weak password. The bare minimum is used here to let
     * the user continue.
     */
    public static final int STRENGTH_WEAK = 0;

    /**
     * A fairly strict rule for generating a password. It encourages a password that is
     * less easy to crack.
     */
    public static final int STRENGTH_MEDIUM = 1;

    /**
     * A strong algorithm that encourages very strong passwords that should be fairly long, with
     * non-alphanumeric, numbers, and upper case.
     */
    public static final int STRENGTH_STRONG = 2;

    private int mStrengthRequirement = -1;
    protected String mPassword;

    public PasswordStrengthView(Context context, AttributeSet attrs) {
        super(context, attrs);

        int COLOR_FAIL = getResources().getColor(R.color.password_strength_low);
        int COLOR_WEAK = getResources().getColor(R.color.password_strength_medium);
        int COLOR_STRONG = getResources().getColor(R.color.password_strength_high);

        TypedArray style = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.PasswordStrengthView,
                0, 0);

        mStrengthRequirement = style.getInteger(R.styleable.PasswordStrengthView_strength,
                STRENGTH_MEDIUM);
        mShowGuides = style.getBoolean(R.styleable.PasswordStrengthView_showGuides, true);
        mColorFail = style.getColor(R.styleable.PasswordStrengthView_color_fail, COLOR_FAIL);
        mColorWeak = style.getColor(R.styleable.PasswordStrengthView_color_weak, COLOR_WEAK);
        mColorStrong = style.getColor(R.styleable.PasswordStrengthView_color_strong,
                COLOR_STRONG);

        // Create and style the paint used for drawing the guide on the indicator
        mGuidePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mGuidePaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mGuidePaint.setColor(Color.BLACK);
        // Create and style paint for indicator
        mIndicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mIndicatorPaint.setStyle(Paint.Style.FILL);

        style.recycle();

    }

    /**
     * This view can determine if the password entered by the user is acceptable for
     * use by your use case. This is based on the strength requirement you have set.
     *
     * @return True if requirement has been met
     */
    public boolean isStrengthRequirementMet() {
        return (mCurrentScore >= 10);
    }

    /**
     * Change the strength requirement of the password entered by the user. This will also
     * re-check the password already entered against these new requirements.
     *
     * @param requiredStrength Use the public constants of this class to set
     */
    public void setStrengthRequirement(int requiredStrength) {
        if (requiredStrength >= 0 && requiredStrength <= 2) {
            mStrengthRequirement = requiredStrength;
            if (mPassword != null && mPassword.length() > 0) {
                generatePasswordScore();
                // Update view with new score
                invalidate();
                requestLayout();
            }
        } else {
            throw new IndexOutOfBoundsException("Input out of expected range");
        }
    }

    /**
     * Update the password string to check strength of
     *
     * @param passwordString String representation of user-input
     */
    public void setPassword(String passwordString) {
        if (passwordString != null && passwordString.length() > 0) {
            mPassword = passwordString;
            generatePasswordScore();
        } else {
            mPassword = "";
            mCurrentScore = 0;
        }

        // Update view with new score
        invalidate();
        requestLayout();
    }

    /**
     * Private convenience method for adding to the password score
     *
     * @param score Amount to be added to current score
     */
    protected void addToPasswordScore(int score) {
        int newScore = mCurrentScore + score;

        // Limit max score
        if (newScore > 20) {
            mCurrentScore = 20;
        } else {
            mCurrentScore = newScore;
        }
    }

    /**
     * Call this to determine the current strength requirement set on the algorithm
     *
     * @return Int representation of the current strength set for the indicator
     */
    public int getStrengthRequirement() {
        return mStrengthRequirement;
    }

    /**
     * Generate a score based on the password. The password will already need to be stored
     * as a class member before running this.
     */
    protected void generatePasswordScore() {
        mCurrentScore = 0;
        int upperCase = getUppercaseCount(mPassword);
        int nonAlpha = getNonAlphanumericCount(mPassword);
        int numbers = getNumberCount(mPassword);
        switch (mStrengthRequirement) {
            case STRENGTH_WEAK:
                addToPasswordScore(mPassword.length() * 2);
                addToPasswordScore(upperCase * 2);
                addToPasswordScore(nonAlpha * 2);
                addToPasswordScore(numbers * 2);
                break;

            case STRENGTH_MEDIUM:
                addToPasswordScore(mPassword.length());
                addToPasswordScore(upperCase);
                addToPasswordScore(nonAlpha * 2);
                addToPasswordScore(numbers);
                break;

            case STRENGTH_STRONG:
                addToPasswordScore(mPassword.length() / 2);
                // Cut the score in half to make this a very high requirement
                addToPasswordScore(upperCase);
                addToPasswordScore(nonAlpha);
                addToPasswordScore(numbers);
                break;
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldW, int oldH) {
        super.onSizeChanged(w, h, oldW, oldH);
        int paddingX = getPaddingLeft();
        int paddingY = getPaddingTop();
        mIndicatorHeight = h - paddingY;
        mIndicatorWidth = w - paddingX;
    }

    /**
     * The standard parts of the onMeasure needed to create the password strength
     * indicator. Subclasses should call super.onMeasure, but also need to set
     * the minimum height and width in the constructor.
     *
     * @param widthMeasureSpec  The measurement given by the system
     * @param heightMeasureSpec The measurement given by the system
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Set minimum space for the view to do it's thing
        int minW = getPaddingLeft() + getPaddingRight() + mMinWidth;
        int w = resolveSizeAndState(minW, widthMeasureSpec, 1);
        // And give it enough height so it's visible
        int minH = mMinHeight + getPaddingBottom() + getPaddingTop();
        int h = resolveSizeAndState(minH, heightMeasureSpec, 0);
        // Feed these back into UIKit
        setMeasuredDimension(w, h);
    }

    /**
     * Set the colour of the indicator {@code Paint} to one that is appropriate
     * for the strength of the password.
     */
    protected void generateIndicatorColor() {
        int color = mColorFail;
        if (mCurrentScore >= 18) {
            color = mColorStrong;
        } else if (mCurrentScore >= 10) {
            color = mColorWeak;
        }
        mIndicatorPaint.setColor(color);
    }

    /**
     * Quick method to determine how many of the characters in a given string are upper case
     *
     * @param stringToCheck The string to examine
     * @return Number of upper case characters
     */
    protected int getUppercaseCount(String stringToCheck) {
        int score = 0;
        int loops = stringToCheck.length() - 1;
        for (int i = 0; i <= loops; i++) {
            if (Character.isUpperCase(stringToCheck.charAt(i))) {
                score++;
            }
        }
        return score;
    }

    /**
     * A convenience method to determine how many characters in the given String aren't
     * letters or numbers.
     *
     * @param stringToCheck
     * @return Number of characters that aren't numbers or letters
     */
    protected int getNonAlphanumericCount(String stringToCheck) {
        int score = 0;
        int loops = stringToCheck.length() - 1;
        for (int i = 0; i <= loops; i++) {
            if (!Character.isLetter(stringToCheck.charAt(i)) &&
                    !Character.isDigit(stringToCheck.charAt(i))) {
                score++;
            }
        }
        return score;
    }

    /**
     * A convenience method for returning the count of numbers in a given String.
     *
     * @param stringToCheck
     * @return The numbers of digits in the String
     */
    protected int getNumberCount(String stringToCheck) {
        int score = 0;
        int loops = stringToCheck.length() - 1;
        for (int i = 0; i <= loops; i++) {
            if (Character.isDigit(stringToCheck.charAt(i))) {
                score++;
            }
        }
        return score;
    }

    /**
     * Set the guides to show on the view.<br />
     * On the line style, the guides will show underneath<br />
     * On the rounded style, the guides will be shown on the outer edges.<br />
     * The view will be redrawn after the method is called.
     *
     * @param showGuides True if you want the guides to be shown
     */
    public void setShowGuides(boolean showGuides) {
        mShowGuides = showGuides;
        if (mPassword != null && mPassword.length() > 0) {
            generatePasswordScore();
        } else {
            mCurrentScore = 0;
        }

        invalidate();
        requestLayout();
    }

    /**
     * Determine whether the view is showing the guides for the password score
     *
     * @return True if the guides are being shown
     */
    public boolean isShowingGuides() {
        return mShowGuides;
    }
}