Source code

KittyORM mig v.1 implementation sources
  1. Click to view MigrationDBv1.class:
     1@KITTY_DATABASE(
     2        isLoggingOn = true,
     3        isProductionOn = false,
     4        databaseName = "mig",
     5        databaseVersion = 1,
     6        logTag = MigrationDBv1.LTAG,
     7        domainPackageNames = {"net.akaish.kittyormdemo.sqlite.migrations.migv1"}
     8)
     9@KITTY_DATABASE_REGISTRY(
    10        domainModels = {net.akaish.kittyormdemo.sqlite.migrations.migv1.MigOneModel.class}
    11)
    12public class MigrationDBv1 extends KittyDatabase {
    13
    14    public static final String LTAG = "MIGv1";
    15
    16    /**
    17     * KittyORM main database class that represents bootstrap and holder for all related with database
    18     * components.
    19     *
    20     * @param ctx
    21     */
    22    public MigrationDBv1(Context ctx) {
    23        super(ctx);
    24    }
    25}

  2. Click to view MigOneModel.class:
     1@KITTY_TABLE(
     2        tableName = "mig_one"
     3)
     4public class MigOneModel extends KittyModel{
     5    @KITTY_COLUMN(
     6            columnOrder = 0,
     7            isIPK = true)
     8    public Long id;
     9
    10    @KITTY_COLUMN(
    11            columnOrder = 1
    12    )
    13    @NOT_NULL
    14    public String creationDate;
    15
    16    @KITTY_COLUMN(
    17            columnOrder = 2
    18    )
    19    public Integer someInteger;
    20
    21    public String toString() {
    22        return new StringBuilder(64)
    23                .append("[ id = ")
    24                .append(id)
    25                .append(" ; creationDate = ")
    26                .append(creationDate)
    27                .append(" ; someInteger = ")
    28                .append(someInteger)
    29                .append(" ]").toString();
    30    }
    31}

Fragment and utility code used in this tutorial
  1. Click to view MigV1RandomModelFactory.class:
     1public class MigV1RandomModelFactory {
     2    final Context ctx;
     3    final Random rnd;
     4
     5    public MigV1RandomModelFactory(Context ctx) {
     6        this.ctx = ctx;
     7        this.rnd = new Random();
     8    }
     9
    10    public MigOneModel newM1RndModel() {
    11        MigOneModel model = new MigOneModel();
    12        model.creationDate = new Date(System.currentTimeMillis()).toString();
    13        model.someInteger = rnd.nextInt();
    14        return model;
    15    }
    16}

  2. Click to view Lesson5Tab1InitialDatabase.class:
      1public class Lesson5Tab1InitialDatabase extends Lesson5BaseFragment {
      2
      3    private MigrationDBv1 databaseV1;
      4    private SharedPreferencesMigDB sf;
      5
      6    private Button insertRandomButton;
      7    private Button clearTableButton;
      8    private Button deleteDatabaseButton;
      9
     10    private ListView eventsListView;
     11
     12    private TextView statusTV;
     13
     14    private MigDatabaseState mdbState;
     15
     16    final static int DB_IMPLEMENTATION_VERSION = 1;
     17    final static int TABLE_AMOUNT = 1;
     18
     19    public Lesson5Tab1InitialDatabase() {}
     20
     21    @Override
     22    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
     23        View rootView = inflater.inflate(R.layout.lesson5_tab1_initial, container, false);
     24
     25        insertRandomButton = rootView.findViewById(R.id.l5_t1_go_button);
     26        clearTableButton = rootView.findViewById(R.id.l5_t1_clear_button);
     27        deleteDatabaseButton = rootView.findViewById(R.id.l5_t1_delete_database_button);
     28
     29        eventsListView = rootView.findViewById(R.id.l5_t1_actions);
     30
     31        insertRandomButton.setOnClickListener(new View.OnClickListener() {
     32            @Override
     33            public void onClick(View v) {
     34                insert25RND();
     35            }
     36        });
     37
     38        clearTableButton.setOnClickListener(new View.OnClickListener() {
     39            @Override
     40            public void onClick(View v) {
     41                clearTable();
     42            }
     43        });
     44
     45        deleteDatabaseButton.setOnClickListener(new View.OnClickListener() {
     46            @Override
     47            public void onClick(View v) {
     48                deleteDatabase();
     49            }
     50        });
     51
     52        statusTV = rootView.findViewById(R.id.l5_t1_status);
     53
     54
     55       setUpExpandedList(
     56               rootView,
     57               R.id._l5_t1_expanded_panel_list,
     58               R.id._l5_t1_expanded_panel_text,
     59               R.string._l5_t1_expanded_text_pattern
     60        );
     61
     62        reloadTableExpandedList();
     63        reloadStatus();
     64        return rootView;
     65    }
     66
     67    public MigDatabaseState getMdbState(Context context, int implVersion, String[] tables) {
     68        if(mdbState != null) return mdbState;
     69        mdbState = new MigDatabaseState(implVersion, tables, context, getSf());
     70        return mdbState;
     71    }
     72
     73    public void reloadStatus() {
     74        if(statusTV != null) {
     75            statusTV.setText(getMdbState(getContext(), DB_IMPLEMENTATION_VERSION, new String[] {M1M1TN}).toString());
     76        }
     77    }
     78
     79
     80    @Override
     81    public void onVisible() {
     82        reloadTableExpandedList();
     83        reloadStatus();
     84    }
     85
     86    private SharedPreferencesMigDB getSf() {
     87        if(sf != null) return sf;
     88        sf = new SharedPreferencesMigDB(getContext());
     89        return sf;
     90    }
     91
     92    private MigrationDBv1 getDatabase() {
     93        if(databaseV1 != null) return databaseV1;
     94        databaseV1 = new MigrationDBv1(getContext());
     95        return databaseV1;
     96    }
     97
     98    private void insert25RND() {
     99        new InsertRandomAsync().execute(0l);
    100    }
    101
    102    private void clearTable() {
    103        new WipeAsync().execute(0l);
    104    }
    105
    106    private void deleteDatabase() {
    107        new DeleteDatabaseAsync().execute(0l);
    108    }
    109
    110    private void reloadTableExpandedList() {
    111        new ReloadTableAsync().execute(0l);
    112    }
    113
    114    @Override
    115    protected int snackbarMessageResource() {
    116        return R.string._l5_t1_snackbar_message;
    117    }
    118
    119
    120
    121    // Asyncs
    122
    123    class ReloadTableAsync extends AsyncTask<Long, Long, List<String>> {
    124
    125        @Override
    126        protected List<String> doInBackground(Long... params) {
    127            LinkedList<String> toListView = new LinkedList<>();
    128            if(getSf().isDatabaseCreated() && !getSf().isDatabaseDeletedManually() && getSf().currentMigDBVersion() == DB_IMPLEMENTATION_VERSION) {
    129                KittyMapper mapper = getDatabase().getMapper(MigOneModel.class);
    130                List<MigOneModel> m1Models = mapper.findAll();
    131                mapper.close();
    132                if(m1Models == null) {
    133                    toListView.addLast(format(getContext().getString(R.string._l5_t1_m1_db), 0));
    134                    return toListView;
    135                } else {
    136                    toListView.addLast(format(getContext().getString(R.string._l5_t1_m1_db), m1Models.size()));
    137                    Iterator<MigOneModel> mI = m1Models.iterator();
    138                    while (mI.hasNext()) {
    139                        toListView.addLast(mI.next().toString());
    140                    }
    141                    return toListView;
    142                }
    143            } else {
    144                if(!getSf().isDatabaseCreated() || getSf().isDatabaseDeletedManually()) {
    145                    toListView.addLast(getString(R.string._l5_t1_m1_db_doesnt_exist));
    146                    return toListView;
    147                } else {
    148                    toListView.addLast(format(getString(R.string._l5_t1_m1_db_has_different_version), getSf().currentMigDBVersion()));
    149                    return toListView;
    150                }
    151            }
    152        }
    153
    154        @Override
    155        protected void onPostExecute(List<String> result) {
    156            int tableAmount = TABLE_AMOUNT;
    157            if(getSf().isDatabaseDeletedManually() || !getSf().isDatabaseCreated() || getSf().currentMigDBVersion() != DB_IMPLEMENTATION_VERSION)
    158                tableAmount = 0;
    159            if(result != null) {
    160                events.setAdapter(new MigAdapter(getContext(), result));
    161                int recordsAmount = result.size() - TABLE_AMOUNT;
    162                if(tableAmount == 0)
    163                    recordsAmount = 0;
    164                expandedTitle.setText(format(expandeddTitlePattern, recordsAmount, tableAmount));
    165            } else {
    166                events.setAdapter(new MigAdapter(getContext(), new LinkedList<String>()));
    167                expandedTitle.setText(format(expandeddTitlePattern, 0, tableAmount));
    168            }
    169        }
    170    }
    171
    172    private static final String ERR_STRING_WIPE = "Lesson5tab1WipeDataError, see exception details!";
    173
    174    class WipeAsync extends AsyncTask<Long, Long, WipeAsyncResult> {
    175
    176        ProgressDialog dialog;
    177
    178        @Override
    179        protected void onPreExecute() {
    180            dialog = ProgressDialog.show(
    181                    getLessonActivity(),
    182                    getString(R.string._l5_t1_running_requested_operation_pg_title),
    183                    getString(R.string._l5_t1_running_requested_operation_pg_body)
    184            );
    185            dialog.setCancelable(false);
    186        }
    187
    188        @Override
    189        protected WipeAsyncResult doInBackground(Long... params) {
    190            if(getSf().isDatabaseCreated() && !getSf().isDatabaseDeletedManually() && getSf().currentMigDBVersion() == DB_IMPLEMENTATION_VERSION) {
    191                try {
    192                    KittyMapper mapper = getDatabase().getMapper(MigOneModel.class);
    193                    long recordsCount = mapper.countAll();
    194                    long affected = mapper.deleteAll();
    195                    mapper.close();
    196                    return new WipeAsyncResult(true, false, DB_IMPLEMENTATION_VERSION, affected, recordsCount);
    197                } catch (Exception e) {
    198                    Log.e(MigrationDBv1.LTAG, ERR_STRING_WIPE, e);
    199                    if (e instanceof KittyRuntimeException) {
    200                        if (((KittyRuntimeException) e).getNestedException() != null) {
    201                            Log.e(MigrationDBv1.LTAG, ERR_STRING_WIPE, ((KittyRuntimeException) e).getNestedException());
    202                        }
    203                    }
    204                    return new WipeAsyncResult(true, false, DB_IMPLEMENTATION_VERSION, -1l, -1l);
    205                }
    206            } else {
    207                return new WipeAsyncResult(
    208                        getSf().isDatabaseCreated(),
    209                        getSf().isDatabaseDeletedManually(),
    210                        getSf().currentMigDBVersion(),
    211                        -1l, -1l);
    212            }
    213        }
    214
    215        @Override
    216        protected void onPostExecute(WipeAsyncResult result) {
    217            dialog.cancel();
    218
    219            if (eventsListView != null) {
    220                eventsListView.setAdapter(new BasicArrayAdapter(getContext(), new LinkedList<String>()));
    221                eventsListView.setOnTouchListener(new View.OnTouchListener() {
    222
    223                    // Setting on Touch Listener for handling the touch inside ScrollView
    224                    @Override
    225                    public boolean onTouch(View v, MotionEvent event) {
    226                        // Disallow the touch request for parent scroll on touch of child view
    227                        v.getParent().requestDisallowInterceptTouchEvent(true);
    228                        return false;
    229                    }
    230                });
    231
    232                if(!result.isCreated) {
    233                    ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(getString(R.string._l5_op_not_existing));
    234                } else if (result.isDeleted) {
    235                    ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(getString(R.string._l5_op_deleted));
    236                } else if (result.dbVersion != DB_IMPLEMENTATION_VERSION) {
    237                    if(result.dbVersion < DB_IMPLEMENTATION_VERSION) {
    238                        ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_op_mig_version_is_lower), result.dbVersion, DB_IMPLEMENTATION_VERSION));
    239                    } else {
    240                        ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_op_mig_version_is_higher), result.dbVersion, DB_IMPLEMENTATION_VERSION));
    241                    }
    242                } else if (result.recordsCount > -1 && result.affectedRows > -1) {
    243                    ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_t1_count_to_events), result.recordsCount));
    244                    ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_t1_deleted_to_events), result.affectedRows));
    245                } else {
    246                    ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(getString(R.string._l5_t1_error_event));
    247                }
    248                ((BasicArrayAdapter) eventsListView.getAdapter()).notifyDataSetChanged();
    249                reloadTableExpandedList();
    250                reloadStatus();
    251            }
    252        }
    253    }
    254
    255    class WipeAsyncResult {
    256        boolean isCreated;
    257        boolean isDeleted;
    258        int dbVersion;
    259        Long affectedRows;
    260        Long recordsCount;
    261
    262        public WipeAsyncResult(boolean isCreated, boolean isDeleted, int dbVersion,
    263                               Long affectedRows, Long recordsCount) {
    264            this.isCreated = isCreated;
    265            this.isDeleted = isDeleted;
    266            this.dbVersion = dbVersion;
    267            this.affectedRows = affectedRows;
    268            this.recordsCount = recordsCount;
    269        }
    270    }
    271
    272    static final int INSERT_AMOUNT = 25;
    273
    274    static final String ERR_INSERT_RND = "Lesson5tab1InsertRNDDataError, see exception details!";
    275
    276    class InsertRandomAsync extends AsyncTask<Long, Long, InsertRandomResults> {
    277        ProgressDialog dialog;
    278
    279        @Override
    280        protected void onPreExecute() {
    281            dialog = ProgressDialog.show(
    282                    getLessonActivity(),
    283                    getString(R.string._l5_t1_running_requested_operation_pg_title),
    284                    getString(R.string._l5_t1_running_requested_operation_pg_body)
    285            );
    286            dialog.setCancelable(false);
    287        }
    288
    289        @Override
    290        protected InsertRandomResults doInBackground(Long... strings) {
    291            if(getSf().currentMigDBVersion() > DB_IMPLEMENTATION_VERSION) {
    292                return new InsertRandomResults(
    293                        null,
    294                        -1l,
    295                        -1l,
    296                        -1l,
    297                        false,
    298                        getSf().currentMigDBVersion()
    299                );
    300            } else {
    301                try {
    302                    KittyMapper mapper = getDatabase().getMapper(MigOneModel.class);
    303                    long recordsCount = mapper.countAll();
    304                    long affected = mapper.deleteAll();
    305                    LinkedList<MigOneModel> modelsToInsert = new LinkedList<>();
    306                    getSf().setDatabaseCreated(true);
    307                    getSf().setCurrentMigDBVersion(DB_IMPLEMENTATION_VERSION);
    308                    getSf().setDatabaseDeletedManually(false);
    309                    MigV1RandomModelFactory factory = new MigV1RandomModelFactory(getContext());
    310                    for (int i = 0; i < INSERT_AMOUNT; i++) {
    311                        MigOneModel m = factory.newM1RndModel();
    312                        modelsToInsert.addLast(m);
    313                    }
    314                    mapper.insertInTransaction(modelsToInsert);
    315                    List<MigOneModel> models = mapper.findAll();
    316                    long recordsCountAfter = mapper.countAll();
    317                    mapper.close();
    318                    Iterator<MigOneModel> mI = models.iterator();
    319                    LinkedList<String> out = new LinkedList<>();
    320                    while (mI.hasNext()) {
    321                        out.addLast(mI.next().toString());
    322                    }
    323                    return new InsertRandomResults(out, affected, recordsCount, recordsCountAfter, true, getSf().currentMigDBVersion());
    324                } catch (Exception e) {
    325                    Log.e(MigrationDBv1.LTAG, ERR_INSERT_RND, e);
    326                    if (e instanceof KittyRuntimeException) {
    327                        if (((KittyRuntimeException) e).getNestedException() != null) {
    328                            Log.e(MigrationDBv1.LTAG, ERR_INSERT_RND, ((KittyRuntimeException) e).getNestedException());
    329                        }
    330                    }
    331                    return new InsertRandomResults(
    332                            null,
    333                            -1l,
    334                            -1l,
    335                            -1l,
    336                            false,
    337                            getSf().currentMigDBVersion()
    338                    );
    339                }
    340            }
    341        }
    342
    343        @Override
    344        protected void onPostExecute(InsertRandomResults result) {
    345            dialog.cancel();
    346            if (eventsListView != null) {
    347                eventsListView.setAdapter(new BasicArrayAdapter(getContext(), new LinkedList<String>()));
    348                eventsListView.setOnTouchListener(new View.OnTouchListener() {
    349
    350                    // Setting on Touch Listener for handling the touch inside ScrollView
    351                    @Override
    352                    public boolean onTouch(View v, MotionEvent event) {
    353                        // Disallow the touch request for parent scroll on touch of child view
    354                        v.getParent().requestDisallowInterceptTouchEvent(true);
    355                        return false;
    356                    }
    357                });
    358                if (result.operationSuccess) {
    359                    ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_t1_count_to_events), result.modelsCountBefore));
    360                    ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_t1_deleted_to_events), result.deletedModelsAffectedRows));
    361                    for (String modelString : result.modelInsertions) {
    362                        ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_t1_inserted_to_events), M1M1TN, modelString));
    363                    }
    364                    ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_t1_count_to_events), result.modelsCountAfter));
    365                } else {
    366                    if(getSf().currentMigDBVersion() > DB_IMPLEMENTATION_VERSION) {
    367                        ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_op_mig_version_is_higher), result.dbVersion, DB_IMPLEMENTATION_VERSION));
    368                    } else {
    369                        ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(getString(R.string._l5_t1_error_event));
    370                    }
    371                }
    372                ((BasicArrayAdapter) eventsListView.getAdapter()).notifyDataSetChanged();
    373                reloadTableExpandedList();
    374                reloadStatus();
    375            }
    376        }
    377
    378
    379    }
    380
    381    class InsertRandomResults {
    382        List<String> modelInsertions;
    383        long deletedModelsAffectedRows;
    384        long modelsCountBefore;
    385        long modelsCountAfter;
    386        boolean operationSuccess;
    387        int dbVersion;
    388
    389        public InsertRandomResults(List<String> modelInsertions, long deletedModelsAffectedRows,
    390                                   long modelsCountBefore, long modelsCountAfter, boolean opSuccess,
    391                                   int dbVersion) {
    392            this.modelInsertions = modelInsertions;
    393            this.deletedModelsAffectedRows = deletedModelsAffectedRows;
    394            this.modelsCountBefore = modelsCountBefore;
    395            this.modelsCountAfter = modelsCountAfter;
    396            this.operationSuccess = opSuccess;
    397            this.dbVersion = dbVersion;
    398        }
    399    }
    400
    401    static final String ERR_DELETION = "Lesson5tab1DBDeleteError, see exception details!";
    402
    403    class DeleteDatabaseAsync extends AsyncTask<Long, Long, Integer> {
    404        ProgressDialog dialog;
    405
    406        final int DELETED = 1;
    407        final int NOT_DELETED = 2;
    408        final int ERROR = 3;
    409
    410        @Override
    411        protected void onPreExecute() {
    412            dialog = ProgressDialog.show(
    413                    getLessonActivity(),
    414                    getString(R.string._l5_t1_running_requested_operation_pg_title),
    415                    getString(R.string._l5_t1_running_requested_operation_pg_body)
    416            );
    417            dialog.setCancelable(false);
    418        }
    419
    420        @Override
    421        protected Integer doInBackground(Long... strings) {
    422            try {
    423                boolean deleted = getDatabase().deleteDatabase();
    424                getSf().setDatabaseDeletedManually(true);
    425                getSf().setDatabaseCreated(false);
    426                getSf().setCurrentMigDBVersion(-1);
    427                if(deleted)
    428                    return DELETED;
    429                else
    430                    return NOT_DELETED;
    431            } catch (Exception e) {
    432                Log.e(MigrationDBv1.LTAG, ERR_DELETION, e);
    433                if (e instanceof KittyRuntimeException) {
    434                    if (((KittyRuntimeException) e).getNestedException() != null) {
    435                        Log.e(MigrationDBv1.LTAG, ERR_DELETION, ((KittyRuntimeException) e).getNestedException());
    436                    }
    437                }
    438                return ERROR;
    439            }
    440        }
    441
    442        @Override
    443        protected void onPostExecute(Integer result) {
    444            dialog.cancel();
    445            if (eventsListView != null) {
    446                eventsListView.setAdapter(new BasicArrayAdapter(getContext(), new LinkedList<String>()));
    447                eventsListView.setOnTouchListener(new View.OnTouchListener() {
    448
    449                    // Setting on Touch Listener for handling the touch inside ScrollView
    450                    @Override
    451                    public boolean onTouch(View v, MotionEvent event) {
    452                        // Disallow the touch request for parent scroll on touch of child view
    453                        v.getParent().requestDisallowInterceptTouchEvent(true);
    454                        return false;
    455                    }
    456                });
    457                switch (result) {
    458                    case DELETED:
    459                        ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_t1_delete_db_success)));
    460                        break;
    461                    case NOT_DELETED:
    462                        ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_t1_delete_db_fail)));
    463                        break;
    464                    case ERROR:
    465                        ((BasicArrayAdapter) eventsListView.getAdapter()).addItemLast(format(getString(R.string._l5_t1_error_event)));
    466                        break;
    467                }
    468                ((BasicArrayAdapter) eventsListView.getAdapter()).notifyDataSetChanged();
    469                reloadTableExpandedList();
    470                reloadStatus();
    471            }
    472        }
    473    }
    474
    475    // Expanded list
    476    MigAdapter migAdapter;
    477
    478    @Override
    479    protected void setUpExpandedList(View rootView, int eventsId, int eventsTitleId, int eventTitleStringPattern) {
    480        events = (ListView) rootView.findViewById(eventsId);
    481        expandedTitle = (TextView) rootView.findViewById(eventsTitleId);
    482        expandeddTitlePattern = getString(eventTitleStringPattern);
    483
    484        expandedTitle.setText(format(expandeddTitlePattern, 0));
    485
    486        if(expandedAdapter == null) {
    487            migAdapter = new MigAdapter(getContext(), new LinkedList<String>());
    488        }
    489
    490        events.setAdapter(migAdapter);
    491        events.setOnTouchListener(new View.OnTouchListener() {
    492
    493            // Setting on Touch Listener for handling the touch inside ScrollView
    494            @Override
    495            public boolean onTouch(View v, MotionEvent event) {
    496                // Disallow the touch request for parent scroll on touch of child view
    497                v.getParent().requestDisallowInterceptTouchEvent(true);
    498                return false;
    499            }
    500        });
    501    }
    502
    503    // Fab menu section
    504
    505    @Override
    506    public View.OnClickListener helpFabMenuAction() {
    507        return new View.OnClickListener() {
    508
    509            /**
    510             * Called when a view has been clicked.
    511             *
    512             * @param v The view that was clicked.
    513             */
    514            @Override
    515            public void onClick(View v) {
    516                ((KittyTutorialActivity) getParentFragment().getActivity()).showWebViewDialog(L5_T1_TUTORIAL);
    517            }
    518        };
    519    }
    520
    521    @Override
    522    public View.OnClickListener sourceFabMenuAction() {
    523        return new View.OnClickListener() {
    524
    525            /**
    526             * Called when a view has been clicked.
    527             *
    528             * @param v The view that was clicked.
    529             */
    530            @Override
    531            public void onClick(View v) {
    532                ((KittyTutorialActivity) getParentFragment().getActivity()).showWebViewDialog(L5_T1_SOURCE);
    533            }
    534        };
    535    }
    536
    537    @Override
    538    public View.OnClickListener schemaFabMenuAction() {
    539        return new View.OnClickListener() {
    540
    541            /**
    542             * Called when a view has been clicked.
    543             *
    544             * @param v The view that was clicked.
    545             */
    546            @Override
    547            public void onClick(View v) {
    548                ((KittyTutorialActivity) getParentFragment().getActivity()).showWebViewDialog(L5_T1_SCHEMA);
    549            }
    550        };
    551    }
    552}