/**
   * called when visibility of current fragment is (potentially) altered by * * drawer being
   * shown/hidden * * whether buffer is shown in the pager (see MainPagerAdapter) * * availability
   * of buffer & activity * * lifecycle
   */
  public void maybeChangeVisibilityState() {
    if (DEBUG_VISIBILITY) logger.debug("maybeChangeVisibilityState()");
    if (activity == null || buffer == null) return;

    // see if visibility has changed. if it hasn't, do nothing
    boolean obscured = activity.isPagerNoticeablyObscured();
    boolean watched = started && pagerVisible && !obscured;

    if (buffer.isWatched == watched) return;

    // visibility has changed.
    if (watched) {
      highlights = buffer.highlights;
      privates = (buffer.type == Buffer.PRIVATE) ? buffer.unreads : 0;
    }
    buffer.setWatched(watched);
    scrollToHotLineIfNeeded();

    // move the read marker in weechat (if preferences dictate)
    if (!watched && P.hotlistSync) {
      EventBus.getDefault()
          .post(new SendMessageEvent("input " + buffer.fullName + " /buffer set hotlist -1"));
      EventBus.getDefault()
          .post(
              new SendMessageEvent(
                  "input " + buffer.fullName + " /input set_unread_current_buffer"));
    }
  }
 // this method is using the following:
 // lastVisibleLine      last line that exists in the buffer. NOTE: "visible" here means line is
 // not filtered in weechat
 // readMarkerLine       used for display. it is:
 //     * saved on app shutdown and restored on start
 //     * altered if a buffer has been read in weechat (see BufferList.saveLastReadLine)
 //     * set to the last displayed line when user navigates away from a buffer
 //     * shifted from invisible line to last visible line if buffer is filtered
 private void maybeMoveReadMarker() {
   if (DEBUG_VISIBILITY) logger.debug("maybeMoveReadMarker()");
   if (buffer != null && buffer.readMarkerLine != buffer.lastVisibleLine) {
     buffer.readMarkerLine = buffer.lastVisibleLine;
     linesAdapter.needMoveLastReadMarker = true;
     onLinesChanged();
   }
 }
  /** attempts to perform tab completion on the current input */
  @SuppressLint("SetTextI18n")
  private void tryTabComplete() {
    if (DEBUG_TAB_COMPLETE) logger.debug("tryTabComplete()");
    if (buffer == null) return;

    String txt = uiInput.getText().toString();
    if (!tcInProgress) {
      // find the end of the word to be completed
      // blabla nick|
      tcWordEnd = uiInput.getSelectionStart();
      if (tcWordEnd <= 0) return;

      // find the beginning of the word to be completed
      // blabla |nick
      tcWordStart = tcWordEnd;
      while (tcWordStart > 0 && txt.charAt(tcWordStart - 1) != ' ') tcWordStart--;

      // get the word to be completed, lowercase
      if (tcWordStart == tcWordEnd) return;
      String prefix = txt.substring(tcWordStart, tcWordEnd).toLowerCase();

      // compute a list of possible matches
      // nicks is ordered in last used comes first way, so we just pick whatever comes first
      // if computed list is empty, abort
      tcMatches = new Vector<>();

      for (String nick : buffer.getLastUsedNicksCopy())
        if (nick.toLowerCase().startsWith(prefix)) tcMatches.add(nick.trim());
      if (tcMatches.size() == 0) return;

      tcIndex = 0;
    } else {
      tcIndex = (tcIndex + 1) % tcMatches.size();
    }

    // get new nickname, adjust the end of the word marker
    // and finally set the text and place the cursor on the end of completed word
    String nick = tcMatches.get(tcIndex);
    if (tcWordStart == 0) nick += ": ";
    uiInput.setText(txt.substring(0, tcWordStart) + nick + txt.substring(tcWordEnd));
    tcWordEnd = tcWordStart + nick.length();
    uiInput.setSelection(tcWordEnd);
    // altering text in the input box sets tcInProgress to false,
    // so this is the last thing we do in this function:
    tcInProgress = true;
  }
  private void attachToBuffer() {
    logger.debug("attachToBuffer()");

    buffer.setBufferEye(this);

    linesAdapter = new ChatLinesAdapter(activity, buffer, uiLines);
    linesAdapter.setFont(P.bufferFont);
    linesAdapter.readLinesFromBuffer();

    activity.runOnUiThread(
        new Runnable() {
          @Override
          public void run() {
            activity.updateCutePagerTitleStrip();
            uiLines.setAdapter(linesAdapter);
            maybeChangeHeader();
          }
        });
    maybeChangeVisibilityState();
  }
 private void maybeChangeHeader() {
   final LINES s = buffer.getLineStatus();
   if (status == s) return;
   status = s;
   activity.runOnUiThread(
       new Runnable() {
         @Override
         public void run() {
           logger.debug("maybeChangeHeader(); {}", s);
           if (s == LINES.EVERYTHING_FETCHED) {
             uiMore.removeAllViews();
           } else {
             if (uiMore.getChildCount() == 0) uiMore.addView(uiMoreButton);
             boolean more = s == LINES.CAN_FETCH_MORE;
             uiMoreButton.setEnabled(more);
             uiMoreButton.setTextColor(more ? 0xff80cbc4 : 0xff777777);
             uiMoreButton.setText(more ? "Fetch more lines" : "Fetching lines…");
           }
         }
       });
 }
 private void requestMoreLines() {
   if (buffer.getLineStatus() == LINES.CAN_FETCH_MORE) {
     buffer.requestMoreLines();
     maybeChangeHeader();
   }
 }
 // buffer might be null if we are closing fragment that is not connected
 private void detachFromBuffer() {
   if (DEBUG_LIFECYCLE) logger.debug("detachFromBuffer()");
   maybeChangeVisibilityState();
   if (buffer != null) buffer.setBufferEye(null);
   buffer = null;
 }