/* KNode, the KDE newsreader Copyright (c) 1999-2005 the KNode authors. See file AUTHORS for details 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US */ #include <tqlayout.h> #include <tqregexp.h> #include <tqapplication.h> #include <tqcursor.h> #include <tdelocale.h> #include <tdemessagebox.h> #include <tdeglobalsettings.h> #include <kdebug.h> #include <tdeio/netaccess.h> #include <tdetempfile.h> #include <tdefiledialog.h> #include "knwidgets.h" #include "knglobals.h" #include "utilities.h" //================================================================================ KNFile::KNFile(const TQString& fname) : TQFile(fname), filePos(0), readBytes(0) { buffer.resize(512); dataPtr=buffer.data(); dataPtr[0]='\0'; } KNFile::~KNFile() { } const TQCString& KNFile::readLine() { filePos=at(); readBytes=TQFile::readLine(dataPtr, buffer.size()-1); if(readBytes!=-1) { while ((dataPtr[readBytes-1]!='\n')&&(static_cast<uint>(readBytes+2)==buffer.size())) { // don't get tricked by files without newline at(filePos); if (!increaseBuffer() || (readBytes=TQFile::readLine(dataPtr, buffer.size()-1))==-1) { readBytes=1; break; } } } else readBytes=1; dataPtr[readBytes-1] = '\0'; return buffer; } const TQCString& KNFile::readLineWnewLine() { filePos=at(); readBytes=TQFile::readLine(dataPtr, buffer.size()-1); if(readBytes!=-1) { while ((dataPtr[readBytes-1]!='\n')&&(static_cast<uint>(readBytes+2)==buffer.size())) { // don't get tricked by files without newline at(filePos); if (!increaseBuffer() || (readBytes=TQFile::readLine(dataPtr, buffer.size()-1))==-1) { dataPtr[0] = '\0'; break; } } } else dataPtr[0] = '\0'; return buffer; } int KNFile::findString(const char *s) { TQCString searchBuffer; searchBuffer.resize(2048); char *buffPtr = searchBuffer.data(), *pos; int readBytes, currentFilePos; while (!atEnd()) { currentFilePos = at(); readBytes = readBlock(buffPtr, 2047); if (readBytes == -1) return -1; else buffPtr[readBytes] = 0; // terminate string pos = strstr(buffPtr,s); if (pos == 0) { if (!atEnd()) at(at()-strlen(s)); else return -1; } else { return currentFilePos + (pos-buffPtr); } } return -1; } bool KNFile::increaseBuffer() { if(buffer.resize(2*buffer.size())) {; dataPtr=buffer.data(); dataPtr[0]='\0'; kdDebug(5003) << "KNFile::increaseBuffer() : buffer doubled" << endl; return true; } else return false; } //=============================================================================== TQString KNSaveHelper::lastPath; KNSaveHelper::KNSaveHelper(TQString saveName, TQWidget *parent) : p_arent(parent), s_aveName(saveName), file(0), tmpFile(0) { } KNSaveHelper::~KNSaveHelper() { if (file) { // local filesystem, just close the file delete file; } else if (tmpFile) { // network location, initiate transaction tmpFile->close(); if (TDEIO::NetAccess::upload(tmpFile->name(),url, 0) == false) KNHelper::displayRemoteFileError(); tmpFile->unlink(); // delete temp file delete tmpFile; } } TQFile* KNSaveHelper::getFile(const TQString &dialogTitle) { url = KFileDialog::getSaveURL(lastPath + s_aveName, TQString(), p_arent, dialogTitle); if (url.isEmpty()) return 0; lastPath = url.upURL().url(); if (url.isLocalFile()) { if (TQFileInfo(url.path()).exists() && (KMessageBox::warningContinueCancel(knGlobals.topWidget, i18n("<qt>A file named <b>%1</b> already exists.<br>Do you want to replace it?</qt>").arg(url.path()), dialogTitle, i18n("&Replace")) != KMessageBox::Continue)) { return 0; } file = new TQFile(url.path()); if(!file->open(IO_WriteOnly)) { KNHelper::displayExternalFileError(); delete file; file = 0; } return file; } else { tmpFile = new KTempFile(); if (tmpFile->status()!=0) { KNHelper::displayTempFileError(); delete tmpFile; tmpFile = 0; return 0; } return tmpFile->file(); } } //=============================================================================== TQString KNLoadHelper::l_astPath; KNLoadHelper::KNLoadHelper(TQWidget *parent) : p_arent(parent), f_ile(0) { } KNLoadHelper::~KNLoadHelper() { delete f_ile; if (!t_empName.isEmpty()) TDEIO::NetAccess::removeTempFile(t_empName); } KNFile* KNLoadHelper::getFile( const TQString &dialogTitle ) { if (f_ile) return f_ile; KURL url = KFileDialog::getOpenURL(l_astPath,TQString(),p_arent,dialogTitle); if (url.isEmpty()) return 0; l_astPath = url.url(-1); l_astPath.truncate(l_astPath.length()-url.fileName().length()); return setURL(url); } KNFile* KNLoadHelper::setURL(KURL url) { if (f_ile) return f_ile; u_rl = url; if (u_rl.isEmpty()) return 0; TQString fileName; if (!u_rl.isLocalFile()) { if (TDEIO::NetAccess::download(u_rl, t_empName, 0)) fileName = t_empName; } else fileName = u_rl.path(); if (fileName.isEmpty()) return 0; f_ile = new KNFile(fileName); if(!f_ile->open(IO_ReadOnly)) { KNHelper::displayExternalFileError(); delete f_ile; f_ile = 0; } return f_ile; } //=============================================================================== // **** keyboard selection dialog ********************************************* int KNHelper::selectDialog(TQWidget *parent, const TQString &caption, const TQStringList &options, int initialValue) { KDialogBase *dlg=new KDialogBase(KDialogBase::Plain, caption, KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, parent); TQFrame *page = dlg->plainPage(); TQHBoxLayout *pageL = new TQHBoxLayout(page,8,5); KNDialogListBox *list = new KNDialogListBox(true, page); pageL->addWidget(list); TQString s; for ( TQStringList::ConstIterator it = options.begin(); it != options.end(); ++it ) { s = (*it); s.replace(TQRegExp("&"),""); // remove accelerators list->insertItem(s); } list->setCurrentItem(initialValue); list->setFocus(); restoreWindowSize("selectBox", dlg, TQSize(247,174)); int ret; if (dlg->exec()) ret = list->currentItem(); else ret = -1; saveWindowSize("selectBox", dlg->size()); delete dlg; return ret; } // **** window geometry managing ********************************************* void KNHelper::saveWindowSize(const TQString &name, const TQSize &s) { TDEConfig *c=knGlobals.config(); c->setGroup("WINDOW_SIZES"); c->writeEntry(name, s); } void KNHelper::restoreWindowSize(const TQString &name, TQWidget *d, const TQSize &defaultSize) { TDEConfig *c=knGlobals.config(); c->setGroup("WINDOW_SIZES"); TQSize s=c->readSizeEntry(name,&defaultSize); if(s.isValid()) { TQRect max = TDEGlobalSettings::desktopGeometry(TQCursor::pos()); if ( s.width() > max.width() ) s.setWidth( max.width()-5 ); if ( s.height() > max.height() ) s.setHeight( max.height()-5 ); d->resize(s); } } // **** scramble password strings ********************************************** const TQString KNHelper::encryptStr(const TQString& aStr) { uint i,val,len = aStr.length(); TQCString result; for (i=0; i<len; i++) { val = aStr[i] - ' '; val = (255-' ') - val; result += (char)(val + ' '); } return result; } const TQString KNHelper::decryptStr(const TQString& aStr) { return encryptStr(aStr); } // **** rot13 ******************************************************************* TQString KNHelper::rot13(const TQString &s) { TQString r(s); for (int i=0; (uint)i<r.length(); i++) { if ( r[i] >= TQChar('A') && r[i] <= TQChar('M') || r[i] >= TQChar('a') && r[i] <= TQChar('m') ) r[i] = (char)((int)TQChar(r[i]) + 13); else if ( r[i] >= TQChar('N') && r[i] <= TQChar('Z') || r[i] >= TQChar('n') && r[i] <= TQChar('z') ) r[i] = (char)((int)TQChar(r[i]) - 13); } return r; } // **** text rewraping ********************************************************* int findBreakPos(const TQString &text, int start) { int i; for(i=start;i>=0;i--) if(text[i].isSpace()) break; if(i>0) return i; for(i=start;i<(int)text.length();i++) // ok, the line is to long if(text[i].isSpace()) break; return i; } void appendTextWPrefix(TQString &result, const TQString &text, int wrapAt, const TQString &prefix) { TQString txt=text; int breakPos; while(!txt.isEmpty()) { if((int)(prefix.length()+txt.length()) > wrapAt) { breakPos=findBreakPos(txt,wrapAt-prefix.length()); result+=(prefix+txt.left(breakPos)+"\n"); txt.remove(0,breakPos+1); } else { result+=(prefix+txt+"\n"); txt=TQString(); } } } TQString KNHelper::rewrapStringList(TQStringList text, int wrapAt, TQChar quoteChar, bool stopAtSig, bool alwaysSpace) { TQString quoted, lastPrefix, thisPrefix, leftover, thisLine; int breakPos; for(TQStringList::Iterator line=text.begin(); line!=text.end(); ++line) { if(stopAtSig && (*line)=="-- ") break; thisLine=(*line); if (!alwaysSpace && (thisLine[0]==quoteChar)) thisLine.prepend(quoteChar); // second quote level without space else thisLine.prepend(TQString(quoteChar)+' '); thisPrefix=TQString(); TQChar c; for(int idx=0; idx<(int)(thisLine.length()); idx++) { c=thisLine.at(idx); if( (c==' ') || (c==quoteChar) || (c=='>') ||(c=='|') || (c==':') || (c=='#') || (c=='[') || (c=='{')) thisPrefix.append(c); else break; } thisLine.remove(0,thisPrefix.length()); thisLine = thisLine.stripWhiteSpace(); if(!leftover.isEmpty()) { // don't break paragraphs, tables and quote levels if(thisLine.isEmpty() || (thisPrefix!=lastPrefix) || thisLine.contains(" ") || thisLine.contains('\t')) appendTextWPrefix(quoted, leftover, wrapAt, lastPrefix); else thisLine.prepend(leftover+" "); leftover=TQString(); } if((int)(thisPrefix.length()+thisLine.length()) > wrapAt) { breakPos=findBreakPos(thisLine,wrapAt-thisPrefix.length()); if(breakPos < (int)(thisLine.length())) { leftover=thisLine.right(thisLine.length()-breakPos-1); thisLine.truncate(breakPos); } } quoted+=thisPrefix+thisLine+"\n"; lastPrefix=thisPrefix; } if (!leftover.isEmpty()) appendTextWPrefix(quoted, leftover, wrapAt, lastPrefix); return quoted; } // **** misc. message-boxes ********************************************************** void KNHelper::displayInternalFileError(TQWidget *w) { KMessageBox::error((w!=0)? w : knGlobals.topWidget, i18n("Unable to load/save configuration.\nWrong permissions on home folder?\nYou should close KNode now to avoid data loss.")); } void KNHelper::displayExternalFileError(TQWidget *w) { KMessageBox::error((w!=0)? w : knGlobals.topWidget, i18n("Unable to load/save file.")); } void KNHelper::displayRemoteFileError(TQWidget *w) { KMessageBox::error((w!=0)? w : knGlobals.topWidget, i18n("Unable to save remote file.")); } void KNHelper::displayTempFileError(TQWidget *w) { KMessageBox::error((w!=0)? w : knGlobals.topWidget, i18n("Unable to create temporary file.")); }