Package passkeep.control

Source Code of passkeep.control.MainController

/*
* Copyright (c) 2005 Elondra S.L. All Rights Reserved.
*/
package passkeep.control;
/* -----------------------------------------------------------------------------
    AppTemplate, an application for building defect management built with BaseMovil
    Copyright (C) 2004-2008 Elondra S.L.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.
    If not, see <a href="http://www.gnu.org/licenses">http://www.gnu.org/licenses</a>.
----------------------------------------------------------------------------- */

import bm.mvc.BaseController;
import bm.core.*;
import bm.core.event.Event;
import bm.core.event.EventListener;
import bm.core.event.ProgressEvent;
import bm.core.fs.FSException;
import bm.core.io.SerializationException;
import bm.core.log.Log;
import bm.core.log.LogFactory;
import bm.core.math.FixedPoint;
import bm.core.mvc.ControllerEvent;
import bm.core.mvc.HelpView;
import bm.core.mvc.View;
import bm.core.tools.DeviceInfo;
import bm.db.*;
import bm.err.ErrorLog;
import bm.mvc.*;
import bm.net.NetException;
import bm.net.rpc.RemoteCall;
import bm.net.rpc.RemoteCallException;
import bm.storage.InvalidRecordIDException;
import bm.storage.RSException;
import bm.storage.RecordStoreFullException;
import bm.storage.Store;
import bm.ui.ProgressView;
import bm.ui.Ui;
import bm.util.Util;
import passkeep.AppState;
import passkeep.Model;

import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Gauge;
import javax.microedition.rms.RecordStoreException;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;

/*
* File Information
*
* Created on       : 27-jul-2005 12:03:31
* Created by       : narciso
* Last modified by : $Author: narciso $
* Last modified on : $Date: 2005/11/30 10:21:30 $
* Revision         : $Revision: 1.9 $
*/

/**
* Controller for general view.
*
* @author <a href="mailto:narciso@elondra.com">Narciso Cerezo</a>
* @version $Revision: 1.9 $
*/
public class MainController
        extends BaseController
        implements EventListener
{
    private static Log log = LogFactory.getLog( "MainController" );

    public static final int VIEW_ID_MAIN                        = 1;
    public static final int VIEW_ID_LANGUAGE                    = 2;
    public static final int VIEW_ID_BROWSE_CATEGORIES           = 3;
    public static final int VIEW_ID_EDIT_CATEGORY               = 4;
    public static final int VIEW_ID_SEARCH_ENTRIES              = 5;
    public static final int VIEW_ID_BROWSE_ENTRIES              = 6;
    public static final int VIEW_ID_EDIT_ENTRY                  = 7;
    public static final int VIEW_ID_TOOLS                       = 15;
    public static final int VIEW_ID_PREFERENCES                 = 16;
    public static final int VIEW_ID_FONTSIZE                    = 18;
    public static final int VIEW_ID_DIAGNOSIS                   = 19;

    private static final int MAINM_CATEGORIES                    = 100;
    private static final int MAINM_SEARCH_ENTRIES                = 101;
    private static final int MAINM_ABOUT                         = 105;

    public static final int TOOLSMENU_DELETE_DATA       = 204;

    public static final int DIAGMENU_INFO                   = 101;
    public static final int DIAGMENU_CHEK_MEM               = 102;
    public static final int DIAGMENU_DEVICE_INFO            = 106;
    public static final int DIAGMENU_FORCE_DEVICE_INFO      = 107;
    public static final int DIAGMENU_VIEW_LOG               = 109;

    private static final int ACTION_FTS_SMALL   = 201;
    private static final int ACTION_FTS_MEDIUM  = 202;
    private static final int ACTION_FTS_LARGE   = 203;

    private static final int ACTION_CATB_NEW_CAT    = 1;
    private static final int ACTION_CATB_DEL_CAT    = 2;
    private static final int ACTION_CATB_EDIT_CAT   = 3;
    private static final int ACTION_CATB_NEW_KEY    = 4;

    private static final int ACTION_ENTB_NEW_ENT    = 1;
    private static final int ACTION_ENTB_DEL_ENT    = 2;


    private static final int LANG_ES                             = 201;
    private static final int LANG_EN                             = 202;

    // Cache for custom view
    private static Hashtable        views       = new Hashtable( 40 );
    // List of view that should not have a back action
    private static Vector           noBack      = new Vector( 3 );
    // List of view taht should have an exit option
    private static Vector           exitPoints  = new Vector( 3 );
    // Event for triggering when creating a new instance of a custom view
//    private static ProgressEvent    waitEvent;

    private EventListener           progressListener        = new ProgressView();

    // -------------------------------------------------------------------------
    // Public methods
    // -------------------------------------------------------------------------

    /**
     * Get access to the application database.
     *
     * @return the application database
     * @throws DBException on database errors
     * @throws RecordStoreFullException if no space left
     * @throws RSException on storage errors
     * @throws SerializationException on object serialization errors
     */
    protected Database getDatabase()
            throws DBException,
                   RecordStoreFullException,
                   RSException,
                   SerializationException
    {
        return Model.getDatabase();
    }

    /**
     * Handle language change events.
     * @param event the event
     */
    public void handleEvent( Event event )
    {
        switch( event.getType().intValue() )
        {
            case Event.ET_LANGUAGE_CHANGE:
                // Create a new progress view when the language changes, so it
                // gets built with the appropriate resources
                progressListener = new ProgressView();
                break;

            case 1000: // ViewFactory.EVENT_VIEW_CREATED:
                final View view = (View) event.getAttachment( "view" );
                addView( (String) event.getAttachment( "viewName" ), view, false );
                if( view instanceof DataboundView )
                {
                    ((DataboundView) view).setResolver(
                            DefaultFieldResolver.getInstance()
                    );
                }
                break;
        }
    }

    /**
     * Release views.
     *
     * @param view view released
     */
    public void onRelease( final View view )
    {
        view.detachAll();
    }

    // <Application Startup> ---------------------------------------------------
    /**
     * Start application.
     */
    public void startApplication()
    {
        // Local variable to improve speed on CDC
        final Log log = MainController.log;
        bm.core.ErrorHandler.setHandler( new ErrorHandler() );
        Event.register( this, Event.LANGUAGE_CHANGE );
        ProgressEvent pe = new ProgressEvent( this, new Integer( 4 ), 0 );
        pe.setTitle( ResourceManager.getResource( "main.StartApplication" ) );
        pe.dispatch();
        try
        {
            init();
            pe.increment();
            pe.dispatch();

            log.debug( "Starting application" );
            if( !checkConfig() )
            {
                exitApplication();
                return;
            }
            setup();
            pe.increment();
            pe.dispatch();

            if( LoginManager.getEncryptedPassword() == null )
            {
                createPin();
            }
            else
            {
                promptPin();
            }

            View nextView = startDatabase();
            checkDatabaseSanity();
            pe.increment();
            pe.dispatch();
            final Database database = Model.getDatabase();
            DefaultFieldResolver.setDatabase( database );
            if( nextView == null )
            {
                nextView = restoreLastView();
            }
            if( nextView == null )
            {
                nextView = ViewFactory.getMenu( "mainMenu" );
            }
            Event.unregisterAll( Event.PROGRESS );
            Event.register( progressListener, Event.PROGRESS );
            nextView.show();
        }
        catch( RuntimeException e )
        {
            e.printStackTrace();
            log.error( e );
            Application.getManager().showError(
                    ResourceManager.getResource( "error.cantStartApp" ),
                    e
            );
            exitApplication();
        }
        catch( Throwable e )
        {
            e.printStackTrace();
            log.error( e );
            Application.getManager().showError(
                    ResourceManager.getResource( "error.cantStartApp" ) +
                    ": " + e.toString()
            );
            exitApplication();
        }
    }

    private void promptPin()
            throws DBException
    {
        final String pin = Application.getManager().promptPassword(
                ResourceManager.getResource( "pin.AskPin" )
        );
        if( pin == null ||
            pin.trim().length() == 0 ||
            !LoginManager.checkOfflinePassword( pin )
                )
        {
            Application.getManager().showError(
                    ResourceManager.getResource( "pin.WrongPin" )
            );
            exitApplication();
        }
        else
        {
            AppState.setPassword( pin );
        }
    }

    private void createPin()
            throws DBException
    {
        boolean done = false;
        while( !done )
        {
            final String pin = Application.getManager().promptPassword(
                    ResourceManager.getResource( "pin.CreatePin" )
            );
            if( pin == null || pin.trim().length() == 0 )
            {
                Application.getManager().showError(
                        ResourceManager.getResource( "pin.CantBeEmpty" )
                );
                continue;
            }
            final String pin2 = Application.getManager().promptPassword(
                    ResourceManager.getResource( "pin.ConfirmPin" )
            );
            if( pin2 == null || pin2.trim().length() == 0 || !pin.equals( pin2 ) )
            {
                Application.getManager().showError(
                        ResourceManager.getResource( "pin.DoNotMatch" )
                );
            }
            else
            {
                LoginManager.storeEncryptedPassword( pin );
                AppState.setPassword( pin );
                done = true;
            }
        }
    }

    private View restoreLastView()
    {
        try
        {
            // ToDo: if there's something to restore do it here and return the view that should be shown next
            return null;
        }
        catch( Exception e )
        {
            log.error( e );
            return null;
        }
    }

    /**
     * Basic setup needed by anything else.
     *
     * @throws IOException on errors
     * @throws DBException on errors
     */
    private void init()
            throws IOException,
                   DBException
    {
        final String locale = Settings.getProperty( Model.CONFIG_ACTIVE_LOCALE );
        if( locale != null )
        {
            ResourceManager.setActiveLocale( locale );
        }
        DefaultFieldResolver.registerDefinition( "/app.resolver" );
        Event.register( this, ViewFactory.EVENT_VIEW_CREATED );
//        waitEvent = new ProgressEvent();
//        waitEvent.setAnimate( true );
//        final String waitMessage = ResourceManager.getResource( "global.Wait" );
//        waitEvent.setMessage( "" );
//        waitEvent.setPhase( waitMessage );
//        waitEvent.setTitle( waitMessage );

        // ToDo: add the id's of the views that should have an exit command
        exitPoints.addElement( new Integer( MainController.VIEW_ID_MAIN ) );

        // ToDo: add the id's of the views that shouldn't have a back action
//        noBack.addElement( new Integer( VIEW_ID ) );
    }

    /**
     * Check that the needed configuration values are set.
     * @return true if so
     */
    private boolean checkConfig()
    {
        // ToDo: check for any configuration setting that must be present
//        if( Application.getManager().getProperty( "server.url" ) == null )
//        {
//            Application.getManager().showError(
//                    ResourceManager.getResource(
//                            "error.missconfigured"
//                    )
//            );
//            return false;
//        }
        return true;
    }

    /**
     * Perform the extended setup
     * @throws DBException on errors
     */
    private void setup()
            throws DBException
    {
        Application.getManager().setMainView( ViewFactory.getMenu( "mainMenu" ) );
        // The server.url property is the default for remote calls if defined
        final String serverURL =
                Application.getManager().getProperty( "server.url" );
        if( serverURL != null )
        {
            RemoteCall.setDefaultURL( serverURL );
        }
        //#ifdef bluetooth
        if( Util.hasBluetoothAPI() )
        {
            ViewFactory.setFlag( "bluetooth" );
        }
        //#endif
        //#ifdef cldc11
        ViewFactory.setFlag( "cldc11" );
        //#endif
    }

    /**
     * Start the database.
     * @return the next view, that will be login if no database or main view if downloaded
     * @throws SerializationException on errors
     * @throws IOException on errors
     * @throws NetException on errors
     * @throws RemoteCallException on errors
     * @throws RSException on errors
     * @throws RecordStoreFullException on errors
     * @throws DBException on errors
     */
    private View startDatabase()
            throws SerializationException,
                   IOException,
                   NetException,
                   RemoteCallException,
                   RSException,
                   RecordStoreFullException,
                   DBException
    {
        final Database database = Model.getDatabase();
        database.start();
        return ViewFactory.getMenu( "mainMenu" );
    }

    /**
     * Entry point for all events.
     *
     * @param event event
     * @throws SerializationException on errors
     * @throws NetException on errors
     * @throws RecordStoreFullException on errors
     * @throws DBException on errors
     * @throws RSException on errors
     * @throws RemoteCallException on errors
     * @throws Exception on errors
     * @noinspection DuplicateThrows
     */
    protected void continueProcess( final ControllerEvent event )
            throws SerializationException,
                   NetException,
                   RecordStoreFullException,
                   DBException,
                   RSException,
                   RemoteCallException,
                   Exception
    {
        switch( event.getSource().getId() )
        {
            case VIEW_ID_MAIN:
                processMainView( event );
                break;

            case VIEW_ID_BROWSE_CATEGORIES:
                processBrowseCategories( event );
                break;

            case VIEW_ID_EDIT_CATEGORY:
                processEditCategory( event );
                break;

            case VIEW_ID_SEARCH_ENTRIES:
                processSearchEntries( event );
                break;

            case VIEW_ID_BROWSE_ENTRIES:
                processBrowseEntries( event );
                break;

            case VIEW_ID_EDIT_ENTRY:
                processEditEntry( event );
                break;

            case VIEW_ID_TOOLS:
                processToolsView( event );
                break;

            case VIEW_ID_LANGUAGE:
                processLanguageView( event );
                break;

            case VIEW_ID_FONTSIZE:
                processFontSizeView( event );
                break;

            case VIEW_ID_PREFERENCES:
                processPreferencesView( event );
                break;

            case VIEW_ID_DIAGNOSIS:
                processDiagnosisView( event );
                break;
        }

    }

    private void processEditEntry( final ControllerEvent event )
            throws DBException,
                   SerializationException,
                   RecordStoreFullException,
                   RSException
    {
        switch( event.getCode() )
        {
            case ControllerEvent.BACK:
                goBack( event.getSource() );
                break;

            case ControllerEvent.ACCEPT:
                saveEntry( event );
                break;
        }
    }

    private void saveEntry( final ControllerEvent event )
            throws DBException, SerializationException,
                   RecordStoreFullException, RSException
    {
        final DataFormView editEntry = (DataFormView) event.getSource();
        final String entryTitle = editEntry.getTextField( "title" ).getString();
        final String entryPassword = editEntry.getTextField( "password" ).getString();
        final String entryPassword2 = editEntry.getTextField( "repeat_password" ).getString();

        if( entryTitle == null || entryTitle.trim().length() == 0 )
        {
            Application.getManager().showError( ResourceManager.getResource(
                    "entries.error.TitleCantBeEmpty"
            ) );
            editEntry.setFocusAt( "title" );
            editEntry.show();
        }
        else if( entryPassword == null || entryPassword.trim().length() == 0 )
        {
            Application.getManager().showError( ResourceManager.getResource(
                    "entries.error.PasswordCantBeEmpty"
            ) );
            editEntry.setFocusAt( "password" );
            editEntry.show();
        }
        else if( entryPassword2 == null || entryPassword2.trim().length() == 0 )
        {
            Application.getManager().showError( ResourceManager.getResource(
                    "entries.error.RepeatPasswordCantBeEmpty"
            ) );
            editEntry.setFocusAt( "password2" );
            editEntry.show();
        }
        else if( !entryPassword.equals( entryPassword2 ) )
        {
            Application.getManager().showError( ResourceManager.getResource(
                    "entries.error.PasswordsDontMatch"
            ) );
            editEntry.setFocusAt( "password2" );
            editEntry.show();
        }
        else if( editEntry.getRow() != null )
        {
            Model.saveEntry(
                    editEntry.getRow(),
                    editEntry.getTextField( "password" ).getString()
            );
            goBack( editEntry );
        }
        else
        {
            final ListBrowser browseCategories = ViewFactory.getListBrowser(
                    "browseCategories"
            );
            final Row selected = browseCategories.getSelected();
            long categoryId =
                    selected != null ?
                        selected.getId() :
                        ((Long) browseCategories.getAttachment( "parentId" ))
                                .longValue();
            Model.createEntry(
                    entryTitle,
                    entryPassword,
                    categoryId,
                    editEntry.getTextField( "user_name" ).getString(),
                    editEntry.getTextField( "url" ).getString(),
                    editEntry.getTextField( "comment" ).getString(),
                    editEntry.getDateField( "expires" ).getDate()
            );
            if( selected != null )
            {
                // It comes from the browserEntries, so reload it and go back
                reloadEntries( event );
                goBack( editEntry );
            }
            else
            {
                // It comes from an empty categoriesBrowser, so fetch the entries
                // (the one just added) and show them as if comming from the
                // categoryBrowser (the caller of the editEntry form)
                final RowSet entries = Model.findEntriesByCategory(
                        categoryId
                );
                final ListBrowser entriesBrowser =
                        ViewFactory.getListBrowser( "browseEntries" );
                entriesBrowser.setScrollSet( entries );
                editEntry.getCaller().go( entriesBrowser );
            }
        }
    }

    private void processBrowseEntries( final ControllerEvent event )
            throws DBException,
                   RecordStoreFullException,
                   RSException,
                   SerializationException
    {
        switch( event.getCode() )
        {
            case ControllerEvent.BACK:
                goBack( event.getSource() );
                break;

            case ACTION_ENTB_DEL_ENT:
                deleteKey( event );
                break;

            case ACTION_ENTB_NEW_ENT:
                createKeyFromBrowser( event );
                break;

            default:
                editKey( event );
                break;
        }
    }

    private void deleteKey( final ControllerEvent event )
            throws DBException,
                   RecordStoreFullException,
                   RSException,
                   SerializationException
    {
        final ListBrowser browseEntries = (ListBrowser) event.getSource();
        if( browseEntries.getSelected() != null )
        {
            final boolean confirm = Application.getManager().confirm(
                    ResourceManager.getResource( "entries.remove.Title" ),
                    ResourceManager.getResource( "entries.remove.message" )
            );
            if( confirm )
            {
                browseEntries.getSelected().remove();
                reloadEntries( event );
            }
            else
            {
                event.getSource().show();
            }
        }
        else
        {
            Application.getManager().showWarning( ResourceManager.getResource(
                    "entries.MustSelectEntry"
            ) );
            event.getSource().show();
        }
    }

    private void reloadEntries( final ControllerEvent event )
            throws DBException, RecordStoreFullException, RSException,
                   SerializationException
    {
        final DataFormView searchEntries =
                ViewFactory.getDataForm( "searchEntries" );
        if( comesFrom( event.getSource(), searchEntries ) )
        {
            final String searchText =
                    searchEntries.getTextField( "search" ).getString();
            final RowSet entries = Model.findEntries( searchText );
            if( entries.size() == 0 )
            {
                Application.getManager().showWarning(
                        ResourceManager.getResource(
                                "global.search.NoResults"
                        )
                );
                goBack( event.getSource() );
            }
            else
            {
                final ListBrowser browseEntries =
                        ViewFactory.getListBrowser( "browseEntries" );
                browseEntries.setScrollSet( entries );
                browseEntries.show();
            }
        }
        else
        {
            final ListBrowser browseCategories = ViewFactory.getListBrowser(
                    "browseCategories"
            );
            final Row selected = browseCategories.getSelected();
            final RowSet entries = Model.findEntriesByCategory(
                    selected.getId()
            );
            if( entries.size() > 0 )
            {
                // There are child entries (passwords) so show them
                final ListBrowser entriesBrowser =
                        ViewFactory.getListBrowser( "browseEntries" );
                entriesBrowser.setScrollSet( entries );
                entriesBrowser.show();
            }
            else
            {
                goBack( event.getSource() );
            }
        }
    }

    private void editKey( final ControllerEvent event )
            throws DBException,
                   RecordStoreFullException,
                   RSException
    {
        final ListBrowser browseEntries = (ListBrowser) event.getSource();
        if( browseEntries.getSelected() != null )
        {
            final DataFormView form = ViewFactory.getDataForm( "editEntry" );
            form.bind( browseEntries.getSelected() );
            final String unencryptedPassword = Model.decryptPassword(
                    browseEntries.getSelected().getBlob( "password" )
            );
            form.getTextField( "password" ).setString( unencryptedPassword );
            form.getTextField( "repeat_password" ).setString(
                    unencryptedPassword
            );
            event.getSource().go( form );
        }
        else
        {
            Application.getManager().showWarning( ResourceManager.getResource(
                    "entries.MustSelectEntry"
            ) );
            event.getSource().show();
        }
    }

    private void createKeyFromBrowser( final ControllerEvent event )
    {
        final ListBrowser browseCategories = ViewFactory.getListBrowser(
                "browseCategories"
        );
        if( comesFrom( event.getSource(), browseCategories ) )
        {
            final Long parentId = (Long)
                    browseCategories.getAttachment( "parentId" );
            final DataFormView form = ViewFactory.getDataForm( "editEntry" );
            form.bind( (Row) null );
            form.getTextField( "title" ).setString( "" );
            form.getTextField( "password" ).setString( "" );
            form.getTextField( "repeat_password" ).setString( "" );
            form.getTextField( "user_name" ).setString( "" );
            form.getTextField( "url" ).setString( "" );
            form.getTextField( "comment" ).setString( "" );
            form.attach(
                    "parentId",
                    parentId == null || parentId.longValue() == 0 ?
                        null :
                        parentId
            );
            event.getSource().go( form );
        }
        else
        {
            Application.getManager().showWarning( ResourceManager.getResource(
                    "entries.CanCreateOnlyFromCategories"
            ) );
            event.getSource().show();
        }
    }

    private void processSearchEntries( final ControllerEvent event )
            throws DBException,
                   RecordStoreFullException,
                   RSException,
                   SerializationException
    {
        switch( event.getCode() )
        {
            case ControllerEvent.BACK:
                goBack( event.getSource() );
                break;

            case ControllerEvent.ACCEPT:
                final DataFormView searchEntries = (DataFormView)
                        event.getSource();
                final String searchText =
                        searchEntries.getTextField( "search" ).getString();
                if( searchText == null || searchText.trim().length() == 0 )
                {
                    Application.getManager().showWarning(
                            ResourceManager.getResource(
                                    "global.search.CantBeEmpty"
                            )
                    );
                    event.getSource().show();
                }
                else
                {
                    final RowSet entries = Model.findEntries( searchText );
                    if( entries.size() == 0 )
                    {
                        Application.getManager().showWarning(
                                ResourceManager.getResource(
                                        "global.search.NoResults"
                                )
                        );
                        event.getSource().show();
                    }
                    else
                    {
                        final ListBrowser browseEntries =
                                ViewFactory.getListBrowser( "browseEntries" );
                        browseEntries.setScrollSet( entries );
                        searchEntries.go( browseEntries );
                    }
                }
                break;
        }
    }

    private void processEditCategory( final ControllerEvent event )
            throws DBException,
                   SerializationException,
                   RecordStoreFullException,
                   RSException
    {
        switch( event.getCode() )
        {
            case ControllerEvent.BACK:
                goBack( event.getSource() );
                break;

            case ControllerEvent.ACCEPT:
                saveCategory( event );
                break;
        }
    }

    private void saveCategory( final ControllerEvent event )
            throws DBException,
                   SerializationException,
                   RecordStoreFullException,
                   RSException
    {
        final DataFormView editCategory = (DataFormView) event.getSource();
        final Row row = editCategory.getRow();
        if( row != null )
        {
            row.setField(
                    Model.FLD_CAT_NAME,
                    editCategory.getTextField( "name" ).getString()
            );
            row.setField(
                    Model.FLD_CAT_DESCRIPTION,
                    editCategory.getTextField( "description" ).getString()
            );
            row.save();
        }
        else
        {
            Model.createCategory(
                    (Long) editCategory.getAttachment( "parentId" ),
                    editCategory.getTextField( "name" ).getString(),
                    editCategory.getTextField( "description" ).getString()
            );
        }
        reloadCategories( (ListBrowser) editCategory.getCaller() );
        goBack( editCategory );
    }

    private void processBrowseCategories( final ControllerEvent event )
            throws DBException,
                   SerializationException,
                   RecordStoreFullException,
                   RSException
    {
        switch( event.getCode() )
        {
            case ControllerEvent.BACK:
                categoriesBack( event );
                break;

            case ACTION_CATB_NEW_CAT:
                createCategory( event );
                break;

            case ACTION_CATB_DEL_CAT:
                removeCategory( event );
                break;

            case ACTION_CATB_EDIT_CAT:
                editCategory( event );
                break;

            case ACTION_CATB_NEW_KEY:
                createKey( event );
                break;

            default:
                categoriesForward( event );
        }
    }

    private void editCategory( final ControllerEvent event )
            throws DBException,
                   RecordStoreFullException,
                   RSException
    {
        final ListBrowser browseCategories = ViewFactory.getListBrowser(
                "browseCategories"
        );
        final Row selected = browseCategories.getSelected();
        if( selected != null )
        {
            final DataFormView form = ViewFactory.getDataForm( "editCategory" );
            form.bind( selected );
            event.getSource().go( form );
        }
        else
        {
            Application.getManager().showWarning( ResourceManager.getResource(
                    "warn.SelectACategory"
            ) );
            event.getSource().show();
        }

    }

    private void createKey( final ControllerEvent event )
    {
        final ListBrowser browseCategories = ViewFactory.getListBrowser(
                "browseCategories"
        );
        if( browseCategories.getScrollSet().size() > 0 )
        {
            Application.getManager().showWarning( "categories.NotALeaf" );
            event.getSource().show();
        }
        else
        {
            final Long parentId = (Long)
                    browseCategories.getAttachment( "parentId" );
            if( parentId == null || parentId.longValue() == 0 )
            {
                Application.getManager().showWarning( "categories.CanCreateAtRoot" );
                event.getSource().show();
            }
            else
            {
                final DataFormView form = ViewFactory.getDataForm( "editEntry" );
                form.bind( (Row) null );
                form.getTextField( "title" ).setString( "" );
                form.getTextField( "password" ).setString( "" );
                form.getTextField( "repeat_password" ).setString( "" );
                form.getTextField( "user_name" ).setString( "" );
                form.getTextField( "url" ).setString( "" );
                form.getTextField( "comment" ).setString( "" );
                form.attach( "parentId", parentId );
                event.getSource().go( form );
            }
        }
    }

    private void removeCategory( final ControllerEvent event )
            throws DBException,
                   RecordStoreFullException,
                   RSException,
                   SerializationException
    {
        final ListBrowser browseCategories = ViewFactory.getListBrowser(
                "browseCategories"
        );
        final Row selected = browseCategories.getSelected();
        if( selected != null )
        {
            final boolean confirm = Application.getManager().confirm(
                    ResourceManager.getResource( "categories.remove.Title" ),
                    ResourceManager.getResource( "categories.remove.message" )
            );
            if( confirm )
            {
                Model.removeCategoryTree( selected );
                reloadCategories( browseCategories );
            }
            else
            {
                event.getSource().show();
            }
        }
        else
        {
            Application.getManager().showWarning( ResourceManager.getResource(
                    "warn.SelectACategory"
            ) );
            event.getSource().show();
        }
    }

    private void reloadCategories( final ListBrowser browseCategories )
            throws DBException, SerializationException,
                   RecordStoreFullException, RSException
    {
        // Refresh the list
        final Long parentId = (Long)
                browseCategories.getAttachment( "parentId" );
        final RowSet children = Model.getChildCategories( parentId );
        browseCategories.setScrollSet( children );
        browseCategories.show();
    }

    private void createCategory( final ControllerEvent event )
    {
        final ListBrowser browseCategories = ViewFactory.getListBrowser(
                "browseCategories"
        );
        final Long parentId = (Long)
                browseCategories.getAttachment( "parentId" );
        final DataFormView form = ViewFactory.getDataForm( "editCategory" );
        form.bind( (Row) null );
        form.getTextField( "name" ).setString( "" );
        form.getTextField( "description" ).setString( "" );
        form.attach(
                "parentId",
                parentId == null || parentId.longValue() == 0 ?
                    null :
                    parentId
        );
        event.getSource().go( form );
    }

    private void categoriesForward( final ControllerEvent event )
            throws
            SerializationException,
            RecordStoreFullException,
            RSException,
            DBException
    {
        final ListBrowser browseCategories = ViewFactory.getListBrowser(
                "browseCategories"
        );
        final Row selected = browseCategories.getSelected();
        if( selected != null )
        {
            final Long parentId = new Long( selected.getId() );
            final RowSet children = Model.getChildCategories( parentId );
            if( children.size() > 0 )
            {
                browseCategories.setScrollSet( children );
                browseCategories.attach( "parentId", parentId );
                browseCategories.show();
            }
            else
            {
                final RowSet entries = Model.findEntriesByCategory(
                        selected.getId()
                );
                if( entries.size() > 0 )
                {
                    // There are child entries (passwords) so show them
                    final ListBrowser entriesBrowser =
                            ViewFactory.getListBrowser( "browseEntries" );
                    entriesBrowser.setScrollSet( entries );
                    event.getSource().go( entriesBrowser );
                }
                else
                {
                    // Show an empty category browser
                    browseCategories.setScrollSet( children );
                    browseCategories.attach( "parentId", parentId );
                    browseCategories.show();
                }
            }
        }
        else
        {
            event.getSource().show();
        }
    }

    private void categoriesBack( final ControllerEvent event )
            throws
            DBException,
            SerializationException,
            RecordStoreFullException,
            RSException
    {
        final ListBrowser browseCategories = ViewFactory.getListBrowser(
                "browseCategories"
        );
        final Long parentId = (Long)
                browseCategories.getAttachment( "parentId" );
        if( parentId == null || parentId.longValue() == 0 )
        {
            goBack( event.getSource() );
        }
        else
        {
            final Row previous = Model.findCategoryById( parentId );
            browseCategories.setScrollSet(
                    Model.getChildCategories( (Long)
                            previous.getField( Model.FLD_CAT_PARENT_ID )
                    )
            );
            browseCategories.attach(
                    "parentId",
                    previous.getField( Model.FLD_CAT_PARENT_ID )
            );
            browseCategories.show();
        }
    }

    private void processDiagnosisView( final ControllerEvent event )
            throws SerializationException,
                   InvalidRecordIDException,
                   RecordStoreFullException,
                   DBException,
                   RSException
    {
        switch( event.getCode() )
        {
            case ControllerEvent.BACK:
                goBack( event.getSource());
                break;

            case DIAGMENU_INFO:
                showSystemInfo( event );
                break;

            case DIAGMENU_CHEK_MEM:
                try
                {
                    checkMemory( event );
                }
                catch( RecordStoreException e )
                {
                    Application.getManager().showError( e );
                }
                break;

            case DIAGMENU_DEVICE_INFO:
                showDeviceInfo( event );
                break;

            case DIAGMENU_FORCE_DEVICE_INFO:
                Store.safeDeleteRecordStore( "sys_devinfo" );
                DeviceInfo.setDeviceInfo( null );
                showDeviceInfo( event );
                break;

            case DIAGMENU_VIEW_LOG:
                try
                {
                    final String logTxt = ErrorLog.getErrors();
                    HelpView v =  HelpView.getInstance();
                    v.setText( logTxt );
                    event.getSource().go( v );
                }
                catch( J2MEException e )
                {
                    Application.getManager().showError( e );
                }
                break;

            case ControllerEvent.HOME:
                ViewFactory.getMenu( "main" ).show();
                break;
        }
    }

    private void showDeviceInfo( final ControllerEvent event )
    {
        final StringBuffer buffer = new StringBuffer();

        final DeviceInfo deviceInfo = DeviceInfo.getDeviceInfo();
        buffer
                .append( ResourceManager.getResource( "deviceInfo.speed" ) )
                .append( ": " )
                .append( deviceInfo.getmHz() )
                .append( "MHz" )
                .append( '\n' )
                .append( ResourceManager.getResource( "deviceInfo.performance" ) )
                .append( ": " )
                .append( deviceInfo.getComputationPerformance() )
                .append( '\n' )
                .append( ResourceManager.getResource( "deviceInfo.memSpeed" ) )
                .append( ": " )
                .append( deviceInfo.getMemoryReadSpeed() )
                .append( "/" )
                .append( deviceInfo.getMemoryWriteSpeed() )
                .append( "/" )
                .append( deviceInfo.getMemoryCopySpeed() )
                .append( '\n' )
                .append( ResourceManager.getResource( "deviceInfo.rsSizeLimit" ) )
                .append( ": " );

        final long rsSizeLimit = deviceInfo.getRsSizeLimit();
        if( rsSizeLimit == DeviceInfo.RS_LIMIT_UNKOWN )
        {
            buffer.append( ResourceManager.getResource(
                    "deviceInfo.rslimit.unknown"
            ) );
        }
        else if( rsSizeLimit == DeviceInfo.RS_LIMIT_NONE )
        {
            buffer.append( ResourceManager.getResource(
                    "deviceInfo.rslimit.none"
            ) );
        }
        else
        {
            buffer.append( (rsSizeLimit / 1024) ).append( "Kb" );
        }
        buffer
                .append( '\n' )
                .append( ResourceManager.getResource( "deviceInfo.allocHandling" ) )
                .append( ": " );
        switch( deviceInfo.getAllocHandling() )
        {
            case DeviceInfo.AH_UNKNOWN:
                buffer.append( ResourceManager.getResource( "deviceInfo.ah.unknown" ) );
                break;

            case DeviceInfo.AH_OK:
                buffer.append( ResourceManager.getResource( "deviceInfo.ah.ok" ) );
                break;

            case DeviceInfo.AH_FREES_ON_RECORD_DELETE:
                buffer.append( ResourceManager.getResource( "deviceInfo.ah.freesOnRecord" ) );
                break;

            case DeviceInfo.AH_FREES_ON_RS_DELETE:
                buffer.append( ResourceManager.getResource( "deviceInfo.ah.freesOnRS" ) );
                break;

            case DeviceInfo.AH_BOGUS:
                buffer.append( ResourceManager.getResource( "deviceInfo.ah.bogus" ) );
                break;
        }
        buffer
                .append( '\n' )
                .append( ResourceManager.getResource( "deviceInfo.hasAllocBug" ) )
                .append( ": " )
                .append( deviceInfo.hasAllocBug() ?
                         ResourceManager.getResource( "global.Yes" ) :
                         ResourceManager.getResource( "global.No" )
                )
                .append( '\n' )
                .append( ResourceManager.getResource( "deviceInfo.growingHeap" ) )
                .append( ": " )
                .append( deviceInfo.isGrowingHeap() ?
                         ResourceManager.getResource( "global.Yes" ) :
                         ResourceManager.getResource( "global.No" )
                )
                .append( '\n' )
                .append( ResourceManager.getResource( "deviceInfo.bluetooth" ) )
                .append( ": " )
                .append( Util.hasBluetoothAPI() ?
                         ResourceManager.getResource( "global.Yes" ) :
                         ResourceManager.getResource( "global.No" )
                )
                .append( '\n' )
                .append( ResourceManager.getResource( "deviceInfo.fileApi" ) )
                .append( ": " )
                .append( Util.hasFileAPI() ?
                         ResourceManager.getResource( "global.Yes" ) :
                         ResourceManager.getResource( "global.No" )
                )
                .append( '\n' )
                .append( ResourceManager.getResource( "deviceInfo.location" ) )
                .append( ": " )
                .append( Util.hasLocationAPI() ?
                         ResourceManager.getResource( "global.Yes" ) :
                         ResourceManager.getResource( "global.No" )
                );

        buffer
                .append( '\n' )
                .append( "Error de tipo de letra en listas: " )
                .append( deviceInfo.hasListFontBug() ? "si" : "no" );

        final HelpView view = HelpView.getInstance();
        view.setTitle( ResourceManager.getResource( "diagnostics.deviceInfo" ) );
        view.setText( buffer.toString() );
        view.setCaller( event.getSource() );
        view.setFont( Util.SMALL_FONT );
        view.show();
    }

    private void checkMemory( final ControllerEvent event )
            throws RecordStoreException
    {
        final String report = Util.buildMemoryReport();
        final HelpView view = HelpView.getInstance();
        view.setTitle( ResourceManager.getResource( "diagnostics.memoryReport" ) );
        view.setText( report );
        view.setCaller( event.getSource() );
        view.show();
    }

    private void showSystemInfo( final ControllerEvent event )
            throws DBException,
                   SerializationException,
                   RecordStoreFullException,
                   RSException
    {
        final ProgressEvent pe = new ProgressEvent();
        pe.setAnimate( true );
        pe.setTitle( ResourceManager.getResource( "sysinfo.Title" ) );
        pe.dispatch();

        final StringBuffer buffer = new StringBuffer();
        final long totalMemory = Runtime.getRuntime().totalMemory() / KB;
        final long freeMemory  = Runtime.getRuntime().freeMemory() / KB;
        final Database db = Model.getDatabase();
        final long dbTotalSize = db.getTotalSize();
//        final int freeDisk = Settings.getFreeDisk();
        buffer.append( ResourceManager.getResource( "sysinfo.totalMemory" ) )
                .append( ": " )
                .append( totalMemory ).append( " Kb" )
                .append( "\n" )
                .append( ResourceManager.getResource( "sysinfo.freeMemory" ) )
                .append( ": " )
                .append( freeMemory ).append( " Kb" )
                .append( "\n" )
                .append( ResourceManager.getResource( "sysinfo.databaseSize" ) )
                .append( ": " )
                .append( sizeIn( dbTotalSize, KB ) )
                .append( " Kb (" )
                .append( sizeIn( dbTotalSize, MB ) )
                .append( " Mb)" );
//                .append( "\n" )
//                .append( ResourceManager.getResource( "sysinfo.freeDisk" ) )
//                .append( ": " )
//                .append( sizeIn( freeDisk, KB ) )
//                .append( " Kb (" )
//                .append( sizeIn( freeDisk, MB ) )
//                .append( " Mb)" );

//        FixedPoint hitRatio = new FixedPoint( SimpleCache.getWideHits() );
//        hitRatio = hitRatio.setPrecision( 2 );
//        final long totalCacheMoves = SimpleCache.getWideHits() +
//                                     SimpleCache.getWideMisses();
//        if( totalCacheMoves  > 0 )
//        {
//            hitRatio = hitRatio.mult( 100 );
//            hitRatio = hitRatio.div( totalCacheMoves );
//        }

//        FixedPoint rsHitRatio = new FixedPoint( Store.getHits() );
//        rsHitRatio = rsHitRatio.setPrecision( 2 );
//        final long totalRsCacheMoves = Store.getHits() +
//                                     Store.getMisses();
//        if( totalRsCacheMoves  > 0 )
//        {
//            rsHitRatio = rsHitRatio.mult( 100 );
//            rsHitRatio = rsHitRatio.div( totalRsCacheMoves );
//        }
//
//        final RecordStoreStats stats = Store.getWideStats();
//        buffer.append( "\n" )
//                .append( ResourceManager.getResource( "sysinfo.avgDeleteTime" ) )
//                .append( ": " )
//                .append( stats.getAverageDeleteTime() )
//                .append( " ms." )
//                .append( "\n" )
//                .append( ResourceManager.getResource( "sysinfo.avgFindTime" ) )
//                .append( ": " )
//                .append( Index.getAverageWideFindTime() )
//                .append( " ms." )
//                .append( "\n" )
//                .append( ResourceManager.getResource( "sysinfo.avgReadTime" ) )
//                .append( ": " )
//                .append( stats.getAverageReadTime() )
//                .append( " ms." )
//                .append( "\n" )
//                .append( ResourceManager.getResource( "sysinfo.avgUpdateTime" ) )
//                .append( ": " )
//                .append( stats.getAverageUpdateTime() )
//                .append( " ms." )
//                .append( "\n" )
//                .append( ResourceManager.getResource( "sysinfo.avgWriteTime" ) )
//                .append( ": " )
//                .append( stats.getAverageAddTime() )
//                .append( " ms." )
//                .append( "\n" )
//                .append( ResourceManager.getResource( "sysinfo.hitRatio" ) )
//                .append( ": " )
//                .append( SimpleCache.getWideHits() )
//                .append( "/" )
//                .append( totalCacheMoves )
//                .append( " (" )
//                .append( hitRatio.toString() )
//                .append( "%)")
//                .append( "\n" )
//                .append( ResourceManager.getResource( "sysinfo.rsCache" ) )
//                .append( ": " )
//                .append( Store.getHits() )
//                .append( "/" )
//                .append( totalRsCacheMoves )
//                .append( " (" )
//                .append( rsHitRatio.toString() )
//                .append( "%)");

        final HelpView helpView = HelpView.getInstance();
        helpView.setText( buffer.toString() );
        helpView.setTitle( ResourceManager.getResource( "sysinfo.Title" ) );
        helpView.setCaller( event.getSource() );
        helpView.show();
    }

    private String sizeIn( final long size, final int divisor )
    {
        FixedPoint f = new FixedPoint( size );
        f = f.setPrecision( 5 );
        f = f.div( divisor );
        f = f.setPrecision( 1 );
        return f.toString();
    }

    private void processPreferencesView( final ControllerEvent event )
            throws SerializationException,
                   DBException,
                   NetException,
                   IOException,
                   RemoteCallException
    {
        switch( event.getCode() )
        {
            case ControllerEvent.BACK:
                goBack( event.getSource() );
                break;

            case ControllerEvent.HOME:
                ViewFactory.getMenu( "mainMenu" ).show();
                event.getSource().release();
                break;
        }
    }

    private void processFontSizeView( final ControllerEvent event )
    {
        switch( event.getCode() )
        {
            case ACTION_FTS_SMALL:
                setFont( event, Font.SIZE_SMALL );
                break;

            case ACTION_FTS_MEDIUM:
                setFont( event, Font.SIZE_MEDIUM );
                break;

            case ACTION_FTS_LARGE:
                setFont( event, Font.SIZE_LARGE );
                break;

            case ControllerEvent.BACK:
                goBack( event.getSource() );
                break;

            case ControllerEvent.HOME:
                Application.getManager().getMainView().show();
                break;
        }
    }

    private void setFont( final ControllerEvent event, final int size )
    {
        final ProgressEvent e = new ProgressEvent( this );
        e.setAnimate( true );
        final String changing =
                ResourceManager.getResource( "fontSize.changing" );
        e.setPhase( changing );
        e.setTitle( changing );
        e.setMessage( "" );
        e.dispatch();
        Ui.setFontSize( size );
        event.getSource().show();
    }

    // <ToolsView> -------------------------------------------------------------
    private void processToolsView( final ControllerEvent event )
            throws
            SerializationException,
            NetException,
            RemoteCallException,
            DBException,
            RSException,
            RecordStoreFullException
    {
        switch( event.getCode() )
        {
            case ControllerEvent.BACK:
                goBack( event.getSource() );
                break;

            case TOOLSMENU_DELETE_DATA:
                tools_clearData();
                break;
        }
    }

    private void tools_clearData()
    {
        final boolean doIt = Application.getManager().confirm(
                ResourceManager.getResource( "tools.eraseData.Title" ),
                ResourceManager.getResource( "tools.eraseData.Message" )
        );
        if( doIt )
        {
            try
            {
                Model.getDatabase().drop();
                Application.getManager().showInfo(
                        ResourceManager.getResource( "tools.eraseData.Done" )
                );
            }
            catch( Exception e )
            {
                log.error( e );
                Application.getManager().showError( e );
            }
            exitApplication();
        }
    }

    /**
     * Utility method to check if a view has another one in the path, that is,
     * if the user comes from that view.
     * @param source current view
     * @param view target view
     * @return true if so
     */
    private boolean comesFrom( final View source, final View view )
    {
        final View caller = source.getCaller();
        return caller != null && (
                    caller.getId() == view.getId() ||
                    comesFrom( caller, view )
        );
    }

    // <MainView> --------------------------------------------------------------
    private void processMainView( final ControllerEvent event )
            throws DBException,
                   NetException,
                   RecordStoreFullException,
                   SerializationException,
                   RemoteCallException,
                   FSException,
                   IOException,
                   RSException
    {
        AppState.clearState();
        switch( event.getCode() )
        {
            case MAINM_CATEGORIES:
                browseCategories( event );
                break;

            case MAINM_SEARCH_ENTRIES:
                event.getSource().go(
                        ViewFactory.getDataForm( "searchEntries" )
                );
                break;

            case ControllerEvent.EXIT:
                mildExitApplication();
                break;

            case ControllerEvent.HELP:
                mildExitApplication();
                break;

            case MAINM_ABOUT:
                showAboutInfo( event );
                break;
        }
    }

    private void browseCategories( final ControllerEvent event )
            throws DBException,
                   RecordStoreFullException,
                   RSException,
                   SerializationException
    {
        // Find the root categories
        final RowSet set = Model.getRootCategories();
        // Fetch the browser view
        final ListBrowser browser =
                ViewFactory.getListBrowser( "browseCategories" );
        // Feed the browser view
        browser.setScrollSet( set );
        // And show it
        event.getSource().go( browser );
    }

    private void showAboutInfo( final ControllerEvent event )
    {
        final StringBuffer buffer = new StringBuffer();
        buffer.append( "BaseMovil " )
                .append( Model.APPLICATION_NAME )
                .append( " v" )
                .append( Application.getManager().getProperty(
                        "basemovil.version"
                ) );
        buffer
                .append( '\n' )
                .append( ResourceManager.getResource( "about.licensedTo" ) )
                .append( ":\n" )
                .append( LoginManager.getCompanyName() != null ? LoginManager.getCompanyName() : "" )
                .append( '\n' )
                .append( LoginManager.getUserFullName() )
                .append( '\n' );
        buffer.append( "id: " ).append( LoginManager.getUserCustomId() );
        buffer.append( '\n' )
                .append( ResourceManager.getResource( "about.text" ) );

        final HelpView view = HelpView.getInstance();
        view.setCaller( event.getSource() );
        view.setText( buffer.toString() );
        view.setTitle( ResourceManager.getResource( "about.Title" ) );
        view.show();
    }
    // </MainView> -------------------------------------------------------------

    // <LanguageView> ----------------------------------------------------------
    private void processLanguageView( final ControllerEvent event )
            throws DBException
    {
        switch( event.getCode() )
        {
            case ControllerEvent.BACK:
                goBack( event.getSource() );
                break;

            default:
                setLanguage( event );
                break;
        }
    }

    private void setLanguage( final ControllerEvent event )
            throws DBException
    {
        final ProgressEvent pe = new ProgressEvent(
                event.getSource(),
                new Integer( Gauge.INDEFINITE ),
                Gauge.CONTINUOUS_RUNNING
        );
        pe.setTitle( ResourceManager.getResource(
                "languageView.LoadingLanguage"
        ));
        pe.dispatch();
        final String locale;
        switch( event.getCode() )
        {
            case LANG_ES:
                locale = "es";
                break;

            default:
                locale = "en";
        }
        if( !locale.equals( ResourceManager.getLocale() ) )
        {
            ResourceManager.setActiveLocale( locale );
            Settings.setProperty( Model.CONFIG_ACTIVE_LOCALE, locale );
            Settings.setProperty(
                    CoreConstants.PROP_RESOURCE_LOCALE,
                    locale
            );
            views.clear();
            ViewFactory.clear();
            System.gc();
        }
        final MenuView mainView = ViewFactory.getMenu( "mainMenu" );
        Application.getManager().setMainView( mainView );
        mainView.show();
    }
    // </LanguageView> ---------------------------------------------------------


    /**
     * Configure default actions and update custom view cache.
     *
     * @param key view key
     * @param view view
     * @param cache add it to the cache
     */
    private static void addView(
            final String    key,
            final View      view,
            final boolean   cache
    )
    {
        final int viewId = view.getId();
        if( exitPoints.contains( new Integer( viewId ) ) )
        {
            view.addCommand( Application.getCommandFactory().exitCommand() );
        }
        else if( !noBack.contains( new Integer( viewId ) ) )
        {
            view.addCommand( Application.getCommandFactory().backCommand() );
        }

        if( view instanceof HelpAssisted && ((HelpAssisted)view).getHelpId() != null )
        {
            view.addCommand( Application.getCommandFactory().helpCommand() );
        }

        if( cache )
        {
            views.put( key, view );
        }
    }
}
TOP

Related Classes of passkeep.control.MainController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.