From 70b1ff1a3f134d75d1539f269d52b34e6762684d Mon Sep 17 00:00:00 2001 From: llornkcor Date: Sun, 06 Apr 2003 17:45:00 +0000 Subject: move malit to head again, since it is working --- (limited to 'noncore/net') diff --git a/noncore/net/mailit/README b/noncore/net/mailit/README new file mode 100644 index 0000000..01781b4 --- a/dev/null +++ b/noncore/net/mailit/README @@ -0,0 +1,83 @@ +Issues regarding Mailit +----------------------- + +Mailit is still in development and is lacking some +features to make it completely usable. Listed below are the +most important issues. + +Due to the development status, numerous messages are passed too +the console during usage of the program. +No messages are deleted from the POP server after retrival. + +Synchronization: +--------------------- +Works by comparing the last known size of the mailbox on the server +to the current size. +Possible problem: If a popserver shuffles the order of the mails +when it receives a new mail, mailit won't know since it only uses +the messagecount as a reference. If this occurs, turn sync off in +the account settings. +Haven't encountered this problem on the currently tested servers, +but if it turns out that several servers do this, it will be resolved. + +Mail parsing +------------ +Parsing of MIME-encoded email works for all currently tested cases. +BASE64 decoding works. +Attatchments are saved in the enclosure subdirectory of qtmail +(in the Documents directory). You can install the files to the documents +folder (creates a doclnk) +Adding enclosures is limited to the preselected directories, and they +are not really correct at the moment (trivial issue awaiting decision +of fileplacements in QPE) +attatched pictures will be displayed (jpg dependant on qte compilation) + + +SMTP +---- +The SMTP-client now supports attatchments, but it's not completly done. +Encoding works, but it doesn't examine the file to check what type of +file you are attatching. In other words, if it doesn't know that you +are attatching a picture, the mime setting for content type could be +wrong. Mail clients with inline viewing of pictures (like hotmail) could +have a problem with displaying the mail correctly. +(Should be fixed soon) + +You can now have multiple recipients. + + +POP +--- +The popclient connects to the all accounts in turn, downloads all headers +and emails smaller than 2000 bytes. After its done, it reconnects +and downloads the mails that were too big (> 2000) +The to-be-downloaded mails are sorted according to size. If you view +a mail, it is shifted to the front of the queue. Deleting a mail(header) +while the download is in progress will remove it from the queue of +mails to download (except if the mail is currently in transfer) +You may exit mailit during a transfer of mails/headers. Next time +you reconnect to the same server it will continue downloading from +where it left off. + +You can now choose between getting mail from only one account or all. +The get all option is just added and not fully testet yet. Get from +a single account should work fine. The current way of downloading +does not work well without sync turned on if you keep old mails in +the inbox. + +Experienced some problems with servers reporting mail size less and +bigger than actual size. Don't know whats causing this yet, but I +have added a workaround. It now scans the mail for endofmail +definition ("\r\n.\r\n"), disregarding size. + + +Saving/Retrieving mail +---------------------- +The inbox is saved and retrieved. Any mail not sent from the outbox +is not saved (will of course be added) + +Miscelaneous issues +------------------- +Numerous cosmetic changes, including icons (which are temporary) + +Very little error checking is done on usertyped variables. diff --git a/noncore/net/mailit/addatt.cpp b/noncore/net/mailit/addatt.cpp new file mode 100644 index 0000000..c030e36 --- a/dev/null +++ b/noncore/net/mailit/addatt.cpp @@ -0,0 +1,209 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include +#include +#include "resource.h" +#include "addatt.h" + +FileItem::FileItem(QListView *parent, QFileInfo fileInfo, QString fileType) + : QListViewItem(parent) +{ + file = fileInfo; + type = fileType; + + setText(0, fileInfo.baseName()); + + if (fileType == "Picture") { + setPixmap(0, Resource::loadPixmap("pixmap")); + } else if (fileType == "Document") { + setPixmap(0, Resource::loadPixmap("txt")); + } else if (fileType == "Sound") { + setPixmap(0, Resource::loadPixmap("play")); + } else if (fileType == "Movie") { + setPixmap(0, Resource::loadPixmap("MPEGPlayer")); + } else if (fileType == "File") { + setPixmap(0, Resource::loadPixmap("exec")); + } +} + +QFileInfo FileItem::getFileInfo() +{ + return file; +} + +QString FileItem::getFileType() +{ + return type; +} + +AddAtt::AddAtt(QWidget *parent, const char *name, WFlags f) + : QDialog(parent, name, f) +{ + setCaption("Adding attatchments"); + + QGridLayout *top = new QGridLayout(this, 3, 2); + + fileCategoryButton = new QPushButton(this); + attatchButton = new QPushButton("Attatch ->", this); + removeButton = new QPushButton("Remove", this); + + fileCategories = new QPopupMenu(fileCategoryButton); + fileCategoryButton->setPopup(fileCategories); + fileCategories->insertItem("Document"); + fileCategories->insertItem("Picture"); + fileCategories->insertItem("Sound"); + fileCategories->insertItem("Movie"); + fileCategories->insertItem("File"); + + fileCategoryButton->setText("Document"); + top->addWidget(fileCategoryButton, 0, 0); + top->addWidget(attatchButton, 2, 0); + top->addWidget(removeButton, 2, 1); + + connect(fileCategories, SIGNAL(activated(int)), this, + SLOT(fileCategorySelected(int)) ); + connect(attatchButton, SIGNAL(clicked()), this, + SLOT(addAttatchment()) ); + connect(removeButton, SIGNAL(clicked()), this, + SLOT(removeAttatchment()) ); + + listView = new QListView(this, "AttView"); + listView->addColumn("Documents"); + connect(listView, SIGNAL(doubleClicked(QListViewItem *)), this, + SLOT(addAttatchment()) ); + + attView = new QListView(this, "Selected"); + attView->addColumn("Attatched"); + connect(attView, SIGNAL(doubleClicked(QListViewItem *)), this, + SLOT(removeAttatchment()) ); + + top->addWidget(listView, 1,0); + top->addWidget(attView, 1,1); + + clear(); +} + +void AddAtt::clear() +{ + attView->clear(); + getFiles(); + modified = FALSE; +} + +void AddAtt::fileCategorySelected(int id) +{ + fileCategoryButton->setText(fileCategories->text(id)); + getFiles(); +} + +void AddAtt::addAttatchment() +{ + QFileInfo info; + QString type; + + if (listView->selectedItem() != NULL) { + item = (FileItem *) listView->selectedItem(); + info = item->getFileInfo(); + type = item->getFileType(); + item = new FileItem(attView, info, type); + } + modified = TRUE; +} + +void AddAtt::removeAttatchment() +{ + if (attView->selectedItem() != NULL) { + attView->takeItem(attView->selectedItem()); + } + modified = TRUE; +} + +void AddAtt::reject() +{ + if (modified) { + attView->clear(); + modified = FALSE; + } +} + +void AddAtt::accept() +{ + modified = FALSE; + hide(); +} + +void AddAtt::getFiles() +{ + QString path, selected; + QDir *dir; + + listView->clear(); + + selected = fileCategoryButton->text(); + if (selected == "Picture") { + path = "../pics/"; + } else if (selected == "Document") { + path = "" ; //sub-dirs not decided + } else if (selected == "Sound") { + path = "../sounds/"; //sub-dirs not decided + } else if (selected == "Movie") { + path = ""; //sub-dirs not decided + } else if (selected == "File") { + path = ""; //sub-dirs not decided + } + + dir = new QDir(path); + dir->setFilter(QDir::Files); + const QFileInfoList *dirInfoList = dir->entryInfoList(); + + QFileInfoListIterator it(*dirInfoList); // create list iterator + + while ( (fi=it.current()) ) { // for each file... + item = new FileItem(listView, *fi, selected); + ++it; // goto next list element + } +} + +QStringList AddAtt::returnAttatchedFiles() +{ + QFileInfo info; + QStringList list; + + item = (FileItem *) attView->firstChild(); + while (item != NULL) { + info = item->getFileInfo(); + list += info.filePath(); + item = (FileItem *) item->nextSibling(); + } + return list; +} + +QStringList AddAtt::returnFileTypes() +{ + QStringList list; + + item = (FileItem *) attView->firstChild(); + while (item != NULL) { + list += item->getFileType(); + item = (FileItem *) item->nextSibling(); + } + return list; +} diff --git a/noncore/net/mailit/addatt.h b/noncore/net/mailit/addatt.h new file mode 100644 index 0000000..867c905 --- a/dev/null +++ b/noncore/net/mailit/addatt.h @@ -0,0 +1,70 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef ADDATT_H +#define ADDATT_H + +#include +#include +#include +#include +#include +#include +#include + +class FileItem : public QListViewItem +{ +public: + FileItem(QListView *parent, QFileInfo fileInfo, QString fileType); + QFileInfo getFileInfo(); + QString getFileType(); + +private: + QFileInfo file; + QString type; +}; + +class AddAtt : public QDialog +{ + Q_OBJECT + +public: + AddAtt(QWidget *parent = 0, const char *name = 0, WFlags f = 0); + QStringList returnAttatchedFiles(); + QStringList returnFileTypes(); + void getFiles(); + void clear(); + +public slots: + void fileCategorySelected(int); + void addAttatchment(); + void removeAttatchment(); + void reject(); + void accept(); + +private: + FileItem *item; + QListView *listView, *attView; + QPushButton *fileCategoryButton, *attatchButton, *removeButton; + QPopupMenu *fileCategories; + bool modified; + QFileInfo *fi; +}; + +#endif diff --git a/noncore/net/mailit/addresslist.cpp b/noncore/net/mailit/addresslist.cpp new file mode 100644 index 0000000..1cf2562 --- a/dev/null +++ b/noncore/net/mailit/addresslist.cpp @@ -0,0 +1,167 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include + +#include "addresslist.h" + +AddressList::AddressList(QString file) +{ + addresses.setAutoDelete(TRUE); + filename = file; + read(); + dirty = FALSE; +} + +AddressList::~AddressList() +{ + write(); + addresses.clear(); +} + +void AddressList::addContact(QString email, QString name) +{ + //skip if not a valid email address, + if (email.find( '@') == -1) + return; + + if ( ! containsEmail(email) ) { + Contact *in = new Contact; + in->email = email; + in->name = name; + addresses.append(in); + dirty = TRUE; + } +} + +bool AddressList::containsEmail(QString email) +{ + return ( getEmailRef(email) != -1 ); +} + +bool AddressList::containsName(QString name) +{ + return ( getNameRef(name) != -1 ); +} + +QString AddressList::getNameByEmail(QString email) +{ + int pos = getEmailRef(email); + if (pos != -1) { + Contact *ptr = addresses.at(pos); + return ptr->name; + } + + return NULL; +} + +QString AddressList::getEmailByName(QString name) +{ + int pos = getNameRef(name); + if (pos != -1) { + Contact *ptr = addresses.at(pos); + return ptr->email; + } + + return NULL; +} + +int AddressList::getEmailRef(QString email) +{ + int pos = 0; + Contact *ptr; + + for (ptr = addresses.first(); ptr != 0; ptr = addresses.next() ) { + if (ptr->email == email) + return pos; + pos++; + } + return -1; +} + +int AddressList::getNameRef(QString name) +{ + int pos = 0; + Contact *ptr; + + for (ptr = addresses.first(); ptr != 0; ptr = addresses.next() ) { + if (ptr->name == name) + return pos; + pos++; + } + return -1; +} + +QList* AddressList::getContactList() +{ + return &addresses; +} + +void AddressList::read() +{ + QFile f(filename); + QString lineEmail, lineName, email, name; + + if (! f.open(IO_ReadOnly) ) + return; + + QTextStream stream(&f); + + while (! stream.atEnd() ) { + lineEmail = stream.readLine(); + if (! stream.atEnd() ) + lineName = stream.readLine(); + else return; + + email = getRightString(lineEmail); + name = getRightString(lineName); + addContact(email, name); + } + f.close(); +} + +QString AddressList::getRightString(QString in) +{ + QString out = ""; + + int pos = in.find('='); + if (pos != -1) { + out = in.mid(pos+1).stripWhiteSpace(); + } + return out; +} + +void AddressList::write() +{ + if ( (addresses.count() == 0) || (!dirty) ) + return; + + QFile f(filename); + if (! f.open(IO_WriteOnly) ) + return; + + QTextStream stream(&f); + Contact *ptr; + for (ptr = addresses.first(); ptr != 0; ptr = addresses.next() ) { + stream << "email = " + ptr->email + "\n"; + stream << "name = " + ptr->name + "\n"; + } + f.close(); +} diff --git a/noncore/net/mailit/addresslist.h b/noncore/net/mailit/addresslist.h new file mode 100644 index 0000000..e87d6f1 --- a/dev/null +++ b/noncore/net/mailit/addresslist.h @@ -0,0 +1,59 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef ADDRESSLIST_H +#define ADDRESSLIST_H + +#include +#include + +struct Contact +{ + QString email; + QString name; +}; + +class AddressList : public QObject +{ + Q_OBJECT + +public: + AddressList(QString file); + ~AddressList(); + void addContact(QString email, QString name); + bool containsEmail(QString email); + bool containsName(QString name); + QString getNameByEmail(QString email); + QString getEmailByName(QString name); + QList* getContactList(); + void write(); + +private: + int getEmailRef(QString email); + int getNameRef(QString name); + QString getRightString(QString in); + void read(); + +private: + QList addresses; + QString filename; + bool dirty; +}; + +#endif diff --git a/noncore/net/mailit/editaccount.cpp b/noncore/net/mailit/editaccount.cpp new file mode 100644 index 0000000..c4f95ea --- a/dev/null +++ b/noncore/net/mailit/editaccount.cpp @@ -0,0 +1,120 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +*** +**********************************************************************/ + +#include "editaccount.h" + +EditAccount::EditAccount( QWidget* parent, const char* name, WFlags fl ) + : QDialog(parent, name, fl) +{ + setCaption( tr("Edit Account") ); + init(); + popPasswInput->setEchoMode(QLineEdit::Password); +} + +void EditAccount::setAccount(MailAccount *in, bool newOne) +{ + account = in; + if (newOne) { + accountNameInput->setText(""); + nameInput->setText(""); + emailInput->setText(""); + popUserInput->setText(""); + popPasswInput->setText(""); + popServerInput->setText(""); + smtpServerInput->setText(""); + syncCheckBox->setChecked(TRUE); + + setCaption( tr("Create new Account") ); + } else { + accountNameInput->setText(account->accountName); + nameInput->setText(account->name); + emailInput->setText(account->emailAddress); + popUserInput->setText(account->popUserName); + popPasswInput->setText(account->popPasswd); + popServerInput->setText(account->popServer); + smtpServerInput->setText(account->smtpServer); + syncCheckBox->setChecked(account->synchronize); + } +} + +void EditAccount::init() +{ + grid = new QGridLayout(this); + grid->setSpacing( 6 ); + grid->setMargin( 11 ); + + accountNameInputLabel = new QLabel(tr("Account name"), this); + grid->addWidget( accountNameInputLabel, 0, 0 ); + accountNameInput = new QLineEdit( this, "account nameInput" ); + grid->addWidget( accountNameInput, 0, 1 ); + + nameInputLabel = new QLabel(tr("Your name"), this); + grid->addWidget( nameInputLabel, 1, 0 ); + nameInput = new QLineEdit( this, "nameInput" ); + grid->addWidget( nameInput, 1, 1 ); + + emailInputLabel = new QLabel("Email", this); + grid->addWidget(emailInputLabel, 2, 0 ); + emailInput = new QLineEdit( this, "emailInput" ); + grid->addWidget( emailInput, 2, 1 ); + + popUserInputLabel = new QLabel("POP username", this); + grid->addWidget( popUserInputLabel, 3, 0 ); + popUserInput = new QLineEdit( this, "popUserInput" ); + grid->addWidget( popUserInput, 3, 1 ); + + popPasswInputLabel = new QLabel( "POP password", this); + grid->addWidget( popPasswInputLabel, 4, 0 ); + popPasswInput = new QLineEdit( this, "popPasswInput" ); + grid->addWidget( popPasswInput, 4, 1 ); + + popServerInputLabel = new QLabel("POP server", this); + grid->addWidget( popServerInputLabel, 5, 0 ); + popServerInput = new QLineEdit( this, "popServerInput" ); + grid->addWidget( popServerInput, 5, 1 ); + + smtpServerInputLabel = new QLabel("SMTP server", this ); + grid->addWidget( smtpServerInputLabel, 6, 0 ); + smtpServerInput = new QLineEdit( this, "smtpServerInput" ); + grid->addWidget( smtpServerInput, 6, 1 ); + + syncCheckBox = new QCheckBox( tr( "Synchronize with server" ), this); + syncCheckBox->setChecked( TRUE ); + grid->addMultiCellWidget( syncCheckBox, 7, 7, 0, 1 ); +} + + +void EditAccount::accept() +{ + account->accountName = accountNameInput->text(); + account->name = nameInput->text(); + account->emailAddress = emailInput->text(); + account->popUserName = popUserInput->text(); + account->popPasswd = popPasswInput->text(); + account->popServer = popServerInput->text(); + account->smtpServer = smtpServerInput->text(); + account->synchronize = syncCheckBox->isChecked(); + + QDialog::accept(); +} + +void EditAccount::reject() +{ +} diff --git a/noncore/net/mailit/editaccount.h b/noncore/net/mailit/editaccount.h new file mode 100644 index 0000000..7a90e50 --- a/dev/null +++ b/noncore/net/mailit/editaccount.h @@ -0,0 +1,66 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef EDITACCOUNT_H +#define EDITACCOUNT_H + +#include +#include +#include +#include +#include +#include "emailhandler.h" + +class EditAccount : public QDialog +{ + Q_OBJECT + +public: + EditAccount( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + void setAccount(MailAccount *in, bool newOne = TRUE); + void init(); + +public slots: + void accept(); + void reject(); + +private: + MailAccount thisAccount, *account; + + QLabel *accountNameInputLabel; + QLabel *nameInputLabel; + QLabel *emailInputLabel; + QLabel *popUserInputLabel; + QLabel *popPasswInputLabel; + QLabel *popServerInputLabel; + QLabel *smtpServerInputLabel; + + QLineEdit *accountNameInput; + QLineEdit *nameInput; + QLineEdit *emailInput; + QLineEdit *popUserInput; + QLineEdit *popPasswInput; + QLineEdit *popServerInput; + QLineEdit *smtpServerInput; + QCheckBox *syncCheckBox; + + QGridLayout *grid; +}; + +#endif diff --git a/noncore/net/mailit/emailclient.cpp b/noncore/net/mailit/emailclient.cpp new file mode 100644 index 0000000..7ba5c75 --- a/dev/null +++ b/noncore/net/mailit/emailclient.cpp @@ -0,0 +1,858 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include +#include +#include +#include +#include +#include "resource.h" +#include "emailclient.h" + +QCollection::Item AccountList::newItem(QCollection::Item d) +{ + return dupl( (MailAccount *) d); +} + +MailAccount* AccountList::dupl(MailAccount *in) +{ + ac = new MailAccount(*in); + return ac; +} + +EmailClient::EmailClient( QWidget* parent, const char* name, WFlags fl ) + : QMainWindow( parent, name, fl ) +{ + emailHandler = new EmailHandler(); + addressList = new AddressList( getPath(FALSE) + "mail_adr"); + + sending = FALSE; + receiving = FALSE; + previewingMail = FALSE; + mailIdCount = 1; + accountIdCount = 1; + allAccounts = FALSE; + + init(); + + connect(emailHandler, SIGNAL(mailSent()), this, SLOT(mailSent()) ); + + connect(emailHandler, SIGNAL(smtpError(int)), this, + SLOT(smtpError(int)) ); + connect(emailHandler, SIGNAL(popError(int)), this, + SLOT(popError(int)) ); + + connect(inboxView, SIGNAL(clicked(QListViewItem *)), this, SLOT(inboxItemSelected()) ); + connect(outboxView, SIGNAL(clicked(QListViewItem *)), this, SLOT(outboxItemSelected()) ); + + connect(emailHandler, SIGNAL(mailArrived(const Email &, bool)), this, + SLOT(mailArrived(const Email &, bool)) ); + connect(emailHandler, SIGNAL(mailTransfered(int)), this, + SLOT(allMailArrived(int)) ); + + mailconf = new Config("mailit"); + //In case Synchronize is not defined in settings.txt + + readSettings(); + + updateAccounts(); + + lineShift = "\n"; + readMail(); + lineShift = "\r\n"; + +} + + +EmailClient::~EmailClient() +{ + //needs to be moved from destructor to closewindow event + saveMail(getPath(FALSE) + "inbox.txt", inboxView); + //does not currently work. Defining outbox in the same + //format as inbox is not a good solution as they have + //different properties + saveMail(getPath(FALSE) + "outbox.txt", outboxView); + saveSettings(); + + mailconf->write(); + delete mailconf; + +} + +void EmailClient::init() +{ + statusBar = new QStatusBar(this); + statusBar->setSizeGripEnabled(FALSE); + + status1Label = new QLabel( tr("Idle"), statusBar); + status2Label = new QLabel("", statusBar); + connect(emailHandler, SIGNAL(updatePopStatus(const QString &)), + status2Label, SLOT(setText(const QString &)) ); + connect(emailHandler, SIGNAL(updateSmtpStatus(const QString &)), + status2Label, SLOT(setText(const QString &)) ); + + progressBar = new QProgressBar(statusBar); + connect(emailHandler, SIGNAL(mailboxSize(int)), + this, SLOT(setTotalSize(int)) ); + connect(emailHandler, SIGNAL(currentMailSize(int)), + this, SLOT(setMailSize(int)) ); + connect(emailHandler, SIGNAL(downloadedSize(int)), + this, SLOT(setDownloadedSize(int)) ); + + statusBar->addWidget(status1Label); + statusBar->addWidget(progressBar); + statusBar->addWidget(status2Label); + + setToolBarsMovable(FALSE); + + bar = new QToolBar(this); + bar->setHorizontalStretchable( TRUE ); + + mb = new QMenuBar( bar ); + + QPopupMenu *mail = new QPopupMenu(mb); + mb->insertItem( tr( "&Mail" ), mail); + + QPopupMenu *configure = new QPopupMenu(mb); + mb->insertItem( tr( "Accounts" ), configure); + + selectAccountMenu = new QPopupMenu(mb); + editAccountMenu = new QPopupMenu(mb); + deleteAccountMenu = new QPopupMenu(mb); + + mail->insertItem(tr("Get Mail in"), selectAccountMenu); + configure->insertItem(tr("Edit account"), editAccountMenu); + configure->insertItem(tr("Delete account"), deleteAccountMenu); + + bar = new QToolBar(this); + + getMailButton = new QAction(tr("Get all mail"), QPixmap("getmail.xpm"), QString::null, 0, this, 0); + connect(getMailButton, SIGNAL(activated()), this, SLOT(getAllNewMail()) ); + getMailButton->addTo(bar); + getMailButton->addTo(mail); + + sendMailButton = new QAction(tr("Send mail"), QPixmap("sendmail.xpm"), QString::null, 0, this, 0); + connect(sendMailButton, SIGNAL(activated()), this, SLOT(sendQuedMail()) ); + sendMailButton->addTo(bar); + sendMailButton->addTo(mail); + + composeButton = new QAction(tr("Compose"), Resource::loadPixmap("new"), QString::null, 0, this, 0); + connect(composeButton, SIGNAL(activated()), this, SLOT(compose()) ); + composeButton->addTo(bar); + composeButton->addTo(mail); + + cancelButton = new QAction(tr("Cancel transfer"), Resource::loadPixmap("reset"), QString::null, 0, this, 0); + connect(cancelButton, SIGNAL(activated()), this, SLOT(cancel()) ); + cancelButton->addTo(mail); + cancelButton->setEnabled(FALSE); + + mailboxView = new QTabWidget( this, "mailboxView" ); + + QWidget* widget = new QWidget( mailboxView, "widget" ); + grid_2 = new QGridLayout( widget ); +// grid_2->setSpacing(6); +// grid_2->setMargin( 11 ); + + inboxView = new QListView( widget, "inboxView" ); + inboxView->addColumn( tr( "From" ) ); + inboxView->addColumn( tr( "Subject" ) ); + inboxView->addColumn( tr( "Date" ) ); + inboxView->setMinimumSize( QSize( 0, 0 ) ); + inboxView->setAllColumnsShowFocus(TRUE); + + grid_2->addWidget( inboxView, 2, 0 ); + mailboxView->insertTab( widget, tr( "Inbox" ) ); + + QWidget* widget_2 = new QWidget( mailboxView, "widget_2" ); + grid_3 = new QGridLayout( widget_2 ); +// grid_3->setSpacing(6); +// grid_3->setMargin( 11 ); + + outboxView = new QListView( widget_2, "outboxView" ); + outboxView->addColumn( tr( "To" ) ); + outboxView->addColumn( tr( "Subject" ) ); + outboxView->setAllColumnsShowFocus(TRUE); + + grid_3->addWidget( outboxView, 0, 0 ); + mailboxView->insertTab( widget_2, tr( "Outbox" ) ); + + setCentralWidget(mailboxView); +} + +void EmailClient::compose() +{ + emit composeRequested(); +} + +void EmailClient::cancel() +{ + emailHandler->cancel(); +} + +AddressList* EmailClient::getAdrListRef() +{ + return addressList; +} + +//this needs to be rewritten to syncronize with outboxView +void EmailClient::enqueMail(const Email &mail) +{ + if (accountList.count() > 0) { + currentAccount = accountList.first(); + qWarning("using account " + currentAccount->name); + } + + Email addMail = mail; + addMail.from = currentAccount->name; + addMail.fromMail = currentAccount->emailAddress; + addMail.rawMail.prepend("From: " + addMail.from + "<" + addMail.fromMail + ">\n"); + item = new EmailListItem(outboxView, addMail, false); + +} + +void EmailClient::sendQuedMail() +{ + int count = 0; + + if (accountList.count() == 0) { + QMessageBox::warning(qApp->activeWindow(), + "No account selected", "You must create an account", "OK\n"); + return; + } + //traverse listview, find messages to send + if (! sending) { + item = (EmailListItem *) outboxView->firstChild(); + if (item != NULL) { + while (item != NULL) { + quedMessages.append(item->getMail()); + item = (EmailListItem *) item->nextSibling(); + count++; + } + setMailAccount(); + emailHandler->sendMail(&quedMessages); + sending = TRUE; + sendMailButton->setEnabled(FALSE); + cancelButton->setEnabled(TRUE); + } else { + qWarning("sendQuedMail(): no messages to send"); + } + } +} + +void EmailClient::setMailAccount() +{ + emailHandler->setAccount(*currentAccount); +} + +void EmailClient::mailSent() +{ + sending = FALSE; + sendMailButton->setEnabled(TRUE); + + quedMessages.clear(); + outboxView->clear(); //should be moved to an sentBox +} + +void EmailClient::getNewMail() { + + if (accountList.count() == 0) { + QMessageBox::warning(qApp->activeWindow(),"No account selected", + "You must create an account", "OK\n"); + return; + } + + setMailAccount(); + + receiving = TRUE; + previewingMail = TRUE; + getMailButton->setEnabled(FALSE); + cancelButton->setEnabled(TRUE); + selectAccountMenu->setEnabled(FALSE); + + status1Label->setText(currentAccount->accountName + " headers"); + progressBar->reset(); + + //get any previous mails not downloaded and add to queue + mailDownloadList.clear(); + Email *mailPtr; + item = (EmailListItem *) inboxView->firstChild(); + while (item != NULL) { + mailPtr = item->getMail(); + if ( (!mailPtr->downloaded) && (mailPtr->fromAccountId == currentAccount->id) ) { + mailDownloadList.sizeInsert(mailPtr->serverId, mailPtr->size); + } + item = (EmailListItem *) item->nextSibling(); + } + + emailHandler->getMailHeaders(); +} + +void EmailClient::getAllNewMail() +{ + allAccounts = TRUE; + currentAccount = accountList.first(); + getNewMail(); +} + +void EmailClient::mailArrived(const Email &mail, bool fromDisk) +{ + Enclosure *ePtr; + Email newMail; + int thisMailId; + emailHandler->parse(mail.rawMail, lineShift, &newMail); + + mailconf->setGroup(newMail.id); + + if (fromDisk) { + newMail.downloaded = mailconf->readBoolEntry("downloaded"); + newMail.size = mailconf->readNumEntry("size"); + newMail.serverId = mailconf->readNumEntry("serverid"); + newMail.fromAccountId = mailconf->readNumEntry("fromaccountid"); + } else { //mail arrived from server + newMail.serverId = mail.serverId; + newMail.size = mail.size; + newMail.downloaded = mail.downloaded; + + newMail.fromAccountId = currentAccount->id; + mailconf->writeEntry("fromaccountid", newMail.fromAccountId); + } + + //add if read or not + newMail.read = mailconf->readBoolEntry("mailread"); + + //check if new mail + if ( (thisMailId = mailconf->readNumEntry("internalmailid", -1)) == -1) { + thisMailId = mailIdCount; + mailIdCount++; + + //set server count, so that if the user aborts, the new + //header is not reloaded + if (currentAccount->synchronize) + currentAccount->lastServerMailCount++; + + mailconf->writeEntry("internalmailid", thisMailId); + mailconf->writeEntry("downloaded", newMail.downloaded); + mailconf->writeEntry("size", (int) newMail.size); + mailconf->writeEntry("serverid", newMail.serverId); + + addressList->addContact(newMail.fromMail, newMail.from); + } else if (!fromDisk) { //body to header arrived + mailconf->writeEntry("downloaded", TRUE); + } + QString stringMailId; + stringMailId.setNum(thisMailId); + //se if any attatchments needs to be stored + for ( ePtr=newMail.files.first(); ePtr != 0; ePtr=newMail.files.next() ) { + QString stringId; + stringId.setNum(ePtr->id); + + int id = mailconf->readNumEntry("enclosureid_" + stringId); + if (id != ePtr->id) { //new entry + mailconf->writeEntry("enclosureid_" + stringId, ePtr->id); + mailconf->writeEntry("name_" + stringId, ePtr->originalName); + mailconf->writeEntry("contenttype_" + stringId, ePtr->contentType); + mailconf->writeEntry("contentattribute_" + stringId, ePtr->contentAttribute); + mailconf->writeEntry("saved_" + stringId, ePtr->saved); + mailconf->writeEntry("installed_" + stringId, FALSE); + + ePtr->name = stringMailId + "_" + stringId; + ePtr->path = getPath(TRUE); + if (emailHandler->getEnclosure(ePtr)) { //file saved + ePtr->saved = TRUE; + mailconf->writeEntry("saved_" + stringId, ePtr->saved); + mailconf->writeEntry("filename_" + stringId, ePtr->name); + mailconf->writeEntry("path_" + stringId, ePtr->path); + } else { + ePtr->saved = FALSE; + mailconf->writeEntry("saved_" + stringId, ePtr->saved); + } + } else { + ePtr->saved = mailconf->readBoolEntry("saved_" + stringId); + ePtr->installed = mailconf->readBoolEntry("installed_" + stringId); + if (ePtr->saved) { + ePtr->name = mailconf->readEntry("filename_" + stringId); + ePtr->path = mailconf->readEntry("path_" + stringId); + } + } + } + if (!previewingMail && !fromDisk) { + Email *mailPtr; + item = (EmailListItem *) inboxView->firstChild(); + while (item != NULL) { + mailPtr = item->getMail(); + if (mailPtr->id == newMail.id) { + item->setMail(newMail); + emit mailUpdated(item->getMail()); + } + item = (EmailListItem *) item->nextSibling(); + } + } else { + item = new EmailListItem(inboxView, newMail, TRUE); + if (!newMail.downloaded) + mailDownloadList.sizeInsert(newMail.serverId, newMail.size); + } + +} + +void EmailClient::allMailArrived(int count) +{ + // not previewing means all mailtransfer has been done + if (!previewingMail) { + if ( (allAccounts) && ( (currentAccount = accountList.next()) !=0 ) ) { + emit newCaption("Mailit - " + currentAccount->accountName); + getNewMail(); + return; + } else { + allAccounts = FALSE; + receiving = FALSE; + getMailButton->setEnabled(TRUE); + cancelButton->setEnabled(FALSE); + selectAccountMenu->setEnabled(TRUE); + status1Label->setText("Idle"); + + progressBar->reset(); + return; + } + } + + // all headers downloaded from server, start downloading remaining mails + previewingMail = FALSE; + status1Label->setText(currentAccount->accountName); + progressBar->reset(); + + emailHandler->getMailByList(&mailDownloadList); +} + +void EmailClient::moveMailFront(Email *mailPtr) +{ + if ( (receiving) && (mailPtr->fromAccountId == currentAccount->id) ) { + mailDownloadList.moveFront(mailPtr->serverId, mailPtr->size); + } +} + +void EmailClient::smtpError(int code) +{ + QString temp; + + if (code == ErrUnknownResponse) + temp = "Unknown response from server"; + + if (code == QSocket::ErrHostNotFound) + temp = "host not found"; + if (code == QSocket::ErrConnectionRefused) + temp = "connection refused"; + if (code == QSocket::ErrSocketRead) + temp = "socket packet error"; + + if (code != ErrCancel) { + QMessageBox::warning(qApp->activeWindow(), "Sending error", temp, "OK\n"); + } else { + status2Label->setText("Aborted by user"); + } + + sending = FALSE; + sendMailButton->setEnabled(TRUE); + cancelButton->setEnabled(FALSE); + quedMessages.clear(); +} + +void EmailClient::popError(int code) +{ + QString temp; + + if (code == ErrUnknownResponse) + temp = "Unknown response from server"; + if (code == ErrLoginFailed) + temp = "Login failed\nCheck user name and password"; + + if (code == QSocket::ErrHostNotFound) + temp = "host not found"; + if (code == QSocket::ErrConnectionRefused) + temp = "connection refused"; + if (code == QSocket::ErrSocketRead) + temp = "socket packet error"; + + if (code != ErrCancel) { + QMessageBox::warning(qApp->activeWindow(), "Receiving error", temp, "OK\n"); + } else { + status2Label->setText("Aborted by user"); + } + + receiving = FALSE; + getMailButton->setEnabled(TRUE); + cancelButton->setEnabled(FALSE); + selectAccountMenu->setEnabled(TRUE); +} + +void EmailClient::inboxItemSelected() +{ + item = (EmailListItem*) inboxView->selectedItem(); + if (item != NULL) { + emit viewEmail(inboxView, item->getMail()); + } +} + +void EmailClient::outboxItemSelected() +{ + item = (EmailListItem*) outboxView->selectedItem(); + if (item != NULL) { + emit viewEmail(outboxView, item->getMail()); + } + +} + +void EmailClient::readMail() +{ + Email mail; + int start, stop; + QString s, del; + + QFile f(getPath(FALSE) + "inbox.txt"); +// QFileInfo fi(f); + qDebug( f.name()); + + if ( f.open(IO_ReadOnly) ) { // file opened successfully + QTextStream t( &f ); // use a text stream + s = t.read(); + f.close(); + + start = 0; + del = "\n.\n"; + while ((uint) start < s.length()) { + stop = s.find(del, start); + if (stop == -1) + stop = s.length() - del.length(); + + mail.rawMail = s.mid(start, stop + del.length() - start ); + start = stop + del.length(); + mailArrived(mail, TRUE); + } + } + + QFile fo(getPath(FALSE) + "outbox.txt"); + if ( fo.open(IO_ReadOnly) ) { // file opened successfully + QTextStream t( &fo ); // use a text stream + s = t.read(); + fo.close(); + + start = 0; + del = "\n.\n"; + while ((uint) start < s.length()) { + stop = s.find(del, start); + if (stop == -1) + stop = s.length() - del.length(); + + mail.rawMail = s.mid(start, stop + del.length() - start ); + start = stop + del.length(); + emailHandler->parse(mail.rawMail, lineShift, &mail); + mail.sent = false; + mail.received = false; + enqueMail(mail); + + } + } +} + +void EmailClient::saveMail(QString fileName, QListView *view) +{ + QFile f(fileName); + Email *mail; + + if (! f.open(IO_WriteOnly) ) { + qWarning("could not open file"); + return; + } + item = (EmailListItem *) view->firstChild(); + qDebug (QString("Write : ") ); + QTextStream t(&f); + while (item != NULL) { + mail = item->getMail(); + qDebug(mail->rawMail); + qDebug(mail->recipients.first()); + t << mail->rawMail; + + mailconf->setGroup(mail->id); + mailconf->writeEntry("mailread", mail->read); + + item = (EmailListItem *) item->nextSibling(); + } + f.close(); +} + +//paths for mailit, is settings, inbox, enclosures +QString EmailClient::getPath(bool enclosurePath) +{ + QString basePath = "qtmail"; + QString enclosures = "enclosures"; + + QDir dir = (QString(getenv("HOME")) + "/Applications/" + basePath); + if ( !dir.exists() ) + dir.mkdir( dir.path() ); + + if (enclosurePath) { + dir = (QString(getenv("HOME")) + "/Applications/" + basePath + "/" + enclosures); + + if ( !dir.exists() ) + dir.mkdir( dir.path() ); + + return (dir.path() + "/"); + + } + return (dir.path() + "/"); +} + +void EmailClient::readSettings() +{ + TextParser *p; + QString s; + int pos, accountPos, y; + QFile f( getPath(FALSE) + "settings.txt"); + + if ( f.open(IO_ReadOnly) ) { // file opened successfully + QTextStream t( &f ); // use a text stream + s = t.read(); + f.close(); + + p = new TextParser(s, "\n"); + + accountPos = 0; + while ( (accountPos = p->find("ACCOUNTSTART",';', accountPos, TRUE)) != -1 ) { + accountPos++; + if ( (pos = p->find("ACCOUNTNAME",':', accountPos, TRUE)) != -1 ) + account.accountName = p->getString(& ++pos, 'z', TRUE); + if ( (pos = p->find("NAME",':', accountPos, TRUE)) != -1) + account.name = p->getString(& ++pos, 'z', TRUE); + if ( (pos = p->find("EMAIL",':', accountPos, TRUE)) != -1) + account.emailAddress = p->getString(& ++pos, 'z', TRUE); + if ( (pos = p->find("POPUSER",':', accountPos, TRUE)) != -1) + account.popUserName = p->getString(& ++pos, 'z', TRUE); + if ( (pos = p->find("POPPASSWORD",':', accountPos, TRUE)) != -1) + account.popPasswd = p->getString(& ++pos, 'z', TRUE); + if ( (pos = p->find("POPSERVER",':', accountPos, TRUE)) != -1) + account.popServer = p->getString(& ++pos, 'z', TRUE); + if ( (pos = p->find("SMTPSERVER",':', accountPos, TRUE)) != -1) + account.smtpServer = p->getString(& ++pos, 'z', TRUE); + if ( (pos = p->find("ACCOUNTID",':', accountPos, TRUE)) != -1) { + s = p->getString(& ++pos, 'z', TRUE); + account.id = s.toInt(); + } + + account.lastServerMailCount = 0; + account.synchronize = FALSE; + if ( (pos = p->find("SYNCHRONIZE",':', accountPos, TRUE)) != -1) { + if (p->getString(& ++pos, 'z', TRUE).upper() == "YES") { + account.synchronize = TRUE; + if ( (pos = p->find("LASTSERVERMAILCOUNT",':', accountPos, TRUE)) != -1) { + s = p->getString(& ++pos, 'z', TRUE); + account.lastServerMailCount = s.toInt(); + } + } + } + accountList.append(&account); + } + delete p; + } + mailconf->setGroup("mailitglobal"); + if ( (y = mailconf->readNumEntry("mailidcount", -1)) != -1) { + mailIdCount = y; + } + if ( (y = mailconf->readNumEntry("accountidcount", -1)) != -1) { + accountIdCount = y; + } +} + +void EmailClient::saveSettings() +{ + QString temp; + QFile f( getPath(FALSE) + "settings.txt"); + MailAccount *accountPtr; + + if (! f.open(IO_WriteOnly) ) { + qWarning("could not save settings file"); + return; + } + QTextStream t(&f); + t << "#Settings for QPE Mailit program\n"; + + for (accountPtr = accountList.first(); accountPtr != 0; + accountPtr = accountList.next()) { + + t << "accountStart;\n"; + t << "AccountName: " + accountPtr->accountName + "\n"; + t << "Name: " + accountPtr->name + "\n"; + t << "Email: " + accountPtr->emailAddress + "\n"; + t << "POPUser: " + accountPtr->popUserName + "\n"; + t << "POPPAssword: " + accountPtr->popPasswd + "\n"; + t << "POPServer: " + accountPtr->popServer + "\n"; + t << "SMTPServer: " + accountPtr->smtpServer + "\n"; + t << "AccountId: " << accountPtr->id << "\n"; + if (accountPtr->synchronize) { + t << "Synchronize: Yes\n"; + t << "LastServerMailCount: "; + t << accountPtr->lastServerMailCount << "\n"; + } else { + t << "Synchronize: No\n"; + } + t << "accountEnd;\n"; + } + f.close(); + + mailconf->setGroup("mailitglobal"); + mailconf->writeEntry("mailidcount", mailIdCount); + mailconf->writeEntry("accountidcount", accountIdCount); +} + +void EmailClient::selectAccount(int id) +{ + if (accountList.count() > 0) { + currentAccount = accountList.at(id); + emit newCaption("Mailit - " + currentAccount->accountName); + getNewMail(); + } else { + emit newCaption("Mailit ! No account defined"); + } +} + +void EmailClient::editAccount(int id) +{ + MailAccount *newAccount; + + editAccountView = new EditAccount(this, "account", TRUE); + if (id == newAccountId) { //new account + newAccount = new MailAccount; + editAccountView->setAccount(newAccount); + } else { + newAccount = accountList.at(id); + editAccountView->setAccount(newAccount, FALSE); + } + + editAccountView->showMaximized(); + editAccountView->exec(); + + if (editAccountView->result() == QDialog::Accepted) { + if (id == newAccountId) { + newAccount->id = accountIdCount; + accountIdCount++; + accountList.append(newAccount); + updateAccounts(); + } else { + updateAccounts(); + } + } + + delete editAccountView; +} + +void EmailClient::deleteAccount(int id) +{ + MailAccount *newAccount; + QString message; + + newAccount = accountList.at(id); + message = "Delete account:\n" + newAccount->accountName; + switch( QMessageBox::warning( this, "Mailit", message, + "Yes", "No", 0, 0, 1 ) ) { + + case 0: accountList.remove(id); + updateAccounts(); + break; + case 1: + break; + } +} + +void EmailClient::updateAccounts() +{ + MailAccount *accountPtr; + + //rebuild menus, clear all first + editAccountMenu->clear(); + selectAccountMenu->clear(); + deleteAccountMenu->clear(); + + newAccountId = editAccountMenu->insertItem("New", this, + SLOT(editAccount(int)) ); + editAccountMenu->insertSeparator(); + + idCount = 0; + for (accountPtr = accountList.first(); accountPtr != 0; + accountPtr = accountList.next()) { + + editAccountMenu->insertItem(accountPtr->accountName, + this, SLOT(editAccount(int)), 0, idCount); + selectAccountMenu->insertItem(accountPtr->accountName, + this, SLOT(selectAccount(int)), 0, idCount); + deleteAccountMenu->insertItem(accountPtr->accountName, + this, SLOT(deleteAccount(int)), 0, idCount); + idCount++; + } +} + +void EmailClient::deleteMail(EmailListItem *mailItem, bool &inbox) +{ + Email *mPtr; + Enclosure *ePtr; + + if (inbox) { + mPtr = mailItem->getMail(); + + //if mail is in queue for download, remove it from + //queue if possible + if ( (receiving) && (mPtr->fromAccountId == currentAccount->id) ) { + if ( !mPtr->downloaded ) + mailDownloadList.remove(mPtr->serverId, mPtr->size); + } + + mailconf->setGroup(mPtr->id); + mailconf->clearGroup(); + + //delete any temporary attatchemnts storing + for ( ePtr=mPtr->files.first(); ePtr != 0; ePtr=mPtr->files.next() ) { + if (ePtr->saved) { + QFile::remove( (ePtr->path + ePtr->name) ); + } + } + inboxView->takeItem(mailItem); + } else { + outboxView->takeItem(mailItem); + } +} + +void EmailClient::setMailSize(int size) +{ + progressBar->reset(); + progressBar->setTotalSteps(size); +} + +void EmailClient::setTotalSize(int size) +{ + +} + +void EmailClient::setDownloadedSize(int size) +{ + int total = progressBar->totalSteps(); + + if (size < total) { + progressBar->setProgress(size); + } else { + progressBar->setProgress(total); + } +} diff --git a/noncore/net/mailit/emailclient.h b/noncore/net/mailit/emailclient.h new file mode 100644 index 0000000..135bfaa --- a/dev/null +++ b/noncore/net/mailit/emailclient.h @@ -0,0 +1,149 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef EMAILCLIENT_H +#define EMAILCLIENT_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "emailhandler.h" +#include "emaillistitem.h" +#include "textparser.h" +#include "editaccount.h" +#include "maillist.h" +#include "addresslist.h" + +#include + +class AccountList : public QList +{ +public: + Item newItem(Item d); +private: + MailAccount* dupl(MailAccount *in); + MailAccount *ac; +}; + +//class EmailClient : public EmailClientBase +class EmailClient : public QMainWindow +{ + Q_OBJECT + +public: + EmailClient( QWidget* parent, const char* name, WFlags fl = 0 ); + ~EmailClient(); + AddressList* getAdrListRef(); + +signals: + void composeRequested(); + void viewEmail(QListView *, Email *); + void mailUpdated(Email *); + void newCaption(const QString &); + +public slots: + void compose(); + void cancel(); + void enqueMail(const Email &mail); + void setMailAccount(); + void sendQuedMail(); + void mailSent(); + void getNewMail(); + void getAllNewMail(); + void smtpError(int code); + void popError(int code); + void inboxItemSelected(); + void outboxItemSelected(); + void mailArrived(const Email &mail, bool fromDisk); + void allMailArrived(int); + void saveMail(QString fileName, QListView *view); + void selectAccount(int); + void editAccount(int); + void updateAccounts(); + void deleteAccount(int); + void deleteMail(EmailListItem *mailItem, bool &inbox); + void setTotalSize(int); + void setMailSize(int); + void setDownloadedSize(int); + void moveMailFront(Email *mailPtr); + +private: + void init(); + void readMail(); + QString getPath(bool enclosurePath); + void readSettings(); + void saveSettings(); + +private: + Config *mailconf; + int newAccountId, idCount, mailIdCount; + int accountIdCount; + AccountList accountList; + AddressList *addressList; + + EditAccount *editAccountView; + EmailListItem *item; + EmailHandler *emailHandler; + QList quedMessages; + MailList mailDownloadList; + bool sending, receiving, previewingMail, allAccounts; + QString lineShift; + MailAccount account, *currentAccount; + + QToolBar *bar; + QProgressBar *progressBar; + QStatusBar *statusBar; + QLabel *status1Label, *status2Label; + QAction *getMailButton; + QAction *sendMailButton; + QAction *composeButton; + QAction *cancelButton; + + QMenuBar *mb; + QPopupMenu *selectAccountMenu; + QPopupMenu *editAccountMenu; + QPopupMenu *deleteAccountMenu; + + QTabWidget* mailboxView; + QListView* inboxView; + QListView* outboxView; + + QGridLayout* grid_2; + QGridLayout* grid_3; +}; + +#endif // EMAILCLIENT_H diff --git a/noncore/net/mailit/emailhandler.cpp b/noncore/net/mailit/emailhandler.cpp new file mode 100644 index 0000000..a086dfc --- a/dev/null +++ b/noncore/net/mailit/emailhandler.cpp @@ -0,0 +1,589 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include +#include +#include +#include +#include "emailhandler.h" +#include +#include + +QCollection::Item EnclosureList::newItem(QCollection::Item d) +{ + return dupl( (Enclosure *) d); +} + +Enclosure* EnclosureList::dupl(Enclosure *in) +{ + ac = new Enclosure(*in); + return ac; +} + +EmailHandler::EmailHandler() +{ + smtpClient = new SmtpClient(); + popClient = new PopClient(); + + connect(smtpClient, SIGNAL(errorOccurred(int)), this, + SIGNAL(smtpError(int)) ); + connect(smtpClient, SIGNAL(mailSent()), this, SIGNAL(mailSent()) ); + connect(smtpClient, SIGNAL(updateStatus(const QString &)), this, + SIGNAL(updateSmtpStatus(const QString &)) ); + + connect(popClient, SIGNAL(errorOccurred(int)), this, + SIGNAL(popError(int)) ); + connect(popClient, SIGNAL(newMessage(const QString &, int, uint, bool)), + this, SLOT(messageArrived(const QString &, int, uint, bool)) ); + connect(popClient, SIGNAL(updateStatus(const QString &)), this, + SIGNAL(updatePopStatus(const QString &)) ); + connect(popClient, SIGNAL(mailTransfered(int)), this, + SIGNAL(mailTransfered(int)) ); + + + //relaying size information + connect(popClient, SIGNAL(currentMailSize(int)), + this, SIGNAL(currentMailSize(int)) ); + connect(popClient, SIGNAL(downloadedSize(int)), + this, SIGNAL(downloadedSize(int)) ); +} + +void EmailHandler::sendMail(QList *mailList) +{ + Email *currentMail; + QString temp; + QString userName = mailAccount.name; + userName += " <" + mailAccount.emailAddress + ">"; + + for (currentMail = mailList->first(); currentMail != 0; + currentMail = mailList->next()) { + + if (encodeMime(currentMail) == 0) { + smtpClient->addMail(userName, currentMail->subject, + currentMail->recipients, currentMail->rawMail); + } else { //error + temp = tr("Could not locate all files in \nmail with subject: ") + + currentMail->subject; + temp += tr("\nMail has NOT been sent"); + QMessageBox::warning(qApp->activeWindow(), tr("Attachment error"), temp, tr("OK\n")); + + } + } + smtpClient->newConnection(mailAccount.smtpServer, 25); +} + +void EmailHandler::setAccount(MailAccount account) +{ + mailAccount = account; +} + +void EmailHandler::getMail() +{ + popClient->setAccount(mailAccount.popUserName, mailAccount.popPasswd); + if (mailAccount.synchronize) { + popClient->setSynchronize(mailAccount.lastServerMailCount); + } else { + popClient->removeSynchronize(); + } + + headers = FALSE; + popClient->headersOnly(headers, 0); + popClient->newConnection(mailAccount.popServer, 110); +} + +void EmailHandler::getMailHeaders() +{ + popClient->setAccount(mailAccount.popUserName, mailAccount.popPasswd); + if (mailAccount.synchronize) { + popClient->setSynchronize(mailAccount.lastServerMailCount); + } else { + popClient->removeSynchronize(); + } + + headers = TRUE; + popClient->headersOnly(headers, 2000); //less than 2000, download all + popClient->newConnection(mailAccount.popServer, 110); +} + +void EmailHandler::getMailByList(MailList *mailList) +{ + if (mailList->count() == 0) { //should not occur though + emit mailTransfered(0); + return; + } + + headers = FALSE; + popClient->headersOnly(FALSE, 0); + popClient->newConnection(mailAccount.popServer, 110); + popClient->setSelectedMails(mailList); +} + +void EmailHandler::messageArrived(const QString &message, int id, uint size, bool complete) +{ + Email mail; + + mail.rawMail = message; + mail.serverId = id; + mail.size = size; + mail.downloaded = complete; + + emit mailArrived(mail, FALSE); +} + +bool EmailHandler::parse(QString in, QString lineShift, Email *mail) +{ + QString temp, boundary; + int pos; + QString delimiter, header, body, mimeHeader, mimeBody; + QString content, contentType, contentAttribute, id, encoding; + QString fileName, storedName; + int enclosureId = 0; + + mail->rawMail = in; + mail->received = TRUE; + mail->files.setAutoDelete(TRUE); + + temp = lineShift + "." + lineShift; + + if (in.right(temp.length()) != temp) { + qWarning(in.right(temp.length())); + qWarning(" . added at end of email as separator"); + mail->rawMail += temp; + } + + + delimiter = lineShift + lineShift; // "\n\n" or "\r\n\r\n" + pos = in.find(delimiter, 0, FALSE); + header = in.left(pos); + body = in.right(in.length() - pos - delimiter.length()); + if ((body.at(body.length()-2) == '.') && (body.at(body.length()-3) == '\n')) + body.truncate(body.length()-2); + + TextParser p(header, lineShift); + + if ((pos = p.find("FROM",':', 0, TRUE)) != -1) { + pos++; + if (p.separatorAt(pos) == ' ') { + mail->from = p.getString(&pos, '<'); + mail->from = mail->from.stripWhiteSpace(); + if ( (mail->from.length() > 2) && (mail->from[0] == '"') ) { + mail->from = mail->from.left(mail->from.length() - 1); + mail->from = mail->from.right(mail->from.length() - 1); + } + pos++; + mail->fromMail = p.getString(&pos, '>'); + } else { + if ((p.separatorAt(pos) == '<') + || (p.separatorAt(pos) == ' ')) //No name.. nasty + pos++; + pos++; + mail->fromMail = p.getString(&pos, 'z', TRUE); + if (mail->fromMail.at(mail->fromMail.length()-1) == '>') + mail->fromMail.truncate(mail->fromMail.length() - 1); + mail->from=mail->fromMail; + } + } + if ((pos = p.find("SUBJECT",':', 0, TRUE)) != -1) { + pos++; + mail->subject = p.getString(&pos, 'z', TRUE); + } + if ((pos = p.find("DATE",':', 0, TRUE)) != -1) { + pos++; + mail->date = p.getString(&pos, 'z', true); + } + if ((pos = p.find("TO",':', 0, TRUE)) != -1) { + pos++; + mail->recipients.append (p.getString(&pos, 'z', TRUE) ); + } + if ((pos = p.find("MESSAGE",'-', 0, TRUE)) != -1) { + pos++; + if ( (p.wordAt(pos).upper() == "ID") && + (p.separatorAt(pos) == ':') ) { + + id = p.getString(&pos, 'z', TRUE); + mail->id = id; + } + } + + pos = 0; + while ( ((pos = p.find("MIME",'-', pos, TRUE)) != -1) ) { + pos++; + if ( (p.wordAt(pos).upper() == "VERSION") && + (p.separatorAt(pos) == ':') ) { + pos++; + if (p.getString(&pos, 'z', true) == "1.0") { + mail->mimeType = 1; + } + } + } + + if (mail->mimeType == 1) { + boundary = ""; + if ((pos = p.find("BOUNDARY", '=', 0, TRUE)) != -1) { + pos++; + boundary = p.getString(&pos, 'z', true); + if (boundary[0] == '"') { + boundary = boundary.left(boundary.length() - 1); //strip " + boundary = boundary.right(boundary.length() - 1); //strip " + } + boundary = "--" + boundary; //create boundary field + } + + if (boundary == "") { //fooled by Mime-Version + mail->body = body; + mail->bodyPlain = body; + return mail; + } + + while (body.length() > 0) { + pos = body.find(boundary, 0, FALSE); + pos = body.find(delimiter, pos, FALSE); + mimeHeader = body.left(pos); + mimeBody = body.right(body.length() - pos - delimiter.length()); + TextParser bp(mimeHeader, lineShift); + + contentType = ""; + contentAttribute = ""; + fileName = ""; + if ((pos = bp.find("CONTENT",'-', 0, TRUE)) != -1) { + pos++; + if ( (bp.wordAt(pos).upper() == "TYPE") && + (bp.separatorAt(pos) == ':') ) { + contentType = bp.nextWord().upper(); + if (bp.nextSeparator() == '/') + contentAttribute = bp.nextWord().upper(); + content = contentType + "/" + contentAttribute; + } + if ((pos = bp.find("ENCODING",':', 0, TRUE)) != -1) { + pos++; + encoding = bp.getString(&pos, 'z', TRUE); + } + + if ( (pos = bp.find("FILENAME",'=', 0, TRUE)) != -1) { + pos++; + fileName = bp.getString(&pos, 'z', TRUE); + fileName = fileName.right(fileName.length() - 1); + fileName = fileName.left(fileName.length() - 1); + } + + } + pos = mimeBody.find(boundary, 0, FALSE); + if (pos == -1) //should not occur, malformed mail + pos = mimeBody.length(); + body = mimeBody.right(mimeBody.length() - pos); + mimeBody = mimeBody.left(pos); + + if (fileName != "") { //attatchments of some type, audio, image etc. + + Enclosure e; + e.id = enclosureId; + e.originalName = fileName; + e.contentType = contentType; + e.contentAttribute = contentAttribute; + e.encoding = encoding; + e.body = mimeBody; + e.saved = FALSE; + mail->addEnclosure(&e); + enclosureId++; + + } else if (contentType == "TEXT") { + if (contentAttribute == "PLAIN") { + mail->body = mimeBody; + mail->bodyPlain = mimeBody; + } + if (contentAttribute == "HTML") { + mail->body = mimeBody; + } + } + } + } else { + mail->bodyPlain = body; + mail->body = body; + } + return TRUE; +} + +bool EmailHandler::getEnclosure(Enclosure *ePtr) +{ + QFile f(ePtr->path + ePtr->name); + char src[4]; + char *destPtr; + QByteArray buffer; + uint bufCount, pos, decodedCount, size, x; + + if (! f.open(IO_WriteOnly) ) { + qWarning("could not save: " + ePtr->path + ePtr->name); + return FALSE; + } + + if (ePtr->encoding.upper() == "BASE64") { + size = (ePtr->body.length() * 3 / 4); //approximate size (always above) + buffer.resize(size); + bufCount = 0; + pos = 0; + destPtr = buffer.data(); + + while (pos < ePtr->body.length()) { + decodedCount = 4; + x = 0; + while ( (x < 4) && (pos < ePtr->body.length()) ) { + src[x] = ePtr->body[pos].latin1(); + pos++; + if (src[x] == '\r' || src[x] == '\n' || src[x] == ' ') + x--; + x++; + } + if (x > 1) { + decodedCount = parse64base(src, destPtr); + destPtr += decodedCount; + bufCount += decodedCount; + } + } + + buffer.resize(bufCount); //set correct length of file + f.writeBlock(buffer); + } else { + QTextStream t(&f); + t << ePtr->body; + } + return TRUE; +} + +int EmailHandler::parse64base(char *src, char *bufOut) { + + char c, z; + char li[4]; + int processed; + + //conversion table withouth table... + for (int x = 0; x < 4; x++) { + c = src[x]; + + if ( (int) c >= 'A' && (int) c <= 'Z') + li[x] = (int) c - (int) 'A'; + if ( (int) c >= 'a' && (int) c <= 'z') + li[x] = (int) c - (int) 'a' + 26; + if ( (int) c >= '0' && (int) c <= '9') + li[x] = (int) c - (int) '0' + 52; + if (c == '+') + li[x] = 62; + if (c == '/') + li[x] = 63; + } + + processed = 1; + bufOut[0] = (char) li[0] & (32+16+8+4+2+1); //mask out top 2 bits + bufOut[0] <<= 2; + z = li[1] >> 4; + bufOut[0] = bufOut[0] | z; //first byte retrived + + if (src[2] != '=') { + bufOut[1] = (char) li[1] & (8+4+2+1); //mask out top 4 bits + bufOut[1] <<= 4; + z = li[2] >> 2; + bufOut[1] = bufOut[1] | z; //second byte retrived + processed++; + + if (src[3] != '=') { + bufOut[2] = (char) li[2] & (2+1); //mask out top 6 bits + bufOut[2] <<= 6; + z = li[3]; + bufOut[2] = bufOut[2] | z; //third byte retrieved + processed++; + } + } + return processed; +} + +int EmailHandler::encodeMime(Email *mail) { + QString fileName, fileType, contentType, newBody, boundary; + Enclosure *ePtr; + + QString userName = mailAccount.name; + userName += " <" + mailAccount.emailAddress + ">"; + + //add standard headers + newBody = "From: " + userName + "\r\nTo: "; + for (QStringList::Iterator it = mail->recipients.begin(); it != mail->recipients.end(); ++it ) { + newBody += *it + " "; + } + newBody += "\r\nSubject: " + mail->subject + "\r\n"; + + if (mail->files.count() == 0) { //just a simple mail + newBody += "\r\n" + mail->body; + mail->rawMail = newBody; + return 0; + } + + //Build mime encoded mail + boundary = "-----4345=next_bound=0495----"; + + newBody += "Mime-Version: 1.0\r\n"; + newBody += "Content-Type: multipart/mixed; boundary=\"" + + boundary + "\"\r\n\r\n"; + + newBody += "This is a multipart message in Mime 1.0 format\r\n\r\n"; + newBody += "--" + boundary + "\r\nContent-Type: text/plain\r\n\r\n"; + newBody += mail->body; + + for ( ePtr=mail->files.first(); ePtr != 0; ePtr=mail->files.next() ) { + fileName = ePtr->originalName; + fileType = ePtr->contentType; + QFileInfo fi(fileName); + + // This specification of contentType is temporary + contentType = ""; + if (fileType == "Picture") { + contentType = "image/x-image"; + } else if (fileType == "Document") { + contentType = "text/plain"; + } else if (fileType == "Sound") { + contentType = "audio/x-wav"; + } else if (fileType == "Movie") { + contentType = "video/mpeg"; + } else { + contentType = "application/octet-stream"; + } + + newBody += "\r\n\r\n--" + boundary + "\r\n"; + newBody += "Content-Type: " + contentType + "; name=\"" + + fi.fileName() + "\"\r\n"; + newBody += "Content-Transfer-Encoding: base64\r\n"; + newBody += "Content-Disposition: inline; filename=\"" + + fi.fileName() + "\"\r\n\r\n"; + + if (encodeFile(fileName, &newBody) == -1) //file not found? + return -1; + } + + newBody += "\r\n\r\n--" + boundary + "--"; + mail->rawMail = newBody; + + return 0; +} + +int EmailHandler::encodeFile(QString fileName, QString *toBody) +{ + char *fileData; + char *dataPtr; + QString temp; + uint dataSize, count; + QFile f(fileName); + + if (! f.open(IO_ReadOnly) ) { + qWarning("could not open file: " + fileName); + return -1; + } + QTextStream s(&f); + dataSize = f.size(); + fileData = (char *) malloc(dataSize + 3); + s.readRawBytes(fileData, dataSize); + + temp = ""; + dataPtr = fileData; + count = 0; + while (dataSize > 0) { + if (dataSize < 3) { + encode64base(dataPtr, &temp, dataSize); + dataSize = 0; + } else { + encode64base(dataPtr, &temp, 3); + dataSize -= 3; + dataPtr += 3; + count += 4; + } + if (count > 72) { + count = 0; + temp += "\r\n"; + } + } + toBody->append(temp); + + delete(fileData); + f.close(); + return 0; +} + +void EmailHandler::encode64base(char *src, QString *dest, int len) +{ + QString temp; + uchar c; + uchar bufOut[4]; + + bufOut[0] = src[0]; + bufOut[0] >>= 2; //Done byte 0 + + bufOut[1] = src[0]; + bufOut[1] = bufOut[1] & (1 + 2); //mask out top 6 bits + bufOut[1] <<= 4; //copy up 4 places + if (len > 1) { + c = src[1]; + } else { + c = 0; + } + + c = c & (16 + 32 + 64 + 128); + c >>= 4; + bufOut[1] = bufOut[1] | c; //Done byte 1 + + bufOut[2] = src[1]; + bufOut[2] = bufOut[2] & (1 + 2 + 4 + 8); + bufOut[2] <<= 2; + if (len > 2) { + c = src[2]; + } else { + c = 0; + } + c >>= 6; + bufOut[2] = bufOut[2] | c; + + bufOut[3] = src[2]; + bufOut[3] = bufOut[3] & (1 + 2 + 4 + 8 + 16 + 32); + + if (len == 1) { + bufOut[2] = 64; + bufOut[3] = 64; + } + if (len == 2) { + bufOut[3] = 64; + } + for (int x = 0; x < 4; x++) { + if (bufOut[x] <= 25) + bufOut[x] += (uint) 'A'; + else if (bufOut[x] >= 26 && bufOut[x] <= 51) + bufOut[x] += (uint) 'a' - 26; + else if (bufOut[x] >= 52 && bufOut[x] <= 61) + bufOut[x] += (uint) '0' - 52; + else if (bufOut[x] == 62) + bufOut[x] = '+'; + else if (bufOut[x] == 63) + bufOut[x] = '/'; + else if (bufOut[x] == 64) + bufOut[x] = '='; + + dest->append(bufOut[x]); + } +} + +void EmailHandler::cancel() +{ + popClient->errorHandling(ErrCancel); + smtpClient->errorHandling(ErrCancel); +} diff --git a/noncore/net/mailit/emailhandler.h b/noncore/net/mailit/emailhandler.h new file mode 100644 index 0000000..17c4414 --- a/dev/null +++ b/noncore/net/mailit/emailhandler.h @@ -0,0 +1,147 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef EmailHandler_H +#define EmailHandler_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "smtpclient.h" +#include "popclient.h" +#include "textparser.h" +#include "maillist.h" + +struct Enclosure +{ + int id; + QString originalName; + QString name; + QString path; + QString contentType; + QString contentAttribute; + QString encoding; + QString body; //might use to much mem. check!! + bool saved, installed; +}; + +class EnclosureList : public QList +{ +public: + Item newItem(Item d); +private: + Enclosure* dupl(Enclosure *in); + Enclosure *ac; +}; + +struct Email +{ + QString id; + QString from; + QString fromMail; + QStringList recipients; + QStringList carbonCopies; + QString date; + QString subject; + QString body; + QString bodyPlain; + bool sent, received, read, downloaded; + QString rawMail; + int mimeType; //1 = Mime 1.0 + int serverId; + int internalId; + int fromAccountId; + QString contentType; //0 = text + QString contentAttribute; //0 = plain, 1 = html + EnclosureList files; + uint size; + + void addEnclosure(Enclosure *e) + { + files.append(e); + } +}; + +struct MailAccount +{ + QString accountName; + QString name; + QString emailAddress; + QString popUserName; + QString popPasswd; + QString popServer; + QString smtpServer; + bool synchronize; + int lastServerMailCount; + int id; +}; + + const int ErrUnknownResponse = 1001; + const int ErrLoginFailed = 1002; + const int ErrCancel = 1003; + + +class EmailHandler : public QObject +{ + Q_OBJECT + +public: + EmailHandler(); + void setAccount(MailAccount account); + void sendMail(QList *mailList); + void getMail(); + void getMailHeaders(); + void getMailByList(MailList *mailList); + bool parse(QString in, QString lineShift, Email *mail); + bool getEnclosure(Enclosure *ePtr); + int parse64base(char *src, char *dest); + int encodeMime(Email *mail); + int encodeFile(QString fileName, QString *toBody); + void encode64base(char *src, QString *dest, int len); + void cancel(); + +signals: + void mailSent(); + void smtpError(int); + void popError(int); + void mailArrived(const Email &, bool); + void updatePopStatus(const QString &); + void updateSmtpStatus(const QString &); + void mailTransfered(int); + void mailboxSize(int); + void currentMailSize(int); + void downloadedSize(int); + +public slots: + void messageArrived(const QString &, int id, uint size, bool complete); + +private: + MailAccount mailAccount; + SmtpClient *smtpClient; + PopClient *popClient; + bool headers; +}; + +#endif diff --git a/noncore/net/mailit/emaillistitem.cpp b/noncore/net/mailit/emaillistitem.cpp new file mode 100644 index 0000000..d47b0b7 --- a/dev/null +++ b/noncore/net/mailit/emaillistitem.cpp @@ -0,0 +1,92 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include "emaillistitem.h" + +EmailListItem::EmailListItem(QListView *parent, Email mailIn, bool inbox) + : QListViewItem(parent) +{ + QString temp; + + mail = mailIn; + + if (inbox) { + setText(0, mail.from); + } else { + QStringList::Iterator it = mail.recipients.begin(); + temp = *it; + if (mail.recipients.count() > 1) + temp += "..."; + setText(0, temp); + } + setText(1, mail.subject); + + selected = FALSE; +} + +Email* EmailListItem::getMail() +{ + return &mail; +} + +void EmailListItem::setMail(Email newMail) +{ + mail = newMail; + repaint(); +} + +void EmailListItem::setItemSelected(bool enable) +{ + selected = enable; + setSelected(enable); + repaint(); +} + +bool EmailListItem::isItemSelected() +{ + return selected; +} + +void EmailListItem::paintCell( QPainter *p, const QColorGroup &cg, + int column, int width, int alignment ) +{ + + QColorGroup _cg( cg ); + QColor c = _cg.text(); + + if ( (! mail.read) && (mail.received) ) + _cg.setColor( QColorGroup::Text, Qt::blue); + if (!mail.downloaded) + _cg.setColor( QColorGroup::Text, Qt::red); + +/* if (selected) { + _cg.setColor(QColorGroup::Base, Qt::blue); + _cg.setColor(QColorGroup::Text, Qt::yellow); + if (isSelected()) { + _cg.setColor(QColorGroup::HighlightedText, Qt::yellow); + } else { + _cg.setColor(QColorGroup::Highlight, Qt::blue); + } + } +*/ + QListViewItem::paintCell( p, _cg, column, width, alignment ); + + _cg.setColor( QColorGroup::Text, c ); +} diff --git a/noncore/net/mailit/emaillistitem.h b/noncore/net/mailit/emaillistitem.h new file mode 100644 index 0000000..642932c --- a/dev/null +++ b/noncore/net/mailit/emaillistitem.h @@ -0,0 +1,44 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef EMAILLISTITEM_H +#define EMAILLISTITEM_H + +#include +#include "emailhandler.h" + +class EmailListItem: public QListViewItem +{ +public: + EmailListItem(QListView *parent, Email mailIn, bool inbox); + Email* getMail(); + void setMail(Email newMail); + void setItemSelected(bool enable); + bool isItemSelected(); + bool itemSelected(); + +protected: + void paintCell( QPainter *p, const QColorGroup &cg, + int column, int width, int alignment ); +private: + Email mail; + bool selected; +}; + +#endif diff --git a/noncore/net/mailit/getmail.xpm b/noncore/net/mailit/getmail.xpm new file mode 100644 index 0000000..d294656 --- a/dev/null +++ b/noncore/net/mailit/getmail.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static char*getmail[]={ +"16 13 5 1", +"# c #040404", +"a c #c3c3c3", +"c c #000000", +". c None", +"b c #ffffff", +".........###....", +"........#...#.#.", +".............##.", +"............###.", +"................", +"..............aa", +".bbbbbbbbbbbbbba", +".bbbcbbcbbbcccba", +".bbcbccbbbbcbcba", +".bbbbbbbbbbcccba", +".bbcbcccbbbbbbba", +".bbbcbbbbbbbbbba", +".bbbbbbbbbbbbbba"}; diff --git a/noncore/net/mailit/mailit.pro b/noncore/net/mailit/mailit.pro new file mode 100644 index 0000000..653f2e2 --- a/dev/null +++ b/noncore/net/mailit/mailit.pro @@ -0,0 +1,44 @@ +TEMPLATE = app +CONFIG = qt warn_on release +HEADERS = emailclient.h \ + emailhandler.h \ + emaillistitem.h \ + mailitwindow.h \ + md5.h \ + popclient.h \ + readmail.h \ + smtpclient.h \ + writemail.h \ + textparser.h \ + viewatt.h \ + addatt.h \ + editaccount.h \ + maillist.h \ + addresslist.h +SOURCES = emailclient.cpp \ + emailhandler.cpp \ + emaillistitem.cpp \ + mailitwindow.cpp \ + main.cpp \ + md5.c \ + popclient.cpp \ + readmail.cpp \ + smtpclient.cpp \ + writemail.cpp \ + textparser.cpp \ + viewatt.cpp \ + addatt.cpp \ + editaccount.cpp \ + maillist.cpp \ + addresslist.cpp + +DESTDIR = ../bin +INCLUDEPATH += $(QPEDIR)/include:../library +DEPENDPATH += $(QPEDIR)/include:../library +LIBS += -lqpe +# -lssl +MOC_DIR=qpeobj +OBJECTS_DIR=qpeobj +DESTDIR=$(OPIEDIR)/bin + +include ( $(OPIEDIR)/include.pro ) diff --git a/noncore/net/mailit/mailitwindow.cpp b/noncore/net/mailit/mailitwindow.cpp new file mode 100644 index 0000000..f9b6de2 --- a/dev/null +++ b/noncore/net/mailit/mailitwindow.cpp @@ -0,0 +1,132 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "mailitwindow.h" + +MailItWindow::MailItWindow(QWidget *parent, const char *name, WFlags fl) + : QMainWindow(parent, name, fl) +{ + currentCaption = "Mailit"; + setCaption(tr(currentCaption)); + views = new QWidgetStack(this); + setCentralWidget(views); + + emailClient = new EmailClient(views, "client"); + writeMail = new WriteMail(views, "writing"); + readMail = new ReadMail(views, "reading"); + + views->raiseWidget(emailClient); + + connect(emailClient, SIGNAL(composeRequested()), + this, SLOT(compose()) ); + connect(emailClient, SIGNAL(viewEmail(QListView *, Email *)), this, + SLOT(viewMail(QListView *, Email *)) ); + connect(emailClient, SIGNAL(mailUpdated(Email *)), this, + SLOT(updateMailView(Email *)) ); + + connect(writeMail, SIGNAL(cancelMail()), this, SLOT(showEmailClient()) ); + connect(writeMail, SIGNAL(sendMailRequested(const Email &)), this, + SLOT(showEmailClient()) ); + connect(writeMail, SIGNAL(sendMailRequested(const Email &)), emailClient, + SLOT(enqueMail(const Email &)) ); + + connect(readMail, SIGNAL(cancelView()), this, SLOT(showEmailClient()) ); + connect(readMail, SIGNAL(replyRequested(Email &)), this, + SLOT(composeReply(Email &)) ); + connect(readMail, SIGNAL(removeItem(EmailListItem *, bool &)), emailClient, + SLOT(deleteMail(EmailListItem *, bool &)) ); + connect(readMail, SIGNAL(viewingMail(Email *)), emailClient, + SLOT(moveMailFront(Email *)) ); + + connect(emailClient, SIGNAL(newCaption(const QString &)), + this, SLOT(updateCaption(const QString &)) ); + viewingMail = FALSE; +} + +MailItWindow::~MailItWindow() +{ +} + +void MailItWindow::closeEvent(QCloseEvent *e) +{ + if (views->visibleWidget() == emailClient) { + e->accept(); + } else { + showEmailClient(); + } +} + +void MailItWindow::compose() +{ + viewingMail = FALSE; + emailClient->hide(); + readMail->hide(); + views->raiseWidget(writeMail); + writeMail->setAddressList(emailClient->getAdrListRef()); + setCaption( tr( "Write mail" ) ); +} + +void MailItWindow::composeReply(Email &mail) +{ + compose(); + writeMail->reply(mail); +} + +void MailItWindow::showEmailClient() +{ + viewingMail = FALSE; + writeMail->hide(); + readMail->hide(); + views->raiseWidget(emailClient); + setCaption( tr(currentCaption) ); +} + +void MailItWindow::viewMail(QListView *view, Email *mail) +{ + viewingMail = TRUE; + emailClient->hide(); + readMail->update(view, mail); + views->raiseWidget(readMail); + setCaption( tr( "Examine mail" ) ); +} + +void MailItWindow::updateMailView(Email *mail) +{ + if (viewingMail) { + readMail->mailUpdated(mail); + } +} + +void MailItWindow::updateCaption(const QString &newCaption) +{ + currentCaption = newCaption; + setCaption(tr(currentCaption)); +} + +void MailItWindow::setDocument(const QString &_address) +{ + // strip leading 'mailto:' + QString address = _address; + if (address.startsWith("mailto:")) + address = address.mid(6); + + compose(); + writeMail->setRecipient(address); +} + diff --git a/noncore/net/mailit/mailitwindow.h b/noncore/net/mailit/mailitwindow.h new file mode 100644 index 0000000..667960b --- a/dev/null +++ b/noncore/net/mailit/mailitwindow.h @@ -0,0 +1,58 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MailItWindow_H +#define MailItWindow_H + +#include +#include +#include +//#include +#include "emailclient.h" +#include "writemail.h" +#include "readmail.h" +#include "addresslist.h" + +class MailItWindow: public QMainWindow +{ + Q_OBJECT +public: + MailItWindow(QWidget *parent = 0, const char *name = 0, WFlags fl = 0); + ~MailItWindow(); + +public slots: + void compose(); + void composeReply(Email &); + void showEmailClient(); + void viewMail(QListView *, Email *mail); + void updateMailView(Email *mail); + void closeEvent(QCloseEvent *e); + void updateCaption(const QString &); + void setDocument(const QString &); + +private: + EmailClient *emailClient; + WriteMail *writeMail; + ReadMail *readMail; + QWidgetStack *views; + QString currentCaption; + bool viewingMail; +}; + +#endif diff --git a/noncore/net/mailit/maillist.cpp b/noncore/net/mailit/maillist.cpp new file mode 100644 index 0000000..b5325a9 --- a/dev/null +++ b/noncore/net/mailit/maillist.cpp @@ -0,0 +1,131 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "maillist.h" + +void MailList::clear() +{ + sortedList.setAutoDelete(TRUE); + sortedList.clear(); + currentPos = 0; +} + +int MailList::count() +{ + return sortedList.count(); +} + +int* MailList::first() +{ + dList *mPtr; + + if (sortedList.count() == 0) + return NULL; + + mPtr = sortedList.at(0); + currentPos = 1; + return &(mPtr->serverId); +} + +int* MailList::next() +{ + dList *mPtr; + + if ( (currentPos) >= sortedList.count()) + return NULL; + + mPtr = sortedList.at(currentPos); + currentPos++; + return &(mPtr->serverId); +} + +void MailList::sizeInsert(int serverId, uint size) +{ + dList *tempPtr; + int x; + + dList *newEntry = new dList; + newEntry->serverId = serverId; + newEntry->size = size; + + for (tempPtr = sortedList.first(); tempPtr != NULL; tempPtr = sortedList.next() ) { + if (newEntry->size < tempPtr->size) { + x = sortedList.at(); + sortedList.insert(x, newEntry); + return; + } + } + sortedList.append(newEntry); +} + +void MailList::moveFront(int serverId, uint size) +{ + dList *currentPtr; + uint tempPos; + QString temp; + + tempPos = currentPos; + if ( tempPos >= sortedList.count() ) + return; + currentPtr = sortedList.at(tempPos); + while ( ((tempPos+1) < sortedList.count()) && ( currentPtr->serverId != serverId) ) { + tempPos++; + currentPtr = sortedList.at(tempPos); + } + + if ( (currentPtr != NULL) && (currentPtr->serverId == serverId) ) { + temp.setNum(currentPtr->serverId); + qWarning("moved to front, message: " + temp); + + dList *itemPtr = sortedList.take(tempPos); + sortedList.insert(currentPos, itemPtr); + } + +} + +//only works if mail is not already in download +bool MailList::remove(int serverId, uint size) +{ + dList *currentPtr; + uint tempPos; + QString temp; + + tempPos = currentPos; + if ( tempPos >=sortedList.count() ) + return FALSE; + currentPtr = sortedList.at(tempPos); + while ( ((tempPos + 1) < sortedList.count()) && ( currentPtr->serverId != serverId) ) { + tempPos++; + currentPtr = sortedList.at(tempPos); + } + + if ( (currentPtr != NULL) && (currentPtr->serverId == serverId) ) { + temp.setNum(currentPtr->serverId); + qWarning("deleted message: " + temp); + sortedList.remove(tempPos); + + return TRUE; + } + return FALSE; +} + +void MailList::insert(int pos, int serverId, uint size) +{ +// sortedList.insert(pos, mPtr); +} diff --git a/noncore/net/mailit/maillist.h b/noncore/net/mailit/maillist.h new file mode 100644 index 0000000..ec996df --- a/dev/null +++ b/noncore/net/mailit/maillist.h @@ -0,0 +1,50 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef MAILLIST_H +#define MAILLIST_H + +#include +#include + +struct dList{ + int serverId; + uint size; +}; + +class MailList : public QObject +{ + Q_OBJECT + +public: + void clear(); + int count(); + int* first(); + int* next(); + void sizeInsert(int serverId, uint size); + void moveFront(int serverId, uint size); + bool remove(int serverId, uint size); + void insert(int pos, int serverId, uint size); + +private: + QList sortedList; + uint currentPos; +}; + +#endif diff --git a/noncore/net/mailit/main.cpp b/noncore/net/mailit/main.cpp new file mode 100644 index 0000000..3a3e1fc --- a/dev/null +++ b/noncore/net/mailit/main.cpp @@ -0,0 +1,29 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include "mailitwindow.h" + +int main(int argc, char* argv[]) +{ + QPEApplication a( argc, argv ); + MailItWindow mw(0, 0); + a.showMainDocumentWidget(&mw); + return a.exec(); +} diff --git a/noncore/net/mailit/md5.c b/noncore/net/mailit/md5.c new file mode 100644 index 0000000..611f151 --- a/dev/null +++ b/noncore/net/mailit/md5.c @@ -0,0 +1,251 @@ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + * + * Changed so as no longer to depend on Colin Plumb's `usual.h' header + * definitions; now uses stuff from dpkg's config.h. + * - Ian Jackson . + * Still in the public domain. + * + * md5_buffer added by Steven Fuller + * Still in the public domain. + */ + +#include /* for memcpy() */ + +#include "md5.h" + +#ifdef WORDS_BIGENDIAN +void +byteSwap(UWORD32 *buf, unsigned words) +{ + md5byte *p = (md5byte *)buf; + + do { + *buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 | + ((unsigned)p[1] << 8 | p[0]); + p += 4; + } while (--words); +} +#else +#define byteSwap(buf,words) +#endif + +/* md5_buffer frontend added for AvP */ +void md5_buffer(char const *buffer, unsigned int len, char *digest) +{ + struct MD5Context md5c; + + MD5Init(&md5c); + MD5Update(&md5c, (md5byte const *)buffer, len); + MD5Final((md5byte *)digest, &md5c); +} + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void +MD5Init(struct MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bytes[0] = 0; + ctx->bytes[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void +MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) +{ + UWORD32 t; + + /* Update byte count */ + + t = ctx->bytes[0]; + if ((ctx->bytes[0] = t + len) < t) + ctx->bytes[1]++; /* Carry from low to high */ + + t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ + if (t > len) { + memcpy((md5byte *)ctx->in + 64 - t, buf, len); + return; + } + /* First chunk is an odd size */ + memcpy((md5byte *)ctx->in + 64 - t, buf, t); + byteSwap(ctx->in, 16); + MD5Transform(ctx->buf, ctx->in); + buf += t; + len -= t; + + /* Process data in 64-byte chunks */ + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteSwap(ctx->in, 16); + MD5Transform(ctx->buf, ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void +MD5Final(md5byte digest[16], struct MD5Context *ctx) +{ + int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ + md5byte *p = (md5byte *)ctx->in + count; + + /* Set the first char of padding to 0x80. There is always room. */ + *p++ = 0x80; + + /* Bytes of padding needed to make 56 bytes (-8..55) */ + count = 56 - 1 - count; + + if (count < 0) { /* Padding forces an extra block */ + memset(p, 0, count + 8); + byteSwap(ctx->in, 16); + MD5Transform(ctx->buf, ctx->in); + p = (md5byte *)ctx->in; + count = 56; + } + memset(p, 0, count); + byteSwap(ctx->in, 14); + + /* Append length in bits and transform */ + ctx->in[14] = ctx->bytes[0] << 3; + ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; + MD5Transform(ctx->buf, ctx->in); + + byteSwap(ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ +} + +#ifndef ASM_MD5 + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f,w,x,y,z,in,s) \ + (w += f(x,y,z) + in, w = (w<>(32-s)) + x) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void +MD5Transform(UWORD32 buf[4], UWORD32 const in[16]) +{ + register UWORD32 a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +#endif diff --git a/noncore/net/mailit/md5.h b/noncore/net/mailit/md5.h new file mode 100644 index 0000000..7e22494 --- a/dev/null +++ b/noncore/net/mailit/md5.h @@ -0,0 +1,55 @@ +/* + * This is the header file for the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + * + * Changed so as no longer to depend on Colin Plumb's `usual.h' + * header definitions; now uses stuff from dpkg's config.h + * - Ian Jackson . + * Still in the public domain. + * + * md5_buffer added by Steven Fuller + * Still in the public domain. + */ + +#ifndef MD5_H +#define MD5_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned int UWORD32; + +#define md5byte unsigned char + +struct MD5Context { + UWORD32 buf[4]; + UWORD32 bytes[2]; + UWORD32 in[16]; +}; + +void MD5Init(struct MD5Context *context); +void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len); +void MD5Final(unsigned char digest[16], struct MD5Context *context); +void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]); + +/* md5_buffer frontend added for AvP */ +void md5_buffer(char const *buffer, unsigned int len, char *digest); + +#ifdef __cplusplus +}; +#endif + +#endif /* !MD5_H */ diff --git a/noncore/net/mailit/opie-mailit.control b/noncore/net/mailit/opie-mailit.control new file mode 100644 index 0000000..db9c23d --- a/dev/null +++ b/noncore/net/mailit/opie-mailit.control @@ -0,0 +1,9 @@ +Files: bin/mailit apps/Applications/mailit.desktop pics/EMail.png +Priority: optional +Section: opie +Maintainer: Warwick Allison +Architecture: arm +Version: $OPIE_VERSION-$SUB_VERSION +Depends: opie-base +Description: EMail + A simple POP3 email client for the Qt Palmtop environment. diff --git a/noncore/net/mailit/popclient.cpp b/noncore/net/mailit/popclient.cpp new file mode 100644 index 0000000..a406af2 --- a/dev/null +++ b/noncore/net/mailit/popclient.cpp @@ -0,0 +1,375 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "popclient.h" +#include "emailhandler.h" +//#define APOP_TEST + +extern "C" { +#include "md5.h" +} + +#include + +PopClient::PopClient() +{ + socket = new QSocket(this, "popClient"); + connect(socket, SIGNAL(error(int)), this, SLOT(errorHandling(int))); + connect(socket, SIGNAL(connected()), this, SLOT(connectionEstablished())); + connect(socket, SIGNAL(readyRead()), this, SLOT(incomingData())); + + stream = new QTextStream(socket); + + receiving = FALSE; + synchronize = FALSE; + lastSync = 0; + headerLimit = 0; + preview = FALSE; +} + +PopClient::~PopClient() +{ + delete socket; + delete stream; +} + +void PopClient::newConnection(QString target, int port) +{ + if (receiving) { + qWarning("socket in use, connection refused"); + return; + } + + status = Init; + + socket->connectToHost(target, port); + receiving = TRUE; + selected = FALSE; + + emit updateStatus("DNS lookup"); +} + +void PopClient::setAccount(QString popUser, QString popPasswd) +{ + popUserName = popUser; + popPassword = popPasswd; +} + +void PopClient::setSynchronize(int lastCount) +{ + synchronize = TRUE; + lastSync = lastCount; +} + +void PopClient::removeSynchronize() +{ + synchronize = FALSE; + lastSync = 0; +} + +void PopClient::headersOnly(bool headers, int limit) +{ + preview = headers; + headerLimit = limit; +} + +void PopClient::setSelectedMails(MailList *list) +{ + selected = TRUE; + mailList = list; +} + +void PopClient::connectionEstablished() +{ + emit updateStatus("Connection established"); +} + +void PopClient::errorHandling(int status) +{ + emit updateStatus("Error Occured"); + emit errorOccurred(status); + socket->close(); + receiving = FALSE; +} + +void PopClient::incomingData() +{ + QString response, temp, temp2, timeStamp; + QString md5Source; + int start, end; +// char *md5Digest; + char md5Digest[16]; +// if ( !socket->canReadLine() ) +// return; + + response = socket->readLine(); + qDebug(response +" %d", status); + + switch(status) { + //logging in + case Init: { +#ifdef APOP_TEST + start = response.find('<',0); + end = response.find('>', start); + if( start >= 0 && end > start ) + { + timeStamp = response.mid( start , end - start + 1); + md5Source = timeStamp + popPassword; + qDebug( md5Source); +// for( int i = 0; i < md5Source.length(); i++) { +// buff[i] = (QChar)md5Source[i]; +// } + + md5_buffer( (char const *)md5Source, md5Source.length(),&md5Digest[0]); +// md5_buffer(char const *buffer, unsigned int len, char *digest); + +// MD5_Init( &ctx); +// MD5_Update( &ctx, buff, sizeof( buff) ); +// MD5_Final( md5Digest, &ctx); +// MD5( buff, md5Source.length(), md5Digest); + + for(int j =0;j < MD5_DIGEST_LENGTH ;j++) + { + printf("%x", md5Digest[j]); + } + printf("\n"); +// qDebug(md5Digest); + *stream << "APOP " << popUserName << " " << md5Digest << "\r\n"; + // qDebug("%s", stream); + status = Stat; + } + else +#endif + { + timeStamp = ""; + *stream << "USER " << popUserName << "\r\n"; + status = Pass; + } + + break; + } + //password shhh. don't tell anyone (implement APOP...) + case Pass: { + *stream << "PASS " << popPassword << "\r\n"; + status = Stat; + break; + } + //ask for number of messages + case Stat: { + if (response[0] == '+') { + *stream << "STAT" << "\r\n"; + status = Mcnt; + } else errorHandling(ErrLoginFailed); + break; + } + //get count of messages, eg "+OK 4 900.." -> int 4 + case Mcnt: { + if (response[0] == '+') { + temp = response.replace(0, 4, ""); + int x = temp.find(" ", 0); + temp.truncate((uint) x); + newMessages = temp.toInt(); + messageCount = 1; + status = List; + + if (synchronize) { + //messages deleted from server, reload all + if (newMessages < lastSync) + lastSync = 0; + messageCount = lastSync + 1; + } + + if (selected) { + int *ptr = mailList->first(); + if (ptr != 0) { + newMessages++; //to ensure no early jumpout + messageCount = *(mailList->first()); + } else newMessages = 0; + } + } else errorHandling(ErrUnknownResponse); + } + //Read message number x, count upwards to messageCount + case List: { + if (messageCount <= newMessages) { + *stream << "LIST " << messageCount << "\r\n"; + status = Size; + temp2.setNum(newMessages - lastSync); + temp.setNum(messageCount - lastSync); + if (!selected) { + emit updateStatus("Retrieving " + temp + "/" + temp2); + } else { + //completing a previously closed transfer + if ( (messageCount - lastSync) <= 0) { + temp.setNum(messageCount); + emit updateStatus("Previous message " + temp); + } else { + emit updateStatus("Completing message " + temp); + } + } + break; + } else { + emit updateStatus("No new Messages"); + status = Quit; + } + } + //get size of message, eg "500 characters in message.." -> int 500 + case Size: { + if (status != Quit) { //because of idiotic switch + if (response[0] == '+') { + temp = response.replace(0, 4, ""); + int x = temp.find(" ", 0); + temp = temp.right(temp.length() - ((uint) x + 1) ); + mailSize = temp.toInt(); + emit currentMailSize(mailSize); + + status = Retr; + } else { + qWarning(response); + errorHandling(ErrUnknownResponse); + } + } + } + //Read message number x, count upwards to messageCount + case Retr: { + if (status != Quit) { + if (!preview || mailSize <= headerLimit) { + *stream << "RETR " << messageCount << "\r\n"; + } else { //only header + *stream << "TOP " << messageCount << " 0\r\n"; + } + messageCount++; + status = Ignore; + break; + } } + case Ignore: { + if (status != Quit) { //because of idiotic switch + if (response[0] == '+') { + message = ""; + status = Read; + if (!socket->canReadLine()) //sync. problems + break; + response = socket->readLine(); + } else errorHandling(ErrUnknownResponse); + } + } + //add all incoming lines to body. When size is reached, send + //message, and go back to read new message + case Read: { + if (status != Quit) { //because of idiotic switch + message += response; + while ( socket->canReadLine() ) { + response = socket->readLine(); + message += response; + } + emit downloadedSize(message.length()); + int x = message.find("\r\n.\r\n",-5); + if (x == -1) { + break; + } else { //message reach entire size + //complete mail downloaded + if ( (!preview ) || ((preview) && (mailSize <= headerLimit)) ){ + emit newMessage(message, messageCount-1, mailSize, TRUE); + } else { //incomplete mail downloaded + emit newMessage(message, messageCount-1, mailSize, FALSE); + } + if (messageCount > newMessages) //that was the last message + status = Quit; + else { //ask for new message + if (selected) { //grab next from queue + int *ptr = mailList->next(); + if (ptr != 0) { + messageCount = *ptr; + *stream << "LIST " << messageCount << "\r\n"; + status = Size; + //completing a previously closed transfer + if ( (messageCount - lastSync) <= 0) { + temp.setNum(messageCount); + emit updateStatus("Previous message " + temp); + } else { + temp.setNum(messageCount - lastSync); + emit updateStatus("Completing message " + temp); + } + break; + } else { + newMessages--; + status = Quit; + } + } else { + *stream << "LIST " << messageCount << "\r\n"; + status = Size; + temp2.setNum(newMessages - lastSync); + temp.setNum(messageCount - lastSync); + emit updateStatus("Retrieving " + temp + "/" + temp2); + + break; + } + } + } + if (status != Quit) + break; + } + } + case Quit: { + *stream << "Quit\r\n"; + status = Done; + int newM = newMessages - lastSync; + if (newM > 0) { + temp.setNum(newM); + emit updateStatus(temp + " new messages"); + } else { + emit updateStatus("No new messages"); + } + + socket->close(); + receiving = FALSE; + emit mailTransfered(newM); + break; + } + } + +} + +// if( bAPOPAuthentication ) +// { +// if( m_strTimeStamp.IsEmpty() ) +// { +// SetLastError("Apop error!"); +// return false; +// } +// strMD5Source = m_strTimeStamp+pszPassword; +// strMD5Dst = MD5_GetMD5( (BYTE*)(const char*)strMD5Source , strMD5Source.GetLength() ); +// sprintf(msg , "apop %s %s\r\n" , pszUser , strMD5Dst); +// ret = send(m_sPop3Socket , msg , strlen(msg) , NULL); +// if(ret == SOCKET_ERROR) +// { +// SetLastError("Socket error!"); +// m_bSocketOK = false; +// m_bConnected = false; +// return false; +// } +// if( !GetSocketResult(&strResult , COMMAND_END_FLAG) ) +// return false; +// if( 0 == strResult.Find('-' , 0) ) +// { +// SetLastError("Username or Password error!"); +// return false; +// } +// m_bConnected = true; + +// } diff --git a/noncore/net/mailit/popclient.h b/noncore/net/mailit/popclient.h new file mode 100644 index 0000000..10b71ab --- a/dev/null +++ b/noncore/net/mailit/popclient.h @@ -0,0 +1,76 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef PopClient_H +#define PopClient_H + +#include +#include +#include +#include +#include +#include +#include "maillist.h" + +class PopClient: public QObject +{ + Q_OBJECT + +public: + PopClient(); + ~PopClient(); + void newConnection(QString target, int port); + void setAccount(QString popUser, QString popPasswd); + void setSynchronize(int lastCount); + void removeSynchronize(); + void headersOnly(bool headers, int limit); + void setSelectedMails(MailList *list); + +signals: + void newMessage(const QString &, int, uint, bool); + void errorOccurred(int status); + void updateStatus(const QString &); + void mailTransfered(int); + void mailboxSize(int); + void currentMailSize(int); + void downloadedSize(int); + +public slots: + void errorHandling(int); + +protected slots: + void connectionEstablished(); + void incomingData(); + +private: + QSocket *socket; + QTextStream *stream; + enum transferStatus + { + Init, Pass, Stat, Mcnt, Read, List, Size, Retr, Acks, + Quit, Done, Ignore + }; + int status, lastSync; + int messageCount, newMessages, mailSize, headerLimit; + bool receiving, synchronize, preview, selected; + QString popUserName, popPassword, message; + MailList *mailList; +}; + +#endif diff --git a/noncore/net/mailit/readmail.cpp b/noncore/net/mailit/readmail.cpp new file mode 100644 index 0000000..4954f34 --- a/dev/null +++ b/noncore/net/mailit/readmail.cpp @@ -0,0 +1,326 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "readmail.h" +#include +#include +#include +#include "resource.h" + +ReadMail::ReadMail( QWidget* parent, const char* name, WFlags fl ) + : QMainWindow(parent, name, fl) +{ + plainTxt = FALSE; + + init(); + viewAtt = new ViewAtt(0, "View Attatchments"); +} + +ReadMail::~ReadMail() +{ + delete emailView->mimeSourceFactory(); + delete viewAtt; +} + +void ReadMail::init() +{ + setToolBarsMovable(FALSE); + + bar = new QToolBar(this); + bar->setHorizontalStretchable( TRUE ); + + menu = new QMenuBar( bar ); + + viewMenu = new QPopupMenu(menu); + menu->insertItem( tr( "&View" ), viewMenu); + + mailMenu = new QPopupMenu(menu); + menu->insertItem( tr( "&Mail" ), mailMenu); + + bar = new QToolBar(this); + + //reply dependant on viewing inbox + replyButton = new QAction( tr( "Reply" ), Resource::loadPixmap( "pass" ), + QString::null, 0, this, 0 ); + connect(replyButton, SIGNAL(activated()), this, SLOT(reply()) ); + + previousButton = new QAction( tr( "Previous" ), Resource::loadPixmap( "back" ), QString::null, 0, this, 0 ); + connect( previousButton, SIGNAL( activated() ), this, SLOT( previous() ) ); + previousButton->addTo(bar); + previousButton->addTo(viewMenu); + + nextButton = new QAction( tr( "Next" ), Resource::loadPixmap( "forward" ), QString::null, 0, this, 0 ); + connect( nextButton, SIGNAL( activated() ), this, SLOT( next() ) ); + nextButton->addTo(bar); + nextButton->addTo(viewMenu); + + attatchmentsButton = new QAction( tr( "Attatchments" ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 ); + connect( attatchmentsButton, SIGNAL( activated() ), this, + SLOT( viewAttatchments() ) ); + attatchmentsButton->addTo(bar); + attatchmentsButton->addTo(viewMenu); + + plainTextButton = new QAction( tr( "Text Format" ), Resource::loadPixmap( "new" ), QString::null, 0, this, 0, TRUE); + connect( plainTextButton, SIGNAL( activated() ), this, SLOT( shiftText() ) ); + plainTextButton->addTo(bar); + plainTextButton->addTo(viewMenu); + + deleteButton = new QAction( tr( "Delete" ), Resource::loadPixmap( "trash" ), QString::null, 0, this, 0 ); + connect( deleteButton, SIGNAL( activated() ), this, SLOT( deleteItem() ) ); + deleteButton->addTo(bar); + deleteButton->addTo(mailMenu); + + viewMenu->insertItem(Resource::loadPixmap("close"), "Close", this, SLOT(close())); + + emailView = new QTextView( this, "emailView" ); + setCentralWidget(emailView); + + mime = new QMimeSourceFactory(); + emailView->setMimeSourceFactory(mime); +} + +void ReadMail::updateView() +{ + Enclosure *ePtr; + QString mailStringSize; + QString text, temp; + + mail->read = TRUE; //mark as read + inbox = mail->received; + + replyButton->removeFrom(mailMenu); + replyButton->removeFrom(bar); + + if (inbox == TRUE) { + replyButton->addTo(bar); + replyButton->addTo(mailMenu); + + if (!mail->downloaded) { + //report currently viewed mail so that it will be + //placed first in the queue of new mails to download + emit viewingMail(mail); + + double mailSize = (double) mail->size; + if (mailSize < 1024) { + mailStringSize.setNum(mailSize); + mailStringSize += " Bytes"; + } else if (mailSize < 1024*1024) { + mailStringSize.setNum( (mailSize / 1024), 'g', 2 ); + mailStringSize += " Kb"; + } else { + mailStringSize.setNum( (mailSize / (1024*1024)), 'g', 3); + mailStringSize += " Mb"; + } + } + } + + QMimeSourceFactory *mime = emailView->mimeSourceFactory(); + + if (! plainTxt) { //use RichText, inline pics etc. + emailView->setTextFormat(QTextView::RichText); + text = "
" + mail->subject + +"

"; + text += "From: " + mail->from + " " + + mail->fromMail + "
"; + + text +="To: "; + for (QStringList::Iterator it = mail->recipients.begin(); + it != mail->recipients.end(); ++it ) { + text += *it + " "; + } + text += "
" + mail->date; + + if (mail->files.count() > 0) { + text += "
Attatchments: "; + + for ( ePtr=mail->files.first(); ePtr != 0; ePtr=mail->files.next() ) { + text += ePtr->originalName + " "; + } + text += "

" + mail->body; + + if (inbox) { + for ( ePtr=mail->files.first(); ePtr != 0; ePtr=mail->files.next() ) { + + text += "

Attatchment: " + + ePtr->originalName + "
"; + + if (ePtr->contentType == "TEXT") { + QFile f(ePtr->path + ePtr->name); + + if (f.open(IO_ReadOnly) ) { + QTextStream t(&f); + temp = t.read(); + text += temp + "
"; + f.close(); + } else { + text += "Could not locate file
"; + } + + } + if (ePtr->contentType == "IMAGE") { +// temp.setNum(emailView->width()); //get display width +// text += "originalName + """> "; + text += "originalName + """> "; + mime->setPixmap(ePtr->originalName, QPixmap( (ePtr->path + ePtr->name) )); + } + } + } + } else { + if (mail->downloaded || !inbox) { + text += "

" + mail->body; + } else { + text += "

Awaiting download
"; + text += "Size of mail: " + mailStringSize; + } + } + emailView->setText(text); + } else { // show plain txt mail + emailView->setTextFormat(QTextView::PlainText); + text = "Subject: " + mail->subject + "\n"; + text += "From: " + mail->from + " " + mail->fromMail + "\n"; + text += "To: "; + for (QStringList::Iterator it = mail->recipients.begin(); + it != mail->recipients.end(); ++it ) { + text += *it + " "; + } + text += "\nDate: " + mail->date + "\n"; + if (mail->files.count() > 0) { + text += "Attatchments: "; + for ( ePtr=mail->files.first(); ePtr != 0; ePtr=mail->files.next() ) { + text += ePtr->originalName + " "; + } + text += "\n\n"; + } else text += "\n"; + + if (!inbox) { + text += mail->body; + } else if (mail->downloaded) { + text += mail->bodyPlain; + } else { + text += "\nAwaiting download\n"; + text += "Size of mail: " + mailStringSize; + } + + emailView->setText(text); + } + + if (mail->files.count() == 0) + attatchmentsButton->setEnabled(FALSE); + else attatchmentsButton->setEnabled(TRUE); + + setCaption("Examining mail: " + mail->subject); +} + +//update view with current EmailListItem (item) +void ReadMail::update(QListView *thisView, Email *mailIn) +{ + view = thisView; + item = (EmailListItem *) view->selectedItem(); + mail = mailIn; + updateView(); + updateButtons(); +} + +void ReadMail::mailUpdated(Email *mailIn) +{ + if (mailIn == mail) { + updateView(); + } else { + updateButtons(); + } +} + +void ReadMail::close() +{ + emit cancelView(); +} + +//gets next item in listview, exits if there is no next +void ReadMail::next() +{ + item = (EmailListItem *) item->nextSibling(); + if (item != NULL) { + mail = item->getMail(); + updateView(); + } + updateButtons(); +} + +//gets previous item in listview, exits if there is no previous +void ReadMail::previous() +{ + item = (EmailListItem *) item->itemAbove(); + if (item != NULL) { + mail = item->getMail(); + updateView(); + } + updateButtons(); +} + +//deletes item, tries bringing up next or previous, exits if unsucessful +void ReadMail::deleteItem() +{ + EmailListItem *temp = item; + temp = (EmailListItem *) item->nextSibling(); //trybelow + if (temp == NULL) + temp = (EmailListItem *) item->itemAbove(); //try above + + emit removeItem(item, inbox); + + item = temp; + if (item != NULL) { //more items in list + mail = item->getMail(); + updateView(); + updateButtons(); + } else close(); //no more items to see +} + +void ReadMail::updateButtons() +{ + EmailListItem *temp; + + temp = item; + if ((EmailListItem *) temp->nextSibling() == NULL) + nextButton->setEnabled(FALSE); + else nextButton->setEnabled(TRUE); + + temp = item; + if ((EmailListItem *) temp->itemAbove() == NULL) + previousButton->setEnabled(FALSE); + else previousButton->setEnabled(TRUE); +} + +void ReadMail::shiftText() +{ + plainTxt = ! plainTxt; + updateView(); +} + +void ReadMail::viewAttatchments() +{ + viewAtt->update(mail, inbox); + viewAtt->showMaximized(); +} + +void ReadMail::reply() +{ + emit replyRequested(*mail); +} diff --git a/noncore/net/mailit/readmail.h b/noncore/net/mailit/readmail.h new file mode 100644 index 0000000..d0bb067 --- a/dev/null +++ b/noncore/net/mailit/readmail.h @@ -0,0 +1,86 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef READMAIL_H +#define READMAIL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "emailhandler.h" +#include "emaillistitem.h" +#include "viewatt.h" + +class ReadMail : public QMainWindow +{ + Q_OBJECT + +public: + ReadMail( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~ReadMail(); + void update(QListView *thisView, Email *mailIn); + void updateView(); + void mailUpdated(Email *mailIn); + +signals: + void cancelView(); + void replyRequested(Email &); + void removeItem(EmailListItem *, bool &); + void viewingMail(Email *); + +public slots: + void close(); + void next(); + void previous(); + void deleteItem(); + void shiftText(); + void viewAttatchments(); + void reply(); + +private: + void init(); + void updateButtons(); + +private: + QListView *view; + EmailListItem *item; + bool plainTxt, inbox; + Email *mail; + ViewAtt *viewAtt; + + QToolBar *bar; + QMenuBar *menu; + QPopupMenu *viewMenu, *mailMenu; + QAction *deleteButton; + QMimeSourceFactory *mime; + QAction *plainTextButton; + QAction *nextButton; + QTextView *emailView; + QAction *attatchmentsButton; + QAction *previousButton; + QAction *replyButton; +}; + +#endif // READMAIL_H diff --git a/noncore/net/mailit/resource.cpp b/noncore/net/mailit/resource.cpp new file mode 100644 index 0000000..dc19880 --- a/dev/null +++ b/noncore/net/mailit/resource.cpp @@ -0,0 +1,136 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "qpeapplication.h" +#include "resource.h" +#include +#include +#include +#include +#include + +#include "inlinepics_p.h" + +/*! + \class Resource resource.h + \brief The Resource class provides access to named resources. + + The resources may be provided from files or other sources. +*/ + +/*! + \fn Resource::Resource() + \internal +*/ + +/*! + Returns the QPixmap named \a pix. You should avoid including + any filename type extension (eg. .png, .xpm). +*/ +QPixmap Resource::loadPixmap( const QString &pix ) +{ + QPixmap pm; + QString key="QPE_"+pix; + if ( !QPixmapCache::find(key,pm) ) { + pm.convertFromImage(loadImage(pix)); + QPixmapCache::insert(key,pm); + } + return pm; +} + +/*! + Returns the QBitmap named \a pix. You should avoid including + any filename type extension (eg. .png, .xpm). +*/ +QBitmap Resource::loadBitmap( const QString &pix ) +{ + QBitmap bm; + bm = loadPixmap(pix); + return bm; +} + +/*! + Returns the filename of a pixmap named \a pix. You should avoid including + any filename type extension (eg. .png, .xpm). + + Normally you will use loadPixmap() rather than this function. +*/ +QString Resource::findPixmap( const QString &pix ) +{ + QString picsPath = QPEApplication::qpeDir() + "pics/"; + + if ( QFile( picsPath + pix + ".png").exists() ) + return picsPath + pix + ".png"; + else if ( QFile( picsPath + pix + ".xpm").exists() ) + return picsPath + pix + ".xpm"; + else if ( QFile( picsPath + pix ).exists() ) + return picsPath + pix; + + //qDebug("Cannot find pixmap: %s", pix.latin1()); + return QString(); +} + +/*! + Returns a sound file for a sound named \a name. + You should avoid including any filename type extension (eg. .wav, .au, .mp3). +*/ +QString Resource::findSound( const QString &name ) +{ + QString picsPath = QPEApplication::qpeDir() + "sounds/"; + + QString result; + if ( QFile( (result = picsPath + name + ".wav") ).exists() ) + return result; + + return QString(); +} + +/*! + Returns a list of all sound names. +*/ +QStringList Resource::allSounds() +{ + QDir resourcedir( QPEApplication::qpeDir() + "sounds/", "*.wav" ); + QStringList entries = resourcedir.entryList(); + QStringList result; + for (QStringList::Iterator i=entries.begin(); i != entries.end(); ++i) + result.append((*i).replace(QRegExp("\\.wav"),"")); + return result; +} + +/*! + Returns the QImage named \a name. You should avoid including + any filename type extension (eg. .png, .xpm). +*/ +QImage Resource::loadImage( const QString &name) +{ + QImage img = qembed_findImage(name.latin1()); + if ( img.isNull() ) + return QImage(findPixmap(name)); + return img; +} + +/*! + \fn QIconSet Resource::loadIconSet( const QString &name ) + + Returns a QIconSet for the pixmap named \a name. A disabled icon is + generated that conforms to the Qtopia look & feel. You should avoid + including any filename type extension (eg. .png, .xpm). +*/ diff --git a/noncore/net/mailit/resource.h b/noncore/net/mailit/resource.h new file mode 100644 index 0000000..982c58a --- a/dev/null +++ b/noncore/net/mailit/resource.h @@ -0,0 +1,80 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef PIXMAPLOADER_H +#define PIXMAPLOADER_H + +#include +#include +#include +#include + +class Resource +{ +public: + Resource() {} + + static QImage loadImage( const QString &name); + + static QPixmap loadPixmap( const QString &name ); + static QBitmap loadBitmap( const QString &name ); + static QString findPixmap( const QString &name ); + + static QIconSet loadIconSet( const QString &name ); + + static QString findSound( const QString &name ); + static QStringList allSounds(); +}; + +// Inline for compatibility with SHARP ROMs +inline QIconSet Resource::loadIconSet( const QString &pix ) +{ + QImage img = loadImage( pix ); + QPixmap pm; + pm.convertFromImage( img ); + QIconSet is( pm ); + QIconSet::Size size = pm.width() <= 22 ? QIconSet::Small : QIconSet::Large; + + QPixmap dpm = loadPixmap( pix + "_disabled" ); + +#ifndef QT_NO_DEPTH_32 // have alpha-blended pixmaps + if ( dpm.isNull() ) { + QImage dimg( img.width(), img.height(), 32 ); + for ( int y = 0; y < img.height(); y++ ) { + for ( int x = 0; x < img.width(); x++ ) { + QRgb p = img.pixel( x, y ); + uint a = (p & 0xff000000) / 3; + p = (p & 0x00ffffff) | (a & 0xff000000); + dimg.setPixel( x, y, p ); + } + } + + dimg.setAlphaBuffer( TRUE ); + dpm.convertFromImage( dimg ); + } +#endif + + if ( !dpm.isNull() ) + is.setPixmap( dpm, size, QIconSet::Disabled ); + + return is; +} + + +#endif diff --git a/noncore/net/mailit/sendmail.xpm b/noncore/net/mailit/sendmail.xpm new file mode 100644 index 0000000..2803793 --- a/dev/null +++ b/noncore/net/mailit/sendmail.xpm @@ -0,0 +1,20 @@ +/* XPM */ +static char*sendmail[]={ +"16 13 4 1", +"a c #c3c3c3", +"# c #000000", +". c None", +"b c #ffffff", +".....#####aaa...", +"....####aaaaa.a.", +"....#.###...aaa.", +"....#..###..aaa.", +".......###......", +"..............aa", +".bbbbbbbbbbbbbba", +".bbb#bb#bbb###ba", +".bb#b##bbbb#b#ba", +".bbbbbbbbbb###ba", +".bb#b###bbbbbbba", +".bbb#bbbbbbbbbba", +".bbbbbbbbbbbbbba"}; diff --git a/noncore/net/mailit/smtpclient.cpp b/noncore/net/mailit/smtpclient.cpp new file mode 100644 index 0000000..7bb7933 --- a/dev/null +++ b/noncore/net/mailit/smtpclient.cpp @@ -0,0 +1,163 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "smtpclient.h" +#include "emailhandler.h" + +SmtpClient::SmtpClient() +{ + socket = new QSocket(this, "smtpClient"); + stream = new QTextStream(socket); + mailList.setAutoDelete(TRUE); + + connect(socket, SIGNAL(error(int)), this, SLOT(errorHandling(int))); + connect(socket, SIGNAL(connected()), this, SLOT(connectionEstablished())); + connect(socket, SIGNAL(readyRead()), this, SLOT(incomingData())); + + sending = FALSE; +} + +SmtpClient::~SmtpClient() +{ + delete socket; + delete stream; +} + +void SmtpClient::newConnection(QString target, int port) +{ + if (sending) { + qWarning("socket in use, connection refused"); + return; + } + + status = Init; + sending = TRUE; + socket->connectToHost(target, port); + + emit updateStatus("DNS lookup"); +} + +void SmtpClient::addMail(QString from, QString subject, QStringList to, QString body) +{ + RawEmail *mail = new RawEmail; + + mail->from = from; + mail->subject = subject; + mail->to = to; + mail->body = body; + + mailList.append(mail); +} + +void SmtpClient::connectionEstablished() +{ + emit updateStatus("Connection established"); + +} + +void SmtpClient::errorHandling(int status) +{ + emit errorOccurred(status); + socket->close(); + mailList.clear(); + sending = FALSE; +} + +void SmtpClient::incomingData() +{ + QString response; + + if (!socket->canReadLine()) + return; + + response = socket->readLine(); + + switch(status) { + case Init: { + if (response[0] == '2') { + status = From; + mailPtr = mailList.first(); + *stream << "HELO there\r\n"; + } else errorHandling(ErrUnknownResponse); + break; + } + case From: { + if (response[0] == '2') { + *stream << "MAIL FROM: <" << mailPtr->from << ">\r\n"; + status = Recv; + } else errorHandling(ErrUnknownResponse); + break; + } + case Recv: { + if (response[0] == '2') { + it = mailPtr->to.begin(); + if (it == NULL) + errorHandling(ErrUnknownResponse); + *stream << "RCPT TO: <" << *it << ">\r\n"; + status = MRcv; + } else errorHandling(ErrUnknownResponse); + break; + } + case MRcv: { + if (response[0] == '2') { + it++; + if ( it != mailPtr->to.end() ) { + *stream << "RCPT TO: <" << *it << ">\r\n"; + break; + } else { + status = Data; + } + } else errorHandling(ErrUnknownResponse); + } + case Data: { + if (response[0] == '2') { + *stream << "DATA\r\n"; + status = Body; + emit updateStatus("Sending: " + mailPtr->subject); + } else errorHandling(ErrUnknownResponse); + break; + } + case Body: { + if (response[0] == '3') { + *stream << mailPtr->body << "\r\n.\r\n"; + mailPtr = mailList.next(); + if (mailPtr != NULL) { + status = From; + } else { + status = Quit; + } + } else errorHandling(ErrUnknownResponse); + break; + } + case Quit: { + if (response[0] == '2') { + *stream << "QUIT\r\n"; + status = Done; + QString temp; + temp.setNum(mailList.count()); + emit updateStatus("Sent " + temp + " messages"); + emit mailSent(); + mailList.clear(); + sending = FALSE; + socket->close(); + } else errorHandling(ErrUnknownResponse); + break; + } + } +} diff --git a/noncore/net/mailit/smtpclient.h b/noncore/net/mailit/smtpclient.h new file mode 100644 index 0000000..ca65af4 --- a/dev/null +++ b/noncore/net/mailit/smtpclient.h @@ -0,0 +1,75 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef SmtpClient_H +#define SmtpClient_H + +//#include +#include +#include +#include +#include +#include +#include + +struct RawEmail +{ + QString from; + QString subject; + QStringList to; + QString body; +}; + +class SmtpClient: public QObject +{ + Q_OBJECT + +public: + SmtpClient(); + ~SmtpClient(); + void newConnection(QString target, int port); + void addMail(QString from, QString subject, QStringList to, QString body); + +signals: + void errorOccurred(int); + void updateStatus(const QString &); + void mailSent(); + +public slots: + void errorHandling(int); + +protected slots: + void connectionEstablished(); + void incomingData(); + +private: + QSocket *socket; + QTextStream *stream; + enum transferStatus + { + Init, From, Recv, MRcv, Data, Body, Quit, Done + }; + int status; + QList mailList; + RawEmail *mailPtr; + bool sending; + QStringList::Iterator it; +}; + +#endif diff --git a/noncore/net/mailit/textparser.cpp b/noncore/net/mailit/textparser.cpp new file mode 100644 index 0000000..f082417 --- a/dev/null +++ b/noncore/net/mailit/textparser.cpp @@ -0,0 +1,294 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "textparser.h" + +TextParser::TextParser(QString in, QString lineBreak) +{ + data = in; + lineSep = lineBreak; + + init(); + createSeparators(); + split(); +} + +TextParser::TextParser(QString in, QString lineBreak, QString sep) +{ + data = in; + lineSep = lineBreak; + + init(); + separators = sep; + split(); +} + +void TextParser::init() +{ + lineCount = 0; + linePos = 0; + totalElmCount = 0; + separatorPos = -1; //not initialized + wordPos = -1; //not initialized + sepAtLine = 0; + sepAtPosElm = -1; //such that nextSep equals 0 + wordAtLine = 0; + wordAtPosElm = -1; //such that nextWord equals 0 + atLine = 0; + atPosElm = 0; +} + +void TextParser::createSeparators() +{ + separators = " @#,.:;<>*/(){}|'?-+=_"; +} + +/* Returns pos of given search criteria, -1 if not found */ +int TextParser::find(QString target, QChar sep, int pos, bool upperCase) +{ + int atLine = 0, atPosElm = 0; + + for (int x = 0; x < totalElmCount; x++) { + if (x >= pos) { + if (upperCase) { + if ((splitDone[atLine].elm[atPosElm].str.upper() == target) && + (splitDone[atLine].elm[atPosElm].separator == sep)) + return x; + } else { + if ((splitDone[atLine].elm[atPosElm].str == target) && + (splitDone[atLine].elm[atPosElm].separator == sep)) + return x; + } + } + atPosElm++; + if (atPosElm >= splitDone[atLine].elmCount) { //new Line + atLine++; + atPosElm = 0; + } + } + + return -1; +} + +int TextParser::elmCount() +{ + return totalElmCount; +} + +QChar TextParser::separatorAt(int pos) +{ + if (getLineReference(pos, &sepAtLine, &sepAtPosElm) == -1) + return QChar::null; + + separatorPos = pos; + return splitDone[sepAtLine].elm[sepAtPosElm].separator; +} + +QChar TextParser::nextSeparator() +{ + sepAtPosElm++; + if (splitDone[sepAtLine].elmCount <= sepAtPosElm) { + sepAtLine++; + sepAtPosElm = 0; + } + + separatorPos++; + return splitDone[sepAtLine].elm[sepAtPosElm].separator; +} + +bool TextParser::hasNextSeparator() +{ + return ((separatorPos+1) < totalElmCount); +} + +QString TextParser::wordAt(int pos) +{ + if (getLineReference(pos, &wordAtLine, &wordAtPosElm) == -1) + return NULL; + + wordPos = pos; + return splitDone[wordAtLine].elm[wordAtPosElm].str; +} + +QString TextParser::nextWord() +{ + wordAtPosElm++; + if (splitDone[wordAtLine].elmCount <= wordAtPosElm) { + wordAtLine++; + wordAtPosElm = 0; + } + + wordPos++; + return splitDone[wordAtLine].elm[wordAtPosElm].str; +} + +bool TextParser::hasNextWord() +{ + return ((wordPos + 1) < totalElmCount); +} + +QString TextParser::getString(int *pos, QChar stop, bool lineEnd = false) +{ + QString returnStr = wordAt(*pos); + QChar chr = separatorAt(*pos); + QString s; + + if (returnStr == "") + return ""; + if (chr == stop) + return returnStr; + + if (!lineEnd) { + while ((chr != stop) && hasNextWord()) { + returnStr.append(chr); + returnStr += nextWord(); + chr = nextSeparator(); + } + } else { //copy from pos to end of line + getLineReference(*pos, &atLine, &atPosElm); + returnStr = ""; + while (atPosElm < splitDone[atLine].elmCount) { + if (splitDone[atLine].elm[atPosElm].str != "") { + returnStr += splitDone[atLine].elm[atPosElm].str; + } + chr = splitDone[atLine].elm[atPosElm].separator; + if (!chr.isNull() && (int) chr != 0) { + returnStr.append(splitDone[atLine].elm[atPosElm].separator); + } + atPosElm++; + } + } + + *pos = wordPos; + return returnStr; +} + +QString TextParser::getNextLine() +{ + atLine++; + atPosElm = 0; + if (atLine < lineCount) + return splitDone[atLine].str; + return ""; +} + +bool TextParser::hasNextLine() +{ + if (atLine+1 < lineCount) + return TRUE;; + return FALSE; +} + +int TextParser::endLinePos(int pos) +{ + if ( (getLineReference(pos, &atLine, &atPosElm)) == -1) + return -1; + + return (pos + (splitDone[atLine].elmCount - atPosElm) + 1); +} + +int TextParser::getLineReference(int pos, int *line, int *inLinePos) +{ + int currentPos = 0; + + for (int x = 0; x < lineCount; x++) { + if ( currentPos + splitDone[x].elmCount > pos) { + *line = x; + *inLinePos = pos - currentPos; + return 0; //pos found okay + } + currentPos += splitDone[x].elmCount; + } + return -1; //no reference found +} + +void TextParser::split() +{ + t_splitLine newLine; + + while ((uint) linePos < data.length()) { + newLine = nextLine(); + splitDone[lineCount] = splitLine(newLine); + totalElmCount += splitDone[lineCount].elmCount; + lineCount++; + } +} + +t_splitLine TextParser::splitLine(t_splitLine line) +{ + uint pos = 0; + uint elmCount = 0; + t_splitLine tempLine = line; + + tempLine.str = line.str.simplifyWhiteSpace(); + tempLine.elm[0].str = ""; + while ( pos < line.str.length() ) { + if ( isSeparator(tempLine.str[pos]) ) { + tempLine.elm[elmCount].separator = tempLine.str[pos]; + elmCount++; + pos++; + while (tempLine.str[pos] == ' ') + pos++; + if (pos > line.str.length()) + elmCount--; + tempLine.elm[elmCount].str = ""; + } else { + if (!tempLine.str[pos].isNull()) + tempLine.elm[elmCount].str += tempLine.str[pos]; + pos++; + } + } + + tempLine.elmCount = elmCount + 1; + return tempLine; +} + +bool TextParser::isSeparator(QChar chr) +{ + for (uint x = 0; x < separators.length(); x++) { + if (chr == separators[x]) + return true; + } + return false; +} + +t_splitLine TextParser::nextLine() +{ + int newLinePos; + t_splitLine lineType; + + newLinePos = data.find(lineSep, linePos); + + lineType.lineType = NewLine; + lineType.str = ""; + + if (newLinePos == -1) { + newLinePos = data.length(); + lineType.lineType = LastLine; + } + + for (int x = linePos; x < newLinePos; x++) + lineType.str += data[x]; + + linePos = newLinePos; + if ((uint) linePos < data.length()) //if not EOF, add length of lineSep + linePos += lineSep.length(); + + return lineType; +} diff --git a/noncore/net/mailit/textparser.h b/noncore/net/mailit/textparser.h new file mode 100644 index 0000000..016effb --- a/dev/null +++ b/noncore/net/mailit/textparser.h @@ -0,0 +1,85 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include + +#ifndef TEXTPARSER_H +#define TEXTPARSER_H + +enum t_strType { Word, Number}; +enum t_lineType {NewLine, LastLine}; + +const uint MAX_ELEMENTS = 200; //Should be dynamic +const uint MAX_LINES = 500; //Should be dynamic + +struct t_splitElm +{ + QChar separator; + int strType; + QString str; +}; + +struct t_splitLine +{ + t_lineType lineType; + QString str; //a bit redundant... + t_splitElm elm[MAX_ELEMENTS]; + int elmCount; +}; + +class TextParser: public QObject +{ + Q_OBJECT + +public: + TextParser(QString in, QString lineBreak); + TextParser(QString in, QString lineBreak, QString sep); + int find(QString target, QChar sep, int pos, bool upperCase); + int elmCount(); + QChar separatorAt(int pos); + QChar nextSeparator(); + bool hasNextSeparator(); + QString wordAt(int pos); + QString nextWord(); + bool hasNextWord(); + QString getString(int *pos, QChar stop, bool lineEnd = false); + QString getNextLine(); + bool hasNextLine(); + int endLinePos(int pos); + +private: + void init(); + void createSeparators(); + t_splitLine nextLine(); + void split(); + t_splitLine splitLine(t_splitLine line); + bool isSeparator(QChar chr); + t_splitLine splitDone[MAX_LINES]; + int getLineReference(int pos, int *line, int *inLinePos); + + int lineCount, linePos, totalElmCount; + int separatorPos, wordPos; + QString data, separators, lineSep; + int sepAtLine, sepAtPosElm; + int wordAtLine, wordAtPosElm; + int atLine, atPosElm; +}; + +#endif diff --git a/noncore/net/mailit/viewatt.cpp b/noncore/net/mailit/viewatt.cpp new file mode 100644 index 0000000..86f119f --- a/dev/null +++ b/noncore/net/mailit/viewatt.cpp @@ -0,0 +1,109 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "resource.h" +#include "viewatt.h" +#include + +ViewAtt::ViewAtt(QWidget *parent, const char *name, WFlags f) + : QMainWindow(parent, name, f) +{ + setCaption("Exploring attatchments"); + + setToolBarsMovable( FALSE ); + bar = new QToolBar(this); + installButton = new QAction( tr( "Install" ), Resource::loadPixmap( "exec" ), QString::null, CTRL + Key_C, this, 0 ); + connect(installButton, SIGNAL(activated()), this, SLOT(install()) ); + + listView = new QListView(this, "AttView"); + listView->addColumn( "Attatchment" ); + listView->addColumn( "Type" ); + listView->addColumn( "Installed" ); + setCentralWidget(listView); +} + +void ViewAtt::update(Email *mailIn, bool inbox) +{ + QListViewItem *item; + Enclosure *ePtr; + + listView->clear(); + if (inbox) { + bar->clear(); + installButton->addTo( bar ); + bar->show(); + } else { + bar->hide(); + } + + mail = mailIn; + for ( ePtr=mail->files.first(); ePtr != 0; ePtr=mail->files.next() ) { + + QString isInstalled = "No"; + if (ePtr->installed) + isInstalled = "Yes"; + item = new QListViewItem(listView, ePtr->originalName, ePtr->contentType, isInstalled); + + if (ePtr->contentType == "TEXT") { + actions = new QAction( tr("View"), Resource::loadPixmap("TextEditor"), QString::null, CTRL + Key_C, this, 0); + actions->addTo(bar); + item->setPixmap(0, Resource::loadPixmap("txt")); + } + if (ePtr->contentType == "AUDIO") { + actions = new QAction( tr("Play"), Resource::loadPixmap("SoundPlayer"), QString::null, CTRL + Key_C, this, 0); + actions->addTo(bar); + item->setPixmap(0, Resource::loadPixmap("play")); + } + if (ePtr->contentType == "IMAGE") { + actions = new QAction( tr("Show"), Resource::loadPixmap("pixmap"), QString::null, CTRL + Key_C, this, 0); + actions->addTo(bar); + item->setPixmap(0, Resource::loadPixmap("pixmap")); + } + } +} + +void ViewAtt::install() +{ + Enclosure *ePtr, *selPtr; + QListViewItem *item; + QString filename; + DocLnk d; + + item = listView->selectedItem(); + if (item != NULL) { + filename = item->text(0); + selPtr = NULL; + for ( ePtr=mail->files.first(); ePtr != 0; ePtr=mail->files.next() ) { + if (ePtr->originalName == filename) + selPtr = ePtr; + } + + if (selPtr == NULL) { + qWarning("Internal error, file is not installed to documents"); + return; + } + + d.setName(selPtr->originalName); + d.setFile(selPtr->path + selPtr->name); + d.setType(selPtr->contentType + "/" + selPtr->contentAttribute); + d.writeLink(); + selPtr->installed = TRUE; + item->setText(2, "Yes"); + } +} diff --git a/noncore/net/mailit/viewatt.h b/noncore/net/mailit/viewatt.h new file mode 100644 index 0000000..9e43407 --- a/dev/null +++ b/noncore/net/mailit/viewatt.h @@ -0,0 +1,46 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef VIEWATT_H +#define VIEWATT_H + +#include +#include +#include +#include +#include "emailhandler.h" + +class ViewAtt : public QMainWindow +{ + Q_OBJECT + +public: + ViewAtt(QWidget *parent = 0, const char *name = 0, WFlags f = 0); + void update(Email *mailIn, bool inbox); + +public slots: + void install(); + +private: + QListView *listView; + QToolBar *bar; + QAction *installButton, *actions; + Email *mail; +}; +#endif diff --git a/noncore/net/mailit/writemail.cpp b/noncore/net/mailit/writemail.cpp new file mode 100644 index 0000000..1a7185e --- a/dev/null +++ b/noncore/net/mailit/writemail.cpp @@ -0,0 +1,299 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include +#include "writemail.h" +#include "resource.h" + +WriteMail::WriteMail( QWidget* parent, const char* name, WFlags fl ) + : QMainWindow( parent, name, fl ) +{ + showingAddressList = FALSE; + init(); + + addAtt = new AddAtt(0, "Add Attatchments"); +} + +WriteMail::~WriteMail() +{ + delete addAtt; +} + +void WriteMail::setAddressList(AddressList *list) +{ + Contact *cPtr; + + addressList = list; + + addressView->clear(); + QList *cListPtr = addressList->getContactList(); + QListViewItem *item; + for (cPtr = cListPtr->first(); cPtr != 0; cPtr = cListPtr->next() ) { + item = new QListViewItem(addressView, cPtr->email, cPtr->name); + } +} + +void WriteMail::init() +{ + setToolBarsMovable(FALSE); + + bar = new QToolBar(this); + bar->setHorizontalStretchable( TRUE ); + + menu = new QMenuBar( bar ); + + mailMenu = new QPopupMenu(menu); + menu->insertItem( tr( "&Mail" ), mailMenu); + addMenu = new QPopupMenu(menu); + menu->insertItem( tr( "&Add" ), addMenu); + + bar = new QToolBar(this); + attatchButton = new QAction(tr("Attatchment"), Resource::loadPixmap("fileopen"), QString::null, 0, this, 0); + attatchButton->addTo(bar); + attatchButton->addTo(addMenu); + connect( attatchButton, SIGNAL( activated() ), this, SLOT( attatchFile() ) ); + + confirmButton = new QAction(tr("Enque mail"), Resource::loadPixmap("OKButton"), QString::null, 0, this, 0); + confirmButton->addTo(bar); + confirmButton->addTo(mailMenu); + connect( confirmButton, SIGNAL( activated() ), this, SLOT( accept() ) ); + + newButton = new QAction(tr("New mail"), Resource::loadPixmap("new"), QString::null, 0, this, 0); + newButton->addTo(mailMenu); + connect( newButton, SIGNAL( activated() ), this, SLOT( newMail() ) ); + + widget = new QWidget(this, "widget"); + grid = new QGridLayout( widget ); + + recipientsBox = new QComboBox( FALSE, widget, "toLabel" ); + recipientsBox->insertItem( tr( "To:" ) ); + recipientsBox->insertItem( tr( "CC:" ) ); + recipientsBox->setCurrentItem(0); + grid->addWidget( recipientsBox, 0, 0 ); + + subjetLabel = new QLabel( widget, "subjetLabel" ); + subjetLabel->setText( tr( "Subject:" ) ); + + grid->addWidget( subjetLabel, 1, 0 ); + + ToolButton13_2 = new QToolButton( widget, "ToolButton13_2" ); + ToolButton13_2->setText( tr( "..." ) ); + grid->addWidget( ToolButton13_2, 1, 2 ); + + subjectInput = new QLineEdit( widget, "subjectInput" ); + grid->addWidget( subjectInput, 1, 1 ); + + toInput = new QLineEdit( widget, "toInput" ); + grid->addWidget( toInput, 0, 1 ); + + addressButton = new QToolButton( widget, "addressButton" ); + addressButton->setPixmap( Resource::loadPixmap("AddressBook") ); + addressButton->setToggleButton(TRUE); + grid->addWidget( addressButton, 0, 2 ); + connect(addressButton, SIGNAL(clicked()), this, SLOT(getAddress()) ); + + emailInput = new QMultiLineEdit( widget, "emailInput" ); + grid->addMultiCellWidget( emailInput, 2, 2, 0, 2); + + addressView = new QListView( widget, "addressView"); + addressView->addColumn("Email"); + addressView->addColumn("Name"); + addressView->setAllColumnsShowFocus(TRUE); + addressView->setMultiSelection(TRUE); + addressView->hide(); + grid->addMultiCellWidget( addressView, 3, 3, 0, 2); + + okButton = new QToolButton(bar, "ok"); + okButton->setPixmap( Resource::loadPixmap("enter") ); + okButton->hide(); + connect(okButton, SIGNAL(clicked()), this, SLOT(addRecipients()) ); + + setCentralWidget(widget); +} + +void WriteMail::reject() +{ + emit cancelMail(); +} + +// need to insert date +void WriteMail::accept() +{ + QStringList attatchedFiles, attatchmentsType; + int idCount = 0; + + if (toInput->text() == "") { + QMessageBox::warning(this,"No recipient", "Send mail to whom?", "OK\n"); + return; + } + if (! getRecipients() ) { + QMessageBox::warning(this,"Incorrect recipient separator", + "Recipients must be separated by ;\nand be valid emailaddresses", "OK\n"); + return; + } + mail.subject = subjectInput->text(); + mail.body = emailInput->text(); + mail.sent = false; + mail.received = false; + mail.rawMail = "To: "; + + for (QStringList::Iterator it = mail.recipients.begin(); + it != mail.recipients.end(); ++it) { + + mail.rawMail += (*it); + mail.rawMail += ",\n"; + } + mail.rawMail.truncate(mail.rawMail.length()-2); + mail.rawMail += mail.from; + mail.rawMail += "\nSubject: "; + mail.rawMail += mail.subject; + mail.rawMail += "\n\n"; + + attatchedFiles = addAtt->returnAttatchedFiles(); + attatchmentsType = addAtt->returnFileTypes(); + + QStringList::Iterator itType = attatchmentsType.begin(); + + Enclosure e; + for ( QStringList::Iterator it = attatchedFiles.begin(); + it != attatchedFiles.end(); ++it ) { + + e.id = idCount; + e.originalName = (*it).latin1(); + e.contentType = (*itType).latin1(); + e.contentAttribute = (*itType).latin1(); + e.saved = TRUE; + mail.addEnclosure(&e); + + itType++; + idCount++; + } + mail.rawMail += mail.body; + mail.rawMail += "\n"; + mail.rawMail += ".\n"; + emit sendMailRequested(mail); + addAtt->clear(); +} + +void WriteMail::getAddress() +{ + showingAddressList = !showingAddressList; + + if (showingAddressList) { + emailInput->hide(); + addressView->show(); + okButton->show(); + + } else { + addressView->hide(); + okButton->hide(); + emailInput->show(); + } +} + +void WriteMail::attatchFile() +{ + addAtt->showMaximized(); +} + +void WriteMail::reply(Email replyMail) +{ + int pos; + + mail = replyMail; + mail.files.clear(); + + toInput->setText(mail.fromMail); + subjectInput->setText("Re: " + mail.subject); + + pos = 0; + mail.body.insert(pos, ">>"); + while (pos != -1) { + pos = mail.body.find('\n', pos); + if (pos != -1) + mail.body.insert(++pos, ">>"); + } + + emailInput->setText(mail.body); +} + +bool WriteMail::getRecipients() +{ + QString str, temp; + int pos = 0; + + mail.recipients.clear(); + + temp = toInput->text(); + while ( (pos = temp.find(';')) != -1) { + str = temp.left(pos).stripWhiteSpace(); + temp = temp.right(temp.length() - (pos + 1)); + if ( str.find('@') == -1) + return false; + mail.recipients.append(str); + addressList->addContact(str, ""); + } + temp = temp.stripWhiteSpace(); + if ( temp.find('@') == -1) + return false; + mail.recipients.append(temp); + addressList->addContact(temp, ""); + + return TRUE; +} + + +void WriteMail::addRecipients() +{ + QString recipients = ""; + + mail.recipients.clear(); + QListViewItem *item = addressView->firstChild(); + while (item != NULL) { + if ( item->isSelected() ) { + if (recipients == "") { + recipients = item->text(0); + } else { + recipients += "; " + item->text(0); + } + } + item = item->nextSibling(); + } + toInput->setText(recipients); + + addressView->hide(); + okButton->hide(); + emailInput->show(); + addressButton->setOn(FALSE); + showingAddressList = !showingAddressList; +} + +void WriteMail::setRecipient(const QString &recipient) +{ + toInput->setText(recipient); +} + +void WriteMail::newMail() +{ + toInput->clear(); + subjectInput->clear(); + emailInput->clear(); + //to clear selected + setAddressList(addressList); +} diff --git a/noncore/net/mailit/writemail.h b/noncore/net/mailit/writemail.h new file mode 100644 index 0000000..dd12063 --- a/dev/null +++ b/noncore/net/mailit/writemail.h @@ -0,0 +1,91 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qt Palmtop Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef WRITEMAIL_H +#define WRITEMAIL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "emailhandler.h" +#include "addresslist.h" +#include "addatt.h" + +class WriteMail : public QMainWindow +{ + Q_OBJECT + +public: + WriteMail( QWidget* parent, const char* name, WFlags fl = 0 ); + ~WriteMail(); + void reply(Email replyMail); + void setRecipient(const QString &recipient); + void setAddressList(AddressList *list); + +signals: + void sendMailRequested(const Email &mail); + void cancelMail(); + +public slots: + void getAddress(); + void attatchFile(); + void addRecipients(); + void newMail(); + void accept(); + void reject(); + +private: + bool getRecipients(); + void init(); + + Email mail; + AddAtt *addAtt; + AddressList *addressList; + bool showingAddressList; + + QToolBar *bar; + QMenuBar *menu; + QPopupMenu *addMenu, *mailMenu; + QListView *addressView; + + QToolButton *okButton; + QWidget *widget; + QAction *attatchButton; + QAction *confirmButton; + QAction *newButton; + QLabel* subjetLabel; + QToolButton* ToolButton13_2; + QComboBox* recipientsBox; + QLineEdit *subjectInput; + QLineEdit *toInput; + QToolButton* addressButton; + QMultiLineEdit* emailInput; + QGridLayout* grid; +}; + +#endif // WRITEMAIL_H -- cgit v0.9.0.2