//============================================================================= // // File : NotifierWindow.cpp // Creation date : Tue Jul 6 2004 20:25:12 CEST by Szymon Stefanek // // This file is part of the KVIrc irc client distribution // Copyright (C) 2004-2008 Iacopo Palazzi < iakko(at)siena.linux.it > // // This program is FREE software. You can redistribute it and/or // modify it under the linkss of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your opinion) any later version. // // This program is distributed in the HOPE that it will be USEFUL, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, write to the Free Software Foundation, // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //============================================================================= #include "kvi_settings.h" #include "NotifierMessage.h" #include "NotifierWindow.h" #include "NotifierWindowBorder.h" #include "NotifierWindowTab.h" #include "KviIconManager.h" #include "KviConfigurationFile.h" #include "KviWindow.h" #include "KviLocale.h" #include "KviMainWindow.h" #include "KviMircCntrl.h" #include "KviOptions.h" #include "KviUserInput.h" #include "KviThemedLineEdit.h" #include #include #include #include #include #include #include #include #include #include #include extern NotifierWindow * g_pNotifierWindow; NotifierWindow::NotifierWindow() : QWidget(0, #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint) #else Qt::FramelessWindowHint | #ifndef COMPILE_ON_MAC Qt::Tool | Qt::X11BypassWindowManagerHint | #endif Qt::WindowStaysOnTopHint) #endif { setObjectName("kvirc_notifier_window"); g_pNotifierWindow = this; m_eState = Hidden; m_dOpacity = 0.0; m_pShowHideTimer = 0; m_pBlinkTimer = 0; m_tAutoHideAt = 0; m_tStartedAt=0; m_pAutoHideTimer = 0; m_pWndBorder = new NotifierWindowBorder(); setFocusPolicy(Qt::NoFocus); setMouseTracking(true); setAutoFillBackground(true); hide(); m_bBlinkOn = false; m_bCloseDown = false; m_bPrevDown = false; m_bNextDown = false; m_bWriteDown = false; m_bLeftButtonIsPressed = false; m_bDiagonalResizing = false; m_bResizing = false; m_pContextPopup = 0; m_pDisablePopup = 0; m_bDragging = false; m_bDisableHideOnMainWindowGotAttention = false; // Positioning the notifier bottom-right QDesktopWidget * pDesktop = QApplication::desktop(); QRect r = pDesktop->availableGeometry(pDesktop->primaryScreen()); m_wndRect.setRect( r.x() + r.width() - (WDG_MIN_WIDTH + SPACING), r.y() + r.height() - (WDG_MIN_HEIGHT + SPACING), WDG_MIN_WIDTH, WDG_MIN_HEIGHT); m_pWndTabs = new QTabWidget(this); m_pWndTabs->setUsesScrollButtons(true); m_pWndTabs->setTabsClosable(true); connect(m_pWndTabs,SIGNAL(tabCloseRequested(int)),this,SLOT(slotTabCloseRequested(int))); m_pProgressBar = new QProgressBar(this); m_pProgressBar->setOrientation(Qt::Vertical); m_pProgressBar->setRange(0, 100); m_pProgressBar->setTextVisible(false); m_pProgressBar->setMaximumWidth(8); m_pProgressBar->installEventFilter(this); m_pLineEdit = new KviThemedLineEdit(this, 0, "notifier_lineedit"); QPalette palette=m_pLineEdit->palette(); palette.setColor(m_pLineEdit->backgroundRole(), Qt::transparent); m_pLineEdit->setPalette(palette); m_pLineEdit->installEventFilter(this); connect(m_pLineEdit,SIGNAL(returnPressed()),this,SLOT(returnPressed())); QGridLayout *layout = new QGridLayout; layout->addWidget(m_pProgressBar, 0,0,2,1); layout->addWidget(m_pWndTabs,0,1,1,1); layout->addWidget(m_pLineEdit,1,1,1,1); layout->setSpacing(SPACING); layout->setGeometry(m_pWndBorder->bodyRect()); layout->setContentsMargins(5,25,5,5); setLayout(layout); connect(g_pApp,SIGNAL(updateNotifier()),this,SLOT(updateGui())); QTimer::singleShot(0,this,SLOT(updateGui())); } NotifierWindow::~NotifierWindow() { stopShowHideTimer(); stopBlinkTimer(); stopAutoHideTimer(); delete m_pWndBorder; m_pWndTabs->deleteLater(); } void NotifierWindow::updateGui() { setFont(KVI_OPTION_FONT(KviOption_fontNotifier)); QPalette palette=m_pLineEdit->palette(); palette.setColor(m_pLineEdit->foregroundRole(), KVI_OPTION_COLOR(KviOption_colorNotifierForeground)); m_pLineEdit->setPalette(palette); m_pLineEdit->setFont(KVI_OPTION_FONT(KviOption_fontNotifier)); for(int i=0; icount();++i) { ((NotifierWindowTab*)m_pWndTabs->widget(i))->updateGui(); } } void NotifierWindow::addMessage(KviWindow * pWnd, const QString & szImageId, const QString & szText, unsigned int uMessageTime) { QPixmap * pIcon; QString szMessage = szText; szMessage.replace( QRegExp("\r([^\r])*\r([^\r])+\r"), "\\2" ); if(szImageId.isEmpty()) pIcon = 0; else pIcon = g_pIconManager->getImage(szImageId); NotifierMessage * pMessage = new NotifierMessage(pIcon ? new QPixmap(*pIcon) : 0,szMessage); //search for an existing tab NotifierWindowTab * pTab = 0, * pTmp = 0; for(int i=0; i < m_pWndTabs->count();++i) { pTmp = (NotifierWindowTab*)m_pWndTabs->widget(i); if(pTmp->wnd() == pWnd) { pTab = pTmp; break; } } if(!pTab) { pTab = new NotifierWindowTab(pWnd, m_pWndTabs); } //if the notifier is already visible, don't steal the focus from the current tab! //the user could be writing a message on it (bug #678) if(!isVisible()) m_pWndTabs->setCurrentWidget(pTab); pTab->appendMessage(pMessage); if(!isActiveWindow()) startBlinking(); if(uMessageTime > 0) { kvi_time_t tAutoHide = kvi_unixTime() + uMessageTime; if(m_tAutoHideAt < tAutoHide) { m_tAutoHideAt = tAutoHide; if(m_eState == Visible) startAutoHideTimer(); } } else { // never hide stopAutoHideTimer(); m_tAutoHideAt = 0; } if(pWnd) { if(pWnd->hasAttention()) m_bDisableHideOnMainWindowGotAttention = true; } if(isVisible()) update(); } void NotifierWindow::stopShowHideTimer() { if(!m_pShowHideTimer) return; delete m_pShowHideTimer; m_pShowHideTimer = 0; } void NotifierWindow::stopBlinkTimer() { if(!m_pBlinkTimer) return; delete m_pBlinkTimer; m_pBlinkTimer = 0; } void NotifierWindow::stopAutoHideTimer() { if(!m_pAutoHideTimer) return; delete m_pAutoHideTimer; m_pAutoHideTimer = 0; m_pProgressBar->setValue(0); } // FIXME: The code for detecting fullscreen window does NOT take into account multi-screen setups. // We also lack the code for MacOSX and Qt-only-X11 compilation. #if COMPILE_KDE_SUPPORT #include static bool active_window_is_full_screen() { WId activeId = KWindowSystem::activeWindow(); KWindowInfo wi = KWindowSystem::windowInfo(activeId, NET::WMState); return (wi.valid() && wi.hasState(NET::FullScreen)); } #else // COMPILE_KDE_SUPPORT #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) #include static bool active_window_is_full_screen() { HWND hForeground = ::GetForegroundWindow(); if(!hForeground) return false; HWND hDesktop = ::GetDesktopWindow(); if(hForeground == hDesktop) return false; HWND hShell = ::GetShellWindow(); if(hForeground == hShell) return false; RECT rct; ::GetWindowRect(hForeground,&rct); if((rct.right - rct.left) < GetSystemMetrics(SM_CXSCREEN)) return false; if((rct.bottom - rct.top) < GetSystemMetrics(SM_CYSCREEN)) return false; return true; } #endif //COMPILE_ON_WINDOWS || COMPILE_ON_MINGW #endif // COMPILE_KDE_SUPPORT void NotifierWindow::doShow(bool bDoAnimate) { if(!KVI_OPTION_BOOL(KviOption_boolEnableNotifier)) return; kvi_time_t tNow = kvi_unixTime(); if(g_tNotifierDisabledUntil > tNow) return; g_tNotifierDisabledUntil = 0; #if defined(COMPILE_KDE_SUPPORT) || defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) if(KVI_OPTION_BOOL(KviOption_boolDontShowNotifierIfActiveWindowIsFullScreen)) { // check if the active window is full screen if(active_window_is_full_screen()) return; } #endif //COMPILE_KDE_SUPPORT || COMPILE_ON_WINDOWS || COMPILE_ON_MINGW switch(m_eState) { case Showing: // already showing up return; break; case Visible: // already visible return; break; case Hiding: // ops.. hiding! m_eState = Showing; break; case Hidden: stopShowHideTimer(); stopBlinkTimer(); m_bDragging = false; m_bCloseDown = false; m_bPrevDown = false; m_bNextDown = false; m_bWriteDown = false; m_bBlinkOn = false; if(bDoAnimate) { m_pShowHideTimer = new QTimer(); connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat())); m_dOpacity = OPACITY_STEP; m_eState = Showing; m_bCrashShowWorkAround = true; setWindowOpacity(m_dOpacity); show(); m_pShowHideTimer->start(40); m_bCrashShowWorkAround = false; } else { m_dOpacity = 1.0; m_eState = Visible; show(); startBlinking(); startAutoHideTimer(); } break; default: break; } } bool NotifierWindow::shouldHideIfMainWindowGotAttention() { if(m_bDisableHideOnMainWindowGotAttention) return false; NotifierWindowTab * pTab = (NotifierWindowTab *) m_pWndTabs->currentWidget(); if(!pTab) return false; if(!pTab->wnd()) return false; return pTab->wnd()->hasAttention(); } void NotifierWindow::heartbeat() { bool bIncreasing; double targetOpacity = 0; switch(m_eState) { case Hidden: hideNow(); break; case Visible: stopShowHideTimer(); m_dOpacity = 1.0; if(!isVisible()) show(); else update(); break; case Showing: // if the main window got attention while // showing up then just hide now if(shouldHideIfMainWindowGotAttention()) { m_eState = Hiding; } else { m_dOpacity += OPACITY_STEP; targetOpacity = isActiveWindow() ? KVI_OPTION_UINT(KviOption_uintNotifierActiveTransparency) : KVI_OPTION_UINT(KviOption_uintNotifierInactiveTransparency); targetOpacity/=100; if(m_dOpacity >= targetOpacity) { m_dOpacity = targetOpacity; m_eState = Visible; stopShowHideTimer(); startBlinking(); startAutoHideTimer(); } if(!isVisible()) show(); setWindowOpacity(m_dOpacity); update(); } break; case FocusingOn: targetOpacity = KVI_OPTION_UINT(KviOption_uintNotifierActiveTransparency); targetOpacity /= 100; bIncreasing = targetOpacity > m_dOpacity; m_dOpacity += bIncreasing? OPACITY_STEP : -(OPACITY_STEP); if((bIncreasing && (m_dOpacity >= targetOpacity)) || (!bIncreasing && (m_dOpacity <= targetOpacity)) ) { m_dOpacity = targetOpacity; m_eState = Visible; stopShowHideTimer(); } setWindowOpacity(m_dOpacity); break; case FocusingOff: targetOpacity = KVI_OPTION_UINT(KviOption_uintNotifierInactiveTransparency); targetOpacity /= 100; bIncreasing = targetOpacity > m_dOpacity; m_dOpacity += bIncreasing ? OPACITY_STEP : -(OPACITY_STEP); //qDebug("%f %f %i %i",m_dOpacity,targetOpacity,bIncreasing,(m_dOpacity >= targetOpacity)); if((bIncreasing && (m_dOpacity >= targetOpacity)) || (!bIncreasing && (m_dOpacity <= targetOpacity)) ) { m_dOpacity = targetOpacity; m_eState = Visible; stopShowHideTimer(); } setWindowOpacity(m_dOpacity); break; case Hiding: m_dOpacity -= OPACITY_STEP; setWindowOpacity(m_dOpacity); if(m_dOpacity <= 0.0) hideNow(); else update(); break; } } void NotifierWindow::hideNow() { stopBlinkTimer(); stopShowHideTimer(); stopAutoHideTimer(); m_eState = Hidden; m_dOpacity = 0.0; m_tAutoHideAt = 0; hide(); } void NotifierWindow::doHide(bool bDoAnimate) { stopAutoHideTimer(); switch(m_eState) { case Hiding: // already hiding up if(!bDoAnimate) hideNow(); return; break; case Hidden: // already hidden if(isVisible()) hideNow(); return; break; case Showing: // ops.. hiding! if(!bDoAnimate) hideNow(); else { // continue animating, but hide m_eState = Hiding; } break; case Visible: stopBlinkTimer(); stopShowHideTimer(); if((!bDoAnimate) || (x() != m_pWndBorder->x()) || (y() != m_pWndBorder->y())) { //qDebug("just hide quickly with notifier x() %d and notifier y() % - WBorderx() %d and WBordery() %d and bDoanimate %d",x(),y(),m_pWndBorder->x(),m_pWndBorder->y(),bDoAnimate); // the user asked to not animate or // the window has been moved and the animation would suck anyway // just hide quickly hideNow(); } else { //qDebug("starting hide animation notifier x() %d and notifier y() % - WBorderx() %d and WBordery() %d and bDoanimate %d",x(),y(),m_pWndBorder->x(),m_pWndBorder->y(),bDoAnimate); m_pShowHideTimer = new QTimer(); connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat())); m_dOpacity = 1.0 - OPACITY_STEP; m_eState = Hiding; setWindowOpacity(m_dOpacity); update(); m_pShowHideTimer->start(40); } break; default: break; } } void NotifierWindow::showEvent(QShowEvent *) { setGeometry(m_wndRect); } void NotifierWindow::hideEvent(QHideEvent *) { if(m_bCrashShowWorkAround) return; stopBlinkTimer(); stopShowHideTimer(); stopAutoHideTimer(); m_eState = Hidden; // make sure it's true m_tAutoHideAt = 0; // make sure it's true m_bDisableHideOnMainWindowGotAttention = false; } void NotifierWindow::startBlinking() { stopBlinkTimer(); m_bBlinkOn = false; if(KVI_OPTION_BOOL(KviOption_boolNotifierFlashing)) { m_pBlinkTimer = new QTimer(); connect(m_pBlinkTimer,SIGNAL(timeout()),this,SLOT(blink())); m_iBlinkCount = 0; m_pBlinkTimer->start(1000); } } void NotifierWindow::startAutoHideTimer() { stopAutoHideTimer(); m_tStartedAt = kvi_unixTime(); if(m_tAutoHideAt <= m_tStartedAt) return; int iSecs = m_tAutoHideAt - m_tStartedAt; if(iSecs < 5) iSecs = 5; m_pAutoHideTimer = new QTimer(); connect(m_pAutoHideTimer,SIGNAL(timeout()),this,SLOT(progressUpdate())); m_pAutoHideTimer->start(100); } void NotifierWindow::blink() { m_iBlinkCount++; m_bBlinkOn = !m_bBlinkOn; if(m_iBlinkCount > 100) { // stop blinking at a certain point and remain highlighted m_bBlinkOn = true; stopBlinkTimer(); } else { // if the main window got attention while // showing up then just hide now if(shouldHideIfMainWindowGotAttention()) { doHide(false); // don't animate: the background has almost surely changed return; } } update(); } void NotifierWindow::paintEvent(QPaintEvent * e) { QPainter * pPaint = new QPainter(this); if(m_wndRect.width() != m_pWndBorder->width() || m_wndRect.height() != m_pWndBorder->height()) m_pWndBorder->resize(m_wndRect.size()); if(m_bBlinkOn) { m_pWndBorder->draw(pPaint,true); } else { m_pWndBorder->draw(pPaint); } pPaint->setPen(KVI_OPTION_COLOR(KviOption_colorNotifierTitleForeground)); pPaint->setFont(KVI_OPTION_FONT(KviOption_fontNotifierTitle)); QString szTitle = "KVIrc - "; NotifierWindowTab * pTab = (NotifierWindowTab *)m_pWndTabs->currentWidget(); if(pTab) { if(pTab->wnd()) { szTitle += pTab->wnd()->plainTextCaption(); } else { szTitle += "notifier"; } } else { szTitle += "notifier"; } pPaint->drawText(m_pWndBorder->titleRect(),Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine,szTitle); delete pPaint; e->ignore(); } void NotifierWindow::mouseMoveEvent(QMouseEvent * e) { if(!m_bLeftButtonIsPressed) { if(checkResizing(e->pos())) goto sartelo; if(m_pWndBorder->captionRect().contains(e->pos())) { if(m_pWndBorder->closeRect().contains(e->pos())) m_pWndBorder->setCloseIcon(WDG_ICON_OVER); else m_pWndBorder->setCloseIcon(WDG_ICON_OUT); goto sartelo; } sartelo: update(); } if(m_bDragging) { setCursor(Qt::SizeAllCursor); int iW = m_wndRect.width(); int iH = m_wndRect.height(); m_wndRect.setX(m_pntPos.x() + cursor().pos().x() - m_pntDrag.x()); m_wndRect.setY(m_pntPos.y() + cursor().pos().y() - m_pntDrag.y()); m_wndRect.setWidth(iW); m_wndRect.setHeight(iH); setGeometry(m_wndRect); } else if(m_bResizing) { resize(e->pos()); } } void NotifierWindow::mousePressEvent(QMouseEvent * e) { // stop blinking first of all :) bool bWasBlinkOn = m_bBlinkOn; m_bBlinkOn = false; stopBlinkTimer(); m_tAutoHideAt = 0; stopAutoHideTimer(); activateWindow(); setFocus(); m_pntClick = e->pos(); if(e->button() == Qt::RightButton) { contextPopup(mapToGlobal(e->pos())); return; } else if(e->button() == Qt::LeftButton) { m_bLeftButtonIsPressed = true; } if(checkResizing(m_pntClick)) { update(); return; } if(m_pWndBorder->captionRect().contains(e->pos())) { if(m_pWndBorder->closeRect().contains(e->pos())) { m_bCloseDown = true; m_pWndBorder->setCloseIcon(WDG_ICON_CLICKED); update(); return; } if(!m_bResizing) { m_bDragging = true; m_pntDrag = cursor().pos(); m_pntPos = pos(); update(); return; } } if(m_pWndBorder->rect().contains(e->pos()) || bWasBlinkOn) update(); } void NotifierWindow::mouseReleaseEvent(QMouseEvent * e) { m_bWriteDown = false; m_bNextDown = false; m_bPrevDown = false; m_bCloseDown = false; m_bLeftButtonIsPressed = false; m_bResizing = false; if(m_bDragging) { m_bDragging = false; if(QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); return; } if(m_pWndBorder->captionRect().contains(e->pos())) { if(m_pWndBorder->closeRect().contains(e->pos())) hideNow(); else update(); } setCursor(-1); } void NotifierWindow::keyPressEvent(QKeyEvent * e) { if(e->key() == Qt::Key_Escape) { hideNow(); return; } } bool NotifierWindow::checkResizing(QPoint e) { if(e.y() < WDG_BORDER_THICKNESS) { if(e.x() < WDG_BORDER_THICKNESS) { //// UP LEFT CORNER //// setCursor(Qt::SizeFDiagCursor); if (m_bLeftButtonIsPressed) { m_bResizing = true; m_whereResizing = WDG_UPSX; } } else if(e.x() > (size().width()-WDG_BORDER_THICKNESS)) { //// UP RIGHT CORNER //// setCursor(Qt::SizeBDiagCursor); if (m_bLeftButtonIsPressed) { m_bResizing = true; m_whereResizing = WDG_UPDX; } } else { //// UP SIDE //// setCursor(Qt::SizeVerCursor); if (m_bLeftButtonIsPressed) { m_bResizing = true; m_whereResizing = WDG_UP; } } } else if(e.y() > (size().height()-WDG_BORDER_THICKNESS)) { if(e.x() < WDG_BORDER_THICKNESS) { //// DOWN LEFT CORNER //// setCursor(Qt::SizeBDiagCursor); if(m_bLeftButtonIsPressed) { m_bResizing = true; m_whereResizing = WDG_DWNSX; } } else if(e.x() > (size().width()-WDG_BORDER_THICKNESS)) { //// DOWN RIGHT CORNER //// setCursor(Qt::SizeFDiagCursor); if(m_bLeftButtonIsPressed) { m_bResizing = true; m_whereResizing = WDG_DWNDX; } } else { //// DOWN SIDE //// setCursor(Qt::SizeVerCursor); if(m_bLeftButtonIsPressed) { m_bResizing = true; m_whereResizing = WDG_DWN; } } } else { if(e.x() < WDG_BORDER_THICKNESS) { //// LEFT SIZE //// setCursor(Qt::SizeHorCursor); if(m_bLeftButtonIsPressed) { m_bResizing = true; m_whereResizing = WDG_SX; } } else if(e.x() > (size().width()-WDG_BORDER_THICKNESS)) { //// RIGHT SIZE //// setCursor(Qt::SizeHorCursor); if(m_bLeftButtonIsPressed) { m_bResizing = true; m_whereResizing = WDG_DX; } } else { //// ELSEWHERE //// m_whereResizing = 0; m_bResizing = false; setCursor(-1); } } return m_bResizing; } void NotifierWindow::resize(QPoint, bool) { if(m_whereResizing == WDG_UPSX || m_whereResizing == WDG_SX || m_whereResizing == WDG_DWNSX) { if((x() + width() - cursor().pos().x()) < WDG_MIN_WIDTH) m_wndRect.setLeft(x() + width() - WDG_MIN_WIDTH); else m_wndRect.setLeft(cursor().pos().x()); } if(m_whereResizing == WDG_UPSX || m_whereResizing == WDG_UP || m_whereResizing == WDG_UPDX) { if(y()+height()-cursor().pos().y() < WDG_MIN_HEIGHT) m_wndRect.setTop(y() + height() - WDG_MIN_HEIGHT); else m_wndRect.setTop(cursor().pos().y()); } if(m_whereResizing == WDG_DX || m_whereResizing == WDG_UPDX || m_whereResizing == WDG_DWNDX) { if((cursor().pos().x() - x()) > WDG_MIN_WIDTH) m_wndRect.setRight(cursor().pos().x()); else m_wndRect.setRight(x() + WDG_MIN_WIDTH); } if(m_whereResizing == WDG_DWN || m_whereResizing == WDG_DWNDX || m_whereResizing == WDG_DWNSX) { if((cursor().pos().y() - y()) > WDG_MIN_HEIGHT) m_wndRect.setBottom(cursor().pos().y()); else m_wndRect.setBottom(y() + WDG_MIN_HEIGHT); } showLineEdit(m_pLineEdit->isVisible()); setGeometry(m_wndRect); } inline void NotifierWindow::setCursor(int iCur) { if(m_cursor.shape() != iCur) { if(QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); m_cursor.setShape((Qt::CursorShape)iCur); QApplication::setOverrideCursor(m_cursor); } else if(iCur == -1) { if(QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); } } void NotifierWindow::enterEvent(QEvent *) { if(!m_pShowHideTimer) { m_pShowHideTimer = new QTimer(); connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat())); } m_eState = FocusingOn; m_pShowHideTimer->start(40); } void NotifierWindow::leaveEvent(QEvent *) { // Leaving the widget area, restore default cursor m_pWndBorder->resetIcons(); if(!m_bResizing) setCursor(-1); if(!m_pShowHideTimer) { m_pShowHideTimer = new QTimer(); connect(m_pShowHideTimer,SIGNAL(timeout()),this,SLOT(heartbeat())); } if(m_eState!=Hidden) { m_eState = FocusingOff; m_pShowHideTimer->start(40); } } void NotifierWindow::contextPopup(const QPoint & pos) { if(!m_pContextPopup) { m_pContextPopup = new KviTalPopupMenu(this); connect(m_pContextPopup,SIGNAL(aboutToShow()),this,SLOT(fillContextPopup())); m_pDisablePopup = new KviTalPopupMenu(this); } m_pContextPopup->popup(pos); } void NotifierWindow::fillContextPopup() { m_pContextPopup->clear(); m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_EDITOR)),__tr2qs_ctx("Show/Hide input line","notifier"),this,SLOT(toggleLineEdit())); m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_CLOSE)),__tr2qs_ctx("Hide","notifier"),this,SLOT(hideNow())); m_pContextPopup->insertSeparator(); m_pDisablePopup->clear(); m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("1 Minute","notifier"),this,SLOT(disableFor1Minute())); m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("5 Minutes","notifier"),this,SLOT(disableFor5Minutes())); m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("15 Minutes","notifier"),this,SLOT(disableFor15Minutes())); m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("30 Minutes","notifier"),this,SLOT(disableFor30Minutes())); m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_TIME)),__tr2qs_ctx("1 Hour","notifier"),this,SLOT(disableFor60Minutes())); m_pDisablePopup->insertSeparator(); m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Until KVIrc is Restarted","notifier"),this,SLOT(disableUntilKVIrcRestarted())); m_pDisablePopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Permanently (Until Explicitly Enabled)","notifier"),this,SLOT(disablePermanently())); m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Disable","notifier"),m_pDisablePopup); } void NotifierWindow::disableFor15Minutes() { kvi_time_t tNow = kvi_unixTime(); g_tNotifierDisabledUntil = tNow + (60 * 15); hideNow(); } void NotifierWindow::disableFor5Minutes() { kvi_time_t tNow = kvi_unixTime(); g_tNotifierDisabledUntil = tNow + (60 * 5); hideNow(); } void NotifierWindow::disableFor1Minute() { kvi_time_t tNow = kvi_unixTime(); g_tNotifierDisabledUntil = tNow + 60; hideNow(); } void NotifierWindow::disableFor30Minutes() { kvi_time_t tNow = kvi_unixTime(); g_tNotifierDisabledUntil = tNow + (60 * 30); hideNow(); } void NotifierWindow::disableFor60Minutes() { kvi_time_t tNow = kvi_unixTime(); g_tNotifierDisabledUntil = tNow + (60 * 60); hideNow(); } void NotifierWindow::disableUntilKVIrcRestarted() { kvi_time_t tNow = kvi_unixTime(); // in fact we just disable for one year g_tNotifierDisabledUntil = tNow + (3600 * 24 * 360); // one year :D // this will NOT work if the module is forcibly unloaded with /notifier.unload // but the user should never do it :D hideNow(); } void NotifierWindow::disablePermanently() { KVI_OPTION_BOOL(KviOption_boolEnableNotifier) = false; hideNow(); } void NotifierWindow::toggleLineEdit() { showLineEdit(!m_pLineEdit->isVisible()); } void NotifierWindow::showLineEdit(bool bShow) { if(bShow) { if(m_pLineEdit->isVisible()) return; if(!((NotifierWindowTab *)m_pWndTabs->currentWidget())->wnd()) return; m_pLineEdit->setToolTip(""); QString szTip = __tr2qs_ctx("Write text or commands to window","notifier"); szTip += " \""; szTip += ((NotifierWindowTab *)m_pWndTabs->currentWidget())->wnd()->plainTextCaption(); szTip += "\""; m_pLineEdit->setToolTip(szTip); m_pLineEdit->show(); m_pLineEdit->setFocus(); activateWindow(); } else { if(!m_pLineEdit->isVisible()) return; m_pLineEdit->hide(); setFocus(); update(); } } bool NotifierWindow::eventFilter(QObject * pEdit, QEvent * e) { if(pEdit != (QObject *)m_pLineEdit) return false; // huh ? if(!m_pLineEdit->isVisible()) return false; if(e->type() == QEvent::MouseButtonPress) { bool bWasBlinkOn = m_bBlinkOn; m_bBlinkOn = false; m_tAutoHideAt = 0; stopAutoHideTimer(); stopBlinkTimer(); activateWindow(); m_pLineEdit->setFocus(); if(bWasBlinkOn) update(); return true; } if(e->type() == QEvent::KeyPress) { if(((QKeyEvent *)e)->key() == Qt::Key_Escape) { hideNow(); return true; } } return false; } void NotifierWindow::returnPressed() { if(!m_pLineEdit->isVisible()) return; NotifierWindowTab * pTab = (NotifierWindowTab *) m_pWndTabs->currentWidget(); if(!pTab) return; if(!pTab->wnd()) return; QString szTxt = m_pLineEdit->text(); if(szTxt.isEmpty()) return; QString szHtml = szTxt; szHtml.replace("<","<"); szHtml.replace(">",">"); KviCString szTmp(KviCString::Format,"%d",KVI_SMALLICON_OWNPRIVMSG); addMessage(pTab->wnd(),szTmp.ptr(),szHtml,0); m_pLineEdit->setText(""); KviUserInput::parse(szTxt,pTab->wnd(),QString(),1); } void NotifierWindow::progressUpdate() { kvi_time_t now = kvi_unixTime(); int iProgress = (int)(100/(m_tAutoHideAt - m_tStartedAt)*(now - m_tStartedAt)); m_pProgressBar->setValue(iProgress); if(now >= m_tAutoHideAt) { m_tAutoHideAt = 0; stopAutoHideTimer(); doHide(true); } } void NotifierWindow::slotTabCloseRequested(int iIndex) { if(m_pWndTabs) { NotifierWindowTab * pTab = (NotifierWindowTab *) m_pWndTabs->widget(iIndex); m_pWndTabs->removeTab(iIndex); if(pTab) pTab->deleteLater(); if(m_pWndTabs->count()==0) hideNow(); } } #ifndef COMPILE_USE_STANDALONE_MOC_SOURCES #include "m_NotifierWindow.moc" #endif //!COMPILE_USE_STANDALONE_MOC_SOURCES