From: Luis P. <lpe...@al...> - 2008-06-14 14:12:03
|
src/Makefile.am | 11 src/Makefile.in | 75 +++- src/configdialog.cpp | 8 src/gmail.cpp | 9 src/gmail.h | 2 src/gmailparser.cpp | 28 - src/gmailparser.h | 6 src/gmailwalletmanager.cpp | 1 src/jsprotocol.cpp | 160 +++++++++ src/jsprotocol.h | 78 ++++ src/kcheckgmailapp.cpp | 8 src/kcheckgmailapp.h | 10 src/kcheckgmailcore.cpp | 739 +++++++++++++++++++++++++++++++++++++++++++++ src/kcheckgmailcore.h | 118 +++++++ src/kcheckgmailcore_p.h | 107 ++++++ src/kcheckgmailtray.cpp | 676 ----------------------------------------- src/kcheckgmailtray.h | 74 ---- src/mailcounter.cpp | 58 +++ src/mailcounter.h | 51 +++ src/main.cpp | 10 20 files changed, 1434 insertions(+), 795 deletions(-) New commits: commit 1491318a194db47803a7a8446a5c86ac05872449 Author: luispereira <luispereira> Date: Thu May 15 15:02:34 2008 +0000 Change SettingsWidget's parents. SettingsWidget's are now ConfigDialog descendants. They will be deleted (automatically) when ConfigDialog is destroyed. diff --git a/src/configdialog.cpp b/src/configdialog.cpp index 2e47492..015e711 100644 --- a/src/configdialog.cpp +++ b/src/configdialog.cpp @@ -35,16 +35,16 @@ ConfigDialog::ConfigDialog(QWidget* parent, const char* name, KConfigSkeleton* // Copied from KCheckGmailTray::initConfigDialog(); - mLoginSettings = new LoginSettingsWidget(0, "LoginSettings"); + mLoginSettings = new LoginSettingsWidget(this, "LoginSettings"); addPage(mLoginSettings, i18n("Login"), "kcheckgmail", i18n("Login Settings")); - NetworkSettingsWidget *nwid = new NetworkSettingsWidget(0, "NetworkSettings"); + NetworkSettingsWidget *nwid = new NetworkSettingsWidget(this, "NetworkSettings"); addPage(nwid, i18n("Network"), "www", i18n("Network Settings")); - AppletSettingsWidget *awid = new AppletSettingsWidget(0, "AppletSettings"); + AppletSettingsWidget *awid = new AppletSettingsWidget(this, "AppletSettings"); addPage(awid, i18n("Behavior"), "configure", i18n("Behavior")); - AdvancedSettingsWidget *cwid = new AdvancedSettingsWidget(0, "AdvancedSettings"); + AdvancedSettingsWidget *cwid = new AdvancedSettingsWidget(this, "AdvancedSettings"); addPage(cwid, i18n("Advanced"), "package_settings", i18n("Advanced Settings")); mLoginSettings->gmailPassword->erase(); diff --git a/src/kcheckgmailcore.cpp b/src/kcheckgmailcore.cpp index 4af37e1..d40b45c 100644 --- a/src/kcheckgmailcore.cpp +++ b/src/kcheckgmailcore.cpp @@ -76,12 +76,12 @@ KCheckGmailCore::KCheckGmailCore(QObject* parent, const char* name) KCheckGmailCore::~KCheckGmailCore() { + if (d->mConfigDialog) + d->mConfigDialog->deleteLater(); + delete d->mTray; d->mTray = 0; - delete d->mConfigDialog; - d->mConfigDialog = 0; - delete d; d = 0; } commit 8d307fbecb30ee09a00879693c2392cb20616b41 Author: luispereira <luispereira> Date: Tue Apr 29 16:41:26 2008 +0000 Unlock mutex before destruction. If they are not unlocked before destruction, we get the following warning: Mutex destroy failure: Device or resource busy. diff --git a/src/gmail.cpp b/src/gmail.cpp index 94c4acb..09af74e 100644 --- a/src/gmail.cpp +++ b/src/gmail.cpp @@ -82,9 +82,13 @@ GMail::GMail(QObject* parent, const char* name) : QObject(parent, name) GMail::~GMail() { + if (mCheckLock->locked()) + mCheckLock->unlock(); delete mCheckLock; mCheckLock = 0; + if (mLoginLock->locked()) + mLoginLock->unlock(); delete mLoginLock; mLoginLock = 0; } commit a7a5816565dd6c546acce6888b425f3ac80cf1a2 Author: luispereira <luispereira> Date: Tue Apr 29 16:37:03 2008 +0000 Move functionality away from KCheckGmailTray. KCheckGmailTray was indeed the core class. It owned every functionality relevant class in the project. KCheckGmailCore is now the core class. It also owns the DCOP interface. Add a JSProtocol (JavaScriptProtocol) class. JSProtocol owns (encapsulates) GMailParser and GMail. Change the way mail count updates are handled.The system tray must be isolated from the internals of a mail count update.It should only receive the updates and display them. The Gmail (object) count update signals are now connected to the mJSP object. mTray object no longer asks for computation of new and unread messages. The loginDone signal is now connected to the mJSP object. The mJSP then reemites a loginDone signal with the info to be displayedin the systemtray. This way we can reset the counters if the connection is lost. MailCounter contains the current count (both new and unread) and also the previous. KCheckGmailTray slotMailCountChanged and slotmailArrived are independent now. slotMailCountChanged receives the number of unread messages updateThreadMenu: No longer computes the Threads menu entries. diff --git a/src/Makefile.am b/src/Makefile.am index c838a51..5b37f40 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,18 +3,18 @@ INCLUDES = $(all_includes) bin_PROGRAMS = kcheckgmail kcheckgmail_SOURCES = advancedsettingswidget.ui appletsettingswidget.ui \ - configdialog.cpp gmail.cpp gmailparser.cpp gmailwalletmanager.cpp kcheckgmailapp.cpp \ - kcheckgmailcore.cpp kcheckgmailiface.skel kcheckgmailtray.cpp loginsettingswidget.ui \ - main.cpp netsettingswidget.ui prefs.kcfgc + configdialog.cpp gmail.cpp gmailparser.cpp gmailwalletmanager.cpp jsprotocol.cpp \ + kcheckgmailapp.cpp kcheckgmailcore.cpp kcheckgmailiface.skel kcheckgmailtray.cpp \ + loginsettingswidget.ui mailcounter.cpp main.cpp netsettingswidget.ui prefs.kcfgc kcheckgmail_LDFLAGS = $(KDE_PLUGIN) $(all_libraries) kcheckgmail_LDADD = $(LIB_KDEUI) $(LIB_KIO) -lkwalletclient METASOURCES = AUTO noinst_HEADERS = advancedsettingswidget.h appletsettingswidget.h configdialog.h \ - gmail.h gmail_constants.h gmailparser.h gmailwalletmanager.h kcheckgmailapp.h \ - kcheckgmailcore.h kcheckgmailiface.h kcheckgmailtray.h loginsettingswidget.h \ - netsettingswidget.h prefs.h + gmail.h gmail_constants.h gmailparser.h gmailwalletmanager.h jsprotocol.h \ + kcheckgmailapp.h kcheckgmailcore.h kcheckgmailcore_p.h kcheckgmailiface.h \ + kcheckgmailtray.h loginsettingswidget.h mailcounter.h netsettingswidget.h prefs.h xdg_apps_DATA = kcheckgmail.desktop diff --git a/src/Makefile.in b/src/Makefile.in index 9747bdd..cfa640a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -54,15 +54,17 @@ binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(bin_PROGRAMS) am_kcheckgmail_OBJECTS = configdialog.$(OBJEXT) gmail.$(OBJEXT) \ gmailparser.$(OBJEXT) gmailwalletmanager.$(OBJEXT) \ - kcheckgmailapp.$(OBJEXT) kcheckgmailcore.$(OBJEXT) \ - kcheckgmailtray.$(OBJEXT) main.$(OBJEXT) + jsprotocol.$(OBJEXT) kcheckgmailapp.$(OBJEXT) \ + kcheckgmailcore.$(OBJEXT) kcheckgmailtray.$(OBJEXT) \ + mailcounter.$(OBJEXT) main.$(OBJEXT) #>- kcheckgmail_OBJECTS = $(am_kcheckgmail_OBJECTS) -#>+ 5 +#>+ 6 kcheckgmail_OBJECTS = configdialog.$(OBJEXT) gmail.$(OBJEXT) \ gmailparser.$(OBJEXT) gmailwalletmanager.$(OBJEXT) \ - kcheckgmailapp.$(OBJEXT) kcheckgmailcore.$(OBJEXT) \ - kcheckgmailtray.$(OBJEXT) main.$(OBJEXT) kcheckgmailiface_skel.$(OBJEXT) advancedsettingswidget.$(OBJEXT) appletsettingswidget.$(OBJEXT) loginsettingswidget.$(OBJEXT) netsettingswidget.$(OBJEXT) prefs.$(OBJEXT)\ -gmailparser.moc.o gmailwalletmanager.moc.o kcheckgmailapp.moc.o kcheckgmailtray.moc.o + jsprotocol.$(OBJEXT) kcheckgmailapp.$(OBJEXT) \ + kcheckgmailcore.$(OBJEXT) kcheckgmailtray.$(OBJEXT) \ + mailcounter.$(OBJEXT) main.$(OBJEXT) kcheckgmailiface_skel.$(OBJEXT) advancedsettingswidget.$(OBJEXT) appletsettingswidget.$(OBJEXT) loginsettingswidget.$(OBJEXT) netsettingswidget.$(OBJEXT) prefs.$(OBJEXT)\ +kcheckgmailapp.moc.o gmailparser.moc.o gmailwalletmanager.moc.o kcheckgmailtray.moc.o am__DEPENDENCIES_1 = kcheckgmail_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) #>- kcheckgmail_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ @@ -357,22 +359,22 @@ xdg_directorydir = @xdg_directorydir@ xdg_menudir = @xdg_menudir@ INCLUDES = $(all_includes) #>- kcheckgmail_SOURCES = advancedsettingswidget.ui appletsettingswidget.ui \ -#>- configdialog.cpp gmail.cpp gmailparser.cpp gmailwalletmanager.cpp kcheckgmailapp.cpp \ -#>- kcheckgmailcore.cpp kcheckgmailiface.skel kcheckgmailtray.cpp loginsettingswidget.ui \ -#>- main.cpp netsettingswidget.ui prefs.kcfgc +#>- configdialog.cpp gmail.cpp gmailparser.cpp gmailwalletmanager.cpp jsprotocol.cpp \ +#>- kcheckgmailapp.cpp kcheckgmailcore.cpp kcheckgmailiface.skel kcheckgmailtray.cpp \ +#>- loginsettingswidget.ui mailcounter.cpp main.cpp netsettingswidget.ui prefs.kcfgc #>+ 4 kcheckgmail_SOURCES= \ - configdialog.cpp gmail.cpp gmailparser.cpp gmailwalletmanager.cpp kcheckgmailapp.cpp \ - kcheckgmailcore.cpp kcheckgmailtray.cpp \ - main.cpp kcheckgmailiface_skel.cpp advancedsettingswidget.cpp appletsettingswidget.cpp loginsettingswidget.cpp netsettingswidget.cpp prefs.cpp + configdialog.cpp gmail.cpp gmailparser.cpp gmailwalletmanager.cpp jsprotocol.cpp \ + kcheckgmailapp.cpp kcheckgmailcore.cpp kcheckgmailtray.cpp \ + mailcounter.cpp main.cpp kcheckgmailiface_skel.cpp advancedsettingswidget.cpp appletsettingswidget.cpp loginsettingswidget.cpp netsettingswidget.cpp prefs.cpp kcheckgmail_LDFLAGS = $(KDE_PLUGIN) $(all_libraries) kcheckgmail_LDADD = $(LIB_KDEUI) $(LIB_KIO) -lkwalletclient #>- METASOURCES = AUTO noinst_HEADERS = advancedsettingswidget.h appletsettingswidget.h configdialog.h \ - gmail.h gmail_constants.h gmailparser.h gmailwalletmanager.h kcheckgmailapp.h \ - kcheckgmailcore.h kcheckgmailiface.h kcheckgmailtray.h loginsettingswidget.h \ - netsettingswidget.h prefs.h + gmail.h gmail_constants.h gmailparser.h gmailwalletmanager.h jsprotocol.h \ + kcheckgmailapp.h kcheckgmailcore.h kcheckgmailcore_p.h kcheckgmailiface.h \ + kcheckgmailtray.h loginsettingswidget.h mailcounter.h netsettingswidget.h prefs.h xdg_apps_DATA = kcheckgmail.desktop rcdir = $(kde_datadir)/kcheckgmail @@ -468,9 +470,11 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmail.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmailparser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmailwalletmanager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jsprotocol.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kcheckgmailapp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kcheckgmailcore.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kcheckgmailtray.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mailcounter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ .cpp.o: @@ -749,6 +753,13 @@ configdialog.moc: $(srcdir)/configdialog.h mocs: configdialog.moc #>+ 3 +kcheckgmailapp.moc.cpp: $(srcdir)/kcheckgmailapp.h + $(MOC) $(srcdir)/kcheckgmailapp.h -o kcheckgmailapp.moc.cpp + +#>+ 2 +mocs: kcheckgmailapp.moc.cpp + +#>+ 3 gmailparser.moc.cpp: $(srcdir)/gmailparser.h $(MOC) $(srcdir)/gmailparser.h -o gmailparser.moc.cpp @@ -763,13 +774,6 @@ gmailwalletmanager.moc.cpp: $(srcdir)/gmailwalletmanager.h mocs: gmailwalletmanager.moc.cpp #>+ 3 -kcheckgmailapp.moc.cpp: $(srcdir)/kcheckgmailapp.h - $(MOC) $(srcdir)/kcheckgmailapp.h -o kcheckgmailapp.moc.cpp - -#>+ 2 -mocs: kcheckgmailapp.moc.cpp - -#>+ 3 kcheckgmailtray.moc.cpp: $(srcdir)/kcheckgmailtray.h $(MOC) $(srcdir)/kcheckgmailtray.h -o kcheckgmailtray.moc.cpp @@ -784,11 +788,18 @@ gmail.moc: $(srcdir)/gmail.h mocs: gmail.moc #>+ 3 +jsprotocol.moc: $(srcdir)/jsprotocol.h + $(MOC) $(srcdir)/jsprotocol.h -o jsprotocol.moc + +#>+ 2 +mocs: jsprotocol.moc + +#>+ 3 clean-metasources: - -rm -f kcheckgmailcore.moc configdialog.moc gmailparser.moc.cpp gmailwalletmanager.moc.cpp kcheckgmailapp.moc.cpp kcheckgmailtray.moc.cpp gmail.moc + -rm -f kcheckgmailcore.moc configdialog.moc kcheckgmailapp.moc.cpp gmailparser.moc.cpp gmailwalletmanager.moc.cpp kcheckgmailtray.moc.cpp gmail.moc jsprotocol.moc #>+ 2 -KDE_DIST=Makefile.in kcheckgmail.lsm advancedsettingswidget.ui appletsettingswidget.ui prefs.kcfgc eventsrc netsettingswidget.ui prefs.kcfg kcheckgmail.desktop loginsettingswidget.ui Makefile.am +KDE_DIST=Makefile.in kcheckgmail.lsm advancedsettingswidget.ui appletsettingswidget.ui prefs.kcfgc eventsrc netsettingswidget.ui prefs.kcfg kcheckgmail.desktop loginsettingswidget.ui Makefile.am #>+ 4 clean-idl: @@ -869,12 +880,14 @@ no-final-install: kde-rpo-clean: -rm -f *.rpo -#>+ 17 +#>+ 21 $(srcdir)/configdialog.cpp: advancedsettingswidget.h appletsettingswidget.h loginsettingswidget.h netsettingswidget.h prefs.h $(srcdir)/main.cpp: advancedsettingswidget.h appletsettingswidget.h loginsettingswidget.h netsettingswidget.h prefs.h $(srcdir)/gmailwalletmanager.cpp: advancedsettingswidget.h appletsettingswidget.h loginsettingswidget.h netsettingswidget.h prefs.h +jsprotocol.lo: jsprotocol.moc $(srcdir)/kcheckgmailcore.cpp: advancedsettingswidget.h appletsettingswidget.h loginsettingswidget.h netsettingswidget.h prefs.h configdialog.o: configdialog.moc +$(srcdir)/mailcounter.cpp: advancedsettingswidget.h appletsettingswidget.h loginsettingswidget.h netsettingswidget.h prefs.h nmcheck: kcheckgmailcore.o: kcheckgmailcore.moc $(srcdir)/gmailparser.cpp: advancedsettingswidget.h appletsettingswidget.h loginsettingswidget.h netsettingswidget.h prefs.h @@ -882,9 +895,11 @@ kcheckgmailcore.lo: kcheckgmailcore.moc $(srcdir)/kcheckgmailtray.cpp: advancedsettingswidget.h appletsettingswidget.h loginsettingswidget.h netsettingswidget.h prefs.h gmail.o: gmail.moc nmcheck-am: nmcheck +$(srcdir)/jsprotocol.cpp: advancedsettingswidget.h appletsettingswidget.h loginsettingswidget.h netsettingswidget.h prefs.h configdialog.lo: configdialog.moc gmail.lo: gmail.moc $(srcdir)/kcheckgmailapp.cpp: advancedsettingswidget.h appletsettingswidget.h loginsettingswidget.h netsettingswidget.h prefs.h +jsprotocol.o: jsprotocol.moc $(srcdir)/gmail.cpp: advancedsettingswidget.h appletsettingswidget.h loginsettingswidget.h netsettingswidget.h prefs.h #>+ 66 diff --git a/src/gmail.cpp b/src/gmail.cpp index d537bab..94c4acb 100644 --- a/src/gmail.cpp +++ b/src/gmail.cpp @@ -49,7 +49,7 @@ #define MILLISECS(x) (x * 1000) -GMail::GMail() : QObject(0, "GMailNetwork") +GMail::GMail(QObject* parent, const char* name) : QObject(parent, name) { mInterval = Prefs::interval(); mCheckLock = new QMutex(); diff --git a/src/gmail.h b/src/gmail.h index 3ef9245..1e5b4d9 100644 --- a/src/gmail.h +++ b/src/gmail.h @@ -39,7 +39,7 @@ class GMail : public QObject { Q_OBJECT public: - GMail(); + GMail(QObject* parent = 0, const char* name = 0); virtual ~GMail(); void checkLoginParams(); diff --git a/src/gmailparser.cpp b/src/gmailparser.cpp index c83c4ca..3e1d6ba 100644 --- a/src/gmailparser.cpp +++ b/src/gmailparser.cpp @@ -36,8 +36,8 @@ * This class parses the resulting data of a call to * Gmail's JavaScript interface. */ -GMailParser::GMailParser() : - QObject(0, "GMailParser"), +GMailParser::GMailParser(QObject* parent, const char* name) : + QObject(parent, name), mInvites(0) { mSummary.inbox = 0; @@ -124,8 +124,6 @@ void GMailParser::parse(const QString &_data) { static QRegExp rx("D\\(\\[(.*)\\][\\s\\n]*\\);"); int pos = 0; - unsigned int previousParsedOnlyUnread = 0; - unsigned int currentUnread = 0; rx.setMinimal(true); @@ -135,7 +133,7 @@ void GMailParser::parse(const QString &_data) } mCurMsgId = 0; - previousParsedOnlyUnread = unread(ParsedOnlyCount); + QMap<QString,bool> *oldMap = getThreadList(); freeThreadList(); @@ -152,6 +150,10 @@ void GMailParser::parse(const QString &_data) QString data = QString::fromUtf8(_data); + /* + * mailsArrived refers to new messages in the parsed threads + */ + unsigned int arrivedMails = 0; while((pos = rx.search(data, pos)) != -1) { QString str = rx.cap(1); QRegExp rxType("^\"([a-z]+)\","); @@ -165,7 +167,7 @@ void GMailParser::parse(const QString &_data) str.remove(tokPos, tokLen); if(tok == D_THREAD) { - currentUnread += parseThread(str, oldMap); + arrivedMails += parseThread(str, oldMap); } else if(tok == D_VERSION) { parseVersion(str); } else if(tok == D_QUOTA) { @@ -190,19 +192,7 @@ void GMailParser::parse(const QString &_data) delete oldMap; oldMap = 0; - kdDebug() << k_funcinfo << "currentUnread=" << currentUnread << endl; - kdDebug() << k_funcinfo << "previousParsedOnlyUnread=" << previousParsedOnlyUnread << endl; - - int currentTotalUnread = unread(TotalCount); - if (previousParsedOnlyUnread == 0 && currentTotalUnread != 0) - currentUnread = currentTotalUnread; - - if(currentUnread > 0) - emit mailArrived(currentUnread); - if(previousParsedOnlyUnread != currentUnread) - emit mailCountChanged(); - if(currentTotalUnread == 0) - emit noUnreadMail(); + emit countUpdate(arrivedMails); } /////////////////////////////////////////////////////////////////////////// diff --git a/src/gmailparser.h b/src/gmailparser.h index 68f0b8c..a0499bd 100644 --- a/src/gmailparser.h +++ b/src/gmailparser.h @@ -104,7 +104,7 @@ public: ParsedOnlyCount }; - GMailParser(); + GMailParser(QObject* parent = 0, const char* name = 0); virtual ~GMailParser(); void parse(const QString &data); @@ -133,11 +133,9 @@ public: static QString cleanUpData(QString data); signals: - void mailArrived(unsigned int count); - void mailCountChanged(); void versionMismatch(); - void noUnreadMail(); void gNameUpdate(QString name); + void countUpdate(unsigned int arrivedMails); protected: void parseQuota(const QString&); diff --git a/src/jsprotocol.cpp b/src/jsprotocol.cpp new file mode 100644 index 0000000..1a97cb7 --- /dev/null +++ b/src/jsprotocol.cpp @@ -0,0 +1,160 @@ +/*************************************************************************** + * Copyright (C) 2008 by Luis Pereira <lui...@gm...> * + * * + * 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. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "jsprotocol.h" + +#include <kdebug.h> + +namespace KCheckGmail { + +JSProtocol::JSProtocol(QObject* parent, const char* name) + : QObject(parent, name), + mParser(new GMailParser(this, "JS_GMailParser")), + mGmail(new GMail(this, "JS_GMailNetwork")), + firstTime(true) +{ + connect(mParser, SIGNAL(countUpdate(unsigned int)), + this, SLOT(slotCountUpdate(unsigned int))); + + connect(mGmail, SIGNAL(loginDone(bool, bool, const QString&)), + this, SLOT(slotLoginDone(bool, bool, const QString&))); + + connect(mGmail, SIGNAL(checkDone(const QString&)), + this, SLOT(slotCheckDone(const QString&))); +} + + +JSProtocol::~JSProtocol() +{ +} + +GMailParser* JSProtocol::parser() +{ + return mParser; +} + +GMail* JSProtocol::retriever() +{ + return mGmail; +} + + +void JSProtocol::slotCheckDone(const QString& data) +{ + mParser->parse(data); + emit checkDone(); +} + + +void JSProtocol::slotLoginDone(bool ok, bool evtFromTimer, const QString &why) +{ + static QString lastExcuse = ""; + bool excuseNeeded = false; + + kdDebug() << k_funcinfo << endl << "ok=" << ok << " evtFromTimer=" << + evtFromTimer << " why=" << why << endl << endl; + + if(!ok) { + mCount.reset(); + firstTime = true; + if(why != lastExcuse || !evtFromTimer) { + lastExcuse = why; + excuseNeeded = true; + } + } + emit loginDone(ok, excuseNeeded, why); +} + + +void JSProtocol::slotCountUpdate(unsigned int currentParsed) +{ + int currentTotal = mParser->unread(GMailParser::TotalCount); + mCount.setCount(currentTotal, currentParsed); + + kdDebug() << k_funcinfo << endl; + kdDebug() << "firstTime: " << firstTime << endl; + kdDebug() << "previousParsed: " << mCount.previousParsed() << endl; + kdDebug() << "currentParsed: " << currentParsed << endl; + kdDebug() << "previousTotal: " << mCount.previousTotal() << endl; + kdDebug() << "currentTotal: " << currentTotal << endl; + + QMap <QString, int> threads = threadMenuEntries(); + if (firstTime) { + firstTime = false; + if (currentTotal != 0) { + emit mailArrived(currentTotal); + emit mailCountChanged(currentTotal); + } + } else { + if (mCount.previousTotal() != currentTotal) + emit mailCountChanged(currentTotal); + + if (mCount.previousParsed() != currentParsed && currentParsed != 0) + emit mailArrived(currentParsed); + } + + if (currentTotal == 0) { + emit noUnreadMail(); + } + emit threadsChanged(threads); +} + +int JSProtocol::unread() const +{ + return mCount.currentTotal(); +} + +QMap<QString, int> JSProtocol::threadMenuEntries() +{ + QMap<QString, int> entries; + QMap<QString,bool> *threads = mParser->getThreadList(); + int numItems = 0; + + if(threads) { + + QValueList<QString> klist = threads->keys(); + QValueList<QString>::iterator iter = klist.begin(); + + kdDebug() << k_funcinfo << "number of threads=" << klist.size() << endl; + + while(iter != klist.end()) { + bool isNew = (*threads)[*iter]; + if(isNew) { + const GMailParser::Thread &t = mParser->getThread(*iter); + if(!t.isNull) { + QString str = t.senders; + str += " - "; + str += t.subject; + str.replace("&","&&"); + + entries.insert(str, t.id); + numItems ++; + } + } + iter ++; + } + delete threads; + threads = 0; + } + return entries; +} + +} // namespace KCheckGmail + +#include "jsprotocol.moc" diff --git a/src/jsprotocol.h b/src/jsprotocol.h new file mode 100644 index 0000000..3f264be --- /dev/null +++ b/src/jsprotocol.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2008 by Luis Pereira <lui...@gm...> * + * * + * 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. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef KCHECKGMAIL_JSPROTOCOL_H +#define KCHECKGMAIL_JSPROTOCOL_H + +#include <qobject.h> + +#include "gmailparser.h" +#include "gmail.h" +#include "mailcounter.h" + + +namespace KCheckGmail { + +/* + * This class contains code moved (and sometimes modified) from the + * following classes: + * + * KCheckGmailTray + * Copyright (C) 2004 by Matthew Wlazlo <mw...@gm...> + * Copyright (C) 2007 by Raphael Geissert <at...@gm...> + * + * GMailParser + * Copyright (C) 2004 by Matthew Wlazlo <mw...@gm...> + * Copyright (C) 2007 by Raphael Geissert <at...@gm...> + */ +class JSProtocol : public QObject { + Q_OBJECT + +public: + JSProtocol(QObject* parent, const char* name = 0); + ~JSProtocol(); + + GMailParser* parser(); + GMail* retriever(); + int unread() const; + QMap<QString, int> threadMenuEntries(); + +signals: + void mailArrived(unsigned int count); + void threadsChanged(QMap<QString, int> menuEntries); + void mailCountChanged(int count); + void noUnreadMail(); + void checkDone(); + void loginDone(bool success, bool isExcuseNeeded, const QString& errmsg); + +private slots: + void slotCountUpdate(unsigned int parsed); + void slotCheckDone(const QString& data); + void slotLoginDone(bool success, bool spawnedFromTimer, const QString &errmsg); + +private: + GMailParser* mParser; + GMail* mGmail; + MailCounter mCount; + bool firstTime; +}; + +} + +#endif diff --git a/src/kcheckgmailcore.cpp b/src/kcheckgmailcore.cpp index 65ec07b..4af37e1 100644 --- a/src/kcheckgmailcore.cpp +++ b/src/kcheckgmailcore.cpp @@ -18,28 +18,722 @@ ***************************************************************************/ #include "kcheckgmailcore.h" +#include "kcheckgmailcore_p.h" #include "kcheckgmailtray.h" +#include "jsprotocol.h" +#include "configdialog.h" +#include "gmailwalletmanager.h" +#include "prefs.h" + +#include <kapp.h> +#include <klocale.h> +#include <kactioncollection.h> +#include <kpopupmenu.h> +#include <kconfigdialog.h> +#include <kconfig.h> +#include <kiconeffect.h> +#include <kmimetype.h> +#include <kglobal.h> +#include <khelpmenu.h> +#include <kiconloader.h> +#include <kmacroexpander.h> +#include <krun.h> +#include <kaboutapplication.h> +#include <knotifydialog.h> +#include <kmessagebox.h> +#include <kdialog.h> +#include <kdialogbase.h> +#include <knotifyclient.h> +#include <dcopclient.h> + +#include <qfile.h> +#include <qtooltip.h> KCheckGmailCore::KCheckGmailCore(QObject* parent, const char* name) - : QObject(parent, name), - mTray(new KCheckGmailTray(0, "KCheckGmailTray")) + : DCOPObject("KCheckGmailIface"), + QObject(parent, name), + d(new Private) { - mTray->show(); - mTray->start(); -} + d->mJSP = new JSProtocol(this, "JSProtocol"); + d->actions = new KActionCollection(this); + + initTray(); + initActions(); + buidTrayPopupMenu(); + initConfigDialog(); + makeConnections(d->mJSP, d->mTray); + // register with dcop + if(!kapp->dcopClient()->isRegistered()) { + kapp->dcopClient()->registerAs(kapp->name()); + } + kapp->dcopClient()->setDefaultObject(objId()); + + start(); + d->mTray->showIcon(); +} KCheckGmailCore::~KCheckGmailCore() { - delete mTray; - mTray = 0; + delete d->mTray; + d->mTray = 0; + + delete d->mConfigDialog; + d->mConfigDialog = 0; + + delete d; + d = 0; } + KCheckGmailCore& KCheckGmailCore::instance() { static KCheckGmailCore object(0, "KCheckGmailCore"); return object; } + +void KCheckGmailCore::initTray() +{ + d->mTray = new KCheckGmailTray(0, "KCheckGmailTray"); + connect(d->mTray, SIGNAL(quitSelected()), kapp, SLOT(quit())); + + connect(d->mTray, SIGNAL(leftButtonClicked()), + this, SLOT(slotLeftButtonClicked())); +} + + +void KCheckGmailCore::initActions() +{ + d->actionShowKNotifyDialog = new KAction(i18n("Configure &Notications"), "knotify", "", this, SLOT(slotShowKNotifyDialog()), d->actions); + + d->actionShowPrefsDialog = new KAction(i18n("&Configure KCheckGMail..."), "configure", "", + this, SLOT( slotShowPrefsDialog()), d->actions); + + d->mLoginCheckMailAction = new KAction(i18n("Login and Chec&k Mail"), "launch", "", + d->mJSP->retriever(), SLOT(slotCheckGmail()), d->actions); + + d->actionLaunchBrowser = new KAction(i18n("&Launch Browser"), "konqueror", "", + this, SLOT(slotLaunchBrowser()), d->actions); + + d->actionComposeMail = new KAction(i18n("Co&mpose Mail"), "email", "", + this, SLOT(slotComposeMail()), d->actions ); +} + + +void KCheckGmailCore::buidTrayPopupMenu() +{ + d->mThreadsMenu = new KPopupMenu(d->mTray, "KCheckGmail Threads menu"); + + connect(d->mThreadsMenu, SIGNAL(activated(int)), + SLOT(slotThreadsMenuActivated(int))); + + connect(d->mThreadsMenu, SIGNAL(highlighted(int)), + SLOT(slotThreadsItemHighlighted(int))); + + d->menu = d->mTray->contextMenu(); + d->menu->clear(); + + d->menu->insertTitle(SmallIcon("kcheckgmail"), i18n("KCheckGMail")); + + d->actionShowKNotifyDialog->plug( d->menu ); + d->actionShowPrefsDialog->plug(d->menu); + + d->menu->insertSeparator(); + + d->mLoginCheckMailAction->plug(d->menu); + d->mLoginCheckMailAction->setEnabled(false); + + d->actionLaunchBrowser->plug(d->menu); + d->actionComposeMail->plug(d->menu); + + d->mThreadsMenuId = d->menu->insertItem(SmallIcon("kcheckgmail"), + i18n("Th&reads"), d->mThreadsMenu); + d->mTray->contextMenu()->setItemEnabled(d->mThreadsMenuId, false); + + d->menu->insertSeparator(); + + d->mHelpMenu = new KHelpMenu(d->mTray, KGlobal::instance()->aboutData(), false, d->actions); + d->menu->insertItem(SmallIcon("help"), KStdGuiItem::help().text(), d->mHelpMenu->menu()); +} + + +void KCheckGmailCore::initConfigDialog() +{ + d->mConfigDialog = new ConfigDialog(0, + "KCheckGmailSettingsDialog", + Prefs::self(), + KDialogBase::IconList, + KDialogBase::Ok | KDialogBase::Cancel); + + connect(d->mConfigDialog, SIGNAL(finished()), + this, SLOT(slotSettingsChanged())); +} + + +void KCheckGmailCore::makeConnections(JSProtocol* mJSP, KCheckGmailTray* mTray) +{ + // hook up JSProtocol + connect(mJSP, SIGNAL(mailArrived(unsigned int)), + this, SLOT(slotMailArrived(unsigned int))); + + connect(mJSP, SIGNAL(mailCountChanged(int)), + mTray, SLOT(slotMailCountChanged(int))); + + connect(mJSP, SIGNAL(threadsChanged(QMap<QString, int>)), + this, SLOT(updateThreadMenu(QMap<QString, int>))); + + connect(mJSP, SIGNAL(noUnreadMail()), + mTray, SLOT(slotNoUnreadMail())); + + connect(mJSP, SIGNAL(checkDone()), + this, SLOT(slotCheckDone())); + + connect(mJSP, SIGNAL(loginDone(bool, bool, const QString&)), + this, SLOT(slotLoginDone(bool, bool, const QString&))); + + + // hook up the GMailParser object + connect(mJSP->parser(), SIGNAL(versionMismatch()), + mTray, SLOT(slotVersionMismatch())); + + connect(mJSP->parser(), SIGNAL(gNameUpdate(QString)), + mTray, SLOT(slotgNameUpdate(QString))); + + + // hook up the GMail object + connect(mJSP->retriever(), SIGNAL(loginStart()), + this, SLOT(slotLoginStart())); + + connect(mJSP->retriever(), SIGNAL(checkStart()), + this, SLOT(slotCheckStart())); + + connect(mJSP->retriever(), SIGNAL(sessionChanged()), + this, SLOT(slotSessionChanged())); + + connect(kapp, SIGNAL(shutDown()), + mJSP->retriever(), SLOT(slotLogOut())); + + + // hook up GMailWalletManager + connect(GMailWalletManager::instance(), SIGNAL(getWalletPassword(const QString&)), + mJSP->retriever(), SLOT(slotGetWalletPassword(const QString&))); + connect(GMailWalletManager::instance(), SIGNAL(setWalletPassword(bool)), + mJSP->retriever(), SLOT(slotSetWalletPassword(bool))); +} + + +void KCheckGmailCore::start() +{ + static bool started = false; + + if(started) { + kdWarning() << k_funcinfo << "Unexpected call!" << endl; + } + + //From RSIBreak + if(KMessageBox::shouldBeShownContinue("welcome_to_kcheckgmail")) { + d->mTray->takeScreenshotOfTrayIcon(); + KMessageBox::information(0, + i18n("<p><center>Welcome to KCheckGMail!</center></p>" + "<p>You can locate KCheckGMail here: </p>" + "<p><center><img source=\"systray_shot\"></center></p>" + "When you right-click on that icon you will see " + "a menu, from which you can see the Threads " + "menu containing the newest email of your account."), + i18n("Welcome")); + + KMessageBox::saveDontShowAgainContinue("welcome_to_kcheckgmail"); + } + + if(KMessageBox::shouldBeShownContinue("kcheckgmail_continue_legal")) { + + int legalCont; + + legalCont = KMessageBox::warningContinueCancel(0, + i18n("Google, Gmail and Google Mail are registered trademarks of Google Inc.\n" + "KCheckGMail nor its authors are in any way affiliated nor endorsed by Google Inc.\n" + "By using this application you may or may not be violating " + "the Terms of Use and/or the Program Policies " + "of Gmail or Google Mail.\n" + "Are you sure you want to use KCheckGMail?"), + i18n("Legal Information")); + + if(legalCont == KMessageBox::Continue) + KMessageBox::saveDontShowAgainContinue("kcheckgmail_continue_legal"); + else { + //NOTE: kapp->quit(); doesn't quit immediately + //There should be no harm on doing this because _nothing_ special has been loaded yet + exit(EXIT_SUCCESS); + } + } + + if(Prefs::gmailUsername().length() == 0) { + d->mConfigDialog->erasePassword(); + slotShowPrefsDialog(); + } + + //Set interval and force the timer to start + d->mJSP->retriever()->setInterval(Prefs::interval(), true); + d->mJSP->retriever()->checkLoginParams(); + + started = true; +} + + +QString KCheckGmailCore::getUrlBase() +{ + QString base = "%1://mail.google.com/%2/"; + + return base.arg((Prefs::useHTTPS())? "https" : "http", d->mJSP->retriever()->getURLPart()); +} + + +void KCheckGmailCore::updateThreadMenu(QMap<QString, int> entries) +{ + d->mThreadsMenu->clear(); + + int id = 0; + unsigned int numItems = 0; + QMapConstIterator<QString, int> it = entries.begin(); + for ( ; it != entries.end(); ++it, ++numItems) { + id = d->mThreadsMenu->insertItem(it.key(), it.data()); + } + + d->mTray->contextMenu()->setItemEnabled(d->mThreadsMenuId, (numItems > 0)); +} + + +/** + * Creates the notifying message displayed when email arrives. + * + * @param n Number of arrived emails + * @param showSender If true shows the email sender + * @param showSubject If true shows the email subject + * @param showSnippet If true shows the email message snippet |