| 1689 | | // ----------------------------------------------------------------------------- |
| 1690 | | |
| 1691 | | void UserInfoDlg::CreateHistory() |
| 1692 | | { |
| 1693 | | tabList[HistoryInfo].label = tr("&History"); |
| 1694 | | QWidget* p = new QWidget(this); |
| 1695 | | tabList[HistoryInfo].tab = p; |
| 1696 | | p->setObjectName(tabList[HistoryInfo].label); |
| 1697 | | tabList[HistoryInfo].loaded = false; |
| 1698 | | |
| 1699 | | QVBoxLayout* lay = new QVBoxLayout(p); |
| 1700 | | |
| 1701 | | QHBoxLayout* l = new QHBoxLayout(); |
| 1702 | | |
| 1703 | | lblHistory = new QLabel(); |
| 1704 | | lblHistory->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); |
| 1705 | | l->addWidget(lblHistory, 1); |
| 1706 | | |
| 1707 | | chkHistoryReverse = new QCheckBox(tr("Rever&se")); |
| 1708 | | connect(chkHistoryReverse, SIGNAL(toggled(bool)), SLOT(HistoryReverse(bool))); |
| 1709 | | chkHistoryReverse->setChecked(m_bHistoryReverse = Config::Chat::instance()->reverseHistory()); |
| 1710 | | chkHistoryReverse->setFixedSize(chkHistoryReverse->sizeHint()); |
| 1711 | | l->addWidget(chkHistoryReverse); |
| 1712 | | |
| 1713 | | lay->addLayout(l); |
| 1714 | | |
| 1715 | | mlvHistory = new HistoryView(true, myId, m_nPPID, p); |
| 1716 | | |
| 1717 | | connect(mlvHistory, SIGNAL(viewurl(QWidget*, QString)), LicqGui::instance(), SLOT(viewUrl(QWidget*, QString))); |
| 1718 | | |
| 1719 | | lay->addWidget(mlvHistory, 1); |
| 1720 | | |
| 1721 | | l = new QHBoxLayout(); |
| 1722 | | |
| 1723 | | lneFilter = new QLineEdit(); |
| 1724 | | lblFilter = new QLabel(tr("&Filter: ")); |
| 1725 | | lblFilter->setBuddy(lneFilter); |
| 1726 | | l->addWidget(lblFilter); |
| 1727 | | l->addWidget(lneFilter, 1); |
| 1728 | | connect(lneFilter, SIGNAL(textChanged(const QString&)), SLOT(slot_showHistoryTimer())); |
| 1729 | | |
| 1730 | | lay->addLayout(l); |
| 1731 | | |
| 1732 | | QShortcut* a = new QShortcut(Qt::Key_U + Qt::CTRL, p); |
| 1733 | | connect(a, SIGNAL(activated()), SLOT(HistoryReload())); |
| 1734 | | |
| 1735 | | a = new QShortcut(Qt::Key_F5, p); |
| 1736 | | connect(a, SIGNAL(activated()), SLOT(HistoryReload())); |
| 1737 | | } |
| 1738 | | |
| 1739 | | /*! \brief Resets and restarts the timeout for the history filter |
| 1740 | | * |
| 1741 | | * Everytime this slot is called, the timer for the history filter |
| 1742 | | * is reset. |
| 1743 | | * The timeout is set to 1000 ms. |
| 1744 | | * This slot is called everytime the user changes the filter |
| 1745 | | * string in the history tab. After 1 second of being idle, the |
| 1746 | | * filter is invoked because SIGNAL(timeout()) is connected to |
| 1747 | | * ShowHistory(). |
| 1748 | | */ |
| 1749 | | void UserInfoDlg::slot_showHistoryTimer() |
| 1750 | | { |
| 1751 | | timer->stop(); |
| 1752 | | timer->setSingleShot(true); |
| 1753 | | timer->start(1000); |
| 1754 | | } |
| 1755 | | |
| 1865 | | |
| 1866 | | void UserInfoDlg::SetupHistory() |
| 1867 | | { |
| 1868 | | tabList[HistoryInfo].loaded = true; |
| 1869 | | |
| 1870 | | ICQUser* u = gUserManager.FetchUser(myId.toLatin1(), m_nPPID, LOCK_R); |
| 1871 | | if (u == NULL) return; |
| 1872 | | |
| 1873 | | if (!u->GetHistory(m_lHistoryList)) |
| 1874 | | { |
| 1875 | | if(u->HistoryFile()) |
| 1876 | | mlvHistory->setText(tr("Error loading history file: %1\nDescription: %2") |
| 1877 | | .arg(u->HistoryFile()).arg(u->HistoryName())); |
| 1878 | | else |
| 1879 | | mlvHistory->setText(tr("Sorry, history is disabled for this person.")); |
| 1880 | | |
| 1881 | | btnMain2->setEnabled(false); |
| 1882 | | gUserManager.DropUser(u); |
| 1883 | | } |
| 1884 | | else |
| 1885 | | { |
| 1886 | | m_bHistoryReverse = chkHistoryReverse->isChecked(); |
| 1887 | | m_iHistoryEIter = m_lHistoryList.end(); |
| 1888 | | m_iHistorySIter = m_iHistoryEIter; |
| 1889 | | for (unsigned short i = 0; |
| 1890 | | (i < Config::Chat::instance()->histMsgNum()) && (m_iHistorySIter != m_lHistoryList.begin()); |
| 1891 | | i++) |
| 1892 | | { |
| 1893 | | m_iHistorySIter--; |
| 1894 | | } |
| 1895 | | m_nHistoryIndex = m_lHistoryList.size(); |
| 1896 | | gUserManager.DropUser(u); |
| 1897 | | ShowHistory(); |
| 1898 | | |
| 1899 | | btnMain2->setEnabled((m_nHistoryIndex - m_nHistoryShowing) != 0); |
| 1900 | | } |
| 1901 | | |
| 1902 | | btnMain3->setEnabled(false); |
| 1903 | | } |
| 1904 | | |
| 1905 | | // ----------------------------------------------------------------------------- |
| 1906 | | |
| 1907 | | |
| 1908 | | void UserInfoDlg::HistoryReload() |
| 1909 | | { |
| 1910 | | ICQUser::ClearHistory(m_lHistoryList); |
| 1911 | | SetupHistory(); |
| 1912 | | } |
| 1913 | | |
| 1914 | | void UserInfoDlg::HistoryReverse(bool newVal) |
| 1915 | | { |
| 1916 | | if (chkHistoryReverse->isChecked() != newVal) |
| 1917 | | chkHistoryReverse->setChecked(newVal); |
| 1918 | | else if(m_bHistoryReverse != newVal) |
| 1919 | | { |
| 1920 | | m_bHistoryReverse = newVal; |
| 1921 | | ShowHistory(); |
| 1922 | | } |
| 1923 | | } |
| 1924 | | |
| 1925 | | void UserInfoDlg::ShowHistoryPrev() |
| 1926 | | { |
| 1927 | | if (m_iHistorySIter != m_lHistoryList.begin()) |
| 1928 | | { |
| 1929 | | m_iHistoryEIter = m_iHistorySIter; |
| 1930 | | m_nHistoryIndex -= Config::Chat::instance()->histMsgNum(); |
| 1931 | | for (unsigned short i = 0; |
| 1932 | | (i < Config::Chat::instance()->histMsgNum()) && (m_iHistorySIter != m_lHistoryList.begin()); |
| 1933 | | i++) |
| 1934 | | { |
| 1935 | | m_iHistorySIter--; |
| 1936 | | } |
| 1937 | | ShowHistory(); |
| 1938 | | btnMain2->setEnabled(m_iHistorySIter != m_lHistoryList.begin()); |
| 1939 | | btnMain3->setEnabled(true); |
| 1940 | | } |
| 1941 | | } |
| 1942 | | |
| 1943 | | void UserInfoDlg::ShowHistoryNext() |
| 1944 | | { |
| 1945 | | if (m_iHistoryEIter != m_lHistoryList.end()) |
| 1946 | | { |
| 1947 | | m_iHistorySIter = m_iHistoryEIter; |
| 1948 | | for (unsigned short i = 0; |
| 1949 | | (i < Config::Chat::instance()->histMsgNum()) && (m_iHistoryEIter != m_lHistoryList.end()); |
| 1950 | | i++) |
| 1951 | | { |
| 1952 | | m_iHistoryEIter++; |
| 1953 | | m_nHistoryIndex++; |
| 1954 | | } |
| 1955 | | ShowHistory(); |
| 1956 | | btnMain3->setEnabled(m_iHistoryEIter != m_lHistoryList.end()); |
| 1957 | | btnMain2->setEnabled(true); |
| 1958 | | } |
| 1959 | | } |
| 1960 | | |
| 1961 | | bool UserInfoDlg::chkContains(const char* d, const char* filter, int len) |
| 1962 | | { |
| 1963 | | if (!d) |
| 1964 | | return false; |
| 1965 | | |
| 1966 | | while (*d) |
| 1967 | | { |
| 1968 | | if (strncasecmp(d, filter, len) == 0) |
| 1969 | | return true; |
| 1970 | | d++; |
| 1971 | | } |
| 1972 | | |
| 1973 | | return false; |
| 1974 | | } |
| 1975 | | |
| 1976 | | void UserInfoDlg::ShowHistory() |
| 1977 | | { |
| 1978 | | m_nHistoryShowing = 0; |
| 1979 | | |
| 1980 | | // Last check (will be true if history is empty) |
| 1981 | | if (m_lHistoryList.size() == 0) return; |
| 1982 | | HistoryListIter tempIter = m_iHistorySIter; |
| 1983 | | |
| 1984 | | QString s; |
| 1985 | | QString tmp; |
| 1986 | | QDateTime date; |
| 1987 | | QString contactName = tr("server"); |
| 1988 | | QTextCodec* codec = QTextCodec::codecForLocale(); |
| 1989 | | ICQUser* u = gUserManager.FetchUser(myId.toLatin1(), m_nPPID, LOCK_R); |
| 1990 | | bool bUseHTML = false; |
| 1991 | | if (u != NULL) |
| 1992 | | { |
| 1993 | | codec = UserCodec::codecForICQUser(u); |
| 1994 | | if (!m_bOwner) |
| 1995 | | contactName = QString::fromUtf8(u->GetAlias()); |
| 1996 | | for (int x = 0; x < myId.length(); x++) |
| 1997 | | { |
| 1998 | | if (!myId[x].isDigit()) |
| 1999 | | { |
| 2000 | | bUseHTML = true; |
| 2001 | | break; |
| 2002 | | } |
| 2003 | | } |
| 2004 | | gUserManager.DropUser(u); |
| 2005 | | } |
| 2006 | | char* ftxt = qstrdup(codec->fromUnicode(lneFilter->text())); |
| 2007 | | int flen = strlen(ftxt); |
| 2008 | | |
| 2009 | | QString ownerName; |
| 2010 | | ICQOwner* o = gUserManager.FetchOwner(m_nPPID, LOCK_R); |
| 2011 | | if (o != NULL) |
| 2012 | | { |
| 2013 | | // Don't use this codec to decode our conversation with the contact |
| 2014 | | // since we're using the contact's encoding, not ours. |
| 2015 | | QTextCodec* ownerCodec = UserCodec::codecForICQUser(o); |
| 2016 | | ownerName = ownerCodec->toUnicode(o->GetAlias()); |
| 2017 | | gUserManager.DropOwner(m_nPPID); |
| 2018 | | } |
| 2019 | | |
| 2020 | | mlvHistory->clear(); |
| 2021 | | mlvHistory->setReverse(m_bHistoryReverse); |
| 2022 | | while (m_nHistoryShowing < Config::Chat::instance()->histMsgNum()) |
| 2023 | | { |
| 2024 | | if(UserInfoDlg::chkContains((*tempIter)->Text(), ftxt, flen)) |
| 2025 | | { |
| 2026 | | date.setTime_t((*tempIter)->Time()); |
| 2027 | | QString messageText; |
| 2028 | | if ((*tempIter)->SubCommand() == ICQ_CMDxSUB_SMS) // SMSs are always in UTF-8 |
| 2029 | | messageText = QString::fromUtf8((*tempIter)->Text()); |
| 2030 | | else |
| 2031 | | messageText = codec->toUnicode((*tempIter)->Text()); |
| 2032 | | |
| 2033 | | mlvHistory->addMsg((*tempIter)->Direction(), false, |
| 2034 | | ((*tempIter)->SubCommand() == ICQ_CMDxSUB_MSG ? QString("") : (EventDescription(*tempIter) + " ")), |
| 2035 | | date, |
| 2036 | | (*tempIter)->IsDirect(), |
| 2037 | | (*tempIter)->IsMultiRec(), |
| 2038 | | (*tempIter)->IsUrgent(), |
| 2039 | | (*tempIter)->IsEncrypted(), |
| 2040 | | ((*tempIter)->Direction() == D_RECEIVER ? contactName : ownerName), |
| 2041 | | MLView::toRichText(messageText, true, bUseHTML)); |
| 2042 | | m_nHistoryShowing++; |
| 2043 | | } |
| 2044 | | |
| 2045 | | tempIter++; |
| 2046 | | if (tempIter == (lneFilter->text().isEmpty() ? |
| 2047 | | m_iHistoryEIter : m_lHistoryList.end())) |
| 2048 | | break; |
| 2049 | | } |
| 2050 | | |
| 2051 | | // History view is buffered so tell it write buffer to output now that all entries have been added |
| 2052 | | mlvHistory->updateContent(); |
| 2053 | | |
| 2054 | | delete [] ftxt; |
| 2055 | | if(lneFilter->text().isEmpty()) |
| 2056 | | lblHistory->setText(tr("[<font color=\"%1\">Received</font>] " |
| 2057 | | "[<font color=\"%2\">Sent</font>] " |
| 2058 | | "%3 to %4 of %5") |
| 2059 | | .arg(Config::Chat::instance()->recvColor()) |
| 2060 | | .arg(Config::Chat::instance()->sentColor()) |
| 2061 | | .arg(m_nHistoryIndex - m_nHistoryShowing + 1) |
| 2062 | | .arg(m_nHistoryIndex) |
| 2063 | | .arg(m_lHistoryList.size())); |
| 2064 | | else |
| 2065 | | lblHistory->setText(tr("[<font color=\"%1\">Received</font>] " |
| 2066 | | "[<font color=\"%2\">Sent</font>] " |
| 2067 | | "%3 out of %4 matches") |
| 2068 | | .arg(Config::Chat::instance()->recvColor()) |
| 2069 | | .arg(Config::Chat::instance()->sentColor()) |
| 2070 | | .arg(m_nHistoryShowing) |
| 2071 | | .arg(m_lHistoryList.size())); |
| 2072 | | /*mlvHistory->append(tmp.left(tmp.length()-4));*/ |
| 2073 | | if(!m_bHistoryReverse) |
| 2074 | | mlvHistory->GotoEnd(); |
| 2075 | | else |
| 2076 | | mlvHistory->GotoHome(); |
| 2077 | | } |
| 2078 | | |
| 2079 | | |
| 2080 | | void UserInfoDlg::SaveHistory() |
| 2081 | | { |
| 2082 | | ICQUser* u = gUserManager.FetchUser(myId.toLatin1(), m_nPPID, LOCK_R); |
| 2083 | | if (u == NULL) return; |
| 2084 | | |
| 2085 | | QTextCodec* codec = UserCodec::codecForICQUser(u); |
| 2086 | | |
| 2087 | | u->SaveHistory(codec->fromUnicode(mlvHistory->toPlainText())); |
| 2088 | | gUserManager.DropUser(u); |
| 2089 | | } |
| 2090 | | |
| 2091 | | |
| 2092 | | // ----------------------------------------------------------------------------- |