diff options
Diffstat (limited to 'kshowmail/kshowmail.cpp')
-rw-r--r-- | kshowmail/kshowmail.cpp | 861 |
1 files changed, 861 insertions, 0 deletions
diff --git a/kshowmail/kshowmail.cpp b/kshowmail/kshowmail.cpp new file mode 100644 index 0000000..16e9db6 --- /dev/null +++ b/kshowmail/kshowmail.cpp @@ -0,0 +1,861 @@ +/*************************************************************************** + kshowmail.cpp - description + ------------------- + begin : Sat May 6 12:13:57 MEST 2000 + copyright : (C) 2000-2002 by Eggert Ehmke + email : eggert.ehmke@berlin.de + + 26 Sep 2002 - Allow for columns to be hidden. Allistar Melville + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kshowmail.h" + +using namespace KIO; + +KAboutData* KShowMailApp::m_pAbout; + +KShowMailApp::KShowMailApp() +{ + //set up actions + initActions(); + + // create GUI from ui resource file + setXMLFile( "kshowmailui.rc", true ); + createGUI(); + + //the main window settings will be saved automatically + setAutoSaveSettings(); + + //initiate GUI parts + initStatusBar(); + initDocument(); + initView(); + + //the application is idle at beginning + m_state = idle; + + //the setup dialog will be created in slotSetup() at first use + SetupDialog = NULL; + + m_pTimer = new QTimer (this); + m_pAlertDialog = NULL; + m_pDockWindow = new KShowMailDock (this, m_actionRefresh); + m_bForceClose = false; + + + //read the setup + m_ConfigList.refreshSetup( m_pView->m_pListAccounts ); + + //load stored mails + m_ConfigList.readStoredMails(); + + //connect signals with slots + + connect (m_pDockWindow, SIGNAL (quitSelected ()), SLOT (slotForceClose ())); + connect (m_pTimer, SIGNAL (timeout ()), SLOT (slotRefresh ())); + connect (m_pView->m_pListAccounts, SIGNAL (currentChanged(QListViewItem*)), SLOT(slotAccountActivated(QListViewItem*))); + connect (m_pView, SIGNAL (signalActiveChanged()), SLOT (slotRefreshView())); + + connect( &m_ConfigList, SIGNAL( sigDeleteReady() ), this, SLOT( slotDeletionReady() ) ); + connect( &m_ConfigList, SIGNAL( sigShowBodiesReady() ), this, SLOT( slotShowMessageReady() ) ); + connect( &m_ConfigList, SIGNAL( sigMessageWindowOpened() ), this, SLOT( slotNormalCursor() ) ); + connect( &m_ConfigList, SIGNAL( sigAllMessageWindowsClosed() ), this, SLOT( slotWaitingCursor() ) ); + connect( &m_ConfigList, SIGNAL( sigRefreshReady() ), this, SLOT( slotRefreshReady() ) ); + + //show welcome message + KMessageBox::information( NULL, i18n( "Thank You for using KShowmail.\nPlease use the feedback dialog to tell us your experience with this program." ), i18n("Welcome"), "WelcomeMessage" ); + + // this starts the one-second-interval timer + // this is a QObject method + startTimer (1000); + + //we are ready to take off! Lets initiate the first refresh (if desired) + initFirstRefresh(); +} + +KShowMailApp::~KShowMailApp() +{ + kdDebug() << "cleaning up" << endl; + delete m_pTimer; + delete m_pDockWindow; + kdDebug() << "cleanup finished" << endl; +} + +/** + * This is reimplemented from QObject + */ +void KShowMailApp::timerEvent (QTimerEvent *) +{ + if (m_nSecondsToGo) + { + QTime time; + time = time.addSecs (m_nSecondsToGo--); + QCString msg (i18n("Autorefresh: %1").arg (time.toString())); + statusBar()->changeItem( msg, STATUSBAR_FIELD_NEXT_REFRESH ); + } + else + statusBar()->changeItem( "", STATUSBAR_FIELD_NEXT_REFRESH ); + + // if busy, animate the traybar + if ( m_state == refreshing || m_state == deleting ) + { + static int color = 0; + color = (color+1)%2; + switch (color) + { + case 0: + m_pDockWindow->clear (); + break; + default: + m_pDockWindow->drawText ("?", Qt::red); + } + } +} + + + +void KShowMailApp::initActions () +{ + // file menu + KStdAction::quit( this, SLOT( slotFileQuit() ), actionCollection() ); + + // action menu + m_actionRefresh = new KAction( i18n( "&Refresh messages" ), "reload", Key_F5, this, SLOT( slotRefresh() ), actionCollection(), "refresh" ); + new KAction( i18n( "Show &header of highlighted messages" ), "letter-closed", Key_F2, this, SLOT( slotShowHeader() ), actionCollection(), "show_header" ); + new KAction( i18n( "Show &complete highlighted messages" ), "letter-open", Key_F3, this, SLOT( slotShowMessage() ), actionCollection(), "show_complete" ); + new KAction( i18n( "&Delete highlighted messages" ), "eraser", Key_Delete, this, SLOT( slotDelete() ), actionCollection(), "delete" ); + new KAction( i18n( "S&top current transfer" ), "stop", 0, this, SLOT( slotStop() ), actionCollection(), "stop" ); + new KAction( i18n( "Show Filter Log" ), "log", Key_F4, this, SLOT( slotShowFilterLog() ), actionCollection(), "show_filterlog" ); + new KAction( i18n( "Add sender to whitelist" ), "add_user", 0, this, SLOT( slotAddToWhitelist() ), actionCollection(), "addWhitelist" ); + new KAction( i18n( "Add sender to blacklist" ), "delete_user", 0, this, SLOT( slotAddToBlacklist() ), actionCollection(), "addBlacklist" ); + + // setup menu + KStdAction::preferences( this, SLOT( slotSetup() ), actionCollection() ); + KStdAction::configureToolbars( this, SLOT( slotEditToolbars() ), actionCollection() ); + + //create menu items for toggle tool and status bar + setStandardToolBarMenuEnabled( true ); + createStandardStatusBarAction(); + + //help menu + new KAction( i18n( "Send &Feedback Mail" ), "email", 0, this, SLOT( slotSendFeedbackMail() ),actionCollection(), "sendFeedback" ); + + //for account context menu + new KAction(i18n( "Setup &account" ), "tool", 0, this, SLOT( slotSetupAccount() ), actionCollection(), "setupAccount" ); +} + + +void KShowMailApp::initStatusBar() +{ + statusBar()->insertItem( i18n( "Ready." ), STATUSBAR_FIELD_STATE ); + statusBar()->insertItem( "", STATUSBAR_FIELD_FILTER, 1 ); + statusBar()->setItemAlignment( STATUSBAR_FIELD_FILTER, AlignLeft | AlignVCenter ); + statusBar()->insertItem( "", STATUSBAR_FIELD_NEXT_REFRESH ); + statusBar()->insertItem( "", STATUSBAR_FIELD_LAST_REFRESH ); + + QToolTip::add( statusBar(), i18n( "Shows the number of deleted, moved or ignored mails by the filter.\nThe positions denotes:\nby last refresh / since application start / listed by the log" ) ); + + refreshFilterStatusBar(); +} + +void KShowMailApp::initDocument() +{ + m_pDoc = new KshowmailDoc(this); + m_pDoc->newDocument(); +} + +void KShowMailApp::initView() +{ + //////////////////////////////////////////////////////////////////// + // create the main widget here that is managed by KMainWindow's view-region and + // connect the widget to your document to display document contents. + + m_pView = new KshowmailView(this); + m_pDoc->addView(m_pView); + setCentralWidget(m_pView); +} + +void KShowMailApp::slotSaveOptions() +{ + KConfig* config = KGlobal::config(); + + //order application parts to save their setup + m_pView->saveOptions( config ); + m_ConfigList.saveOptions (); + fLog.save(); + + //save config to file + config->sync (); + +} + +bool KShowMailApp::queryClose() +{ + bool result; + kdDebug() << "KShowMailApp::queryClose()" << endl; + + if (m_bForceClose) { + // We are forced to close app - so just do it + kdDebug() << "forced exit" << endl; + result = true; + } else if( m_ConfigList.closeToTray() ) { + // Don't close - close button must minimize the window + result = false; + kdDebug() << "ignoring close request and minimizing the window" << endl; + KMainWindow* w = memberList->first(); + w->hide(); + } else { + // Need to ask user first + result = askCloseConfirmation(); + } + return result; +} + +bool KShowMailApp::queryExit() +{ + kdDebug() << "KShowMailApp::queryExit()" << endl; + slotSaveOptions (); + + return true; +} + +///////////////////////////////////////////////////////////////////// +// SLOT IMPLEMENTATION +///////////////////////////////////////////////////////////////////// + +void KShowMailApp::slotFileQuit() +{ + kdDebug () << "KShowMailApp::slotFileQuit()" << endl; + if(memberList && askCloseConfirmation()) + { + m_bForceClose = true; // Forcing the closing + KMainWindow* w = memberList->first(); + w->close(); + } +} + + +void KShowMailApp::slotSetupAccount() +{ + //just open the dialog, if the app is idle + if (m_state != idle) + { + kapp->beep(); + return; + } + + //set application state + m_state = configure; + + //stop the refresh timer + stopRefreshTimer(); + + //get account to configure + ConfigElem* pConfig = m_ConfigList.getSelectedAccount(); + + if( pConfig != NULL ) + { + //open dialog + //the dialog sets the new options directly in the account + ServerDialog dlg( this, pConfig ); + + if( dlg.exec() == QDialog::Accepted ) + { + //if OK was clicked, refresh the account list view + slotConfChanged(); + } + } + + //we are ready, set application state to idle and initiate next refresh + m_state = idle; + initNextRefresh(); +} + +void KShowMailApp::slotAccountActivated (QListViewItem* pItem) +{ + QPtrListIterator<ConfigElem> it(m_ConfigList); + // this is = not == !!! + while (ConfigElem* pConfig = it()) + { + if (pConfig->getListViewItem() == pItem) + { + setCaption (pConfig->getAccountName()); + return; + } + } +} + +void KShowMailApp::slotAlertDestroyed() +{ + m_pAlertDialog = NULL; +} + +void KShowMailApp::slotAlertOk () +{ + //switch main window to normal view + showNormal(); + raise(); +} + +void KShowMailApp::slotRefresh() +{ + //return, if the app is not idle + if ( m_state != idle ) + { + kapp->beep(); + initNextRefresh(); + return; + } + + //stop the refresh timer + stopRefreshTimer(); + + //set the state + m_state = refreshing; + + //show status message + slotStatusMsg( i18n( "Refreshing ..." ) ); + + //set waiting cursor + QApplication::setOverrideCursor( Qt::waitCursor ); + + //order the account list to refresh its mail lists + m_ConfigList.refreshMailLists( &fLog ); + + return; +} + +void KShowMailApp::slotStop () +{ + if (m_state == idle) + { + kapp->beep (); + return; + } + kdDebug() << "KShowMailApp::slotStop" << endl; + + //kill all running pop3 jobs + m_ConfigList.killPOP3Jobs(); + + slotRefreshView (); + + // make sure the view is refreshed before the state gets idle again + // bug #853651 + + //set state to idle + m_state = idle; + + //set normal cursor + //might be more than one override cursor ... + while (QApplication::overrideCursor()) + QApplication::restoreOverrideCursor (); + + //print status message + slotStatusMsg(i18n("Job was stopped")); +} + +void KShowMailApp::slotRefreshView () +{ + + //clear mail list view + m_pView->clearMailListView(); + + //fill mail list view + m_ConfigList.fillMailListView( m_pView ); + + //refresh account list + m_ConfigList.refreshAccountList(); + + //get some informations + int numberMails = m_ConfigList.getNumberMails(); + bool hasNewMails = m_ConfigList.getNumberNewMails() > 0; + + //draw number of mails into dock + if( hasNewMails ) + //draw red number, because we have new mails + m_pDockWindow->drawNumber( numberMails, Qt::red ); + else + //we haven't new mails, draw black + m_pDockWindow->drawNumber( numberMails, Qt::black ); + + //show message in status bar + long totalSize = m_ConfigList.getTotalSize(); + slotStatusMsg( i18n( "%1 message(s) with a total of %2 bytes are waiting" ).arg( numberMails ).arg( totalSize ) ); + + //refresh filter view in the status bar + refreshFilterStatusBar(); +} + +void KShowMailApp::slotDelete() +{ + //just delete, if no operation is running + if( m_state != idle ) + { + kapp->beep(); + return; + } + + //return, if no mails are selected + if( !m_ConfigList.hasSelectedMails() ) + return; + + //confirm deletion if required + if( m_ConfigList.confirmDeletion() ) + { + //get subjects off all selected mails + QStringList subjects = m_ConfigList.getSelectedSubjects(); + + //show question + int answer = KMessageBox::questionYesNoList( this, i18n( "Do you want to delete these mails?"), subjects, i18n( "Delete?" ) ); + + if( answer == KMessageBox::No ) + return; + } + + //set the state + m_state = deleting; + + //show status message + slotStatusMsg( i18n( "Deleting Mail(s) ..." ) ); + + //set waiting cursor + QApplication::setOverrideCursor( Qt::waitCursor ); + + //order the account list to delete the selected mails + //test! + m_ConfigList.deleteSelectedMails(); +} + +void KShowMailApp::slotShowHeader () +{ + //only show headers, if the app is idle + if( m_state != idle ) + { + kapp->beep (); + return; + } + + //show the headers + m_ConfigList.showSelectedHeaders(); + +} + +void KShowMailApp::slotShowMessage () +{ + //return, if application is not idle + if( m_state != idle ) + { + kapp->beep (); + return; + } + + //return, if no mails are selected + if( !m_ConfigList.hasSelectedMails() ) + return; + + //set the state + m_state = showing; + + //show status message + slotStatusMsg( i18n( "Downloading ..." ) ); + + //set waiting cursor + QApplication::setOverrideCursor( Qt::waitCursor ); + + //order the account list to show the selected mails + m_ConfigList.showSelectedMails(); +} + +void KShowMailApp::slotStatusMsg(const QString& text) +{ + //get current time + // added by Gustavo Zamorano to include time + QString sTime = QTime::currentTime ().toString (); + + //clear status bar + statusBar()->clear(); + + //set given text + statusBar()->changeItem( text, STATUSBAR_FIELD_STATE ); + + //set current time + statusBar()->changeItem( i18n( "Last Refresh: %1" ).arg( sTime ), STATUSBAR_FIELD_LAST_REFRESH ); +} + +void KShowMailApp::slotStatusHelpMsg(const QString &text) +{ + statusBar()->message(text, 2000); +} + + + + +bool KShowMailApp::event(QEvent *e) +{ + // to hide the taskbar button; any better solution ?? + if ((e->type() == QEvent::Hide) && m_ConfigList.minimizesToTray() ) { + hide (); + } + + return(KMainWindow::event(e)); +} + +void KShowMailApp::slotForceClose() +{ + m_bForceClose = true; +} + +bool KShowMailApp::askCloseConfirmation() +{ + bool result; + + if( m_ConfigList.confirmClose() ) { + // Need to ask user + result = (KMessageBox::questionYesNo (this, i18n ("KShowmail will be closed.\n" + "Are you sure?")) == KMessageBox::Yes); + } else { + // User doesn't want to be asked - just close it + result = true; + } + + return result; +} + +void KShowMailApp::slotDeletionReady( ) +{ + //set state to idle + m_state = idle; + + //set normal cursor + while( QApplication::overrideCursor() ) + QApplication::restoreOverrideCursor(); + + //show status message + slotStatusMsg( i18n( "Ready." ) ); + + //refresh mail list + slotRefresh(); +} + +void KShowMailApp::slotShowMessageReady( ) +{ + //set state to idle + m_state = idle; + + //set normal cursor + while( QApplication::overrideCursor() ) + QApplication::restoreOverrideCursor(); + + //show status message + slotStatusMsg( i18n( "Ready." ) ); + + +} + +void KShowMailApp::slotNormalCursor( ) +{ + //set normal cursor + while( QApplication::overrideCursor() ) + QApplication::restoreOverrideCursor(); + +} + +void KShowMailApp::slotWaitingCursor( ) +{ + //set waiting cursor + QApplication::setOverrideCursor( Qt::waitCursor ); +} + +void KShowMailApp::slotRefreshReady( ) +{ + //set state to idle + m_state = idle; + + //set normal cursor + while( QApplication::overrideCursor() ) + QApplication::restoreOverrideCursor(); + + //refresh mail list view + slotRefreshView(); + + //inform the user about new mails + bool hasNewMails = m_ConfigList.getNumberNewMails() > 0; + if ( hasNewMails ) + { + //show main window if desired + if( m_ConfigList.showMainWindowForNewMails() ) + { + showNormal(); + raise(); + } + + //get out some sounds + m_ConfigList.beep(); + m_ConfigList.playSound(); + + //execute a command + m_ConfigList.executeNewMailCommand(); + + //show alert message if desired + if( m_ConfigList.showAlertMessageForNewMails() ) + { + //have we created one already? + if( m_pAlertDialog != NULL ) + { + //yes, we have one + m_pAlertDialog->show(); + m_pAlertDialog->raise(); + } + else + { + //create a message dialog + m_pAlertDialog = new AlertDialog( this ); + connect( m_pAlertDialog, SIGNAL( destroyed() ), SLOT( slotAlertDestroyed() ) ); + connect( m_pAlertDialog, SIGNAL( signalOk() ), SLOT( slotAlertOk() ) ); + } + } + + } + else + { + //no new mails was received + //perform configured actions + + //terminate app if desired + if( m_ConfigList.quitNoNewMails() ) + slotFileQuit(); + else if( m_ConfigList.minimizeMainWindowNoNewMails() ) + { + showMinimized(); + hide(); + } + } + + //show status message + slotStatusMsg( i18n( "Ready." ) ); + + + //prepare next refresh cycle + initNextRefresh(); +} + +void KShowMailApp::initFirstRefresh( ) +{ + //is auto refresh on? if not, we do nothing + if( m_ConfigList.AutoRefreshOn() ) + { + //is an initial time configured? if not, we refresh immediately + if( m_ConfigList.hasInitTime() ) + { + //starts refresh timer with the configured initial time to first refresh + m_pTimer->start( m_ConfigList.getInitTime() * 1000, true ); + m_nSecondsToGo = m_ConfigList.getInitTime(); + } + else + { + //just to set a defined state + m_pTimer->stop(); + m_nSecondsToGo = 0; + + //start refresh cycle + slotRefresh(); + } + } + else + { + //set a defined state + m_pTimer->stop(); + m_nSecondsToGo = 0; + } +} + +void KShowMailApp::stopRefreshTimer( ) +{ + m_pTimer->stop(); + m_nSecondsToGo = 0; +} + +void KShowMailApp::initNextRefresh( ) +{ + if( m_ConfigList.AutoRefreshOn() ) + { + //auto refresh is activated + //restart the refresh timer + m_pTimer->start( m_ConfigList.getRefreshTimeInterval() * 60000, true ); + m_nSecondsToGo = m_ConfigList.getRefreshTimeInterval() * 60; + } + else + { + //auto refresh is not activated + //set a defined state of the refresh timer + m_pTimer->stop(); + m_nSecondsToGo = 0; + } +} + +void KShowMailApp::delayNextRefresh( ) +{ + const unsigned long DELAY_TIME = 60; + + //delay only if the timer is active and the remaining time is less than one minute + if( m_pTimer->isActive() ) + { + if( m_nSecondsToGo < DELAY_TIME ) + { + m_pTimer->start( DELAY_TIME * 1000, true ); + m_nSecondsToGo = DELAY_TIME; + } + } +} + +void KShowMailApp::slotEditToolbars() +{ + //create the toolbar config dialog + KEditToolbar *dlg = new KEditToolbar(guiFactory()); + if( dlg->exec() ) + { + //if dialog closed by OK, create the GUI new + //the dialog has changed the kshowmailui.rc file + createGUI(); + } + + //destruct dialog + delete dlg; +} + +void KShowMailApp::slotSetup( ) +{ + //just open the dialog, if the app is idle + if (m_state != idle) + { + kapp->beep(); + return; + } + + //set application state + m_state = configure; + + //stop the refresh timer + stopRefreshTimer(); + + if ( SetupDialog == NULL ) + { + //if no preferences dialog was created as yet, create one + SetupDialog = new KCMultiDialog( KCMultiDialog::IconList, i18n( "Options" ), this, "SetupDialog" ); + SetupDialog->addModule( "kshowmailconfigaccounts.desktop" ); + SetupDialog->addModule( "kshowmailconfiggeneral.desktop" ); + SetupDialog->addModule( "kshowmailconfigdisplay.desktop" ); + SetupDialog->addModule( "kshowmailconfigactions.desktop" ); + SetupDialog->addModule( "kshowmailconfigfilter.desktop" ); + SetupDialog->addModule( "kshowmailconfigspamcheck.desktop" ); + SetupDialog->addModule( "kshowmailconfiglog.desktop" ); + + //If the configuration was changed, it will call slotConfChanged + connect( SetupDialog, SIGNAL( configCommitted() ), this, SLOT( slotConfChanged() ) ); + } + + //execute preferences dialog + SetupDialog->exec(); + + //we are ready, set application state to idle and initiate next refresh + m_state = idle; + initNextRefresh(); + +} + +void KShowMailApp::slotConfChanged( ) +{ + //read the new setup + m_ConfigList.refreshSetup( m_pView->m_pListAccounts ); + m_pView->refreshSetup(); + fLog.loadSetup(); + +} + +void KShowMailApp::slotShowFilterLog( ) +{ + //open dialog + FilterLogView view( this, &fLog ); + view.exec(); + + refreshFilterStatusBar(); +} + +void KShowMailApp::refreshFilterStatusBar( ) +{ + int numberDeletedLastRefresh = m_ConfigList.numberDeletedMailsLastRefresh(); + int numberDeletedSinceStart = m_ConfigList.numberDeletedMailsStart(); + int numberDeletedLog = fLog.numberDeletedMails(); + + int numberMovedLastRefresh = m_ConfigList.numberMovedMailsLastRefresh(); + int numberMovedSinceStart = m_ConfigList.numberMovedMailsStart(); + int numberMovedLog = fLog.numberMovedMails(); + + int numberIgnored = m_ConfigList.numberIgnoredMails(); + + statusBar()->changeItem( i18n( "Filter: Deleted: %1/%2/%3; Moved: %4/%5/%6; Ignored: %7" ).arg( numberDeletedLastRefresh ).arg( numberDeletedSinceStart ).arg( numberDeletedLog ).arg( numberMovedLastRefresh ).arg( numberMovedSinceStart ).arg( numberMovedLog ).arg( numberIgnored ), STATUSBAR_FIELD_FILTER ); +} + +void KShowMailApp::slotAddToWhitelist( ) +{ + //get new entries + QStringList newEntries = m_ConfigList.getSelectedSenders(); + + //get previous whitelist from config + KConfig* config = KApplication::kApplication()->config(); + config->setGroup( CONFIG_GROUP_FILTER ); + QStringList whiteList = config->readListEntry( CONFIG_ENTRY_FILTER_WHITELIST ); + + //append new entries + for( QStringList::Iterator it = newEntries.begin(); it != newEntries.end(); ++it ) + { + if( whiteList.contains( *it ) == 0 ) + { + whiteList.append( *it ); + } + } + + //write extended whitelist back + config->writeEntry( CONFIG_ENTRY_FILTER_WHITELIST, whiteList ); + config->sync(); + + //load new config + m_ConfigList.refreshFilterSetup(); +} + +void KShowMailApp::slotAddToBlacklist( ) +{ + //get new entries + QStringList newEntries = m_ConfigList.getSelectedSenders(); + + //get previous blacklist from config + KConfig* config = KApplication::kApplication()->config(); + config->setGroup( CONFIG_GROUP_FILTER ); + QStringList blackList = config->readListEntry( CONFIG_ENTRY_FILTER_BLACKLIST ); + + //append new entries + for( QStringList::Iterator it = newEntries.begin(); it != newEntries.end(); ++it ) + { + if( blackList.contains( *it ) == 0 ) + { + blackList.append( *it ); + } + } + + //write extended whitelist back + config->writeEntry( CONFIG_ENTRY_FILTER_BLACKLIST, blackList ); + config->sync(); + + //load new config + m_ConfigList.refreshFilterSetup(); +} + |