diff --git a/karchie/KArchie.cpp b/karchie/KArchie.cpp index dc9e86f3..13f92445 100644 --- a/karchie/KArchie.cpp +++ b/karchie/KArchie.cpp @@ -1,857 +1,857 @@ /*************************************************************************** * KArchie.cpp * * ------------------- * * Source file for KArchie * * -A programm to display archie queries * * * * KArchie is written for the KDE-Project * * http://www.kde.org * * * * Copyright (C) Oct 1997 Jörg Habenicht * * E-Mail: j.habenicht@europemail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * ***************************************************************************/ #include //#include "KArchie.h" #include "KArchie.moc" #include "KAMenu.h" #include "KAStatusBar.h" #include "KASettings.h" #include "KASettingsTypes.h" #include "KAView.h" #include "KAQuery.h" #include "KAQueryFile.h" #include #include #include #include #include #include #include #include -#define KFM_WINDOW "kfmclient" +#define KFM_WINDOW "kfmclient1" #define KFM_OPEN_URL "openURL" TmpOpenFile::~TmpOpenFile() { } KArchie::KArchie(const char *name) : KTopLevelWidget (name), queryResult( 0 )//, downloadTmpFileList( 0 ) { setMinimumSize(420,200); config = KApplication::getKApplication()->getConfig(); QString currenthost; QStrList archiehostlist; // int archiehostlistnumber = KConfigGroupSaver *saveGroup = new KConfigGroupSaver( config, "HostConfig" ); config->readListEntry( "Hosts", archiehostlist ); // QString currenthost = config->readEntry( "CurrentHost", "archie.sura.net" ); uint currentHostId = config->readUnsignedNumEntry( "CurrentHostId", 0 ); QString defaulthost = "archie.sura.net" ; if ( archiehostlist.isEmpty() ) { archiehostlist.append( defaulthost ); currentHostId = 0; // archiehostlistnumber++; } else if (archiehostlist.count() < currentHostId) { currentHostId = 0; } currenthost = archiehostlist.at(currentHostId); // config->setGroup( ConfigEntries::HostConfigGroup ); // currenthost = config->readEntry( ConfigEntries::CurrentHostEntry, // ConfigEntries::CurrentHostDefault ); // debug("setup menu"); menu = new KAMenu( this, "mainmenu" ); setMenu( menu ); connect( menu, SIGNAL(sigSettingsAll()), this, SLOT(slotChangeSettings()) ); connect( menu, SIGNAL(sigFileOpen()), this, SLOT(slotOpenFileSelected()) ); connect( menu, SIGNAL(sigFileOpenDir()), this, SLOT(slotOpenDirSelected()) ); connect( menu, SIGNAL(sigFileGet()), this, SLOT(slotGetfileSelected()) ); connect( menu, SIGNAL(sigFileLoadList()), this, SLOT(slotLoadfilelistSelected()) ); connect( menu, SIGNAL(sigFileStoreList()), this, SLOT(slotStorefilelistSelected()) ); connect( menu, SIGNAL(sigFileWriteList()), this, SLOT(slotWritefilelistSelected()) ); connect( menu, SIGNAL(sigQueryFile()), this, SLOT(slotSearchFile()) ); connect( menu, SIGNAL(sigQueryPath()), this, SLOT(slotSearchPath()) ); connect( menu, SIGNAL(sigQueryHost()), this, SLOT(slotSearchHost()) ); connect( menu, SIGNAL(sigSortHostname()), this, SLOT(slotSortListHostname()) ); connect( menu, SIGNAL(sigSortDomain()), this, SLOT(slotSortListDomain()) ); connect( menu, SIGNAL(sigSortDate()), this, SLOT(slotSortListDate()) ); connect( menu, SIGNAL(sigSortFilesize()), this, SLOT(slotSortListFilesize()) ); menu->show(); menu->setFileGetEnable( FALSE ); menu->setFileOpenEnable( FALSE ); menu->setFileOpenDirEnable( FALSE ); menu->setFileStoreListEnable( FALSE ); menu->setFileWriteListEnable( FALSE ); menu->setSortEnable( FALSE ); // debug("setup statusbar"); statbar = new KAStatusBar( this, "statusbar" ); setStatusBar( statbar ); statbar->slotChangeHost( currenthost ); statbar->show(); connect( menu, SIGNAL(sigArchieHost(const char *)), statbar, SLOT(slotChangeHost(const char *)) ); delete saveGroup; saveGroup = new KConfigGroupSaver( config, "WindowConfig" ); // debug( "setup view" ); view = new KAView( this, "view" ); setView( view ); // view->slotShowFileDiscriptor(config->readBoolEntry("FAttr", true)); view->show(); connect( menu, SIGNAL(sigSettingsShowFileDiscription( bool )), view, SLOT(slotShowFileDiscriptor( bool )) ); connect( &(view->getSearchterm()), SIGNAL(sigTextSelected()), SLOT(slotSearchFile()) ); connect( &(view->getList()), SIGNAL(sigOpenFileSelected()), SLOT(slotOpenFileSelected()) ); connect( &(view->getList()), SIGNAL(sigOpenDirSelected()), SLOT(slotOpenDirSelected()) ); connect( &(view->getList()), SIGNAL(sigGetFileSelected()), SLOT(slotGetfileSelected()) ); show(); // changeSettings(); delete saveGroup; } KArchie::~KArchie() { delete menu; delete statbar; delete view; if (queryResult){ // alte Liste loeschen queryResult->setAutoDelete(TRUE); delete queryResult; } /* if (downloadTmpFileList) { downloadTmpFileList->setAutoDelete(TRUE); delete downloadTmpFileList; }*/ // delete config; } void KArchie::slotChangeSettings() { // debug( "KArchie::slotChangeSettings request" ); changeSettings(); } void KArchie::slotSearchFile() { //debug("KArchie::slotSearchFile"); slotQuerySearch('f'); } void KArchie::slotSearchPath() { slotQuerySearch('p'); } void KArchie::slotSearchHost() { slotQuerySearch('h'); } void KArchie::slotQuerySearch(char type) { // debug("KArchie::slotQuerySearch"); QStrList archiehostlist; KConfigGroupSaver *saveGroup = new KConfigGroupSaver( config, "HostConfig" ); config->readListEntry( "Hosts", archiehostlist ); uint currentHostId = config->readUnsignedNumEntry( "CurrentHostId", 0 ); QString defaulthost = "archie.sura.net" ; if ( archiehostlist.isEmpty() ) { archiehostlist.append( defaulthost ); currentHostId = 0; // archiehostlistnumber++; } else if (archiehostlist.count() < currentHostId) { currentHostId = 0; } QString host(archiehostlist.at(currentHostId)); int retries = config->readNumEntry("Retries", CLIENT_DIRSRV_RETRY); int timeout = config->readNumEntry("Timeout", CLIENT_DIRSRV_TIMEOUT); delete saveGroup; saveGroup = new KConfigGroupSaver( config, "SearchConfig" ); const QString searchInput = config->readEntry("Search", "="); SearchMode searchmode(((const char*)searchInput)[0]); NiceLevel nicelevel = NiceLevel::toLevel(config->readNumEntry("Nice", (int)NiceLevel::norm)); int maxhits = config->readNumEntry("hits", CLIENT_MAX_HITS); delete saveGroup; // debug( host ); QString search; switch (type) { case 'p': search = "path"; break; case 'h': search = "host"; break; case 'f': // fall through default: search = "file"; break; } // debug( search ); query = new KAQuery((const char *)host, view->getSearchterm().getText(), searchmode.getMode(), maxhits, retries, nicelevel.getLevel(), timeout); connect( query, SIGNAL(sigQueryRunning()), menu, SLOT(slotQueryBegin()) ); connect( query, SIGNAL(sigQueryFinished()), menu, SLOT(slotQueryEnd()) ); connect( query, SIGNAL(sigQueryStatus(const char *)), statbar, SLOT(slotChangeStatus(const char *)) ); connect( query, SIGNAL(sigQueryTryNum(int)), statbar, SLOT(slotChangeTries(int)) ); connect( query, SIGNAL(sigQueryResults(int)), statbar, SLOT(slotChangeHits(int)) ); connect ( query, SIGNAL(sigQueryFinished()), this, SLOT(slotReturnQuery()) ); connect ( menu, SIGNAL(sigQueryStop()), query, SLOT(slotAbort()) ); // start periodic windowupdates // startTimer(1000); QString tmp(search + " query start"); statbar->slotChangeStatus( tmp ); // start timer for doing other things while querying queryTimer = startTimer(300); query->start(); /* if (bSuccess) { if (queryResult){ // alte Liste loeschen queryResult->setAutoDelete(TRUE); delete queryResult; } statbar->slotChangeStatus( "Success" ); debug("getfilelist"); queryResult = &(query->getFileList()); statbar->slotChangeHits( queryResult->count() ); debug("displayfilelist"); view->newFileList( *queryResult ); bool listitemhighlighted = -1 != view->getList().currentItem(); menu->setFileOpenEnable( listitemhighlighted ); menu->setFileOpenDirEnable( listitemhighlighted ); menu->setFileGetEnable( listitemhighlighted ); menu->setFileWriteListEnable( view->getList().count > 0 ); } else { // print status on SLine const char *cError = query->getError(); debug( cError ); statbar->slotChangeStatus( cError ); statbar->slotChangeHits( 0 ); // no changes to the view->viewlist // so we dont change the filemenu } // killTimers(); // if there is an old list from previous queries // enable/disable the file->get menu // QString tmp; // tmp.setNum( view->getList().currentItem() ); // tmp += " current list item"; // debug( tmp ); debug("ready"); delete query; */ } void KArchie::slotOpenFileSelected() { QString downloadfile; /* if (!downloadTmpFileList) { downloadTmpFileList = new TmpOpenFileList; }*/ // KProcess *process = new KProcess; // debug ("file open"); - KURL url("file:/usr/local/kde/bin/kfmclient"); + KURL url("file:/usr/local/kde/bin/kfmclient1"); openFile(url); } void KArchie::slotOpenDirSelected() { // debug ("dir open"); // KURL url("file:/usr/local/kde/"); // openDir(url); const KAQueryFile *file = checkViewSelection(); if (file) { slotOpenDirSelected(file); } } void KArchie::slotGetfileSelected() { const KAQueryFile *file = checkViewSelection(); if (file) { slotGetfileSelected(file); } } void KArchie::slotOpenFileSelected(const KAQueryFile *file) { KURL url; if (checkFtpFile(url,file)) openFile(url); } void KArchie::slotOpenDirSelected(const KAQueryFile *file) { KURL url; if (checkFtpPath(url,file)) openDir(url); } void KArchie::slotGetfileSelected(const KAQueryFile *file) { KURL url; if (checkFtpFile(url,file)) getFile( url ); } void KArchie::slotLoadfilelistSelected() { QString loadfile = KFileDialog::getOpenFileName( 0, "*", this ); if ( !loadfile.isEmpty() ) { // datei oeffnen die Liste abspeichern KAQueryFile *qrfile; QFile file(loadfile); if ( file.open(IO_ReadOnly)) { int i, count; // = queryResult->count(); QDataStream data(&file); data >> count; //debug("loading %i items", count); //debug("queryResult is %ld", (long)queryResult); if ( queryResult ) { //debug("enable autodelete querylist"); queryResult->setAutoDelete( TRUE ); //debug("deleting querylist"); delete queryResult; } queryResult = new KAQueryList; for ( i=0; iat()); // qrfile = queryResult->at(i); qrfile = new KAQueryFile; data >> *qrfile; //debug ("Item %s%s%s", (const char *)qrfile->getHost(), (const char *)qrfile->getPath(), (const char *)qrfile->getFile()); queryResult->append(qrfile); } file.close(); //debug("put new filelist"); view->newFileList(*queryResult); //debug("setting menu:"); if (view->getList().count() > 0) { // list contains items //debug("\tsetstore"); menu->setFileStoreListEnable( TRUE ); //debug("\tsetwrite"); menu->setFileWriteListEnable( TRUE ); //debug("\tsetsort"); menu->setSortEnable( TRUE ); if (-1 != view->getList().currentItem()) { // list has item selected/highlighted //debug("\tsetopen"); menu->setFileOpenEnable( TRUE ); //debug("\tsetopendir"); menu->setFileOpenDirEnable( TRUE ); //debug("\tsetget"); menu->setFileGetEnable( TRUE ); } } //debug ("loading ready"); } else { QString errstr = i18n("Couldn't open \n\"%s\""); QString tmp(loadfile.length() + errstr.length() + 1); tmp.sprintf((const char *)errstr, (const char *)loadfile); warning("%s", (const char *)tmp); KMsgBox::message( this, i18n("KArchie: bad file"), tmp, KMsgBox::EXCLAMATION, i18n("OK") ); } } } void KArchie::slotStorefilelistSelected() { if ( !queryResult ) return; QString storefile = KFileDialog::getSaveFileName( 0, "*", this ); if ( !storefile.isEmpty() ) { if (!checkSaveFile(storefile)) return; // please don't overwrite // datei oeffnen die Liste abspeichern KAQueryFile *qrfile; QFile file(storefile); int count = queryResult->count(); if ( file.open(IO_WriteOnly | IO_Truncate)) { QDataStream data(&file); data << count; for ( qrfile = queryResult->first(); qrfile; qrfile = queryResult->next() ) { // fprintf(stderr,"[%i] ", queryResult->at()); // qrfile = queryResult->at(i); data << *qrfile; } file.close(); } else { QString errstr = i18n("Couldn't open \n\"%s\""); QString tmp(storefile.length() + errstr.length() + 1); tmp.sprintf((const char *)errstr, (const char *)storefile); warning("%s", (const char *)tmp); KMsgBox::message( this, i18n("KArchie: bad file"), tmp, KMsgBox::EXCLAMATION, i18n("OK") ); } } } void KArchie::slotWritefilelistSelected() { if ( !queryResult ) return; QString savefile = KFileDialog::getSaveFileName( 0, "*.txt", this ); if ( !savefile.isEmpty() ) { if (!checkSaveFile(savefile)) return; // please don't overwrite // datei oeffnen die Liste abspeichern KAQueryFile *qrfile; ofstream file(savefile); int i, count = queryResult->count(); for ( i=0; iat()); qrfile = queryResult->at(i); file << qrfile->getHost() << qrfile->getPath() << qrfile->getFile() << endl; } file.close(); } } void KArchie::slotSortListHostname() { // mache eine neue Liste aus der alten // und gib sie der Viewlist zur Darstellung. // danach löschen. if (queryResult) { KAHostList *sortList = new KAHostList; KAQueryFile *file; int i, count = queryResult->count(); for ( i=0; iat( i ); // binaer einsortieren sortList->inSort( file ); } KAQueryList *tmp = queryResult; queryResult = sortList; tmp->setAutoDelete(FALSE); delete tmp; view->newFileList( *sortList ); } } void KArchie::slotSortListDomain() { if (queryResult) { KADomainList *sortList = new KADomainList; KAQueryFile *file; int i, count = queryResult->count(); for ( i=0; iat( i ); // binaer einsortieren sortList->inSort( file ); } KAQueryList *tmp = queryResult; queryResult = sortList; tmp->setAutoDelete(FALSE); delete tmp; view->newFileList( *sortList ); } } void KArchie::slotSortListDate() { if (queryResult) { KADateList *sortList = new KADateList; KAQueryFile *file; int i, count = queryResult->count(); for ( i=0; iat( i ); // binaer einsortieren sortList->inSort( file ); } KAQueryList *tmp = queryResult; queryResult = sortList; tmp->setAutoDelete(FALSE); delete tmp; view->newFileList( *sortList ); } } void KArchie::slotSortListFilesize() { if (queryResult) { KASizeList *sortList = new KASizeList; KAQueryFile *file; int i, count = queryResult->count(); for ( i=0; iat( i ); // binaer einsortieren sortList->inSort( file ); } KAQueryList *tmp = queryResult; queryResult = sortList; tmp->setAutoDelete(FALSE); delete tmp; view->newFileList( *sortList ); } } void KArchie::timerEvent( QTimerEvent * ) { // repaint(); // statbar->slotChangeHits(query->getProcessedResults()); } void KArchie::changeSettings() { KASettings *dialog = new KASettings( this, "setup", TRUE ); // connect(dialog, SIGNAL(applyButtonPressed()), menu, SLOT(slotConfigChanged()) ); // dialog->setMinimumSize( 520, 460 ); if (dialog->exec()) { statbar->slotConfigChanged(); menu->slotConfigChanged(); } delete dialog; } void KArchie::getFile(const KURL &url) { KURL myurl(url); QString tmp; tmp = "./"; tmp += myurl.filename(); QString savefile = KFileDialog::getSaveFileName( tmp, 0, this ); if ( !savefile.isEmpty() ) { if (!checkSaveFile(savefile)) return; // please don't overwrite // ok, lets copy ftp://url to file://savefile KFM kfm; QString tmp( "file://" ); tmp += savefile; kfm.copy( url.url(), tmp ); } } void KArchie::openFile(const KURL &url) { // currently doesn't work KFM kfm; kfm.openURL(url.url()); } void KArchie::openDir(const KURL &url) { // Prozess erstellen KProcess p; // .. mit Daten fuettern // debug("starting process: %s %s %s", KFM_WINDOW, KFM_OPEN_URL, (const char*)url.url()); p << KFM_WINDOW << KFM_OPEN_URL << (const char*)url.url(); // .. und durchstarten p.start(KProcess::DontCare, KProcess::NoCommunication); // hoping the process is still running, when I get out of here } bool KArchie::checkFtpFile(KURL &url, const KAQueryFile *file) { QString tmpstr("ftp://"); tmpstr += file->getHost(); tmpstr += file->getPath(); tmpstr += file->getFile(); // make an url of the data and check for correctness url = tmpstr; return checkUrl(url); } bool KArchie::checkFtpPath(KURL &url, const KAQueryFile *file) { QString tmpstr("ftp://"); tmpstr += file->getHost(); tmpstr += file->getPath(); // tmpstr += file->getFile(); // make an url of the data and check for correctness url = tmpstr; return checkUrl(url); } bool KArchie::checkFtpHost(KURL &url, const KAQueryFile *file) { QString tmpstr("ftp://"); tmpstr += file->getHost(); // tmpstr += file->getPath(); // tmpstr += file->getFile(); // make an url of the data and check for correctness url = tmpstr; return checkUrl(url); } bool KArchie::checkUrl(const KURL &url) { if (url.isMalformed() ) { QString tmp( i18n("Malformed url")); tmp += "\n\""; tmp += url.url(); tmp += "\"\n"; tmp += i18n("Maybe bad list entry, please select an other file"); KMsgBox::message( this, i18n("KArchie: bad URL"), tmp, KMsgBox::EXCLAMATION, i18n("OK") ); return FALSE; } return TRUE; } bool KArchie::checkSaveFile(QString filename) { QFileInfo file(filename); if (!file.exists()) { return TRUE; // Datei nicht vorhanden: kann angelegt werden. } // file exists.. if (!file.isWritable()) { KMsgBox::message(this, i18n("KArchie: Wrong fileselection"), i18n("The selected file is not writeable"), KMsgBox::EXCLAMATION, i18n("OK")); return FALSE; } // file exists AND is writeable -> ask for permission return (2 == KMsgBox::yesNo(this, i18n("KArchie: Overwrite file ?"), i18n("The selected file is not write protected\n" "Should it be overwritten ?"), KMsgBox::QUESTION, i18n("No"), i18n("Yes"))); } const KAQueryFile * KArchie::checkViewSelection() { // get the selected file from the viewlist int selected = view->getList().currentItem(); if (-1 == selected) { KMsgBox::message( this, i18n("KArchie: bad selection"), i18n("No file selected !\n" "Please select a file in the list of queryresults\n" "or do a query."), KMsgBox::EXCLAMATION, i18n("OK") ); return 0; } // get the fileentry from the filelist // KAQueryFile *file = return queryResult->at( selected ); } void KArchie::slotReturnQuery() { // no need to look for queryhits anymore killTimer(queryTimer); if (query->getSuccess()) { setCaption("KArchie - "+query->getSearchString()); if (queryResult){ // alte Liste loeschen queryResult->setAutoDelete(TRUE); delete queryResult; } statbar->slotChangeStatus( i18n("Success") ); // debug("getfilelist"); queryResult = &(query->getFileList()); statbar->slotChangeHits( queryResult->count() ); // debug("displayfilelist"); view->newFileList( *queryResult ); if (view->getList().count() > 0) { // list contains items menu->setFileStoreListEnable( TRUE ); menu->setFileWriteListEnable( TRUE ); menu->setSortEnable( TRUE ); if (-1 != view->getList().currentItem()) { // list has item selected/highlighted menu->setFileOpenEnable( TRUE ); menu->setFileOpenDirEnable( TRUE ); menu->setFileGetEnable( TRUE ); } } } else { // print status on SLine const char *cError = query->getError(); debug( cError ); statbar->slotChangeStatus( cError ); statbar->slotChangeHits( 0 ); // no changes to the view->viewlist // so we dont change the filemenu } // killTimers(); // if there is an old list from previous queries // enable/disable the file->get menu // QString tmp; // tmp.setNum( view->getList().currentItem() ); // tmp += " current list item"; // debug( tmp ); // debug("ready"); delete query; query = 0; } /************************MAIN****************************/ int main (int argc, char **argv) { KApplication *archie; KArchie *window; // set main application // debug("setup application"); archie = new KApplication(argc, argv,"karchie"); //archie->setFont(QFont("Helvetica",12),true); // debug("setup window"); window = new KArchie("main"); archie->setMainWidget( window ); window->setCaption("KArchie"); // debug("goto event loop"); return archie->exec(); } diff --git a/kmail/kmmainwin.cpp b/kmail/kmmainwin.cpp index c44a233d..36f9b559 100644 --- a/kmail/kmmainwin.cpp +++ b/kmail/kmmainwin.cpp @@ -1,1248 +1,1248 @@ // kmmainwin.cpp #include #include "kmfoldermgr.h" #include "kmsettings.h" #include "kmfolderdia.h" #include "kmaccount.h" #include "kmacctmgr.h" #include "kbusyptr.h" #include "kmmessage.h" #include "kmfoldertree.h" #include "kmheaders.h" #include "kmreaderwin.h" #include "kmfolder.h" #include "kmmessage.h" #include "kmcomposewin.h" #include "kmglobal.h" #include "kmfolderseldlg.h" #include "kmfiltermgr.h" #include "kmsender.h" #include "kmaddrbookdlg.h" #include "kmaddrbook.h" #include "kwm.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kmmainwin.moc" //----------------------------------------------------------------------------- KMMainWin::KMMainWin(QWidget *, char *name) : KMMainWinInherited(name) { int idx; // must be the first line of the constructor: mStartupDone = FALSE; mIntegrated = TRUE; mFolder = NULL; setMinimumSize(400, 300); readPreConfig(); createWidgets(); readConfig(); activatePanners(); setupMenuBar(); setupToolBar(); setupStatusBar(); // set active folder to `inbox' folder idx = mFolderTree->indexOfFolder(inboxFolder); if (idx>=0) mFolderTree->setCurrentItem(idx); connect(msgSender, SIGNAL(statusMsg(const char*)), SLOT(statusMsg(const char*))); connect(acctMgr, SIGNAL( newMail(KMAccount *)), SLOT( slotNewMail(KMAccount *))); // must be the last line of the constructor: mStartupDone = TRUE; } //----------------------------------------------------------------------------- KMMainWin::~KMMainWin() { //debug("~KMMainWin()"); writeConfig(); if (mHeaders) delete mHeaders; if (mToolBar) delete mToolBar; if (mMenuBar) delete mMenuBar; if (mStatusBar) delete mStatusBar; } //----------------------------------------------------------------------------- void KMMainWin::readPreConfig(void) { KConfig *config = app->getConfig(); QString str; config->setGroup("Geometry"); mLongFolderList = config->readBoolEntry("longFolderList", false); } //----------------------------------------------------------------------------- void KMMainWin::readConfig(void) { KConfig *config = app->getConfig(); bool oldLongFolderList=false; int w, h, folderIdx=0; QString str; if (mStartupDone) { folderIdx = mFolderTree->currentItem(); writeConfig(); oldLongFolderList = mLongFolderList; readPreConfig(); if (oldLongFolderList != mLongFolderList) { hide(); if (mHorizPanner->parent()==this) delete mHorizPanner; else delete mVertPanner; readPreConfig(); createWidgets(); } } config->setGroup("Geometry"); str = config->readEntry("MainWin", "300,600"); if (!str.isEmpty() && str.find(',')>=0) { sscanf(str,"%d,%d",&w,&h); resize(w,h); } str = config->readEntry("Panners", "100,100"); if ((!str.isEmpty()) && (str.find(',')!=-1)) sscanf(str,"%d,%d",&mVertPannerSep,&mHorizPannerSep); else mHorizPannerSep = mVertPannerSep = 100; config->setGroup("General"); mSendOnCheck = config->readBoolEntry("SendOnCheck",false); mMsgView->readConfig(); mHeaders->readConfig(); // Re-activate panners if (mStartupDone && oldLongFolderList != mLongFolderList) { activatePanners(); show(); mFolderTree->setCurrentItem(folderIdx); } } //----------------------------------------------------------------------------- void KMMainWin::writeConfig(void) { QString s(32); KConfig *config = app->getConfig(); QRect r = geometry(); mMsgView->writeConfig(); config->setGroup("Geometry"); s.sprintf("%i,%i", r.width(), r.height()); config->writeEntry("MainWin", s); s.sprintf("%i,%i", mVertPanner->absSeparatorPos(), mHorizPanner->absSeparatorPos()); config->writeEntry("Panners", s); } //----------------------------------------------------------------------------- void KMMainWin::createWidgets(void) { KNewPanner *pnrMsgView, *pnrMsgList, *pnrFldList; QAccel *accel = new QAccel(this); // create panners if (mLongFolderList) { mHorizPanner = new KNewPanner(this, "horizPanner", KNewPanner::Vertical, KNewPanner::Absolute); mHorizPanner->resize(size()); setView(mHorizPanner); mVertPanner = new KNewPanner(mHorizPanner, "vertPanner", KNewPanner::Horizontal,KNewPanner::Absolute); pnrFldList = mHorizPanner; pnrMsgView = mVertPanner; pnrMsgList = mVertPanner; } else { mVertPanner = new KNewPanner(this, "vertPanner", KNewPanner::Horizontal, KNewPanner::Absolute); mVertPanner->resize(size()); setView(mVertPanner); mHorizPanner = new KNewPanner(mVertPanner,"horizPanner", KNewPanner::Vertical, KNewPanner::Absolute); pnrMsgView = mVertPanner; pnrMsgList = mHorizPanner; pnrFldList = mHorizPanner; } // create list of messages mHeaders = new KMHeaders(this, pnrMsgList, "headers"); connect(mHeaders, SIGNAL(selected(KMMessage*)), this, SLOT(slotMsgSelected(KMMessage*))); connect(mHeaders, SIGNAL(activated(KMMessage*)), this, SLOT(slotMsgActivated(KMMessage*))); accel->connectItem(accel->insertItem(Key_Left), mHeaders, SLOT(prevMessage())); accel->connectItem(accel->insertItem(Key_Right), mHeaders, SLOT(nextMessage())); accel->connectItem(accel->insertItem(Key_Left+SHIFT), mHeaders, SLOT(prevMessageMark())); accel->connectItem(accel->insertItem(Key_Right+SHIFT), mHeaders, SLOT(nextMessageMark())); // create HTML reader widget mMsgView = new KMReaderWin(pnrMsgView); connect(mMsgView, SIGNAL(statusMsg(const char*)), this, SLOT(statusMsg(const char*))); connect(mMsgView, SIGNAL(popupMenu(const char*,const QPoint&)), this, SLOT(slotMsgPopup(const char*,const QPoint&))); connect(mMsgView, SIGNAL(urlClicked(const char*,int)), this, SLOT(slotUrlClicked(const char*,int))); connect(mMsgView, SIGNAL(showAtmMsg(KMMessage *)), this, SLOT(slotAtmMsg(KMMessage *))); accel->connectItem(accel->insertItem(Key_Up), mMsgView, SLOT(slotScrollUp())); accel->connectItem(accel->insertItem(Key_Down), mMsgView, SLOT(slotScrollDown())); accel->connectItem(accel->insertItem(Key_Prior), mMsgView, SLOT(slotScrollPrior())); accel->connectItem(accel->insertItem(Key_Next), mMsgView, SLOT(slotScrollNext())); accel->connectItem(accel->insertItem(Key_Delete), this, SLOT(slotDeleteMsg())); // create list of folders mFolderTree = new KMFolderTree(pnrFldList, "folderTree"); connect(mFolderTree, SIGNAL(folderSelected(KMFolder*)), this, SLOT(folderSelected(KMFolder*))); connect(mFolderTree, SIGNAL(msgMoved(KMFolder*,int)), mHeaders, SLOT(moveMsgToFolder(KMFolder*,int))); } //----------------------------------------------------------------------------- void KMMainWin::activatePanners(void) { // glue everything together if (mLongFolderList) { mVertPanner->activate(mHeaders, mMsgView); mHorizPanner->activate(mFolderTree, mVertPanner); } else { mVertPanner->activate(mHorizPanner, mMsgView); mHorizPanner->activate(mFolderTree, mHeaders); } } //----------------------------------------------------------------------------- int KMMainWin::statusBarAddItem(const char* aText) { return mStatusBar->insertItem(aText, -1); } //----------------------------------------------------------------------------- void KMMainWin::statusBarChangeItem(int aId, const char* aText) { mStatusBar->changeItem(aText, aId); } //----------------------------------------------------------------------------- void KMMainWin::statusMsg(const char* aText) { mStatusBar->changeItem(aText, mMessageStatusId); kapp->flushX(); kapp->processEvents(100); } //----------------------------------------------------------------------------- void KMMainWin::hide() { mVertPannerSep = mVertPanner->absSeparatorPos(); mHorizPannerSep = mHorizPanner->absSeparatorPos(); KMMainWinInherited::hide(); } //----------------------------------------------------------------------------- void KMMainWin::show() { if (!mLongFolderList) { mVertPanner->setAbsSeparatorPos(mVertPannerSep); mHorizPanner->setAbsSeparatorPos(mHorizPannerSep); } else { mHorizPanner->setAbsSeparatorPos(mHorizPannerSep); mVertPanner->setAbsSeparatorPos(mVertPannerSep); } KMMainWinInherited::show(); } //----------------------------------------------------------------------------- void KMMainWin::slotClose() { close(TRUE); } //----------------------------------------------------------------------------- void KMMainWin::slotHelp() { app->invokeHTMLHelp("",""); } //----------------------------------------------------------------------------- void KMMainWin::slotNewMailReader() { KMMainWin *d; d = new KMMainWin(NULL); d->show(); d->resize(d->size()); } //----------------------------------------------------------------------------- void KMMainWin::slotSettings() { // markus: we write the Config here cause otherwise the // geometry will be set to the value in the config. // Problem arises when we change the geometry during the // session are press the OK button in the settings. Then we // lose the current geometry! Not anymore ;-) writeConfig(); KMSettings dlg(this); dlg.exec(); } //----------------------------------------------------------------------------- void KMMainWin::slotFilter() { filterMgr->openDialog(); } //----------------------------------------------------------------------------- void KMMainWin::slotAddrBook() { KMAddrBookEditDlg dlg(addrBook); dlg.exec(); } //----------------------------------------------------------------------------- void KMMainWin::slotUnimplemented() { warning(i18n("Sorry, but this feature\nis still missing")); } //----------------------------------------------------------------------------- void KMMainWin::slotAddFolder() { KMFolderDialog dlg(NULL, this); dlg.setCaption(i18n("New Folder")); if (dlg.exec()) mFolderTree->reload(); } //----------------------------------------------------------------------------- void KMMainWin::slotCheckMail() { bool rc; if(checkingMail) { KMsgBox::message(0,i18n("KMail error"), i18n("Already checking for mail!")); return; } checkingMail = TRUE; kbp->busy(); rc = acctMgr->checkMail(); kbp->idle(); if (!rc) statusMsg(i18n("No new mail available")); if(mSendOnCheck) slotSendQueued(); checkingMail = FALSE; } //----------------------------------------------------------------------------- void KMMainWin::slotMenuActivated() { if ( !actMenu->isVisible() ) getAccountMenu(); } //----------------------------------------------------------------------------- void KMMainWin::slotCheckOneAccount(int item) { bool rc = FALSE; if(checkingMail) { KMsgBox::message(0,i18n("KMail error"), i18n("Already checking for mail!")); return; } checkingMail = TRUE; kbp->busy(); rc = acctMgr->intCheckMail(item); kbp->idle(); if (!rc) warning(i18n("No new mail available")); if(mSendOnCheck) slotSendQueued(); checkingMail = FALSE; } void KMMainWin::slotNewMail(KMAccount *) { mHeaders->sortAndShow(); } //----------------------------------------------------------------------------- void KMMainWin::slotCompose() { KMComposeWin *win; KMMessage* msg = new KMMessage; msg->initHeader(); win = new KMComposeWin(msg); win->show(); } //----------------------------------------------------------------------------- void KMMainWin::slotModifyFolder() { KMFolderDialog *d; if (!mFolder) return; d = new KMFolderDialog((KMFolder*)mFolder, this); d->setCaption(i18n("Modify Folder")); if (d->exec()) mFolderTree->reload(); delete d; } //----------------------------------------------------------------------------- void KMMainWin::slotEmptyFolder() { QString str(256); KMMessage* msg; if (!mFolder) return; kbp->busy(); // begin of critical part // from here to "end..." no signal may change to another mFolder, otherwise // the wrong folder will be truncated in expunge (dnaber, 1999-08-29) mFolder->open(); mHeaders->setFolder(NULL); mMsgView->clear(); if (mFolder != trashFolder) { while ((msg = mFolder->take(0)) != NULL) trashFolder->addMsg(msg); } mFolder->close(); mFolder->expunge(); // end of critical if (mFolder != trashFolder) statusMsg(i18n("Moved all messages into trash")); mHeaders->setFolder(mFolder); kbp->idle(); } //----------------------------------------------------------------------------- void KMMainWin::slotRemoveFolder() { QString str(256); QDir dir; if (!mFolder) return; //debug("TYPE: %s", (const char*)mFolder->type()); if (mFolder->isSystemFolder() || strcmp(mFolder->type(),"plain")!=0) { warning(i18n("Cannot remove a\nsystem folder.")); return; } str.sprintf(i18n("Are you sure you want to remove the folder\n" "\"%s\", discarding it's contents ?"), (const char*)mFolder->label()); if ((KMsgBox::yesNo(this,i18n("Confirmation"),str, KMsgBox::DB_SECOND))==1) { mHeaders->setFolder(NULL); mMsgView->clear(); folderMgr->remove(mFolder); } } //----------------------------------------------------------------------------- void KMMainWin::slotCompactFolder() { int idx = mHeaders->currentItem(); if (mFolder) { kbp->busy(); mFolder->compact(); kbp->idle(); } mHeaders->setCurrentItem(idx); } //----------------------------------------------------------------------------- void KMMainWin::slotPrintMsg() { if(mHeaders->currentItem() >= 0) mMsgView->printMsg(); } //----------------------------------------------------------------------------- void KMMainWin::slotReplyToMsg() { mHeaders->replyToMsg(); } //----------------------------------------------------------------------------- void KMMainWin::slotReplyAllToMsg() { mHeaders->replyAllToMsg(); } //----------------------------------------------------------------------------- void KMMainWin::slotForwardMsg() { mHeaders->forwardMsg(); } //----------------------------------------------------------------------------- void KMMainWin::slotEditMsg() { KMMessage *msg; int aIdx; if(mFolder != outboxFolder) { KMsgBox::message(0,i18n("KMail notification!"), i18n("Only messages in the outbox folder can be edited!")); return; } if((aIdx = mHeaders->currentItem()) <= -1) return; if(!(msg = mHeaders->getMsg(aIdx))) return; KMComposeWin *win = new KMComposeWin; win->setMsg(msg,FALSE); win->show(); } //----------------------------------------------------------------------------- void KMMainWin::slotResendMsg() { mHeaders->resendMsg(); } //----------------------------------------------------------------------------- void KMMainWin::slotDeleteMsg() { mHeaders->deleteMsg(); } //----------------------------------------------------------------------------- void KMMainWin::slotShowMsgSrc() { KMMessage* msg = mHeaders->getMsg(-1); if (msg) msg->viewSource(i18n("Message as Plain Text")); } //----------------------------------------------------------------------------- void KMMainWin::slotMoveMsg() { KMFolderSelDlg dlg(i18n("Select Folder")); KMFolder* dest; if (!dlg.exec()) return; if (!(dest = dlg.folder())) return; mHeaders->moveMsgToFolder(dest); } //----------------------------------------------------------------------------- void KMMainWin::slotApplyFilters() { mHeaders->applyFiltersOnMsg(); } //----------------------------------------------------------------------------- void KMMainWin::slotCopyMsg() { KMFolderSelDlg dlg(i18n("Select Folder")); KMFolder* dest; if (!dlg.exec()) return; if (!(dest = dlg.folder())) return; mHeaders->copyMsgToFolder(dest); } //----------------------------------------------------------------------------- void KMMainWin::slotSaveMsg() { if(mHeaders->currentItem() == -1) return; mHeaders->saveMsg(-1); } //----------------------------------------------------------------------------- void KMMainWin::slotSendQueued() { if (msgSender->sendQueued()) statusMsg(i18n("Queued messages successfully sent.")); else statusMsg(i18n("Failed to send (some) queued messages.")); } //----------------------------------------------------------------------------- void KMMainWin::slotViewChange() { if(mBodyPartsMenu->isItemChecked(mBodyPartsMenu->idAt(0))) { mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(0),FALSE); mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(1),TRUE); } else if(mBodyPartsMenu->isItemChecked(mBodyPartsMenu->idAt(1))) { mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(1),FALSE); mBodyPartsMenu->setItemChecked(mBodyPartsMenu->idAt(0),TRUE); } //mMsgView->setInline(!mMsgView->isInline()); } //----------------------------------------------------------------------------- void KMMainWin::slotSetHeaderStyle(int id) { if(id <= 5) { mViewMenu->setItemChecked((int)mMsgView->headerStyle(), FALSE); mMsgView->setHeaderStyle((KMReaderWin::HeaderStyle)id); mViewMenu->setItemChecked(id, TRUE); } else { mViewMenu->setItemChecked((int)mMsgView->attachmentStyle()+5, FALSE); mViewMenu->setItemChecked(id, TRUE); mMsgView->setAttachmentStyle(id-5); } // Can only update the message view if a message is displayed //if(mHeaders->currentItem() >= 0) mMsgView->update(true); } //----------------------------------------------------------------------------- void KMMainWin::folderSelected(KMFolder* aFolder) { //debug ("Entering folderSelected\n"); if(!aFolder) { debug("KMMainWin::folderSelected(): aFolder == NULL"); return; } if (mFolder == aFolder) return; kbp->busy(); mFolder = (KMFolder*)aFolder; mMsgView->clear(); mHeaders->setFolder(mFolder); kbp->idle(); } //----------------------------------------------------------------------------- void KMMainWin::slotMsgSelected(KMMessage *msg) { //assert(msg != NULL); if(msg == NULL) return; mMsgView->setMsg(msg); } //----------------------------------------------------------------------------- void KMMainWin::slotSetMsgStatus(int id) { mHeaders->setMsgStatus((KMMsgStatus)id); } //----------------------------------------------------------------------------- //called from heders. Message must not be deleted on close void KMMainWin::slotMsgActivated(KMMessage *msg) { KMReaderWin *win; assert(msg != NULL); win = new KMReaderWin; showMsg(win, msg); } //called from reader win. message must be deleted on close void KMMainWin::slotAtmMsg(KMMessage *msg) { KMReaderWin *win; assert(msg != NULL); win = new KMReaderWin; win->setAutoDelete(true); //delete on end showMsg(win, msg); } void KMMainWin::showMsg(KMReaderWin *win, KMMessage *msg) { KWM::setMiniIcon(win->winId(), kapp->getMiniIcon()); win->setCaption(msg->subject()); win->setMsg(msg); win->resize(550,600); connect(win, SIGNAL(statusMsg(const char*)), this, SLOT(statusMsg(const char*))); connect(win, SIGNAL(popupMenu(const char*,const QPoint&)), this, SLOT(slotMsgPopup(const char*,const QPoint&))); connect(win, SIGNAL(urlClicked(const char*,int)), this, SLOT(slotUrlClicked(const char*,int))); QAccel *accel = new QAccel(win); accel->connectItem(accel->insertItem(Key_Up), win, SLOT(slotScrollUp())); accel->connectItem(accel->insertItem(Key_Down), win, SLOT(slotScrollDown())); accel->connectItem(accel->insertItem(Key_Prior), win, SLOT(slotScrollPrior())); accel->connectItem(accel->insertItem(Key_Next), win, SLOT(slotScrollNext())); win->show(); } //----------------------------------------------------------------------------- void KMMainWin::slotCopyText() { QString temp; temp = mMsgView->copyText(); app->clipboard()->setText(temp); } //----------------------------------------------------------------------------- void KMMainWin::slotMarkAll() { int i; for(i = 0; i < mHeaders->numRows(); i++) mHeaders->markItem(i); } //----------------------------------------------------------------------------- void KMMainWin::slotUrlClicked(const char* aUrl, int) { KMComposeWin *win; KMMessage* msg; if (!strnicmp(aUrl, "mailto:", 7)) { msg = new KMMessage; msg->initHeader(); msg->setTo(aUrl+7); win = new KMComposeWin(msg); win->show(); } else if (!strnicmp(aUrl, "http:", 5) || !strnicmp(aUrl, "ftp:", 4) || !strnicmp(aUrl, "file:", 5)) { statusMsg(i18n("Opening URL...")); - system("kfmclient openURL \""+QString(aUrl)+"\""); + system("kfmclient1 openURL \""+QString(aUrl)+"\""); } } //----------------------------------------------------------------------------- void KMMainWin::slotMailtoCompose() { KMComposeWin *win; KMMessage *msg = new KMMessage; msg->initHeader(); msg->setTo(mUrlCurrent.mid(7,255)); win = new KMComposeWin(msg); win->show(); } //----------------------------------------------------------------------------- void KMMainWin::slotMailtoReply() { KMComposeWin *win; KMMessage *msg; if (!(msg = mHeaders->getMsg(-1))) return; msg = msg->createReply(FALSE); msg->setTo(mUrlCurrent.mid(7,255)); win = new KMComposeWin(msg); win->show(); } //----------------------------------------------------------------------------- void KMMainWin::slotMailtoForward() { KMComposeWin *win; KMMessage *msg; if (!(msg = mHeaders->getMsg(-1))) return; msg = msg->createForward(); msg->setTo(mUrlCurrent.mid(7,255)); win = new KMComposeWin(msg); win->show(); } //----------------------------------------------------------------------------- void KMMainWin::slotMailtoAddAddrBook() { if (mUrlCurrent.isEmpty()) return; addrBook->insert(mUrlCurrent.mid(7,255)); statusMsg(i18n("Address added to addressbook.")); } //----------------------------------------------------------------------------- void KMMainWin::slotUrlCopy() { QClipboard* clip = QApplication::clipboard(); if (strnicmp(mUrlCurrent,"mailto:",7)==0) { clip->setText(mUrlCurrent.mid(7,255)); statusMsg(i18n("Address copied to clipboard.")); } else { clip->setText(mUrlCurrent); statusMsg(i18n("URL copied to clipboard.")); } } //----------------------------------------------------------------------------- void KMMainWin::slotUrlOpen() { if (mUrlCurrent.isEmpty()) return; mMsgView->slotUrlOpen(mUrlCurrent,0); } //----------------------------------------------------------------------------- void KMMainWin::slotMsgPopup(const char* aUrl, const QPoint& aPoint) { QPopupMenu* menu = new QPopupMenu; mUrlCurrent = aUrl; mUrlCurrent.detach(); if (aUrl) { if (strnicmp(aUrl,"mailto:",7)==0) { // popup on a mailto URL menu = new QPopupMenu(); menu->insertItem(i18n("Send to..."), this, SLOT(slotMailtoCompose())); menu->insertItem(i18n("Send reply to..."), this, SLOT(slotMailtoReply())); menu->insertItem(i18n("Forward to..."), this, SLOT(slotMailtoForward())); menu->insertSeparator(); menu->insertItem(i18n("Add to addressbook"), this, SLOT(slotMailtoAddAddrBook())); menu->insertItem(i18n("Copy to clipboard"), this, SLOT(slotUrlCopy())); menu->popup(aPoint,0); } else { // popup on a not-mailto URL menu->insertItem(i18n("Open URL..."), this, SLOT(slotUrlOpen())); menu->insertItem(i18n("Copy to clipboard"), this, SLOT(slotUrlCopy())); menu->popup(aPoint,0); } } else { // popup somewhere else on the document menu->insertItem(i18n("&Reply..."), this, SLOT(slotReplyToMsg())); menu->insertItem(i18n("Reply &All..."), this, SLOT(slotReplyAllToMsg())); menu->insertItem(i18n("&Forward..."), this, SLOT(slotForwardMsg()), Key_F); menu->insertSeparator(); menu->insertItem(i18n("&Move..."), this, SLOT(slotMoveMsg()), Key_M); menu->insertItem(i18n("&Copy..."), this, SLOT(slotCopyText()), Key_S); menu->insertItem(i18n("&Delete"), this, SLOT(slotDeleteMsg()), Key_D); menu->popup(aPoint, 0); } } //----------------------------------------------------------------------------- void KMMainWin::getAccountMenu() { QStrList actList; actMenu->clear(); actList = acctMgr->getAccounts(); QString tmp; for(tmp = actList.first(); tmp ; tmp = actList.next()) actMenu->insertItem(tmp); } //----------------------------------------------------------------------------- void KMMainWin::setupMenuBar() { //----- File Menu fileMenu = new QPopupMenu(); fileMenu->insertItem(i18n("New Composer"), this, SLOT(slotCompose()), keys->openNew()); fileMenu->insertItem(i18n("New Mailreader"), this, SLOT(slotNewMailReader())); fileMenu->insertSeparator(); fileMenu->insertItem(i18n("Save As..."), this, SLOT(slotSaveMsg()), keys->save()); fileMenu->insertItem(i18n("Print..."), this, SLOT(slotPrintMsg()), keys->print()); fileMenu->insertSeparator(); fileMenu->insertItem(i18n("Compact all folders"), folderMgr, SLOT(compactAll())); fileMenu->insertSeparator(); fileMenu->insertItem(i18n("Check Mail..."), this, SLOT(slotCheckMail()), CTRL+Key_L); actMenu = new QPopupMenu(); getAccountMenu(); connect(actMenu,SIGNAL(activated(int)),this,SLOT(slotCheckOneAccount(int))); connect(fileMenu,SIGNAL(highlighted(int)),this,SLOT(slotMenuActivated())); fileMenu->insertItem(i18n("Check Mail in..."),actMenu); fileMenu->insertItem(i18n("Send Queued"), this, SLOT(slotSendQueued())); fileMenu->insertSeparator(); fileMenu->insertItem(i18n("&Settings..."), this, SLOT(slotSettings())); fileMenu->insertItem(i18n("&Addressbook..."), this, SLOT(slotAddrBook())); fileMenu->insertItem(i18n("&Filter..."), this, SLOT(slotFilter())); fileMenu->insertSeparator(); fileMenu->insertItem(i18n("&Close"), this, SLOT(slotClose()), keys->close()); fileMenu->insertItem(i18n("&Quit"), this, SLOT(quit()), keys->quit()); //----- Edit Menu QPopupMenu *editMenu = new QPopupMenu(); editMenu->insertItem(i18n("&Copy"), this, SLOT(slotCopyText()), keys->copy()); editMenu->insertSeparator(); #ifdef BROKEN editMenu->insertItem(i18n("&Find..."), this, SLOT(slotUnimplemented()), keys->find()); #endif //----- Folder Menu QPopupMenu *folderMenu = new QPopupMenu(); folderMenu->insertItem(i18n("&Create..."), this, SLOT(slotAddFolder())); folderMenu->insertItem(i18n("&Modify..."), this, SLOT(slotModifyFolder())); folderMenu->insertItem(i18n("C&ompact"), this, SLOT(slotCompactFolder())); folderMenu->insertSeparator(); folderMenu->insertItem(i18n("&Empty"), this, SLOT(slotEmptyFolder())); folderMenu->insertItem(i18n("&Remove"), this, SLOT(slotRemoveFolder())); //----- Message-Status Submenu QPopupMenu *msgStatusMenu = new QPopupMenu; connect(msgStatusMenu, SIGNAL(activated(int)), this, SLOT(slotSetMsgStatus(int))); msgStatusMenu->insertItem(i18n("New"), (int)KMMsgStatusNew); msgStatusMenu->insertItem(i18n("Unread"), (int)KMMsgStatusUnread); msgStatusMenu->insertItem(i18n("Read"), (int)KMMsgStatusOld); msgStatusMenu->insertItem(i18n("Replied"), (int)KMMsgStatusReplied); msgStatusMenu->insertItem(i18n("Queued"), (int)KMMsgStatusQueued); msgStatusMenu->insertItem(i18n("Sent"), (int)KMMsgStatusSent); //----- Message Menu QPopupMenu *messageMenu = new QPopupMenu; messageMenu->insertItem(i18n("&Next"), mHeaders, SLOT(nextMessage()), Key_N); messageMenu->insertItem(i18n("Next unread"), mHeaders, SLOT(nextUnreadMessage()), Key_Plus); messageMenu->insertItem(i18n("&Previous"), mHeaders, SLOT(prevMessage()), Key_P); messageMenu->insertItem(i18n("Previous unread"), mHeaders, SLOT(prevUnreadMessage()), Key_Minus); messageMenu->insertSeparator(); messageMenu->insertItem(i18n("&Reply..."), this, SLOT(slotReplyToMsg()), Key_R); messageMenu->insertItem(i18n("Reply &All..."), this, SLOT(slotReplyAllToMsg()), Key_A); messageMenu->insertItem(i18n("&Forward..."), this, SLOT(slotForwardMsg()), Key_F); messageMenu->insertSeparator(); messageMenu->insertItem(i18n("Edi&t..."),this, SLOT(slotEditMsg()), Key_T); messageMenu->insertSeparator(); messageMenu->insertItem(i18n("&Set Status"), msgStatusMenu); messageMenu->insertSeparator(); messageMenu->insertItem(i18n("Mar&k all"), this, SLOT(slotMarkAll()), Key_K); messageMenu->insertItem(i18n("&Move..."), this, SLOT(slotMoveMsg()), Key_M); messageMenu->insertItem(i18n("&Copy..."), this, SLOT(slotCopyMsg()), Key_S); messageMenu->insertItem(i18n("&Delete"), this, SLOT(slotDeleteMsg()), Key_D); messageMenu->insertSeparator(); messageMenu->insertItem(i18n("Send again..."), this, SLOT(slotResendMsg())); messageMenu->insertItem(i18n("Apply filters"), this, SLOT(slotApplyFilters()), CTRL+Key_J); messageMenu->insertSeparator(); messageMenu->insertItem(i18n("View Source..."), this, SLOT(slotShowMsgSrc())); //----- View Menu mViewMenu = new QPopupMenu(); mViewMenu->setCheckable(TRUE); connect(mViewMenu,SIGNAL(activated(int)),SLOT(slotSetHeaderStyle(int))); mViewMenu->insertItem(i18n("&Brief Headers"), KMReaderWin::HdrBrief); mViewMenu->insertItem(i18n("&Fancy Headers"), KMReaderWin::HdrFancy); mViewMenu->insertItem(i18n("&Standard Headers"), KMReaderWin::HdrStandard); mViewMenu->insertItem(i18n("&Long Headers"), KMReaderWin::HdrLong); mViewMenu->insertItem(i18n("&All Headers"), KMReaderWin::HdrAll); mViewMenu->insertSeparator(); mViewMenu->insertItem(i18n("Iconic Attachments")); mViewMenu->insertItem(i18n("Smart Attachments")); mViewMenu->insertItem(i18n("Inlined Attachments")); mViewMenu->setItemChecked((int)mMsgView->headerStyle(), TRUE); mViewMenu->setItemChecked((int)mMsgView->attachmentStyle()+5, TRUE); //----- Help Menu QPopupMenu *helpMenu = kapp->getHelpMenu(TRUE, aboutText); //----- Menubar mMenuBar = new KMenuBar(this); mMenuBar->insertItem(i18n("&File"), fileMenu); mMenuBar->insertItem(i18n("&Edit"), editMenu); mMenuBar->insertItem(i18n("F&older"), folderMenu); mMenuBar->insertItem(i18n("&Message"), messageMenu); mMenuBar->insertItem(i18n("&View"), mViewMenu); mMenuBar->insertSeparator(); mMenuBar->insertItem(i18n("&Help"), helpMenu); setMenu(mMenuBar); } //----------------------------------------------------------------------------- void KMMainWin::setupToolBar() { KIconLoader* loader = kapp->getIconLoader(); mToolBar = new KToolBar(this); mToolBar->insertButton(loader->loadIcon("filenew.xpm"), 0, SIGNAL(clicked()), this, SLOT(slotCompose()), TRUE, i18n("Compose new message")); mToolBar->insertButton(loader->loadIcon("filefloppy.xpm"), 0, SIGNAL(clicked()), this, SLOT(slotSaveMsg()), TRUE, i18n("Save message to file")); mToolBar->insertButton(loader->loadIcon("fileprint.xpm"), 0, SIGNAL(clicked()), this, SLOT(slotPrintMsg()), TRUE, i18n("Print message")); mToolBar->insertSeparator(); mToolBar->insertButton(loader->loadIcon("checkmail.xpm"), 0, SIGNAL(clicked()), this, SLOT(slotCheckMail()), TRUE, i18n("Get new mail")); mToolBar->insertSeparator(); mToolBar->insertButton(loader->loadIcon("filereply.xpm"), 0, SIGNAL(clicked()), this, SLOT(slotReplyToMsg()), TRUE, i18n("Reply to author")); mToolBar->insertButton(loader->loadIcon("filereplyall.xpm"), 0, SIGNAL(clicked()), this, SLOT(slotReplyAllToMsg()), TRUE, i18n("Reply to all recipients")); mToolBar->insertButton(loader->loadIcon("fileforward.xpm"), 0, SIGNAL(clicked()), this, SLOT(slotForwardMsg()), TRUE, i18n("Forward message")); mToolBar->insertButton(loader->loadIcon("filedel2.xpm"), 0, SIGNAL(clicked()), this, SLOT(slotDeleteMsg()), TRUE, i18n("Delete message")); mToolBar->insertSeparator(); mToolBar->insertButton(loader->loadIcon("openbook.xpm"), 0, SIGNAL(clicked()), this, SLOT(slotAddrBook()), TRUE, i18n("Open addressbook...")); addToolBar(mToolBar); } //----------------------------------------------------------------------------- void KMMainWin::setupStatusBar() { mStatusBar = new KStatusBar(this); mMessageStatusId = statusBarAddItem(i18n("Initializing...")); mStatusBar->enable(KStatusBar::Show); setStatusBar(mStatusBar); } void KMMainWin::quit() { //if((KMsgBox::yesNo(0,"KMail Confirm","Do you really want to quit?") ==2)) // return; qApp->quit(); } diff --git a/kmail/kmreaderwin.cpp b/kmail/kmreaderwin.cpp index 39483976..4124d879 100644 --- a/kmail/kmreaderwin.cpp +++ b/kmail/kmreaderwin.cpp @@ -1,1224 +1,1224 @@ // kmreaderwin.cpp // Author: Markus Wuebben #include #include #include #include #include #include #ifndef KRN #include "kmglobal.h" #include "kmmainwin.h" #else #endif #include "kmimemagic.h" #include "kmmessage.h" #include "kmmsgpart.h" #include "kmreaderwin.h" #include "kfileio.h" #include "kbusyptr.h" #include "kmmsgpartdlg.h" #include "kpgp.h" #include "kfontutils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // for selection #include #include #include //--- Sven's save attachments to /tmp start --- #include // for access and getpid //--- Sven's save attachments to /tmp end --- // Do the tmp stuff correctly - thanks to Harri Porten for // reminding me (sven) #ifdef HAVE_PATHS_H #include #endif #ifndef KMAIL_TMP // a '&' as first char in _PATH_TMP will be replaced with kapp->localkdedir() #define KMAIL_TMP "&/share/apps/kmail/tmp/" #endif #ifdef KRN extern KApplication *app; extern KLocale *nls; extern KBusyPtr *kbp; #endif QString KMReaderWin::mAttachDir; //----------------------------------------------------------------------------- KMReaderWin::KMReaderWin(QWidget *aParent, const char *aName, int aFlags) :KMReaderWinInherited(aParent, aName, aFlags) { initMetaObject(); mPicsDir = app->kde_datadir()+"/kmail/pics/"; mAutoDelete = FALSE; mMsg = NULL; initHtmlWidget(); readConfig(); if (mAttachDir.isNull()) makeAttachDir(); } //----------------------------------------------------------------------------- KMReaderWin::~KMReaderWin() { if (mAutoDelete) delete mMsg; } //----------------------------------------------------------------------------- void KMReaderWin::makeAttachDir(void) { QString str; bool ok = true; str = KMAIL_TMP; if (str[0] == '&') str = app->localkdedir() + str.mid(1,1023); mAttachDir.sprintf("%skmail%d", (const char*)str, getpid()); if (access(mAttachDir, W_OK) != 0) // Not there or not writable { if (mkdir(str, S_IRWXU) != 0 && chmod(str, S_IRWXU) != 0) ok=false; //failed create new or chmod existing tmp/ else if (mkdir(mAttachDir, S_IRWXU) != 0 && chmod(mAttachDir, S_IRWXU) != 0) ok=false; //failed create new or chmod exisiting kmail/ } if (!ok) warning(i18n("Failed to create temporary " "attachment directory '%s': %s"), (const char*)mAttachDir, strerror(errno)); } //----------------------------------------------------------------------------- void KMReaderWin::readConfig(void) { KConfig *config = kapp->getConfig(); config->setGroup("Reader"); mAtmInline = config->readNumEntry("attach-inline", 100); mHeaderStyle = (HeaderStyle)config->readNumEntry("hdr-style", HdrFancy); mAttachmentStyle = (AttachmentStyle)config->readNumEntry("attmnt-style", SmartAttmnt); #ifdef KRN config->setGroup("ArticleListOptions"); #endif QColor c1=QColor("black"); QColor c2=QColor("blue"); QColor c3=QColor("red"); QColor c4=QColor("white"); mViewer->setDefaultBGColor(config->readColorEntry("BackgroundColor",&c4)); mViewer->setDefaultTextColors(config->readColorEntry("ForegroundColor",&c1) ,config->readColorEntry("LinkColor",&c2) ,config->readColorEntry("FollowedColor",&c3)); //moved to #ifdef KRN where it was before (sven): //mViewer->setDefaultFontBase(config->readNumEntry("DefaultFontBase",3)); #ifndef KRN config->setGroup("Fonts"); mBodyFont = config->readEntry("body-font", "helvetica-medium-r-12"); mViewer->setStandardFont(kstrToFont(mBodyFont).family()); // --- sven's get them font sizes right! start --- int i, fntSize=0, diff; fntSize = kstrToFont(mBodyFont).pointSize(); //debug ("Fontsize: %d", fntSize); int fontsizes[7]; mViewer->resetFontSizes(); mViewer->getFontSizes(fontsizes); diff= fntSize - fontsizes[3]; if (fontsizes[0]+diff > 0) { for (i=0;i<7; i++) { //debug ("Old fontsize #%d: %d", i, fontsizes[i]); fontsizes[i]+=diff; //debug ("New fontsize #%d: %d", i, fontsizes[i]); } } mViewer->setFontSizes(fontsizes); // --- sven's get them font sizes right! end --- //mViewer->setFixedFont(mFixedFont); #else mViewer->setDefaultFontBase(config->readNumEntry("DefaultFontBase",3)); mViewer->setStandardFont(config->readEntry("StandardFont","helvetica")); mViewer->setFixedFont(config->readEntry("FixedFont","courier")); #endif update(); } //----------------------------------------------------------------------------- void KMReaderWin::writeConfig(bool aWithSync) { KConfig *config = kapp->getConfig(); config->setGroup("Reader"); config->writeEntry("attach-inline", mAtmInline); config->writeEntry("hdr-style", (int)mHeaderStyle); config->writeEntry("attmnt-style",(int)mAttachmentStyle); config->setGroup("Fonts"); // config->writeEntry("body-font", mBodyFont); // config->writeEntry("fixed-font", mFixedFont); if (aWithSync) config->sync(); } //----------------------------------------------------------------------------- void KMReaderWin::initHtmlWidget(void) { mViewer = new KHTMLWidget(this, mPicsDir); mViewer->resize(width()-16, height()-110); mViewer->setURLCursor(KCursor::handCursor()); mViewer->setDefaultBGColor(QColor("#ffffff")); /* mViewer->setDefaultBGColor(pal->normal().background()); mViewer->setDefaultTextColor(app->textColor, app->); */ connect(mViewer,SIGNAL(URLSelected(const char *,int)),this, SLOT(slotUrlOpen(const char *,int))); connect(mViewer,SIGNAL(onURL(const char *)),this, SLOT(slotUrlOn(const char *))); connect(mViewer,SIGNAL(popupMenu(const char *, const QPoint &)), SLOT(slotUrlPopup(const char *, const QPoint &))); connect(mViewer,SIGNAL(textSelected(bool)), SLOT(slotTextSelected(bool))); mSbVert = new QScrollBar(0, 110, 12, height()-110, 0, QScrollBar::Vertical, this); mSbHorz = new QScrollBar(0, 0, 24, width()-32, 0, QScrollBar::Horizontal, this); connect(mViewer, SIGNAL(scrollVert(int)), SLOT(slotScrollVert(int))); connect(mViewer, SIGNAL(scrollHorz(int)), SLOT(slotScrollHorz(int))); connect(mSbVert, SIGNAL(valueChanged(int)), mViewer, SLOT(slotScrollVert(int))); connect(mSbHorz, SIGNAL(valueChanged(int)), mViewer, SLOT(slotScrollHorz(int))); connect(mViewer, SIGNAL(documentChanged()), SLOT(slotDocumentChanged())); connect(mViewer, SIGNAL(documentDone()), SLOT(slotDocumentDone())); } //----------------------------------------------------------------------------- void KMReaderWin::setBodyFont(const QString aFont) { mBodyFont = aFont.copy(); update(); } //----------------------------------------------------------------------------- void KMReaderWin::setHeaderStyle(KMReaderWin::HeaderStyle aHeaderStyle) { mHeaderStyle = aHeaderStyle; update(); } //----------------------------------------------------------------------------- void KMReaderWin::setAttachmentStyle(int aAttachmentStyle) { mAttachmentStyle = (AttachmentStyle)aAttachmentStyle; update(); } //----------------------------------------------------------------------------- void KMReaderWin::setInlineAttach(int aAtmInline) { mAtmInline = aAtmInline; update(); } //----------------------------------------------------------------------------- void KMReaderWin::setMsg(KMMessage* aMsg, bool force) { // If not forced and there is aMsg and aMsg is same as mMsg then return if (!force && aMsg && mMsg == aMsg) return; mMsg = aMsg; mViewer->stopParser(); if (mMsg) parseMsg(); else { mViewer->begin(mPicsDir); mViewer->write(""); mViewer->end(); mViewer->parse(); } } //----------------------------------------------------------------------------- void KMReaderWin::parseMsg(void) { //assert(mMsg!=NULL); if(mMsg == NULL) return; mViewer->begin(mPicsDir); mViewer->write(""); #if defined CHARSETS printf("Setting viewer charset to %s\n",(const char *)mMsg->charset()); mViewer->setCharset(mMsg->charset()); #endif parseMsg(mMsg); mViewer->write(""); mViewer->end(); mViewer->parse(); } //----------------------------------------------------------------------------- void KMReaderWin::parseMsg(KMMessage* aMsg) { KMMessagePart msgPart; int i, numParts; QString type, subtype, str, contDisp; bool asIcon = false; inlineImage=false; assert(aMsg!=NULL); writeMsgHeader(); numParts = aMsg->numBodyParts(); if (numParts > 0) { // ---sven: handle multipart/alternative start --- // This is for multipart/alternative messages WITHOUT attachments // main header has type=multipart/alternative and one attachment is // text/html type = aMsg->typeStr(); if (type.find("multipart/alternative") != -1 && numParts == 2) { debug("Alternative message, type: %s",type.data()); //Now: Only two attachments one of them is html for (i=0; i<2; i++) // count parts... { aMsg->bodyPart(i, &msgPart); // set part... subtype = msgPart.subtypeStr(); // get subtype... if (stricmp(subtype, "html")==0) // is it html? { // yes... str = msgPart.bodyDecoded(); // decode it... mViewer->write(str); // write it... return; // return, finshed. } // wasn't html ignore. } // end for. // if we are here we didnt find any html part. Handle it normaly then } // This works only for alternative msgs without attachments. Alternative // messages with attachments are broken with or without this. No need // to bother with strib or here, because if any part // follows this will not be shown correctly. You'll still be able to read the // main message and deal with attachments. Nothing I can do now :-( // ---sven: handle multipart/alternative end --- for (i=0; ibodyPart(i, &msgPart); type = msgPart.typeStr(); subtype = msgPart.subtypeStr(); contDisp = msgPart.contentDisposition(); debug("type: %s",type.data()); debug("subtye: %s",subtype.data()); debug("contDisp %s",contDisp.data()); if (i <= 0) asIcon = FALSE; else switch (mAttachmentStyle) { case IconicAttmnt: asIcon=TRUE; break; case InlineAttmnt: asIcon=FALSE; break; case SmartAttmnt: asIcon=(contDisp.find("inline")<0); } if (!asIcon) { if (i<=0 || stricmp(type, "text")==0)//||stricmp(type, "message")==0) { str = msgPart.bodyDecoded(); if (i>0) mViewer->write("


"); if (stricmp(subtype, "html")==0) { // ---Sven's strip and from end of attachment start- // We must fo this, or else we will see only 1st inlined html attachment // It is IMHO enough to search only for and put \0 there. int i; i = str.findRev("", -1, false); //case insensitive if (i>0) str.truncate(i); else // just in case - search for { i = str.findRev("", -1, false); //case insensitive if (i>0) str.truncate(i); } // ---Sven's strip and from end of attachment end- mViewer->write(str); } else writeBodyStr(str); } // ---Sven's view smart or inline image attachments in kmail start--- else if (stricmp(type, "image")==0) { inlineImage=true; writePartIcon(&msgPart, i); inlineImage=false; } // ---Sven's view smart or inline image attachments in kmail end--- else asIcon = TRUE; } if (asIcon) { writePartIcon(&msgPart, i); } } } else // if numBodyParts <= 0 { writeBodyStr(aMsg->bodyDecoded()); } } //----------------------------------------------------------------------------- void KMReaderWin::writeMsgHeader(void) { if (!mMsg) return; QString str; switch (mHeaderStyle) { case HdrBrief: mViewer->write("" + strToHtml(mMsg->subject()) + "  (" + KMMessage::emailAddrAsAnchor(mMsg->from(),TRUE) + ", "); if (!mMsg->cc().isEmpty()) mViewer->write(i18n("Cc: ")+ KMMessage::emailAddrAsAnchor(mMsg->cc(),TRUE) + ", "); mViewer->write(strToHtml(mMsg->dateShortStr()) + ")
\n"); break; case HdrStandard: mViewer->write("" + strToHtml(mMsg->subject()) + "
\n"); mViewer->write(i18n("From: ") + KMMessage::emailAddrAsAnchor(mMsg->from(),FALSE) + "
\n"); mViewer->write(i18n("To: ") + KMMessage::emailAddrAsAnchor(mMsg->to(),FALSE) + "
\n"); if (!mMsg->cc().isEmpty()) mViewer->write(i18n("Cc: ")+ KMMessage::emailAddrAsAnchor(mMsg->cc(),FALSE) + "
\n"); #ifdef KRN if (!mMsg->references().isEmpty()) mViewer->write(i18n("References: ") + KMMessage::refsAsAnchor(mMsg->references()) + "
"); #endif mViewer->write("
"); break; case HdrFancy: mViewer->write(QString("
"); mViewer->write(strToHtml(mMsg->subject()) + "
"); mViewer->write(i18n("From: ")+ KMMessage::emailAddrAsAnchor(mMsg->from(),FALSE) + "
\n"); mViewer->write(i18n("To: ")+ KMMessage::emailAddrAsAnchor(mMsg->to(),FALSE) + "
\n"); if (!mMsg->cc().isEmpty()) mViewer->write(i18n("Cc: ")+ KMMessage::emailAddrAsAnchor(mMsg->cc(),FALSE) + "
\n"); mViewer->write(i18n("Date: ")+ strToHtml(mMsg->dateStr()) + "
\n"); #ifdef KRN if (!mMsg->references().isEmpty()) mViewer->write(i18n("References: ") + KMMessage::refsAsAnchor(mMsg->references()) + "

\n"); #endif mViewer->write("

\n"); break; case HdrLong: mViewer->write("" + strToHtml(mMsg->subject()) + "
"); mViewer->write(i18n("Date: ")+strToHtml(mMsg->dateStr())+"
"); mViewer->write(i18n("From: ")+ KMMessage::emailAddrAsAnchor(mMsg->from(),FALSE) + "
"); mViewer->write(i18n("To: ")+ KMMessage::emailAddrAsAnchor(mMsg->to(),FALSE) + "
"); if (!mMsg->cc().isEmpty()) mViewer->write(i18n("Cc: ")+ KMMessage::emailAddrAsAnchor(mMsg->cc(),FALSE) + "
"); if (!mMsg->bcc().isEmpty()) mViewer->write(i18n("Bcc: ")+ KMMessage::emailAddrAsAnchor(mMsg->bcc(),FALSE) + "
"); if (!mMsg->replyTo().isEmpty()) mViewer->write(i18n("Reply to: ")+ KMMessage::emailAddrAsAnchor(mMsg->replyTo(),FALSE) + "
"); #ifdef KRN if (!mMsg->references().isEmpty()) mViewer->write(i18n("References: ")+ KMMessage::refsAsAnchor(mMsg->references()) + "
\n"); if (!mMsg->groups().isEmpty()) mViewer->write(i18n("Groups: ") + mMsg->groups()+"
\n"); #endif mViewer->write("
\n"); break; case HdrAll: str = strToHtml(mMsg->headerAsString()); mViewer->write(str); mViewer->write("\n
\n"); break; default: warning("Unsupported header style %d", mHeaderStyle); } mViewer->write("
\n"); } //----------------------------------------------------------------------------- void KMReaderWin::writeBodyStr(const QString aStr) { QString line(256), sig, htmlStr = ""; Kpgp* pgp = Kpgp::getKpgp(); assert(pgp != NULL); assert(!aStr.isNull()); bool pgpMessage = false; if (pgp->setMessage(aStr)) { QString str = pgp->frontmatter(); if(!str.isEmpty()) htmlStr += quotedHTML(str.data()); htmlStr += "
"; if (pgp->isEncrypted()) { pgpMessage = true; if(pgp->decrypt()) { line.sprintf("%s
", (const char*)i18n("Encrypted message")); htmlStr += line; } else { line.sprintf("%s
%s

", (const char*)i18n("Cannot decrypt message:"), (const char*)pgp->lastErrorMsg()); htmlStr += line; } } // check for PGP signing if (pgp->isSigned()) { pgpMessage = true; if (pgp->goodSignature()) sig = i18n("Message was signed by"); else sig = i18n("Warning: Bad signature from"); /* HTMLize signedBy data */ QString *sdata=new QString(pgp->signedBy()); sdata->replace(QRegExp("\""), """); sdata->replace(QRegExp("<"), "<"); sdata->replace(QRegExp(">"), ">"); if (sdata->contains(QRegExp("unknown key ID"))) { sdata->replace(QRegExp("unknown key ID"), i18n("unknown key ID")); line.sprintf("%s %s
",sig.data(), sdata->data()); } else line.sprintf("%s %s
", sig.data(), sdata->data(),sdata->data()); delete sdata; htmlStr += line; } htmlStr += quotedHTML(pgp->message().data()); if(pgpMessage) htmlStr += "
End pgp message

"; str = pgp->backmatter(); if(!str.isEmpty()) htmlStr += quotedHTML(str.data()); } else htmlStr += quotedHTML(aStr.data()); mViewer->write(htmlStr); } //----------------------------------------------------------------------------- QString KMReaderWin::quotedHTML(char * pos) { QString htmlStr, line; char ch, *beg; bool quoted = FALSE; bool lastQuoted = FALSE; bool atStart = TRUE; htmlStr = ""; // skip leading empty lines for (beg=pos; *pos && *pos<=' '; pos++) { if (*pos=='\n') beg = pos+1; } pos = beg; int tcnt = 0; QString tmpStr; while (1) { ch = *pos; if (ch=='\n' || ch=='\0') { tcnt ++; *pos = '\0'; line = strToHtml(beg,TRUE,TRUE); *pos = ch; if (quoted && !lastQuoted) line.prepend(""); else if (!quoted && lastQuoted) line.prepend(""); tmpStr += line + "
\n"; if (!(tcnt % 100)) { htmlStr += tmpStr; tmpStr.truncate(0); } beg = pos+1; atStart = TRUE; lastQuoted = quoted; quoted = FALSE; } else if (ch > ' ' && atStart) { if (ch=='>' || /*ch==':' ||*/ ch=='|') quoted = TRUE; atStart = FALSE; } if (!ch) break; pos++; } htmlStr += tmpStr; return htmlStr; } //----------------------------------------------------------------------------- void KMReaderWin::writePartIcon(KMMessagePart* aMsgPart, int aPartNum) { QString iconName, href(255), label, comment, tmpStr, contDisp; QString fileName; if(aMsgPart == NULL) { debug("writePartIcon: aMsgPart == NULL\n"); return; } debug("writePartIcon: PartNum: %i",aPartNum); comment = aMsgPart->contentDescription(); fileName = aMsgPart->fileName(); if (fileName.isEmpty()) fileName = aMsgPart->name(); label = fileName; //--- Sven's save attachments to /tmp start --- QString fname; bool ok = true; fname.sprintf("%s/part%d", (const char*)mAttachDir, aPartNum+1); if (access(fname.data(), W_OK) != 0) // Not there or not writable if (mkdir(fname.data(), 0) != 0 || chmod (fname.data(), S_IRWXU) != 0) ok = false; //failed create if (ok) { if (fileName.isEmpty()) fname += "/unnamed"; else { fname = fname + "/" + fileName; // remove quotes from the filename so that the shell does not get confused int c = 0; while ((c = fname.find('"', c)) >= 0) fname.remove(c, 1); c = 0; while ((c = fname.find('\'', c)) >= 0) fname.remove(c, 1); } tmpStr = aMsgPart->bodyDecoded(); if (!kStringToFile(tmpStr, fname, false, false, false)) ok = false; } if (ok) { href.sprintf("file:%s", fname.data()); //debug ("Wrote attachment to %s", href.data()); } else //--- Sven's save attachments to /tmp end --- href.sprintf("part://%i", aPartNum+1); // sven: for viewing images inline if (inlineImage) iconName = href; else iconName = aMsgPart->iconName(); if (iconName.left(11)=="unknown.xpm") { aMsgPart->magicSetType(); iconName = aMsgPart->iconName(); } mViewer->write("
" + label + "
" + comment + "
"); } //----------------------------------------------------------------------------- const QString KMReaderWin::strToHtml(const QString aStr, bool aDecodeQP, bool aPreserveBlanks) const { QString qpstr, iStr, result; char ch, *pos, str[256]; int i, i1, x, len; int maxLen = 30000; char htmlStr[maxLen+256]; char* htmlPos; if (aDecodeQP) qpstr = KMMsgBase::decodeRFC1522String(aStr); else qpstr = aStr; #define HTML_ADD(str,len) strcpy(htmlPos,str),htmlPos+=len htmlPos = htmlStr; for (pos=qpstr.data(),x=0; *pos; pos++,x++) { if ((int)(htmlPos-htmlStr) >= maxLen) { *htmlPos = '\0'; result += htmlStr; htmlPos = htmlStr; } ch = *pos; if (aPreserveBlanks) { if (ch==' ') { while (*pos==' ') { HTML_ADD(" ", 6); pos++, x++; } pos--, x--; continue; } else if (ch=='\t') { do { HTML_ADD(" ", 6); x++; } while((x&7) != 0); } // else aPreserveBlanks = FALSE; } if (ch=='<') HTML_ADD("<", 4); else if (ch=='>') HTML_ADD(">", 4); else if (ch=='\n') HTML_ADD("
", 4); else if (ch=='&') HTML_ADD("&", 5); else if ((ch=='h' && strncmp(pos,"http:", 5)==0) || (ch=='f' && strncmp(pos,"ftp:", 4)==0) || (ch=='m' && strncmp(pos,"mailto:", 7)==0)) { for (i=0; *pos && *pos>' ' && i<255; i++, pos++) str[i] = *pos; pos--; while (i>0 && ispunct(str[i-1]) && str[i-1]!='/') { i--; pos--; } str[i] = '\0'; HTML_ADD("", 2); HTML_ADD(str, strlen(str)); HTML_ADD("", 4); } else if (ch=='@') { char *startofstring = qpstr.data(); char *startpos = pos; for (i=0; pos >= startofstring && *pos && (isalnum(*pos) || *pos=='@' || *pos=='.' || *pos=='_'||*pos=='-' || *pos=='*' || *pos=='[' || *pos==']') && i<255; i++, pos--) { } i1 = i; pos++; for (i=0; *pos && (isalnum(*pos)||*pos=='@'||*pos=='.'|| *pos=='_'||*pos=='-' || *pos=='*' || *pos=='[' || *pos==']') && i<255; i++, pos++) { iStr += *pos; } pos--; len = iStr.length(); while (len>2 && ispunct(*pos) && (pos > startpos)) { len--; pos--; } iStr.truncate(len); htmlPos -= (i1 - 1); if (iStr.length()>3) iStr = "" + iStr + ""; HTML_ADD(iStr.data(), iStr.length()); iStr = ""; } else *htmlPos++ = ch; } *htmlPos = '\0'; result += htmlStr; return result; } //----------------------------------------------------------------------------- void KMReaderWin::printMsg(void) { if (!mMsg) return; mViewer->print(); } //----------------------------------------------------------------------------- int KMReaderWin::msgPartFromUrl(const char* aUrl) { QString url; if (!aUrl || !mMsg) return -1; url.sprintf("file:%s/part", (const char*)mAttachDir); int s = url.length(); if (strncmp(aUrl, url, s) == 0) { url = aUrl; int i = url.find('/', s); url = url.mid(s, i-s); //debug ("Url num = %s", url.data()); return atoi(url.data()); } return -1; } //----------------------------------------------------------------------------- void KMReaderWin::resizeEvent(QResizeEvent *) { mViewer->setGeometry(0, 0, width()-16, height()-16); mSbHorz->setGeometry(0, height()-16, width()-16, 16); mSbVert->setGeometry(width()-16, 0, 16, height()-16); mSbHorz->setSteps( 12, mViewer->width() - 12 ); mSbVert->setSteps( 12, mViewer->height() - 12 ); } //----------------------------------------------------------------------------- void KMReaderWin::closeEvent(QCloseEvent *e) { KMReaderWinInherited::closeEvent(e); writeConfig(); } //----------------------------------------------------------------------------- void KMReaderWin::slotUrlOn(const char* aUrl) { int id; KMMessagePart msgPart; QString str; id = msgPartFromUrl(aUrl); if (id <= 0) { emit statusMsg(aUrl); } else { mMsg->bodyPart(id-1, &msgPart); str = msgPart.fileName(); if (str.isEmpty()) str = msgPart.name(); emit statusMsg(i18n("Attachment: ") + str); } } //----------------------------------------------------------------------------- void KMReaderWin::slotUrlOpen(const char* aUrl, int aButton) { int id; id = msgPartFromUrl(aUrl); if (id > 0) { // clicked onto an attachment mAtmCurrent = id-1; slotAtmOpen(); } else emit urlClicked(aUrl, aButton); } //----------------------------------------------------------------------------- void KMReaderWin::slotUrlPopup(const char* aUrl, const QPoint& aPos) { KMMessagePart msgPart; int id; QPopupMenu *menu; id = msgPartFromUrl(aUrl); if (id <= 0) emit popupMenu(aUrl, aPos); else { // Attachment popup mAtmCurrent = id-1; menu = new QPopupMenu(); menu->insertItem(i18n("Open..."), this, SLOT(slotAtmOpen())); menu->insertItem(i18n("View..."), this, SLOT(slotAtmView())); menu->insertItem(i18n("Save as..."), this, SLOT(slotAtmSave())); //menu->insertItem(i18n("Print..."), this, SLOT(slotAtmPrint())); menu->insertItem(i18n("Properties..."), this, SLOT(slotAtmProperties())); menu->popup(aPos,0); } } //----------------------------------------------------------------------------- void KMReaderWin::atmViewMsg(KMMessagePart* aMsgPart) { KMMessage* msg = new KMMessage; assert(aMsgPart!=NULL); msg->fromString(aMsgPart->bodyDecoded()); emit showAtmMsg(msg); } //----------------------------------------------------------------------------- void KMReaderWin::slotAtmView() { QString str, pname; KMMessagePart msgPart; // ---Sven's view text, html and image attachments in html widget start --- // Sven commented out //QMultiLineEdit* edt = new QMultiLineEdit; // ---Sven's view text, html and image attachments in html widget end --- mMsg->bodyPart(mAtmCurrent, &msgPart); pname = msgPart.fileName(); if (pname.isEmpty()) pname=msgPart.name(); if (pname.isEmpty()) pname=msgPart.contentDescription(); if (pname.isEmpty()) pname="unnamed"; if (stricmp(msgPart.typeStr(), "message")==0) { atmViewMsg(&msgPart); return; } kbp->busy(); // ---Sven's view text, html and image attachments in html widget start --- // ***start commenting out old stuff //str = msgPart.bodyDecoded(); //edt->setCaption(i18n("View Attachment: ") + pname); //edt->insertLine(str); //edt->setReadOnly(TRUE); //edt->show(); // *** end commenting out old stuff { KMReaderWin* win = new KMReaderWin; //new reader if (stricmp(msgPart.typeStr(), "text")==0) { win->mViewer->begin(mPicsDir); win->mViewer->write(""); QString str = msgPart.bodyDecoded(); if (stricmp(msgPart.subtypeStr(), "html")==0) win->mViewer->write(str); else //plain text win->writeBodyStr(str); win->mViewer->write(""); win->mViewer->end(); win->mViewer->parse(); win->setCaption(i18n("View Attachment: ") + pname); win->show(); } else if (stricmp(msgPart.typeStr(), "image")==0) { //image QString linkName; // Attachment is saved already; this is the file: linkName.sprintf ("", (const char*)mAttachDir, mAtmCurrent+1, pname.data()); // set linkname win->mViewer->begin(mPicsDir); win->mViewer->write(""); win->mViewer->write(linkName.data()); win->mViewer->write(""); win->mViewer->end(); win->mViewer->parse(); win->setCaption(i18n("View Attachment: ") + pname); win->show(); } } // ---Sven's view text, html and image attachments in html widget end --- kbp->idle(); } //----------------------------------------------------------------------------- void KMReaderWin::slotAtmOpen() { QString str, pname, cmd, fileName; KMMessagePart msgPart; // char* tmpName; // int old_umask; int c; mMsg->bodyPart(mAtmCurrent, &msgPart); if (stricmp(msgPart.typeStr(), "message")==0) { atmViewMsg(&msgPart); return; } pname = msgPart.fileName(); if (pname.isEmpty()) pname=msgPart.name(); if (pname.isEmpty()) pname="unnamed"; //--- Sven's save attachments to /tmp start --- // Sven added: fileName.sprintf ("%s/part%d/%s", (const char*)mAttachDir, mAtmCurrent+1, pname.data()); // Sven commented out: //tmpName = tempnam(NULL, NULL); //if (!tmpName) //{ // warning(i18n("Could not create temporary file")); // return; //} //fileName = tmpName; //free(tmpName); //fileName += '-'; //fileName += pname; // remove quotes from the filename so that the shell does not get confused c = 0; while ((c = fileName.find('"', c)) >= 0) fileName.remove(c, 1); c = 0; while ((c = fileName.find('\'', c)) >= 0) fileName.remove(c, 1); // Sven commented out: //kbp->busy(); //str = msgPart.bodyDecoded(); //old_umask = umask(077); //if (!kStringToFile(str, fileName, TRUE)) // warning(i18n("Could not save temporary file %s"), // (const char*)fileName); //umask(old_umask); //kbp->idle(); //--- Sven's save attachments to /tmp end --- - cmd = "kfmclient openURL \'"; + cmd = "kfmclient1 openURL \'"; cmd += fileName; cmd += "\'"; system(cmd); } //----------------------------------------------------------------------------- void KMReaderWin::slotAtmSave() { KMMessagePart msgPart; QString fileName, str; fileName = QDir::currentDirPath(); fileName.append("/"); mMsg->bodyPart(mAtmCurrent, &msgPart); fileName.append(msgPart.name()); fileName = KFileDialog::getSaveFileName(fileName.data(), "*", this); if(fileName.isEmpty()) return; kbp->busy(); str = msgPart.bodyDecoded(); if (!kStringToFile(str, fileName, TRUE)) warning(i18n("Could not save file")); kbp->idle(); } //----------------------------------------------------------------------------- void KMReaderWin::slotAtmPrint() { KMMessagePart msgPart; mMsg->bodyPart(mAtmCurrent, &msgPart); warning("KMReaderWin::slotAtmPrint()\nis not implemented"); } //----------------------------------------------------------------------------- void KMReaderWin::slotAtmProperties() { KMMessagePart msgPart; KMMsgPartDlg dlg(0,TRUE); kbp->busy(); mMsg->bodyPart(mAtmCurrent, &msgPart); dlg.setMsgPart(&msgPart); kbp->idle(); dlg.exec(); } //----------------------------------------------------------------------------- void KMReaderWin::slotScrollVert(int _y) { mSbVert->setValue(_y); } //----------------------------------------------------------------------------- void KMReaderWin::slotScrollHorz(int _x) { mSbHorz->setValue(_x); } //----------------------------------------------------------------------------- void KMReaderWin::slotScrollUp() { mSbVert->setValue(mSbVert->value() - 10); } //----------------------------------------------------------------------------- void KMReaderWin::slotScrollDown() { mSbVert->setValue(mSbVert->value() + 10); } //----------------------------------------------------------------------------- void KMReaderWin::slotScrollPrior() { mSbVert->setValue(mSbVert->value() - (int)(height()*0.8)); } //----------------------------------------------------------------------------- void KMReaderWin::slotScrollNext() { mSbVert->setValue(mSbVert->value() + (int)(height()*0.8)); } //----------------------------------------------------------------------------- void KMReaderWin::slotDocumentChanged() { if (mViewer->docHeight() > mViewer->height()) mSbVert->setRange(0, mViewer->docHeight() - mViewer->height()); else mSbVert->setRange(0, 0); if (mViewer->docWidth() > mViewer->width()) mSbHorz->setRange(0, mViewer->docWidth() - mViewer->width()); else mSbHorz->setRange(0, 0); } //----------------------------------------------------------------------------- void KMReaderWin::slotTextSelected(bool) { QString temp; mViewer->getSelectedText(temp); kapp->clipboard()->setText(temp); } //----------------------------------------------------------------------------- QString KMReaderWin::copyText() { QString temp; mViewer->getSelectedText(temp); return temp; } //----------------------------------------------------------------------------- void KMReaderWin::slotDocumentDone() { // mSbVert->setValue(0); } //----------------------------------------------------------------------------- #include "kmreaderwin.moc" diff --git a/krn/kmreaderwin.cpp b/krn/kmreaderwin.cpp index 47acc31c..973da87f 100644 --- a/krn/kmreaderwin.cpp +++ b/krn/kmreaderwin.cpp @@ -1,979 +1,979 @@ // kmreaderwin.cpp // Author: Markus Wuebben #include #include #include #include #ifndef KRN #include "kmglobal.h" #include "kmmainwin.h" #else #endif #include "kmimemagic.h" #include "kmmessage.h" #include "kmmsgpart.h" #include "kmreaderwin.h" #include "kfileio.h" #include "kbusyptr.h" #include "kmmsgpartdlg.h" #include "kpgp.h" #include "kfontutils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // for selection #include #include #include #define hand_width 16 #define hand_height 16 static unsigned char hand_bits[] = { 0x00,0x00,0xfe,0x01,0x01,0x02,0x7e,0x04,0x08,0x08,0x70,0x08,0x08,0x08,0x70, 0x14,0x08,0x22,0x30,0x41,0xc0,0x20,0x40,0x12,0x80,0x08,0x00,0x05,0x00,0x02, 0x00,0x00}; static unsigned char hand_mask_bits[] = { 0xfe,0x01,0xff,0x03,0xff,0x07,0xff,0x0f,0xfe,0x1f,0xf8,0x1f,0xfc,0x1f,0xf8, 0x3f,0xfc,0x7f,0xf8,0xff,0xf0,0x7f,0xe0,0x3f,0xc0,0x1f,0x80,0x0f,0x00,0x07, 0x00,0x02}; #ifdef KRN extern KApplication *app; extern KLocale *nls; extern KBusyPtr *kbp; #endif //----------------------------------------------------------------------------- KMReaderWin::KMReaderWin(QWidget *aParent, const char *aName, int aFlags) :KMReaderWinInherited(aParent, aName, aFlags) { initMetaObject(); mPicsDir = app->kde_datadir()+"/kmail/pics/"; mAutoDelete = FALSE; mMsg = NULL; initHtmlWidget(); readConfig(); } //----------------------------------------------------------------------------- KMReaderWin::~KMReaderWin() { if (mAutoDelete) delete mMsg; } //----------------------------------------------------------------------------- void KMReaderWin::readConfig(void) { KConfig *config = kapp->getConfig(); config->setGroup("Reader"); mAtmInline = config->readNumEntry("attach-inline", 100); mHeaderStyle = (HeaderStyle)config->readNumEntry("hdr-style", HdrFancy); mAttachmentStyle = (AttachmentStyle)config->readNumEntry("attmnt-style", SmartAttmnt); #ifdef KRN config->setGroup("ArticleListOptions"); #endif QColor c1=QColor("black"); QColor c2=QColor("blue"); QColor c3=QColor("red"); QColor c4=QColor("white"); mViewer->setDefaultBGColor(config->readColorEntry("BackgroundColor",&c4)); mViewer->setDefaultTextColors(config->readColorEntry("ForegroundColor",&c1) ,config->readColorEntry("LinkColor",&c2) ,config->readColorEntry("FollowedColor",&c3)); mViewer->setDefaultFontBase(config->readNumEntry("DefaultFontBase",3)); #ifndef KRN config->setGroup("Fonts"); mBodyFont = config->readEntry("body-font", "helvetica-medium-r-12"); mViewer->setStandardFont(kstrToFont(mBodyFont).family()); //mViewer->setFixedFont(mFixedFont); #else mViewer->setStandardFont(config->readEntry("StandardFont","helvetica")); mViewer->setFixedFont(config->readEntry("FixedFont","courier")); #endif update(); } //----------------------------------------------------------------------------- void KMReaderWin::writeConfig(bool aWithSync) { KConfig *config = kapp->getConfig(); config->setGroup("Reader"); config->writeEntry("attach-inline", mAtmInline); config->writeEntry("hdr-style", (int)mHeaderStyle); config->writeEntry("attmnt-style",(int)mAttachmentStyle); config->setGroup("Fonts"); config->writeEntry("body-font", mBodyFont); // config->writeEntry("fixed-font", mFixedFont); if (aWithSync) config->sync(); } //----------------------------------------------------------------------------- void KMReaderWin::initHtmlWidget(void) { QBitmap handImg(hand_width, hand_height, hand_bits, TRUE); QBitmap handMask(hand_width, hand_height, hand_mask_bits, TRUE); QCursor handCursor(handImg, handMask, 0, 0); mViewer = new KHTMLWidget(this, mPicsDir); mViewer->resize(width()-16, height()-110); mViewer->setURLCursor(handCursor); mViewer->setDefaultBGColor(QColor("#ffffff")); /* mViewer->setDefaultBGColor(pal->normal().background()); mViewer->setDefaultTextColor(app->textColor, app->); */ connect(mViewer,SIGNAL(URLSelected(const char *,int)),this, SLOT(slotUrlOpen(const char *,int))); connect(mViewer,SIGNAL(onURL(const char *)),this, SLOT(slotUrlOn(const char *))); connect(mViewer,SIGNAL(popupMenu(const char *, const QPoint &)), SLOT(slotUrlPopup(const char *, const QPoint &))); connect(mViewer,SIGNAL(textSelected(bool)), SLOT(slotTextSelected(bool))); mSbVert = new QScrollBar(0, 110, 12, height()-110, 0, QScrollBar::Vertical, this); mSbHorz = new QScrollBar(0, 0, 24, width()-32, 0, QScrollBar::Horizontal, this); connect(mViewer, SIGNAL(scrollVert(int)), SLOT(slotScrollVert(int))); connect(mViewer, SIGNAL(scrollHorz(int)), SLOT(slotScrollHorz(int))); connect(mSbVert, SIGNAL(valueChanged(int)), mViewer, SLOT(slotScrollVert(int))); connect(mSbHorz, SIGNAL(valueChanged(int)), mViewer, SLOT(slotScrollHorz(int))); connect(mViewer, SIGNAL(documentChanged()), SLOT(slotDocumentChanged())); connect(mViewer, SIGNAL(documentDone()), SLOT(slotDocumentDone())); } //----------------------------------------------------------------------------- void KMReaderWin::setBodyFont(const QString aFont) { mBodyFont = aFont.copy(); update(); } //----------------------------------------------------------------------------- void KMReaderWin::setHeaderStyle(KMReaderWin::HeaderStyle aHeaderStyle) { mHeaderStyle = aHeaderStyle; update(); } //----------------------------------------------------------------------------- void KMReaderWin::setAttachmentStyle(int aAttachmentStyle) { mAttachmentStyle = (AttachmentStyle)aAttachmentStyle; update(); } //----------------------------------------------------------------------------- void KMReaderWin::setInlineAttach(int aAtmInline) { mAtmInline = aAtmInline; update(); } //----------------------------------------------------------------------------- void KMReaderWin::setMsg(KMMessage* aMsg) { mMsg = aMsg; if (mMsg) parseMsg(); else { mViewer->begin(mPicsDir); mViewer->write(""); mViewer->end(); mViewer->parse(); } } //----------------------------------------------------------------------------- void KMReaderWin::parseMsg(void) { //assert(mMsg!=NULL); if(mMsg == NULL) return; mViewer->begin(mPicsDir); mViewer->write(""); #if defined CHARSETS printf("Setting viewer charset to %s\n",(const char *)mMsg->charset()); mViewer->setCharset(mMsg->charset()); #endif parseMsg(mMsg); mViewer->write(""); mViewer->end(); mViewer->parse(); } //----------------------------------------------------------------------------- void KMReaderWin::parseMsg(KMMessage* aMsg) { KMMessagePart msgPart; int i, numParts; QString type, subtype, str, contDisp; bool asIcon = false; assert(aMsg!=NULL); writeMsgHeader(); numParts = aMsg->numBodyParts(); if (numParts > 0) { for (i=0; ibodyPart(i, &msgPart); type = msgPart.typeStr(); subtype = msgPart.subtypeStr(); contDisp = msgPart.contentDisposition(); debug("type: %s",type.data()); debug("subtye: %s",subtype.data()); debug("contDisp %s",contDisp.data()); if (i <= 0) asIcon = FALSE; else switch (mAttachmentStyle) { case IconicAttmnt: asIcon=TRUE; break; case InlineAttmnt: asIcon=FALSE; break; case SmartAttmnt: asIcon=(contDisp.find("inline")<0); } if (!asIcon) { if (i<=0 || stricmp(type, "text")==0)//||stricmp(type, "message")==0) { str = msgPart.bodyDecoded(); if (i>0) mViewer->write("


"); if (stricmp(subtype, "html")==0) mViewer->write(str); else writeBodyStr(str); } else asIcon = TRUE; } if (asIcon) { writePartIcon(&msgPart, i); } } } else // if numBodyParts <= 0 { writeBodyStr(aMsg->bodyDecoded()); } } //----------------------------------------------------------------------------- void KMReaderWin::writeMsgHeader(void) { QString str; switch (mHeaderStyle) { case HdrBrief: mViewer->write("" + strToHtml(mMsg->subject()) + "  (" + KMMessage::emailAddrAsAnchor(mMsg->from(),TRUE) + ", "); if (!mMsg->cc().isEmpty()) mViewer->write(i18n("Cc: ")+ KMMessage::emailAddrAsAnchor(mMsg->cc(),TRUE) + ", "); mViewer->write(strToHtml(mMsg->dateShortStr()) + ")
\n"); break; case HdrStandard: mViewer->write("" + strToHtml(mMsg->subject()) + "
\n"); mViewer->write(i18n("From: ") + KMMessage::emailAddrAsAnchor(mMsg->from(),FALSE) + "
\n"); mViewer->write(i18n("To: ") + KMMessage::emailAddrAsAnchor(mMsg->to(),FALSE) + "
\n"); if (!mMsg->cc().isEmpty()) mViewer->write(i18n("Cc: ")+ KMMessage::emailAddrAsAnchor(mMsg->cc(),FALSE) + "
\n"); #ifdef KRN if (!mMsg->references().isEmpty()) mViewer->write(i18n("References: ") + KMMessage::refsAsAnchor(mMsg->references()) + "
"); #endif mViewer->write("
"); break; case HdrFancy: mViewer->write(QString("
"); mViewer->write(strToHtml(mMsg->subject()) + "
"); mViewer->write(i18n("From: ")+ KMMessage::emailAddrAsAnchor(mMsg->from(),FALSE) + "
\n"); mViewer->write(i18n("To: ")+ KMMessage::emailAddrAsAnchor(mMsg->to(),FALSE) + "
\n"); if (!mMsg->cc().isEmpty()) mViewer->write(i18n("Cc: ")+ KMMessage::emailAddrAsAnchor(mMsg->cc(),FALSE) + "
\n"); mViewer->write(i18n("Date: ")+ strToHtml(mMsg->dateStr()) + "
\n"); #ifdef KRN if (!mMsg->references().isEmpty()) mViewer->write(i18n("References: ") + KMMessage::refsAsAnchor(mMsg->references()) + "

\n"); #endif mViewer->write("

\n"); break; case HdrLong: mViewer->write("" + strToHtml(mMsg->subject()) + "
"); mViewer->write(i18n("Date: ")+strToHtml(mMsg->dateStr())+"
"); mViewer->write(i18n("From: ")+ KMMessage::emailAddrAsAnchor(mMsg->from(),FALSE) + "
"); mViewer->write(i18n("To: ")+ KMMessage::emailAddrAsAnchor(mMsg->to(),FALSE) + "
"); if (!mMsg->cc().isEmpty()) mViewer->write(i18n("Cc: ")+ KMMessage::emailAddrAsAnchor(mMsg->cc(),FALSE) + "
"); if (!mMsg->bcc().isEmpty()) mViewer->write(i18n("Bcc: ")+ KMMessage::emailAddrAsAnchor(mMsg->bcc(),FALSE) + "
"); if (!mMsg->replyTo().isEmpty()) mViewer->write(i18n("Reply to: ")+ KMMessage::emailAddrAsAnchor(mMsg->replyTo(),FALSE) + "
"); #ifdef KRN if (!mMsg->references().isEmpty()) mViewer->write(i18n("References: ")+ KMMessage::refsAsAnchor(mMsg->references()) + "
\n"); if (!mMsg->groups().isEmpty()) mViewer->write(i18n("Groups: ") + mMsg->groups()+"
\n"); #endif mViewer->write("
\n"); break; case HdrAll: str = strToHtml(mMsg->headerAsString()); mViewer->write(str); mViewer->write("\n
\n"); break; default: warning("Unsupported header style %d", mHeaderStyle); } mViewer->write("
\n"); return; } //----------------------------------------------------------------------------- void KMReaderWin::writeBodyStr(const QString aStr) { QString line(256), sig, htmlStr = ""; Kpgp* pgp = Kpgp::getKpgp(); assert(pgp != NULL); assert(!aStr.isNull()); bool pgpMessage = false; if (pgp->setMessage(aStr)) { QString str = pgp->frontmatter(); if(!str.isEmpty()) htmlStr += quotedHTML(str.data()); htmlStr += "
"; if (pgp->isEncrypted()) { pgpMessage = true; if(pgp->decrypt()) { line.sprintf("%s
", (const char*)i18n("Encrypted message")); htmlStr += line; } else { line.sprintf("%s
%s

", (const char*)i18n("Cannot decrypt message:"), (const char*)pgp->lastErrorMsg()); htmlStr += line; } } // check for PGP signing if (pgp->isSigned()) { pgpMessage = true; if (pgp->goodSignature()) sig = i18n("Message was signed by"); else sig = i18n("Warning: Bad signature from"); /* HTMLize signedBy data */ QString *sdata=new QString(pgp->signedBy()); sdata->replace(QRegExp("\""), """); sdata->replace(QRegExp("<"), "<"); sdata->replace(QRegExp(">"), ">"); if (sdata->contains(QRegExp("unknown key ID"))) { sdata->replace(QRegExp("unknown key ID"), i18n("unknown key ID")); line.sprintf("%s %s
",sig.data(), sdata->data()); } else line.sprintf("%s %s
", sig.data(), sdata->data(),sdata->data()); delete sdata; htmlStr += line; } htmlStr += quotedHTML(pgp->message().data()); if(pgpMessage) htmlStr += "
End pgp message

"; str = pgp->backmatter(); if(!str.isEmpty()) htmlStr += quotedHTML(str.data()); } else htmlStr += quotedHTML(aStr.data()); mViewer->write(htmlStr); } QString KMReaderWin::quotedHTML(char * pos) { QString htmlStr, line; char ch, *beg; bool quoted = FALSE; bool lastQuoted = FALSE; bool atStart = TRUE; htmlStr = ""; // skip leading empty lines for (beg=pos; *pos && *pos<=' '; pos++) { if (*pos=='\n') beg = pos+1; } pos = beg; int tcnt = 0; QString tmpStr; while (1) { ch = *pos; if (ch=='\n' || ch=='\0') { tcnt ++; *pos = '\0'; line = strToHtml(beg,TRUE,TRUE); *pos = ch; if (quoted && !lastQuoted) line.prepend(""); else if (!quoted && lastQuoted) line.prepend(""); tmpStr += line + "
\n"; if (!(tcnt % 100)) { htmlStr += tmpStr; tmpStr.truncate(0); } beg = pos+1; atStart = TRUE; lastQuoted = quoted; quoted = FALSE; } else if (ch > ' ' && atStart) { if (ch=='>' || /*ch==':' ||*/ ch=='|') quoted = TRUE; atStart = FALSE; } if (!ch) break; pos++; } htmlStr += tmpStr; return htmlStr; } //----------------------------------------------------------------------------- void KMReaderWin::writePartIcon(KMMessagePart* aMsgPart, int aPartNum) { QString iconName, href(255), label, comment; if(aMsgPart == NULL) { debug("writePartIcon: aMsgPart == NULL\n"); return; } debug("writePartIcon: PartNum: %i",aPartNum); label = aMsgPart->name(); comment = aMsgPart->contentDescription(); href.sprintf("part://%i", aPartNum+1); iconName = aMsgPart->iconName(); if (iconName.left(11)=="unknown.xpm") { aMsgPart->magicSetType(); iconName = aMsgPart->iconName(); } mViewer->write("
" + label + "
" + comment + "
"); } //----------------------------------------------------------------------------- const QString KMReaderWin::strToHtml(const QString aStr, bool aDecodeQP, bool aPreserveBlanks) const { QString htmlStr, qpstr, iStr; char ch, *pos, str[256]; int i, i1, x, len; if (aDecodeQP) qpstr = KMMsgBase::decodeRFC1522String(aStr); else qpstr = aStr; for (pos=qpstr.data(),x=0; *pos; pos++,x++) { ch = *pos; if (aPreserveBlanks) { if (ch==' ' && pos[1]==' ') { htmlStr += "  "; for (pos++, x++; pos[1]==' '; pos++, x++) htmlStr += " "; continue; } else if (ch=='\t') { do { htmlStr += " "; x++; } while((x&7) != 0); } // else aPreserveBlanks = FALSE; } if (ch=='<') htmlStr += "<"; else if (ch=='>') htmlStr += ">"; else if (ch=='\n') htmlStr += "
"; else if (ch=='&') htmlStr += "&"; else if ((ch=='h' && strncmp(pos,"http:",5)==0) || (ch=='f' && strncmp(pos,"ftp:",4)==0) || (ch=='m' && strncmp(pos,"mailto:",7)==0)) { for (i=0; *pos && *pos>' ' && i<255; i++, pos++) str[i] = *pos; pos--; while (i>0 && ispunct(str[i-1]) && str[i-1]!='/') { i--; pos--; } str[i] = '\0'; htmlStr += ""; htmlStr += str; htmlStr += ""; } else if (ch=='@') { char *startofstring = qpstr.data(); char *startpos = pos; for (i=0; pos >= startofstring && *pos && (isalnum(*pos) || *pos=='@' || *pos=='.' || *pos=='_'||*pos=='-' || *pos=='*' || *pos=='[' || *pos==']') && i<255; i++, pos--) { } i1 = i; pos++; for (i=0; *pos && (isalnum(*pos)||*pos=='@'||*pos=='.'|| *pos=='_'||*pos=='-' || *pos=='*' || *pos=='[' || *pos==']') && i<255; i++, pos++) { iStr += *pos; } pos--; len = iStr.length(); while (len>2 && ispunct(*pos) && (pos > startpos)) { len--; pos--; } iStr.truncate(len); htmlStr.truncate(htmlStr.length() - i1 + 1); if (iStr.length()>3) htmlStr += "" + iStr + ""; else htmlStr += iStr; iStr = ""; } else htmlStr += ch; } return htmlStr; } //----------------------------------------------------------------------------- void KMReaderWin::printMsg(void) { if (!mMsg) return; mViewer->print(); } //----------------------------------------------------------------------------- int KMReaderWin::msgPartFromUrl(const char* aUrl) { if (!aUrl || !mMsg || strncmp(aUrl,"part://",7)) return -1; return (aUrl ? atoi(aUrl+7) : 0); } //----------------------------------------------------------------------------- void KMReaderWin::resizeEvent(QResizeEvent *) { mViewer->setGeometry(0, 0, width()-16, height()-16); mSbHorz->setGeometry(0, height()-16, width()-16, 16); mSbVert->setGeometry(width()-16, 0, 16, height()-16); mSbHorz->setSteps( 12, mViewer->width() - 12 ); mSbVert->setSteps( 12, mViewer->height() - 12 ); } //----------------------------------------------------------------------------- void KMReaderWin::closeEvent(QCloseEvent *e) { KMReaderWinInherited::closeEvent(e); writeConfig(); } //----------------------------------------------------------------------------- void KMReaderWin::slotUrlOn(const char* aUrl) { int id; KMMessagePart msgPart; id = msgPartFromUrl(aUrl); if (id <= 0) { emit statusMsg(aUrl); } else { mMsg->bodyPart(id-1, &msgPart); emit statusMsg(i18n("Attachment: ") + msgPart.name()); } } //----------------------------------------------------------------------------- void KMReaderWin::slotUrlOpen(const char* aUrl, int aButton) { int id; id = msgPartFromUrl(aUrl); if (id > 0) { // clicked onto an attachment mAtmCurrent = id-1; slotAtmOpen(); } else emit urlClicked(aUrl, aButton); } //----------------------------------------------------------------------------- void KMReaderWin::slotUrlPopup(const char* aUrl, const QPoint& aPos) { KMMessagePart msgPart; int id; QPopupMenu *menu; id = msgPartFromUrl(aUrl); if (id <= 0) emit popupMenu(aUrl, aPos); else { // Attachment popup mAtmCurrent = id-1; menu = new QPopupMenu(); menu->insertItem(i18n("Open..."), this, SLOT(slotAtmOpen())); menu->insertItem(i18n("View..."), this, SLOT(slotAtmView())); menu->insertItem(i18n("Save as..."), this, SLOT(slotAtmSave())); //menu->insertItem(i18n("Print..."), this, SLOT(slotAtmPrint())); menu->insertItem(i18n("Properties..."), this, SLOT(slotAtmProperties())); menu->popup(aPos,0); } } //----------------------------------------------------------------------------- void KMReaderWin::atmViewMsg(KMMessagePart* aMsgPart) { KMMessage* msg = new KMMessage; KMReaderWin* win = new KMReaderWin; assert(aMsgPart!=NULL); msg->fromString(aMsgPart->bodyDecoded()); win->setMsg(msg); win->setAutoDelete(TRUE); win->show(); } //----------------------------------------------------------------------------- void KMReaderWin::slotAtmView() { QString str, pname; KMMessagePart msgPart; QMultiLineEdit* edt = new QMultiLineEdit; mMsg->bodyPart(mAtmCurrent, &msgPart); pname = msgPart.name(); if (pname.isEmpty()) pname=msgPart.contentDescription(); if (pname.isEmpty()) pname="unnamed"; if (stricmp(msgPart.typeStr(), "message")==0) { atmViewMsg(&msgPart); return; } kbp->busy(); str = msgPart.bodyDecoded(); edt->setCaption(i18n("View Attachment: ") + pname); edt->insertLine(str); edt->setReadOnly(TRUE); edt->show(); kbp->idle(); } //----------------------------------------------------------------------------- void KMReaderWin::slotAtmOpen() { QString str, pname, cmd, fileName; KMMessagePart msgPart; char* tmpName; int old_umask; int c; mMsg->bodyPart(mAtmCurrent, &msgPart); if (stricmp(msgPart.typeStr(), "message")==0) { atmViewMsg(&msgPart); return; } pname = msgPart.name(); if (pname.isEmpty()) pname="unnamed"; tmpName = tempnam(NULL, NULL); if (!tmpName) { warning(i18n("Could not create temporary file")); return; } fileName = tmpName; free(tmpName); fileName += '-'; fileName += pname; // remove quotes from the filename so that the shell does not get confused c = 0; while ((c = fileName.find('"', c)) >= 0) fileName.remove(c, 1); c = 0; while ((c = fileName.find('\'', c)) >= 0) fileName.remove(c, 1); kbp->busy(); str = msgPart.bodyDecoded(); old_umask = umask(077); if (!kStringToFile(str, fileName, TRUE)) warning(i18n("Could not save temporary file %s"), (const char*)fileName); umask(old_umask); kbp->idle(); - cmd = "kfmclient openURL \'"; + cmd = "kfmclient1 openURL \'"; cmd += fileName; cmd += "\'"; system(cmd); } //----------------------------------------------------------------------------- void KMReaderWin::slotAtmSave() { KMMessagePart msgPart; QString fileName, str; fileName = QDir::currentDirPath(); fileName.append("/"); mMsg->bodyPart(mAtmCurrent, &msgPart); fileName.append(msgPart.name()); fileName = KFileDialog::getSaveFileName(fileName.data(), "*", this); if(fileName.isEmpty()) return; kbp->busy(); str = msgPart.bodyDecoded(); if (!kStringToFile(str, fileName, TRUE)) warning(i18n("Could not save file")); kbp->idle(); } //----------------------------------------------------------------------------- void KMReaderWin::slotAtmPrint() { KMMessagePart msgPart; mMsg->bodyPart(mAtmCurrent, &msgPart); warning("KMReaderWin::slotAtmPrint()\nis not implemented"); } //----------------------------------------------------------------------------- void KMReaderWin::slotAtmProperties() { KMMessagePart msgPart; KMMsgPartDlg dlg(0,TRUE); kbp->busy(); mMsg->bodyPart(mAtmCurrent, &msgPart); dlg.setMsgPart(&msgPart); kbp->idle(); dlg.exec(); } //----------------------------------------------------------------------------- void KMReaderWin::slotScrollVert(int _y) { mSbVert->setValue(_y); } //----------------------------------------------------------------------------- void KMReaderWin::slotScrollHorz(int _x) { mSbHorz->setValue(_x); } //----------------------------------------------------------------------------- void KMReaderWin::slotScrollUp() { mSbVert->setValue(mSbVert->value() - 10); } //----------------------------------------------------------------------------- void KMReaderWin::slotScrollDown() { mSbVert->setValue(mSbVert->value() + 10); } //----------------------------------------------------------------------------- void KMReaderWin::slotScrollPrior() { mSbVert->setValue(mSbVert->value() - (int)(height()*0.8)); } //----------------------------------------------------------------------------- void KMReaderWin::slotScrollNext() { mSbVert->setValue(mSbVert->value() + (int)(height()*0.8)); } //----------------------------------------------------------------------------- void KMReaderWin::slotDocumentChanged() { if (mViewer->docHeight() > mViewer->height()) mSbVert->setRange(0, mViewer->docHeight() - mViewer->height()); else mSbVert->setRange(0, 0); if (mViewer->docWidth() > mViewer->width()) mSbHorz->setRange(0, mViewer->docWidth() - mViewer->width()); else mSbHorz->setRange(0, 0); } //----------------------------------------------------------------------------- void KMReaderWin::slotTextSelected(bool) { QString temp; mViewer->getSelectedText(temp); kapp->clipboard()->setText(temp); } //----------------------------------------------------------------------------- QString KMReaderWin::copyText() { QString temp; mViewer->getSelectedText(temp); return temp; } //----------------------------------------------------------------------------- void KMReaderWin::slotDocumentDone() { // mSbVert->setValue(0); } //----------------------------------------------------------------------------- #include "kmreaderwin.moc"