summaryrefslogtreecommitdiffstats
path: root/knode/utilities.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'knode/utilities.cpp')
-rw-r--r--knode/utilities.cpp478
1 files changed, 478 insertions, 0 deletions
diff --git a/knode/utilities.cpp b/knode/utilities.cpp
new file mode 100644
index 000000000..5f9c2e98c
--- /dev/null
+++ b/knode/utilities.cpp
@@ -0,0 +1,478 @@
+/*
+ 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 <qlayout.h>
+#include <qregexp.h>
+#include <qapplication.h>
+#include <qcursor.h>
+
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kglobalsettings.h>
+#include <kdebug.h>
+#include <kio/netaccess.h>
+#include <ktempfile.h>
+#include <kfiledialog.h>
+
+#include "knwidgets.h"
+#include "knglobals.h"
+#include "utilities.h"
+
+
+
+//================================================================================
+
+KNFile::KNFile(const QString& fname)
+ : QFile(fname), filePos(0), readBytes(0)
+{
+ buffer.resize(512);
+ dataPtr=buffer.data();
+ dataPtr[0]='\0';
+}
+
+
+KNFile::~KNFile()
+{
+}
+
+
+const QCString& KNFile::readLine()
+{
+ filePos=at();
+ readBytes=QFile::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=QFile::readLine(dataPtr, buffer.size()-1))==-1) {
+ readBytes=1;
+ break;
+ }
+ }
+ } else
+ readBytes=1;
+
+ dataPtr[readBytes-1] = '\0';
+ return buffer;
+}
+
+
+const QCString& KNFile::readLineWnewLine()
+{
+ filePos=at();
+ readBytes=QFile::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=QFile::readLine(dataPtr, buffer.size()-1))==-1) {
+ dataPtr[0] = '\0';
+ break;
+ }
+ }
+ }
+ else dataPtr[0] = '\0';
+
+ return buffer;
+}
+
+
+int KNFile::findString(const char *s)
+{
+ QCString 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;
+}
+
+
+//===============================================================================
+
+QString KNSaveHelper::lastPath;
+
+KNSaveHelper::KNSaveHelper(QString saveName, QWidget *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 (KIO::NetAccess::upload(tmpFile->name(),url, 0) == false)
+ KNHelper::displayRemoteFileError();
+ tmpFile->unlink(); // delete temp file
+ delete tmpFile;
+ }
+}
+
+
+QFile* KNSaveHelper::getFile(const QString &dialogTitle)
+{
+ url = KFileDialog::getSaveURL(lastPath + s_aveName, QString::null, p_arent, dialogTitle);
+
+ if (url.isEmpty())
+ return 0;
+
+ lastPath = url.upURL().url();
+
+ if (url.isLocalFile()) {
+ if (QFileInfo(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 QFile(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();
+ }
+}
+
+
+//===============================================================================
+
+QString KNLoadHelper::l_astPath;
+
+KNLoadHelper::KNLoadHelper(QWidget *parent)
+ : p_arent(parent), f_ile(0)
+{
+}
+
+
+KNLoadHelper::~KNLoadHelper()
+{
+ delete f_ile;
+ if (!t_empName.isEmpty())
+ KIO::NetAccess::removeTempFile(t_empName);
+}
+
+
+KNFile* KNLoadHelper::getFile( const QString &dialogTitle )
+{
+ if (f_ile)
+ return f_ile;
+
+ KURL url = KFileDialog::getOpenURL(l_astPath,QString::null,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;
+
+ QString fileName;
+ if (!u_rl.isLocalFile()) {
+ if (KIO::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(QWidget *parent, const QString &caption, const QStringList &options, int initialValue)
+{
+ KDialogBase *dlg=new KDialogBase(KDialogBase::Plain, caption, KDialogBase::Ok|KDialogBase::Cancel,
+ KDialogBase::Ok, parent);
+ QFrame *page = dlg->plainPage();
+ QHBoxLayout *pageL = new QHBoxLayout(page,8,5);
+
+ KNDialogListBox *list = new KNDialogListBox(true, page);
+ pageL->addWidget(list);
+
+ QString s;
+ for ( QStringList::ConstIterator it = options.begin(); it != options.end(); ++it ) {
+ s = (*it);
+ s.replace(QRegExp("&"),""); // remove accelerators
+ list->insertItem(s);
+ }
+
+ list->setCurrentItem(initialValue);
+ list->setFocus();
+ restoreWindowSize("selectBox", dlg, QSize(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 QString &name, const QSize &s)
+{
+ KConfig *c=knGlobals.config();
+ c->setGroup("WINDOW_SIZES");
+ c->writeEntry(name, s);
+}
+
+
+void KNHelper::restoreWindowSize(const QString &name, QWidget *d, const QSize &defaultSize)
+{
+ KConfig *c=knGlobals.config();
+ c->setGroup("WINDOW_SIZES");
+
+ QSize s=c->readSizeEntry(name,&defaultSize);
+
+ if(s.isValid()) {
+ QRect max = KGlobalSettings::desktopGeometry(QCursor::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 QString KNHelper::encryptStr(const QString& aStr)
+{
+ uint i,val,len = aStr.length();
+ QCString result;
+
+ for (i=0; i<len; i++)
+ {
+ val = aStr[i] - ' ';
+ val = (255-' ') - val;
+ result += (char)(val + ' ');
+ }
+
+ return result;
+}
+
+
+const QString KNHelper::decryptStr(const QString& aStr)
+{
+ return encryptStr(aStr);
+}
+
+// **** rot13 *******************************************************************
+
+QString KNHelper::rot13(const QString &s)
+{
+ QString r(s);
+
+ for (int i=0; (uint)i<r.length(); i++) {
+ if ( r[i] >= QChar('A') && r[i] <= QChar('M') ||
+ r[i] >= QChar('a') && r[i] <= QChar('m') )
+ r[i] = (char)((int)QChar(r[i]) + 13);
+ else
+ if ( r[i] >= QChar('N') && r[i] <= QChar('Z') ||
+ r[i] >= QChar('n') && r[i] <= QChar('z') )
+ r[i] = (char)((int)QChar(r[i]) - 13);
+ }
+
+ return r;
+}
+
+// **** text rewraping *********************************************************
+
+int findBreakPos(const QString &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(QString &result, const QString &text, int wrapAt, const QString &prefix)
+{
+ QString 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=QString::null;
+ }
+ }
+}
+
+
+QString KNHelper::rewrapStringList(QStringList text, int wrapAt, QChar quoteChar, bool stopAtSig, bool alwaysSpace)
+{
+ QString quoted, lastPrefix, thisPrefix, leftover, thisLine;
+ int breakPos;
+
+ for(QStringList::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(quoteChar+' ');
+
+ thisPrefix=QString::null;
+ QChar 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=QString::null;
+ }
+
+ 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(QWidget *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(QWidget *w)
+{
+ KMessageBox::error((w!=0)? w : knGlobals.topWidget, i18n("Unable to load/save file."));
+}
+
+
+void KNHelper::displayRemoteFileError(QWidget *w)
+{
+ KMessageBox::error((w!=0)? w : knGlobals.topWidget, i18n("Unable to save remote file."));
+}
+
+
+void KNHelper::displayTempFileError(QWidget *w)
+{
+ KMessageBox::error((w!=0)? w : knGlobals.topWidget, i18n("Unable to create temporary file."));
+}