private void setPrevNextButtonState(PageModel pageModel) {
    if (_menu != null) {
      boolean isNextEnabled = false;
      boolean isPrevEnabled = false;

      try {
        PageModel prevPage =
            novelDetails.getPrev(
                pageModel.getPage(), UIHelper.getShowMissing(this), UIHelper.getShowRedlink(this));
        if (prevPage != null) isPrevEnabled = true;
      } catch (Exception ex) {
        Log.e(TAG, "Failed to get prev chapter: " + pageModel.getPage(), ex);
      }
      try {
        PageModel nextPage =
            novelDetails.getNext(
                pageModel.getPage(), UIHelper.getShowMissing(this), UIHelper.getShowRedlink(this));
        if (nextPage != null) isNextEnabled = true;
      } catch (Exception ex) {
        Log.e(TAG, "Failed to get next chapter: " + pageModel.getPage(), ex);
      }

      _menu.findItem(R.id.menu_chapter_next).setEnabled(isNextEnabled);
      _menu.findItem(R.id.menu_chapter_previous).setEnabled(isPrevEnabled);
    }
  }
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    UIHelper.SetTheme(this, R.layout.activity_display_light_novel_content);
    UIHelper.SetActionBarDisplayHomeAsUp(this, true);

    try {
      PageModel tempPage = new PageModel();
      tempPage.setPage(getIntent().getStringExtra(Constants.EXTRA_PAGE));
      pageModel = dao.getPageModel(tempPage, null);
    } catch (Exception e) {
      Log.e(
          TAG,
          "Failed to get the PageModel for content: "
              + getIntent().getStringExtra(Constants.EXTRA_PAGE),
          e);
    }

    // compatibility search box
    final EditText searchText = (EditText) findViewById(R.id.searchText);
    searchText.setOnEditorActionListener(
        new TextView.OnEditorActionListener() {
          public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            search(searchText.getText().toString());
            return false;
          }
        });

    webView = (WebView) findViewById(R.id.webView1);
    Log.d(TAG, "OnCreate Completed: " + pageModel.getPage());

    restored = false;
  }
예제 #3
0
 public PageModel getPageModel() throws Exception {
   if (this.pageModel == null) {
     NovelsDao dao = NovelsDao.getInstance();
     PageModel tempPage = new PageModel();
     tempPage.setPage(this.page);
     this.pageModel = dao.getPageModel(tempPage, null);
   }
   return pageModel;
 }
예제 #4
0
 public PageModel getParentPageModel() throws Exception {
   if (this.parentPageModel == null) {
     NovelsDao dao = NovelsDao.getInstance();
     PageModel tempPage = new PageModel();
     if (this.type.contentEquals(TYPE_CONTENT)) {
       String tempParent = parent.substring(0, parent.indexOf(Constants.NOVEL_BOOK_DIVIDER));
       tempPage.setPage(tempParent);
     } else {
       tempPage.setPage(this.parent);
     }
     this.parentPageModel = dao.getPageModel(tempPage, null);
   }
   return parentPageModel;
 }
 private void handleOK(EditText input, EditText inputTitle) {
   String novel = input.getText().toString();
   String title = inputTitle.getText().toString();
   if (novel != null && novel.length() > 0 && inputTitle != null && inputTitle.length() > 0) {
     PageModel temp = new PageModel();
     temp.setPage(novel);
     temp.setTitle(title);
     temp.setType(PageModel.TYPE_NOVEL);
     temp.setParent("Main_Page");
     executeAddTask(temp);
   } else {
     Toast.makeText(getSherlockActivity(), "Empty Input", Toast.LENGTH_LONG).show();
   }
 }
 @Override
 public boolean onContextItemSelected(android.view.MenuItem item) {
   if (!(item.getMenuInfo() instanceof AdapterContextMenuInfo))
     return super.onContextItemSelected(item);
   Log.d(TAG, "Context menu called");
   AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
   switch (item.getItemId()) {
     case R.id.add_to_watch:
       /*
        * Implement code to toggle watch of this novel
        */
       if (info.position > -1) {
         PageModel novel = listItems.get(info.position);
         if (novel.isWatched()) {
           novel.setWatched(false);
           Toast.makeText(
                   getSherlockActivity(),
                   "Removed from watch list: " + novel.getTitle(),
                   Toast.LENGTH_SHORT)
               .show();
         } else {
           novel.setWatched(true);
           Toast.makeText(
                   getSherlockActivity(),
                   "Added to watch list: " + novel.getTitle(),
                   Toast.LENGTH_SHORT)
               .show();
         }
         NovelsDao.getInstance(getSherlockActivity()).updatePageModel(novel);
         adapter.notifyDataSetChanged();
       }
       return true;
     case R.id.download_novel:
       /*
        * Implement code to download novel synopsis
        */
       if (info.position > -1) {
         PageModel novel = listItems.get(info.position);
         ArrayList<PageModel> novels = new ArrayList<PageModel>();
         novels.add(novel);
         touchedForDownload = novel.getTitle() + "'s information";
         executeDownloadTask(novels);
       }
       return true;
     case R.id.delete_novel:
       if (info.position > -1) {
         toggleProgressBar(true);
         PageModel novel = listItems.get(info.position);
         boolean result = NovelsDao.getInstance(getSherlockActivity()).deleteNovel(novel);
         if (result) {
           listItems.remove(novel);
           adapter.notifyDataSetChanged();
         }
         toggleProgressBar(false);
       }
       return true;
     default:
       return super.onContextItemSelected(item);
   }
 }
  /** Back to Novel Details */
  public void backToIndex() {
    String page = getIntent().getStringExtra(Constants.EXTRA_PAGE);
    PageModel pageModel = new PageModel(page);
    try {
      pageModel =
          NovelsDao.getInstance().getExistingPageModel(pageModel, null).getParentPageModel();

      Intent i = new Intent(this, DisplayLightNovelDetailsActivity.class);
      i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
      i.putExtra(Constants.EXTRA_PAGE, pageModel.getPage());
      startActivity(i);
      finish();
    } catch (Exception e) {
      Log.e(TAG, "Failed to get parent page model", e);
    }
  }
 public void onRestoreInstanceState(Bundle savedInstanceState) {
   super.onRestoreInstanceState(savedInstanceState);
   try {
     // replace the current pageModel with the saved instance
     PageModel tempPage = new PageModel();
     tempPage.setPage(savedInstanceState.getString(Constants.EXTRA_PAGE));
     // if(pageModel == null) {
     pageModel = dao.getPageModel(tempPage, null);
     executeTask(pageModel);
     // }
   } catch (Exception e) {
     Log.e(TAG, "Error when restoring instance", e);
   }
   Log.d(TAG, "onRestoreInstanceState Completed");
   restored = true;
 }
  /**
   * Move between chapters
   *
   * @param page
   */
  public void jumpTo(PageModel page) {
    setLastReadState();
    tts.stop();
    Intent currIntent = this.getIntent();
    currIntent.putExtra(Constants.EXTRA_PAGE, page.getPage());
    currIntent.putExtra(Constants.EXTRA_PAGE_IS_EXTERNAL, page.isExternal());

    // open external page as Intent to open browser
    if (page.isExternal() && !getHandleExternalLinkPreferences()) {
      try {
        Uri url = Uri.parse(page.getPage());
        Intent browserIntent = new Intent(Intent.ACTION_VIEW, url);
        startActivity(browserIntent);
      } catch (Exception ex) {
        String message = getResources().getString(R.string.error_parsing_url, page.getPage());
        Log.e(TAG, message, ex);
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
      }
    } else executeTask(page, false);
  }
  @Override
  public void onResume() {
    super.onResume();

    // compare the settings from OnCreate and after user resume.
    if (isFullscreen != getFullscreenPreferences()) {
      UIHelper.Recreate(this);
    }

    // show/hide option button
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
      Button btnOption = (Button) findViewById(R.id.btnMenu);
      // do not show option button for KitKat, immersive mode will show action bar
      if (getFullscreenPreferences() && Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        btnOption.setVisibility(View.VISIBLE);
      } else {
        btnOption.setVisibility(View.GONE);
      }
    }

    // moved page loading here rather than onCreate
    // to avoid only the first page loaded when resume from sleep
    // (activity destroyed, onCreate called again)
    // when the user navigate using next/prev/jumpTo
    if (!restored) {
      PageModel pageModel = new PageModel(getIntent().getStringExtra(Constants.EXTRA_PAGE));
      try {
        pageModel = NovelsDao.getInstance().getPageModel(pageModel, null, false);
        if (pageModel == null) {
          Toast.makeText(
                  this,
                  getResources().getString(R.string.bookmark_content_load_error),
                  Toast.LENGTH_LONG)
              .show();
          onBackPressed();
        } else {
          currPageModel = pageModel;
          this.getIntent().putExtra(Constants.EXTRA_PAGE_IS_EXTERNAL, currPageModel.isExternal());
          executeTask(pageModel, false);
        }
      } catch (Exception e) {
        Log.e(
            TAG,
            "Failed to get the PageModel for content: "
                + getIntent().getStringExtra(Constants.EXTRA_PAGE),
            e);
      }
    }
    setWebViewSettings();
    if (UIHelper.isTTSEnabled(this)) tts.setupTtsService();

    Log.d(TAG, "onResume Completed");
  }
 /**
  * Load chapter from DB
  *
  * @param pageModel
  * @param refresh
  */
 @SuppressLint("NewApi")
 private void executeTask(PageModel pageModel, boolean refresh) {
   NonLeakingWebView webView = (NonLeakingWebView) findViewById(R.id.webViewContent);
   if (pageModel.isExternal()) {
     loadExternalUrl(pageModel, refresh);
   } else {
     isPageLoaded = false;
     task = new LoadNovelContentTask(pageModel, refresh, this);
     String key = TAG + ":" + pageModel.getPage();
     boolean isAdded = LNReaderApplication.getInstance().addTask(key, task);
     if (isAdded) {
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
         task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
       else task.execute();
     } else {
       if (UIHelper.getColorPreferences(this))
         webView.loadData(
             "<p style='background: black; color: white;'>"
                 + getResources().getString(R.string.background_task_load)
                 + "</p>",
             "text/html",
             "utf-8");
       else
         webView.loadData(
             "<p style='background: white; color: black;'>"
                 + getResources().getString(R.string.background_task_load)
                 + "</p>",
             "text/html",
             "utf-8");
       LoadNovelContentTask tempTask =
           (LoadNovelContentTask) LNReaderApplication.getInstance().getTask(key);
       if (tempTask != null) {
         task = tempTask;
         task.owner = this;
       }
       toggleProgressBar(true);
     }
   }
   setPrevNextButtonState(pageModel);
 }
  /**
   * Load chapter for external url (not hosted in Baka-Tsuki). Used local cache if available
   * (wac/mht).
   *
   * @param pageModel
   * @param refresh
   */
  public void loadExternalUrl(PageModel pageModel, boolean refresh) {
    try {
      // check if .wac available
      String url = pageModel.getPage();
      String wacName = Util.getSavedWacName(url);
      final NonLeakingWebView wv = (NonLeakingWebView) findViewById(R.id.webViewContent);
      if (!Util.isStringNullOrEmpty(wacName) && !refresh) {
        client.setExternalNeedSave(false);
        String[] urlParts = url.split("#", 2);
        if (urlParts.length == 2) {
          executeLoadWacTask(wacName, urlParts[1], url);
        } else executeLoadWacTask(wacName, "", url);
      } else {
        if (refresh) {
          Toast.makeText(this, "Refreshing WAC: " + wacName, Toast.LENGTH_SHORT).show();
          Log.i(TAG, "Refreshing WAC: " + wacName);
        } else {
          Log.w(TAG, "WAC not available: " + wacName);
        }

        client.setExternalNeedSave(true);

        setWebViewSettings();
        wv.loadUrl(url);

        Intent currIntent = this.getIntent();
        currIntent.putExtra(Constants.EXTRA_PAGE, url);
        currIntent.putExtra(Constants.EXTRA_PAGE_IS_EXTERNAL, true);
      }
      setChapterTitle(pageModel);
      buildTOCMenu(pageModel);
      content = null;
    } catch (Exception ex) {
      Log.e(TAG, "Cannot load external content: " + pageModel.getPage(), ex);
    }
  }
 public void setLastReadState() {
   if (content != null) {
     // save last position and zoom
     WebView wv = (WebView) findViewById(R.id.webView1);
     content.setLastXScroll(wv.getScrollX());
     content.setLastYScroll(wv.getScrollY());
     content.setLastZoom(wv.getScale());
     try {
       content = dao.updateNovelContent(content);
     } catch (Exception ex) {
       ex.printStackTrace();
     }
     if (wv.getContentHeight() <= wv.getScrollY() + wv.getBottom()) {
       try {
         PageModel page = content.getPageModel();
         page.setFinishedRead(true);
         page = dao.updatePageModel(page);
         Log.d(
             TAG,
             "Update Content: "
                 + content.getLastXScroll()
                 + " "
                 + content.getLastYScroll()
                 + " "
                 + content.getLastZoom());
       } catch (Exception ex) {
         ex.printStackTrace();
         Log.d(TAG, "Error updating PageModel for Content: " + content.getPage());
       }
     }
     SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
     SharedPreferences.Editor editor = sharedPrefs.edit();
     editor.putString(Constants.PREF_LAST_READ, content.getPage());
     editor.commit();
   }
 }
 @SuppressLint("NewApi")
 private void executeAddTask(PageModel novel) {
   addTask = new AddNovelTask(this);
   String key = DisplayLightNovelDetailsActivity.TAG + ":Add:" + novel.getPage();
   boolean isAdded = LNReaderApplication.getInstance().addTask(key, addTask);
   if (isAdded) {
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
       addTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new PageModel[] {novel});
     else addTask.execute(new PageModel[] {novel});
   } else {
     Log.i(TAG, "Continue Add task: " + key);
     AddNovelTask tempTask = (AddNovelTask) LNReaderApplication.getInstance().getTask(key);
     if (tempTask != null) {
       addTask = tempTask;
       addTask.owner = this;
     }
     toggleProgressBar(true);
   }
 }
  @Override
  public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    try {
      if (content == null)
        savedInstanceState.putString(
            Constants.EXTRA_PAGE, getIntent().getStringExtra(Constants.EXTRA_PAGE));
      else savedInstanceState.putString(Constants.EXTRA_PAGE, content.getPageModel().getPage());

      if (currPageModel == null)
        savedInstanceState.putBoolean(Constants.EXTRA_PAGE_IS_EXTERNAL, false);
      else
        savedInstanceState.putBoolean(Constants.EXTRA_PAGE_IS_EXTERNAL, currPageModel.isExternal());

    } catch (Exception e) {
      Log.e(TAG, "Error when saving instance", e);
    }
    Log.d(TAG, "onSaveInstanceState Completed");
  }
 /**
  * Set activity title to current chapter title.
  *
  * @param pageModel
  */
 private void setChapterTitle(PageModel pageModel) {
   String title = pageModel.getPage();
   try {
     if (pageModel.getParent() != null) {
       Log.d(TAG, "Parent Page: " + pageModel.getParent());
       novelDetails =
           NovelsDao.getInstance().getNovelDetails(pageModel.getParentPageModel(), null, false);
       String volume =
           pageModel
               .getParent()
               .replace(
                   pageModel.getParentPageModel().getPage() + Constants.NOVEL_BOOK_DIVIDER, "");
       title = pageModel.getTitle() + " (" + volume + ")";
     }
   } catch (Exception ex) {
     Log.e(TAG, "Error when setting title: " + ex.getMessage(), ex);
   }
   setTitle(title);
 }
  /**
   * Build Table-of-Contents
   *
   * @param referencePageModel
   */
  private void buildTOCMenu(PageModel referencePageModel) {
    Log.d(TAG, "Trying to create TOC");
    try {
      BookModel book = referencePageModel.getBook(false);
      if (book != null) {
        ArrayList<PageModel> chapters = book.getChapterCollection();
        for (PageModel chapter : chapters) {
          if (chapter.getPage().contentEquals(referencePageModel.getPage())) {
            chapter.setHighlighted(true);
          } else chapter.setHighlighted(false);
        }
        Log.d(TAG, "TOC Found: " + chapters.size());

        int resourceId = R.layout.jumpto_list_item;
        // if (UIHelper.IsSmallScreen(this)) {
        // resourceId = R.layout.jumpto_list_item;
        // }
        jumpAdapter = new PageModelAdapter(this, resourceId, chapters);
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(getResources().getString(R.string.content_toc));
        builder.setAdapter(
            jumpAdapter,
            new OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int which) {
                PageModel page = jumpAdapter.getItem(which);
                jumpTo(page);
              }
            });
        builder.setNegativeButton(
            R.string.back_to_index,
            new OnClickListener() {

              @Override
              public void onClick(DialogInterface dialog, int which) {
                backToIndex();
              }
            });
        tocMenu = builder.create();
      }
    } catch (Exception e) {
      Log.e(TAG, "Cannot get current page for TOC menu.", e);
    }
  }
 private void buildTOCMenu() {
   if (novelDetails != null) {
     BookModel book = pageModel.getBook();
     if (book != null) {
       ArrayList<PageModel> chapters = book.getChapterCollection();
       int resourceId = R.layout.novel_list_item;
       if (UIHelper.IsSmallScreen(this)) {
         resourceId = R.layout.novel_list_item_small;
       }
       jumpAdapter = new PageModelAdapter(this, resourceId, chapters);
       AlertDialog.Builder builder = new AlertDialog.Builder(this);
       builder.setTitle("Jump To");
       builder.setAdapter(
           jumpAdapter,
           new OnClickListener() {
             public void onClick(DialogInterface dialog, int which) {
               PageModel page = jumpAdapter.getItem(which);
               jumpTo(page);
             }
           });
       tocMenu = builder.create();
     }
   }
 }
  @Override
  public void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    // Get the item that was clicked
    PageModel o = adapter.getItem(position);
    String novel = o.toString();

    // Create a bundle containing information about the novel that is clicked
    Bundle bundle = new Bundle();
    bundle.putString(Constants.EXTRA_NOVEL, novel);
    bundle.putString(Constants.EXTRA_PAGE, o.getPage());
    bundle.putString(Constants.EXTRA_TITLE, o.getTitle());
    bundle.putBoolean(
        Constants.EXTRA_ONLY_WATCHED,
        getSherlockActivity().getIntent().getBooleanExtra(Constants.EXTRA_ONLY_WATCHED, false));

    mFragListener.changeNextFragment(bundle);

    Log.d("DisplayLightNovelsActivity", o.getPage() + " (" + o.getTitle() + ")");

    // Need to send it through
  }
  @Override
  public void onGetResult(AsyncTaskResult<?> result, Class<?> t) {
    Exception e = result.getError();
    if (e == null) {
      // from LoadNovelsTask
      if (t == PageModel[].class) {
        PageModel[] list = (PageModel[]) result.getResult();
        Log.d(TAG, "LoadNovelsTask result ok");
        if (list != null && list.length > 0) {
          adapter.clear();
          adapter.addAll(list);
          toggleProgressBar(false);

          // Show message if watch list is empty
          if (list.length == 0 && onlyWatched) {
            Log.d(TAG, "WatchList result set message empty");
            loadingText.setVisibility(TextView.VISIBLE);
            loadingText.setText("Watch List is empty.");
          }
        } else {
          toggleProgressBar(false);
          loadingText.setVisibility(TextView.VISIBLE);
          loadingText.setText("List is empty.");
          Log.w(TAG, "Empty ArrayList!");
        }
      }
      // from DownloadNovelDetailsTask
      else if (t == NovelCollectionModel[].class) {
        setMessageDialog(new CallbackEventData("Download complete."));
        NovelCollectionModel[] list = (NovelCollectionModel[]) result.getResult();
        for (NovelCollectionModel novelCol : list) {
          try {
            PageModel page = novelCol.getPageModel();
            boolean found = false;
            for (PageModel temp : adapter.data) {
              if (temp.getPage().equalsIgnoreCase(page.getPage())) {
                found = true;
                break;
              }
            }
            if (!found) {
              adapter.data.add(page);
            }
          } catch (Exception e1) {
            Log.e(TAG, e1.getClass().toString() + ": " + e1.getMessage(), e1);
          }
        }
        adapter.notifyDataSetChanged();
        toggleProgressBar(false);
      } else {
        Log.e(TAG, "Unknown ResultType: " + t.getName());
      }
    } else {
      Log.e(TAG, e.getClass().toString() + ": " + e.getMessage(), e);
      Toast.makeText(
              getSherlockActivity(),
              e.getClass().toString() + ": " + e.getMessage(),
              Toast.LENGTH_LONG)
          .show();
    }
  }
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
      case R.id.menu_settings:
        Intent launchNewIntent = new Intent(this, DisplaySettingsActivity.class);
        startActivity(launchNewIntent);
        return true;
      case R.id.menu_refresh_chapter_content:

        /*
         * Implement code to refresh chapter content
         */
        PageModel page = null;
        if (content != null) {
          try {
            page = content.getPageModel();
          } catch (Exception e) {
            Log.e(TAG, "Cannot get current chapter.", e);
          }
        } else {
          String pageStr = getIntent().getStringExtra(Constants.EXTRA_PAGE);
          try {
            page = NovelsDao.getInstance().getExistingPageModel(new PageModel(pageStr), null);
            if (page == null) {
              // no page model, just url
              page = new PageModel(pageStr);
              page.setExternal(true);
            }
          } catch (Exception e) {
            Log.e(TAG, "Cannot get current chapter.", e);
          }
        }

        if (page != null) {
          executeTask(page, true);
        }
        return true;
      case R.id.invert_colors:

        /*
         * Implement code to invert colors
         */
        UIHelper.ToggleColorPref(this);
        UIHelper.Recreate(this);
        return true;
      case R.id.menu_chapter_previous:

        /*
         * Implement code to move to previous chapter
         */
        String currentPage = getIntent().getStringExtra(Constants.EXTRA_PAGE);
        try {
          if (novelDetails == null)
            novelDetails =
                NovelsDao.getInstance().getNovelDetails(content.getPageModel(), null, false);
          PageModel prev =
              novelDetails.getPrev(
                  currentPage, UIHelper.getShowMissing(this), UIHelper.getShowRedlink(this));
          if (prev != null) {
            jumpTo(prev);
          } else {
            Toast.makeText(
                    this,
                    getResources().getString(R.string.first_available_chapter),
                    Toast.LENGTH_SHORT)
                .show();
          }
        } catch (Exception e) {
          Log.e(TAG, "Cannot get previous chapter.", e);
        }
        return true;
      case R.id.menu_chapter_next:

        /*
         * Implement code to move to next chapter
         */
        String currentPage2 = getIntent().getStringExtra(Constants.EXTRA_PAGE);
        try {
          if (novelDetails == null)
            novelDetails =
                NovelsDao.getInstance().getNovelDetails(content.getPageModel(), null, false);

          PageModel next =
              novelDetails.getNext(
                  currentPage2, UIHelper.getShowMissing(this), UIHelper.getShowRedlink(this));
          if (next != null) {
            jumpTo(next);
          } else {
            Toast.makeText(
                    this,
                    getResources().getString(R.string.last_available_chapter),
                    Toast.LENGTH_SHORT)
                .show();
          }
        } catch (Exception e) {
          Log.e(TAG, "Cannot get next chapter.", e);
        }
        return true;
      case R.id.menu_chapter_toc:
        if (tocMenu != null) tocMenu.show();
        return true;
      case R.id.menu_search:
        showSearchBox();
        return true;
      case R.id.menu_bookmarks_here:
        if (bookmarkMenu != null) bookmarkMenu.show();
        return true;
      case R.id.menu_bookmarks:
        Intent bookmarkIntent = new Intent(this, DisplayBookmarkActivity.class);
        startActivity(bookmarkIntent);
        return true;
      case R.id.menu_downloads_list:
        Intent downloadsItent = new Intent(this, DownloadListActivity.class);
        startActivity(downloadsItent);
        return true;
      case R.id.menu_speak:
        tts.start(webView, content.getLastYScroll());
        return true;
      case R.id.menu_pause_tts:
        tts.pause();
        return true;
      case R.id.menu_save_external:
        // save based on current intent page name.
        String url = getIntent().getStringExtra(Constants.EXTRA_PAGE);
        NonLeakingWebView wv = (NonLeakingWebView) findViewById(R.id.webViewContent);
        if (!url.startsWith("http")) {
          url = getTitle().toString();
          Log.w(
              TAG,
              "Current page is not started with http, resolve from current webView url: " + url);
        }

        if (wv != null && !Util.isStringNullOrEmpty(url)) wv.saveMyWebArchive(url);
        return true;
      case R.id.menu_browser_back:
        if (webView != null && webView.canGoBack()) {
          // only good for android 4.4++
          webView.goBack();
        }
        return true;
      case android.R.id.home:
        finish();
        return true;
      default:
        return super.onOptionsItemSelected(item);
    }
  }
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
      case R.id.menu_settings:
        Intent launchNewIntent = new Intent(this, DisplaySettingsActivity.class);
        startActivity(launchNewIntent);
        return true;
      case R.id.menu_refresh_chapter_content:

        /*
         * Implement code to refresh chapter content
         */
        refresh = true;
        executeTask(pageModel);
        Toast.makeText(getApplicationContext(), "Refreshing", Toast.LENGTH_SHORT).show();
        return true;
      case R.id.invert_colors:

        /*
         * Implement code to invert colors
         */
        UIHelper.ToggleColorPref(this);
        UIHelper.Recreate(this);
        return true;
      case R.id.menu_chapter_previous:

        /*
         * Implement code to move to previous chapter
         */
        PageModel prev = novelDetails.getPrev(pageModel.getPage());
        if (prev != null) {
          jumpTo(prev);
        } else {
          Toast.makeText(getApplicationContext(), "First available chapter.", Toast.LENGTH_SHORT)
              .show();
        }
        return true;
      case R.id.menu_chapter_next:

        /*
         * Implement code to move to next chapter
         */
        PageModel next = novelDetails.getNext(pageModel.getPage());
        if (next != null) {
          jumpTo(next);
        } else {
          Toast.makeText(getApplicationContext(), "Last available chapter.", Toast.LENGTH_SHORT)
              .show();
        }

        return true;
      case R.id.menu_chapter_toc:
        tocMenu.show();
        return true;
      case R.id.menu_search:
        showSearchBox();
        return true;
      case android.R.id.home:
        tocMenu.show();
        return true;
    }
    return super.onOptionsItemSelected(item);
  }
  /**
   * Setup the chapter from DB, Internal page only Including JS for Bookmark highlighting, last read
   * position, and CSS
   *
   * @param loadedContent
   */
  @SuppressLint("NewApi")
  public void setContent(NovelContentModel loadedContent) {
    this.content = loadedContent;
    try {
      PageModel pageModel = content.getPageModel();

      if (content.getLastUpdate().getTime() < pageModel.getLastUpdate().getTime())
        Toast.makeText(
                this,
                getResources()
                    .getString(
                        R.string.content_may_updated,
                        content.getLastUpdate().toString(),
                        pageModel.getLastUpdate().toString()),
                Toast.LENGTH_LONG)
            .show();

      // load the contents here
      final NonLeakingWebView wv = (NonLeakingWebView) findViewById(R.id.webViewContent);
      setWebViewSettings();

      int lastPos = content.getLastYScroll();
      int pIndex = getIntent().getIntExtra(Constants.EXTRA_P_INDEX, -1);
      if (pIndex > 0) lastPos = pIndex;

      if (content.getLastZoom() > 0) {
        wv.setInitialScale((int) (content.getLastZoom() * 100));
      } else {
        wv.setInitialScale(100);
      }

      StringBuilder html = new StringBuilder();
      html.append("<html><head>");
      html.append(DisplayNovelContentHtmlHelper.getCSSSheet());
      html.append(DisplayNovelContentHtmlHelper.getViewPortMeta());
      html.append(
          DisplayNovelContentHtmlHelper.prepareJavaScript(
              lastPos, content.getBookmarks(), getBookmarkPreferences()));
      html.append("</head><body onclick='toogleHighlight(this, event);' onload='setup();'>");
      html.append(content.getContent());
      html.append("</body></html>");

      wv.loadDataWithBaseURL(
          UIHelper.getBaseUrl(this),
          html.toString(),
          "text/html",
          "utf-8",
          NonLeakingWebView.PREFIX_PAGEMODEL + content.getPage());
      setChapterTitle(pageModel);
      Log.d(
          TAG,
          "Load Content: "
              + content.getLastXScroll()
              + " "
              + content.getLastYScroll()
              + " "
              + content.getLastZoom());

      buildTOCMenu(pageModel);
      buildBookmarkMenu();

      invalidateOptionsMenu();

      Log.d(TAG, "Loaded: " + content.getPage());

      Intent currIntent = this.getIntent();
      currIntent.putExtra(Constants.EXTRA_PAGE, content.getPage());
      currIntent.putExtra(Constants.EXTRA_PAGE_IS_EXTERNAL, false);

    } catch (Exception e) {
      Log.e(TAG, "Cannot load content.", e);
    }
  }