⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tailview.cpp

📁 Ever wanted to just type tail -f error_log on Windows?Envious of your Unix friends who can track cha
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    if (m_pSettings->GetBeepOnChanges ())
    {
      MessageBeep (MB_ICONINFORMATION);  
    }
  }

  free ((void*) pszBuffer); 
}

/////////////////////////////////////////////////////////////////////////////
// 
//
void UpdateStatusBar (
  CTailView* pView,
  char*      pszText)
{
  char szBuf[1024] = "";
  char szTS[1024] = "";

  pView->m_ctlStatusBar.SetText (pszText, 0, 0);  
}

/////////////////////////////////////////////////////////////////////////////
// 
//
void UpdateStatusBar (
  CStatusBarCtrl* pStatus,
  long            lMatches,
  BOOL            bMatch)
{
  char szBuf[1024] = "";
  char szTS[1024] = "";

  GetTimeStamp (szTS);

  sprintf (szBuf, "Last updated: %s", szTS);
  pStatus->SetText (szBuf, 0, 0);

  if (bMatch)
  {
    sprintf (szBuf, "Last match: %s Total matches: %ld", szTS, lMatches);
    pStatus->SetText (szBuf, 1, 0);  
  }
}

/////////////////////////////////////////////////////////////////////////////
// 
//
void UpdateStatusBarPause (
  CStatusBarCtrl* pStatus,
  BOOL            bPaused)
{
  if (bPaused)
  {
    pStatus->SetText ("Paused", 3, 0);
  }
  else
  {
    pStatus->SetText ("", 3, 0);
  }
}

/////////////////////////////////////////////////////////////////////////////
// 
//
// This function determines whether a keyword is to be actioned,
// and by which plugin, and then calls the appropriate plugin's 
// handler function.
static void FireEvent (
  CTailView*  pView,
  const char* pszKeyword,
  const char* pszLine)
{
  CKeywordListItem* pKeyword = NULL;
  CKeywordPlugin*   pPlugin = NULL;
  CTailApp*         theApp = (CTailApp*) AfxGetApp ();
  int               i = 0;
  int               j = 0;

  // Loop over the keywords.
  if (pKeyword = pView->m_pSettings->FindKeyword (pszKeyword))
  {    
    // Only fire the event if this keyword is active. 
    // We should only be here if that is so, but it makes
    // the logic look a little more obvious.
    if (pKeyword->Active ())
    {
      // Loop over all plugins for this keyword.
      while (pPlugin = pKeyword->FindPlugin (j++))
      {
        // Only fire the event if the plugin is active for this keyword.
        if (pPlugin->Active ())
        {
          LogMessage ("Firing plugin '%s' for keyword '%s'...", pPlugin->GetShortName (), pszKeyword);

          pPlugin->m_pPlugin->Action ((const char*) pszKeyword, (const char*) pszLine, (const char*) pView->m_stParams.szFileName);
        }
      }
    }
  }
}

/////////////////////////////////////////////////////////////////////////////
// 
//
// PP: This should really be named 'UpdateView' or similar,
// as its function has grown significantly.
BOOL InsertText (
  CTailView*      pView,
  char*           pszText,
  BOOL            bDoColouring,
  long*           plMatchCount,
  BOOL*           pbMatch)
{
  CHARFORMAT stCF;
  CHARFORMAT2 stCF2;
  char szLine[2048] = "";
  char szLineBuffer[2048] = "";
  char* pszPtr;
  char* pszStart;
  char* pszLineEnd;
  char* pszToken;
  char** ppszKeywords;
  KEYWORD_LIST* pstKeywords = NULL;
  BOOL bFound = FALSE;
  BOOL bEnd = FALSE;
  BOOL bUpdated = FALSE;
  BOOL bShownLine = FALSE;
  DWORD dwIndex = -1;
  char  szTS[TIMESTAMP_LEN + 1] = "";
  long lLineLen = 0;
  CKeywordListItem* pKeyword;
  long lNumKeywords = 0;

  CTailApp* theApp = (CTailApp*) AfxGetApp ();

  GetTimeStamp (szTS);

  if (!bDoColouring)
  {
//    if (pView->m_ctlEdit.GetSafeHwnd())
    {
      pView->m_ctlEdit.ReplaceSel (pszText, FALSE);    
    }

    bUpdated = TRUE;

    if (!pView->m_pSettings->GetPaused () && !pView->m_bPaused)
    {
      ScrollToBottom (pView->m_ctlEdit.GetSafeHwnd());
    }

    if (pView->m_pSettings->GetBeepOnChanges() && bUpdated)
    {
      MessageBeep (MB_ICONINFORMATION);  
    }  

    return bUpdated;
  }

  memset (&stCF, 0, sizeof (CHARFORMAT));
  memset (&stCF2, 0, sizeof (CHARFORMAT2));

  pView->m_ctlEdit.SetSel (-1, -1);

  pszPtr = pszText;

  // Chew off a line at a time.
  while (1)
  {
    long lSelStart = 0;
    long lSelEnd = 0;

    long lLineSelStart = 0;
    long lLineSelEnd = 0;

    bShownLine = FALSE;

    //PP: NEW ***
    bFound = FALSE;

    pView->m_ctlEdit.SetSel (-1, -1);

    // Find the end of line.
    pszLineEnd = strchr (pszPtr, '\n');

    memset (szLine, 0, sizeof (szLine));

    if (pszLineEnd)
    {
      // Take off the CR+LF.
      lLineLen = MIN ((sizeof (szLine) - 1), (pszLineEnd - pszPtr + 1)) - 2;
      strncpy (szLine, pszPtr, MIN ((sizeof (szLine) - 1), (pszLineEnd - pszPtr + 1)));
    }
    else
    {
      lLineLen = MIN ((sizeof (szLine) - 1), (strlen (pszPtr)));
      strncpy (szLine, pszPtr, MIN ((sizeof (szLine) - 1), (strlen (pszPtr))));

      bEnd = TRUE;
    }
    
    // PP: This needs moving around.
    if (pView->m_pSettings->GetShowAllLines ())
    {
      if (pView->m_pSettings->GetHighlightLine() && pView->m_pSettings->GetHighlightWholeLine ())
      {
        if (pszLineEnd && ((strlen (szLine) + 1) <= LINE_PAD))
        {
          memset (&szLineBuffer[0], ' ', LINE_PAD);

          strncpy (szLineBuffer, szLine, lLineLen);

          if (pszLineEnd)
          {
            szLineBuffer[LINE_PAD - 1] = 0x0d;
            szLineBuffer[LINE_PAD]     = 0x0a;
            szLineBuffer[LINE_PAD + 1] = '\0';
          }
          else
          {
            szLineBuffer[LINE_PAD - 1] = '\0';
          } 
        }
        else
        {
          strcpy (szLineBuffer, szLine);
        }
      }
      else
      {
          strcpy (szLineBuffer, szLine);      
      }

//      LogMessage ("Writing '%s'", szLineBuffer);

//      pView->m_ctlEdit.ReplaceSel (szLine, FALSE);
      pView->m_ctlEdit.ReplaceSel (szLineBuffer, FALSE);

      bUpdated = TRUE;
      bShownLine = TRUE; // Warlock, added
    }

    // Get the keyword list.
    ppszKeywords = pView->m_ppszList;
    pstKeywords = pView->m_pstKeywordList;

    pszPtr = &szLine[0];

    lNumKeywords = pView->m_pSettings->GetNumKeywords ();

//    if (ppszKeywords && *ppszKeywords)
//    if (pView->lNumKeywords)
    if (lNumKeywords)
    {
      // Loop over each keyword.
//      while (*ppszKeywords)

      dwIndex = -1;

//      for (int iIndex = 0; iIndex < pView->lNumKeywords; iIndex++)
      for (int iIndex = 0; iIndex < lNumKeywords; iIndex++)
      {
        CString msg;

        pKeyword = pView->m_pSettings->FindKeyword (pstKeywords[iIndex].szKeyword);

        pszStart = pszPtr = &szLine[0];

        dwIndex++;

        // Search for the keyword on the line.
        if (pKeyword && pKeyword->Active ())
        {
//        while (pszToken = strstr (pszStart, *ppszKeywords))
//      while (pszToken = strstr (pszStart, pstKeywords[iIndex].szKeyword)) // Warlock, commented out, changed to below
        while (pszToken = strstr (pszPtr, pstKeywords[iIndex].szKeyword)) // Warlock, using pszPtr, fix multiple keywords per line
//        while ((pszToken = strstr (pszPtr, pKeyword->Keyword ())) // Warlock, using pszPtr, fix multiple keywords per line
//              && pKeyword->Active ()) 
        {
          // We've got another match.
          (*plMatchCount)++;
          pstKeywords[iIndex].dwMatches++;
          strcpy (pstKeywords[iIndex].szTimestamp, szTS);

          // Call the event associated with this keyword.
//          FireEvent (pView, *ppszKeywords, szLine);
          FireEvent (pView, pstKeywords[iIndex].szKeyword, szLine);
          
          // if (!theApp->m_bShowAllLines && !bShownLine && !pstKeywords[iIndex].bExclude) // Warlock, commented out
          if (!pView->m_pSettings->GetShowAllLines() && !bShownLine && pstKeywords[iIndex].bExclude) // Warlock, show keyword lines
          {
            if ((strlen (szLine) + 1) <= LINE_PAD)
            {
              memset (&szLineBuffer[0], ' ', LINE_PAD);

              strncpy (szLineBuffer, szLine, strlen (szLine));

              szLineBuffer[LINE_PAD - 1] = '\0';
            }

            pView->m_ctlEdit.ReplaceSel (szLine, FALSE);
//            pView->m_ctlEdit.ReplaceSel (szLineBuffer, FALSE);

//            pView->m_ctlEdit.GetSel (lOrgSelStart, lOrgSelEnd);

            bUpdated = TRUE;
            bShownLine = TRUE;
          }

          pView->m_ctlEdit.SetSel (-1, -1);

          pView->m_ctlEdit.GetSel (lSelStart, lSelEnd);

//          lSelStart -= (strlen (szLine) - (pszToken - pszStart));
//          lSelEnd -= (strlen (szLine) - ((pszToken - pszStart) + strlen (*ppszKeywords)));
//          lSelEnd -= (strlen (szLine) - ((pszToken - pszStart) + strlen (pstKeywords[iIndex].szKeyword)));
//          lSelStart -= (strlen (szLine) - (pszToken - pszStart) - 1); // Warlock, - 1
     
          lSelStart -= (strlen (szLine) - (pszToken - pszStart)); // PP: No minus at all!
          lSelEnd -= (strlen (szLine) - ((pszToken - pszStart) + strlen (pstKeywords[iIndex].szKeyword)) - 1); // Warlock, - 1
  
          if (lLineSelStart == 0)
          {
            lLineSelStart = lSelStart - (pszToken - pszStart);
            lLineSelEnd = lLineSelStart + strlen (szLine);
          }
          
          pView->m_ctlEdit.SetSel (lSelStart, lSelEnd);

          pView->m_ctlEdit.GetSelectionCharFormat (stCF);

          stCF.dwMask = CFM_COLOR | CFM_BOLD;
          stCF.dwEffects = CFE_BOLD;

          stCF.crTextColor = pKeyword->Colour ();

          pView->m_ctlEdit.SetSelectionCharFormat (stCF);

          pszPtr = pszToken + strlen (*ppszKeywords);
//          pszPtr = pszToken + strlen (pstKeywords[iIndex].szKeyword);

          // pszStart = pszPtr; // Warlock, commented out, fix multiple keywords per line

          bFound = TRUE;

          *pbMatch = TRUE;
        }
        } // if (pKeyword->Active ())

        // Get the next keyword.
//        ppszKeywords++;
      }

      // Highlight the entire line.
      if (bFound && pView->m_pSettings->GetHighlightLine())
      {
          pView->m_ctlEdit.SetSel (lLineSelStart, lLineSelEnd);

          stCF2.cbSize = sizeof (stCF2);
          stCF2.dwMask = CFM_PROTECTED|CFM_BACKCOLOR;
          stCF2.crBackColor = pView->m_pSettings->GetHighlightColour();

          SendMessage(pView->m_ctlEdit, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&stCF2);
      } 
    }

    if (bEnd)
    {
      break;
    }

    // Poke the pointer on by one.
    pszPtr = pszLineEnd + 1;

    bFound = FALSE;

    // We've reached the end of the string - don't bother going round again.
    if (!*pszPtr)
    {
      break;
    }
  }   

  // Update the stats.
  UpdateStatusBar (&pView->m_ctlStatusBar, *plMatchCount, *pbMatch);
  
  // Update the tally window.
  // Warlock, added bTallyVisible check
//  if (pView->bTallyVisible)
//  if (theApp->m_bTallyVisible)
  {
    if (AfxIsValidAddress (pView->m_pTallyWindow, sizeof (TallyWindow)) && pView->m_pTallyWindow->GetSafeHwnd ())
    {
      pView->m_pTallyWindow->UpdateMatches ();
    }
  }

  if (!pView->m_pSettings->GetPaused() && !pView->m_bPaused)
  {
    ScrollToBottom (pView->m_ctlEdit.GetSafeHwnd());// hwndEdit);
  }

  if (pView->m_pSettings->GetBeepOnChanges() && bUpdated)
  {
    MessageBeep (MB_ICONINFORMATION);  
  } 

  return bUpdated;
}

/////////////////////////////////////////////////////////////////////////////
// 
//
void CTailView::CopyText()
{  
  m_ctlEdit.Copy ();
}


/////////////////////////////////////////////////////////////////////////////
// 
//
void ScrollToBottom (
  HWND hwnd)
{
  CTailApp* theApp = NULL;

  theApp = (CTailApp*) AfxGetApp ();

  ::SendMessage (hwnd, WM_VSCROLL, (WPARAM) SB_BOTTOM, 0);

  /* 4.1.2 Added version check to fix W2K bug in RichEdit control. */
  if (! ((theApp->m_fVersion >= 5.0) && (theApp->m_dwPlatformID == VER_PLATFORM_WIN32_NT)) ) // Warlock, scroll to bottom, compiled with MSVC2002, tested on Win2K-SP? and WinXP-SP1
  {
    ::SendMessage (hwnd, WM_VSCROLL, (WPARAM) SB_PAGEUP, (LPARAM) 0); 
  }
}

/////////////////////////////////////////////////////////////////////////////
// 
//
void CTailView::ReloadKeywords (
  void)
{
  char* pszItem = NULL;
  FILE* fp = NULL;
  char szLine[MAX_KEYWORD_LEN + 1] = "";
  char szAppPath[_MAX_PATH] = "";
  char szDrive[_MAX_DRIVE] = "";
  char szPath[_MAX_PATH] = "";
  char szConfigFile[_MAX_PATH] = "";
  char** ppszNewList = NULL;
  KEYWORD_LIST* pstNewKeywordList = NULL;
  long lKeywordCount = 0;
  int i = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -