[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kopete-devel
Subject:    [kopete-devel] History Import extension
From:       Timo_Schlüßler <timo () schluessler ! org>
Date:       2008-12-03 16:03:22
Message-ID: 4936ADCA.7010205 () schluessler ! org
[Download RAW message or body]

Hello,

attached is a patch and the two files which add the ability to import
logs from pidgin to kopete. The source-code files belong to
kdenetwork/kopete/plugins/history.
I changed HistoryLogger slightly so that appendMessage() uses the
timestamp from the message that is to be imported  but not
QDate::currentDate().

I don't know what happens if you want to import multiuser chatlogs
because i haven't got any ... i would be glad if you can check that.
For me it works just fine, but the logs from pidgin are very unsteady.
anyway i hope it works for all pidgin logs.

thanks for testing,
timo


["historyimport.cpp" (text/plain)]

/*
    historyimport.cpp

    Copyright (c) 2008 by Timo Schluessler

    Kopete    (c) 2008 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * 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.                                   *
    *                                                                       *
    *************************************************************************
*/


#include "historyimport.h"

#include "historylogger.h"

#include <kdebug.h>

#include <kopetecontactlist.h>
#include <kopetemetacontact.h>
#include <kopeteprotocol.h>
#include <kopeteaccount.h>

HistoryImport::HistoryImport(QWidget *parent)
	: KDialog(parent)
{

	// set dialog settings
	setButtons(KDialog::Ok | KDialog::Details | KDialog::Cancel);
	setWindowTitle(KDialog::makeStandardCaption("Import History"));
	setButtonText(KDialog::Ok, "Import listed logs");

	// create widgets
	QWidget *w = new QWidget(this);
	QGridLayout *l = new QGridLayout(w);

	display = new QTextEdit(w);
	display->setReadOnly(true);
	treeView = new QTreeView(w);

	QPushButton *fromPidgin = new QPushButton("Get history from &Pidgin", w);
	
	l->addWidget(treeView, 0, 0, 1, 3);
	l->addWidget(display, 0, 4, 1, 10);
	l->addWidget(fromPidgin, 1, 0);

	setMainWidget(w);


	// create details widget
	QWidget *details = new QWidget(w);
	QVBoxLayout *dL = new QVBoxLayout(w);

	QTextEdit *detailsEdit = new QTextEdit(details);
	detailsEdit->setReadOnly(true);
	selectByHand = new QCheckBox(tr("Select log directory by hand"), details);
	
	dL->addWidget(selectByHand);
	dL->addWidget(detailsEdit);
	details->setLayout(dL);

	setDetailsWidget(details);
	detailsCursor = QTextCursor(detailsEdit->document());

	// create model for treeView
	QStandardItemModel *model = new QStandardItemModel(treeView);
	treeView->setModel(model);
	model->setHorizontalHeaderLabels(QStringList("Parsed History"));

	// connect everything
	connect(treeView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(itemClicked(const \
QModelIndex &)));  connect(fromPidgin, SIGNAL(clicked()), this, \
SLOT(importPidgin()));  connect(this, SIGNAL(okClicked()), this, SLOT(save()));

	// define variables
	amount = 0;
	cancel = false;

	timeFormats << "(MM/dd/yyyy hh:mm:ss)" << "(MM/dd/yyyy hh:mm:ss AP)" << "(MM/dd/yy \
hh:mm:ss)" << "(MM/dd/yy hh:mm:ss AP)" << "(dd.MM.yyyy hh:mm:ss)" << "(dd.MM.yyyy \
hh:mm:ss AP)" << "(dd.MM.yy hh:mm:ss)" << "(dd.MM.yyyy hh:mm:ss AP)" << "(dd/MM/yyyy \
hh:mm:ss)" << "(dd/MM/yyyy hh:mm:ss AP)" << "(dd/MM/yy hh:mm:ss)" << "(dd/MM/yy \
hh:mm:ss AP)";

	show();
}

HistoryImport::~HistoryImport(void)
{
}

void HistoryImport::save(void)
{
	QProgressDialog progress("Saving logs to disk ...", "Abort Saving", 0, amount, \
this);  progress.setWindowTitle("Saving");

	Log log;

	foreach (log, logs) {
		HistoryLogger logger(log.other, this);
		Message message;
		foreach (message, log.messages) {
			Kopete::Message kMessage;
			if (message.incoming) {
				kMessage = Kopete::Message(log.other, log.me);
				kMessage.setDirection(Kopete::Message::Inbound);
			} else {
				kMessage = Kopete::Message(log.me, log.other);
				kMessage.setDirection(Kopete::Message::Outbound);
			}
			kMessage.setPlainBody(message.text);
			kMessage.setTimestamp(message.timestamp);
			logger.appendMessage(kMessage, log.other);
			
			progress.setValue(progress.value()+1);
			qApp->processEvents();
			if (progress.wasCanceled()) {
				cancel = true;
				break;
			}
		}
		if (cancel)
			break;
	}
}

void HistoryImport::displayLog(struct Log *log)
{
	Message message;

	QStandardItem *root = \
dynamic_cast<QStandardItemModel*>(treeView->model())->invisibleRootItem(), *item;

	foreach(message, log->messages) {
		amount++; // for QProgressDialog in save()
		item = findItem(log->other->protocol()->pluginId().append(" \
(").append(log->other->account()->accountId()).append(")"), root);  item = \
findItem(log->other->nickName(), item);  item = \
findItem(message.timestamp.toString("yyyy-MM-dd"), item);

		if (!item->data(Qt::UserRole).isValid())
			item->setData((int)logs.indexOf(*log), Qt::UserRole);
	}

}

QStandardItem * HistoryImport::findItem(QString text, QStandardItem *parent)
{
	int i;
	bool found = false;
	QStandardItem *child = 0L;

	for (i=0; i < parent->rowCount(); i++) {
		child = parent->child(i, 0);
		if (child->data(Qt::DisplayRole) == text) {
			found = true;
			break;
		}
	}
	if (!found) {
		child = new QStandardItem(text);
		parent->appendRow(child);
	}

	return child;
}
		
void HistoryImport::itemClicked(const QModelIndex & index)
{
	QVariant id = index.data(Qt::UserRole);

	if (id.canConvert<int>()) {
		Log log = logs.at(id.toInt());
		display->document()->clear();
		QTextCursor cursor(display->document());

		Message message;
		QDate date = QDate::fromString(index.data(Qt::DisplayRole).toString(), \
"yyyy-MM-dd");  foreach (message, log.messages) {
			if (date != message.timestamp.date())
				continue;
			cursor.insertText(message.timestamp.toString("hh:mm:ss "));
			if (message.incoming)
				cursor.insertText(log.other->nickName().append(": "));
			else
				cursor.insertText(log.me->nickName().append(": "));
			cursor.insertText(message.text);
			cursor.insertBlock();
		}
	}
}

int HistoryImport::countLogs(QDir dir, int depth)
{
	int res = 0;
	QStack<int> pos;
	QStringList files;
	pos.push(0);

	depth++;

	forever {
		files = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);

		if (pos.size() == depth) {
			res += dir.entryList(QDir::Files).size();
		}
		if (files.isEmpty() || files.size() <= pos.top() || pos.size() == depth) {
			dir.cdUp();
			pos.pop();
			if (pos.isEmpty())
				break;
			pos.top()++;
		}
		else if (pos.size() != depth) {
			dir.cd(files.at(pos.top()));
			pos.push(0);
		}
	}

	return res;
}

void HistoryImport::importPidgin()
{
	QDir logDir = QDir::homePath();
	if (selectByHand->isChecked() || !logDir.cd(".purple/logs"))
		logDir = QFileDialog::getExistingDirectory(mainWidget(), tr("Select log \
directory"), QDir::homePath());

	int total = countLogs(logDir, 3);
	QProgressDialog progress("Parsing history from pidgin ...", "Abort parsing", 0, \
total, mainWidget());  progress.setWindowTitle("Parsing history");
	progress.show();
	cancel = false;

	QString protocolFolder;
	foreach (protocolFolder, logDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
		logDir.cd(protocolFolder);

		QString accountFolder;
		foreach (accountFolder, logDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
			logDir.cd(accountFolder);

			Kopete::ContactList * cList = Kopete::ContactList::self();
			QList<Kopete::Contact *> meList = cList->myself()->contacts();
			Kopete::Contact *me;
			bool found = false;
			foreach (me, meList) {
				qDebug() << me->protocol()->pluginId() << protocolFolder << \
me->account()->accountId() << accountFolder;  if \
                (me->protocol()->pluginId().contains(protocolFolder, \
                Qt::CaseInsensitive) &&
				 me->account()->accountId().contains(accountFolder, Qt::CaseInsensitive)) {
					found = true;
					break;
				}
			}
			if (!found) {
				detailsCursor.insertText(QString("WARNING: Can't find matching account for %1 \
(%2)!\n").arg(accountFolder).arg(protocolFolder));  qDebug() << logDir.path();
				logDir.cdUp();
				qDebug() << logDir.path();
				continue;
			}

			QString chatPartner;
			foreach (chatPartner, logDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
				logDir.cd(chatPartner);

				Kopete::Contact *other = cList->findContact(me->protocol()->pluginId(), \
me->account()->accountId(), chatPartner);  struct Log log;
				if (!other) {
					detailsCursor.insertText(QString("WARNING: Can't find %1 (%2) in your contact \
list. Found logs will not be imported!\n").arg(chatPartner).arg(protocolFolder));  \
logDir.cdUp();  continue;
				}
				else {
					log.me = me;
					log.other = other;
				}

				QString logFile;
				QStringList filter;
				filter << "*.html" << "*.txt";
				foreach(logFile, logDir.entryList(filter, QDir::Files)) {
					QFile file(logDir.filePath(logFile));
					if (!file.open(QIODevice::ReadOnly)) {
						detailsCursor.insertText(QString("WARNING: Can't open file %1. \
Skipping.\n").arg(logDir.filePath(logFile)));  continue;
					}

					if (logFile.endsWith(".html"))
						parsePidginXml(file, &log, QDate::fromString(logFile.left(10), "yyyy-MM-dd"));
					else if (logFile.endsWith(".txt"))
						parsePidginTxt(file, &log, QDate::fromString(logFile.left(10), "yyyy-MM-dd"));

					file.close();

					progress.setValue(progress.value()+1);
					qApp->processEvents();
					if (cancel || progress.wasCanceled()) {
						cancel = true;
						break;
					}
				}

				logs.append(log);
				displayLog(&log);

				if (cancel)
					break;
				logDir.cdUp();
			}
			if (cancel)
				break;
			logDir.cdUp();
		}	
		if (cancel)
			break;
		logDir.cdUp();
	}

}

bool HistoryImport::isNickIncoming(QString nick, struct Log *log)
{
	bool incoming;

	if (nick == log->me->nickName())
		incoming = false;
	else if (nick == log->other->nickName())
		incoming = true;
	else if (knownNicks.contains(nick)) 
		incoming = knownNicks.value(nick);
	else {
		int r = QMessageBox::question(NULL,
			tr("Can't map nickname to account"),
			tr("Did you use \"%1\" as nickname in history?").arg(nick),
			QMessageBox::Yes | QMessageBox::No | QMessageBox::Abort);

		if (r == QMessageBox::Yes) {
			knownNicks.insert(nick, true);
			incoming = true;
		}
		else if (r == QMessageBox::No) {
			knownNicks.insert(nick, false);
			incoming = false;
		}
		else {
			cancel = true;
			return false;
		}
	}
	return incoming;
}

QDateTime HistoryImport::extractTime(QString string, QDate ref)
{
	QDateTime dateTime;
	QTime time;

	// try some formats used by pidgin
	if      ((time = QTime::fromString(string, "(hh:mm:ss)"))    .isValid());
	else if ((time = QTime::fromString(string, "(hh:mm:ss AP)")) .isValid());
	else {
		QString format;
		foreach (format, timeFormats) {
			if ((dateTime = QDateTime::fromString(string, format)).isValid())
				break;
		}
	}

	// check if the century in dateTime is equal to that of our date reference
	if (dateTime.isValid()) {
		int diff = ref.year() - dateTime.date().year();
		dateTime = dateTime.addYears(diff - (diff % 100));
	}

	// if string contains only a time we use ref as date
	if (time.isValid())
		dateTime = QDateTime(ref, time);

	// inform the user about the date problems
	if (!dateTime.isValid())
		detailsCursor.insertText(tr("WARNING: can't parse date \"%1\". You may want to edit \
the file containing this date manually. (example for recognized date strings: \
\"05/31/2008 15:24:30\")\n").arg(string, dateTime.toString("yyyy-MM-dd hh:mm:ss")));


	return dateTime;
}

void HistoryImport::parsePidginTxt(QFile & file, struct Log *log, QDate date)
{
	QByteArray line;
	QTime time;
	QDateTime dateTime;
	QString messageText, nick;
	bool incoming = false; // =false to make the compiler not complain

	while (!file.atEnd()) {
		line = file.readLine();

		if (line[0] == '(') {
			if (!messageText.isEmpty()) {
				// messageText contains an unwished newline at the end
				if (messageText.endsWith("\n"))
					messageText.remove(-1, 1);
				struct Message message;
				message.incoming = incoming;
				message.text = messageText;
				message.timestamp = dateTime;
				log->messages.append(message);
				messageText.clear();
			}

			int endTime = line.indexOf(")")+1;
			dateTime = extractTime(line.left(endTime), date);

			int nickEnd = QRegExp("\\s").indexIn(line, endTime + 1);
			// TODO what if a nickname consists of two words? is this possible?
			// the following while can't be used because in status logs there is no : after \
the nickname :(  //while (line[nickEnd-1] != ':')
			//	nickEnd = QRegExp("\\").indexIn(line, nickEnd);
			if (line[nickEnd -1] != ':') // this line is a status message
				continue;

			nick = line.mid(endTime+1, nickEnd - endTime - 2); // -2 to delete the colon

			incoming = isNickIncoming(nick, log);
			if (cancel)
				return;

			messageText = line.mid(nickEnd + 1);
		}
		else if (line[0] == ' ') {
			// an already started message is continued in this line
			int start = QRegExp("\\S").indexIn(line);
			messageText.append("\n" + line.mid(start));
		}
	}
	if (!messageText.isEmpty()) {
		struct Message message;
		message.incoming = incoming;
		message.text = messageText;
		message.timestamp = dateTime;
		log->messages.append(message);
		messageText.clear();
	}
}
			

void HistoryImport::parsePidginXml(QFile & file, struct Log * log, QDate date)
{
	bool incoming = false, inMessage = false, textComes = false;
	QString messageText, status;
	QTime time;
	QDateTime dateTime;

	// unfortunately pidgin doesn't write <... /> for the <meta> tag
	QByteArray data = file.readAll();
	if (data.contains("<meta")) {
		int metaEnd = data.indexOf(">", data.indexOf("<meta"));
		if (data.at(metaEnd-1) != '/')
			data.insert(metaEnd, "/");
	}

	QXmlStreamReader reader(data);

	while (!reader.atEnd()) {
		reader.readNext();

		if (reader.isStartElement() && reader.name() == "font" && \
!reader.attributes().value("color").isEmpty()) {  if \
(reader.attributes().value("color") == "#A82F2F")  incoming = true;
			else
				incoming = false;

			while (reader.readNext() != QXmlStreamReader::Characters);

			dateTime = extractTime(reader.text().toString(), date);
			inMessage = true;
		}
		if (inMessage && reader.isStartElement() && reader.name() == "b") {
			reader.readNext();
			status = reader.text().toString();
			textComes = true;
		}
		else if (textComes && reader.isCharacters()) {
			messageText += reader.text().toString();
		}
		else if (reader.isStartElement() && reader.name() == "br" && \
!messageText.isEmpty()) {  messageText.remove(0, 1); // remove the leading blank
		
			struct Message message;
			message.incoming = incoming;
			message.text = messageText;
			message.timestamp = dateTime;
			log->messages.append(message);

			messageText.clear();
			textComes = false;
			inMessage = false;
		}
			 
	}
	if (reader.hasError()) {
		// we ignore error 4: premature end of document
		if (reader.error() != 4) {
			int i, pos = 0;
			for (i=1;i<reader.lineNumber();i++)
				pos = data.indexOf('\n', pos) + 1;
			detailsCursor.insertText(tr("WARNING: XML parser error in %1 at line %2, character \
%3: %4").  arg(file.fileName()).arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString()));
  detailsCursor.insertBlock();
			detailsCursor.insertText(tr("\t%1").arg(QString(data.mid(pos, data.indexOf('\n', \
pos) - pos))));  detailsCursor.insertBlock();
		}
	}
}

#include "historyimport.moc"


["historyimport.h" (text/plain)]

/*
    historylogger.cpp

    Copyright (c) 2008 by Timo Schluessler       <timo@schluessler.org>

    Kopete    (c) 2008 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * 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.                                   *
    *                                                                       *
    *************************************************************************
*/


#ifndef HISTORYIMPORT_H
#define HISTORYIMPORT_H

#include <QtGui>

#include <kdialog.h>

#include "kopeteglobal.h"
#include "kopetecontact.h"
#include "kopetemessage.h"

/**
 * @author Timo Schluessler <timo@schluessler.org>
 */
class HistoryImport : public KDialog
{
Q_OBJECT
public:

	HistoryImport(QWidget *parent);
	~HistoryImport();

private:

	/**
	 * Used for internal storage of a message.
	 */
	struct Message {
		bool incoming;
		QString text;
		QDateTime timestamp;
	};
		
	/**
	 * Holds the messages sent and received between two specified contacts.
	 */
	struct Log {
		Kopete::Contact *me;
		Kopete::Contact *other;
		QList<Message> messages;
		/**
		 * Comparison between the Message lists is not neccessary because we need this operator
		 * only in displayLog() to get the index of this log in logs.
		 */
		bool operator==(const struct Log & cmp) {
			if (cmp.me == me && cmp.other == other/* && other.messages == messages*/)
				return true;
			else
				return false;
		}
	};
		
	/**
	 * Parses @param file and appends the found messages to @param log.
	 */
	void parsePidginXml(QFile & file, struct Log *log, QDate date);

	/**
	 * Parses @param file and appends the found messages to @param log.
	 */
	void parsePidginTxt(QFile & file, struct Log *log, QDate date);


	/**
	 * Inserts @param log into treeView and prepares to display it when clicking on it.
	 */
	void displayLog(struct Log *log);

	/**
	 * Looks up if an item with @param text exists already as child of @param parent.
	 * If not, it creates one.
	 */
	QStandardItem * findItem(QString text, QStandardItem *parent);

	/**
	 * @return the number of files found in @param depth th subdir of @param dir.
	 */
	int countLogs(QDir dir, int depth);

	/**
	 * Checks if nickname @param nick can be mapped to either @param log ->me or @param log ->other.
	 * If not it asks the user if it is his nickname or someone elses.
	 */
	bool isNickIncoming(QString nick, struct Log *log);

	/**
	 * Trys to extract the time from @param string using formats specified in timeFormats.
	 * @param ref is used when @param string doesn't contain a date or to adjust a found date.
	 * @param ref is taken from the filename of the log.
	 */
	QDateTime extractTime(QString string, QDate ref);

	QStringList timeFormats;

	QTreeView *treeView;
	QTextEdit *display;

	/**
	 * Used for adding details to the details widget.
	 */
	QTextCursor detailsCursor;

	/**
	 * Enables/disables auto search for log dirs.
	 */
	QCheckBox *selectByHand;

	/**
	 * Contains all already parsed logs.
	 */
	QList<Log> logs;

	/**
	 * Used for mapping nickname to account. See isNickIncoming().
	 */
	QHash<QString, bool> knownNicks;

	int amount;
	bool cancel;

private slots:
	/**
	 * Starts parsing history from pidgin.
	 * Default path is ~/.purple/logs.
	 */
	void importPidgin(void);

	void save(void);
	void itemClicked(const QModelIndex & index);
};

#endif


["kopete-history-import.patch" (text/plain)]

Index: kopete/plugins/history/historylogger.cpp
===================================================================
--- kopete/plugins/history/historylogger.cpp	(revision 890701)
+++ kopete/plugins/history/historylogger.cpp	(working copy)
@@ -117,16 +117,16 @@
 }
 
 
-QDomDocument HistoryLogger::getDocument(const Kopete::Contact *c, unsigned int month \
, bool canLoad , bool* contain) +QDomDocument HistoryLogger::getDocument(const \
Kopete::Contact *c, unsigned int month , const QDate date , bool canLoad , bool* \
contain)  {
-	if(m_realMonth!=QDate::currentDate().month())
+	if(m_realMonth!=date.month() /*QDate::currentDate().month()*/)
 	{ //We changed month, our index is not correct anymore, clean memory.
 	  // or we will see what i called "the 31 midnight bug"(TM) :-)  -Olivier
 		m_documents.clear();
 		m_cachedMonth=-1;
 		m_currentMonth++; //Not usre it's ok, but should work;
 		m_oldMonth++;     // idem
-		m_realMonth=QDate::currentDate().month();
+		m_realMonth=date.month();//QDate::currentDate().month();
 	}
 
 	if(!m_metaContact)
@@ -149,7 +149,7 @@
 		return documents[month];
 
 
-	QDomDocument doc =  getDocument(c, QDate::currentDate().addMonths(0-month), \
canLoad, contain); +	QDomDocument doc =  getDocument(c, date.addMonths(0-month) \
/*QDate::currentDate().addMonths(0-month)*/, canLoad, contain);  
 	documents.insert(month, doc);
 	m_documents[c]=documents;
@@ -255,7 +255,9 @@
 		return;
 	}
 
-	QDomDocument doc=getDocument(c,0);
+
+
+	QDomDocument doc=getDocument(c, 0, msg.timestamp().date());
 	QDomElement docElem = doc.documentElement();
 
 	if(docElem.isNull())
@@ -293,7 +295,7 @@
 	// On hight-traffic channel, saving can take lots of CPU. (because the file is big)
 	// So i wait a time proportional to the time needed to save..
 
-	const QString filename=getFileName(c,QDate::currentDate());
+	const QString filename=getFileName(c, msg.timestamp().date());
 	if(!m_toSaveFileName.isEmpty() && m_toSaveFileName != filename)
 	{ //that mean the contact or the month has changed, save it now.
 		saveToDisk();
Index: kopete/plugins/history/historylogger.h
===================================================================
--- kopete/plugins/history/historylogger.h	(revision 890701)
+++ kopete/plugins/history/historylogger.h	(working copy)
@@ -20,6 +20,7 @@
 
 #include <QObject>
 #include <QList>
+#include <QDate>
 #include <QtCore/QMap>
 #include <QtXml/QDomDocument>
 
@@ -148,7 +149,7 @@
 	 * Get the document, open it is @param canload is true, contain is set to false if \
                the document
 	 * is not already contained
 	 */
-	QDomDocument getDocument(const Kopete::Contact *c, unsigned int month , bool \
canLoad=true , bool* contain=0L); +	QDomDocument getDocument(const Kopete::Contact \
*c, unsigned int month , const QDate date = QDate::currentDate(), bool canLoad=true , \
bool* contain=0L);  
 	QDomDocument getDocument(const Kopete::Contact *c, const QDate date, bool \
canLoad=true, bool* contain=0L);  
Index: kopete/plugins/history/historypreferences.cpp
===================================================================
--- kopete/plugins/history/historypreferences.cpp	(revision 890701)
+++ kopete/plugins/history/historypreferences.cpp	(working copy)
@@ -19,6 +19,7 @@
 #include "historypreferences.h"
 #include "historyconfig.h"
 #include "ui_historyprefsui.h"
+#include "historyimport.h"
 
 #include <kgenericfactory.h>
 
@@ -51,6 +52,7 @@
 		this, SLOT(slotModified()));
 	connect(p->History_color, SIGNAL(changed(const QColor&)),
 		this, SLOT(slotModified()));
+	connect(p->importLogs, SIGNAL(clicked(void)), this, SLOT(importLogs(void)));
 }
 
 HistoryPreferences::~HistoryPreferences()
@@ -94,4 +96,10 @@
 	emit KCModule::changed(true);
 }
 
+void HistoryPreferences::importLogs(void)
+{
+	HistoryImport importer(this);
+	importer.exec();
+}
+
 #include "historypreferences.moc"
Index: kopete/plugins/history/historypreferences.h
===================================================================
--- kopete/plugins/history/historypreferences.h	(revision 890701)
+++ kopete/plugins/history/historypreferences.h	(working copy)
@@ -42,6 +42,7 @@
 	private slots:
 		void slotModified();
 		void slotShowPreviousChanged(bool);
+		void importLogs(void);
 
 	private:
 		Ui::HistoryPrefsUI *p;
Index: kopete/plugins/history/historyprefsui.ui
===================================================================
--- kopete/plugins/history/historyprefsui.ui	(revision 890701)
+++ kopete/plugins/history/historyprefsui.ui	(working copy)
@@ -14,42 +14,21 @@
    <property name="spacing" >
     <number>6</number>
    </property>
-   <property name="leftMargin" >
+   <property name="margin" >
     <number>0</number>
    </property>
-   <property name="topMargin" >
-    <number>0</number>
-   </property>
-   <property name="rightMargin" >
-    <number>0</number>
-   </property>
-   <property name="bottomMargin" >
-    <number>0</number>
-   </property>
    <item>
     <widget class="QGroupBox" name="groupBox" >
      <property name="title" >
       <string>Chat History</string>
      </property>
      <layout class="QGridLayout" >
-      <property name="leftMargin" >
+      <property name="margin" >
        <number>9</number>
       </property>
-      <property name="topMargin" >
-       <number>9</number>
-      </property>
-      <property name="rightMargin" >
-       <number>9</number>
-      </property>
-      <property name="bottomMargin" >
-       <number>9</number>
-      </property>
-      <property name="horizontalSpacing" >
+      <property name="spacing" >
        <number>6</number>
       </property>
-      <property name="verticalSpacing" >
-       <number>6</number>
-      </property>
       <item row="2" column="0" >
        <spacer>
         <property name="orientation" >
@@ -58,7 +37,7 @@
         <property name="sizeType" >
          <enum>QSizePolicy::Fixed</enum>
         </property>
-        <property name="sizeHint" >
+        <property name="sizeHint" stdset="0" >
          <size>
           <width>16</width>
           <height>20</height>
@@ -164,6 +143,13 @@
         </property>
        </widget>
       </item>
+      <item row="4" column="1" >
+       <widget class="QPushButton" name="importLogs" >
+        <property name="text" >
+         <string>Import History</string>
+        </property>
+       </widget>
+      </item>
      </layout>
     </widget>
    </item>
@@ -175,7 +161,7 @@
      <property name="sizeType" >
       <enum>QSizePolicy::Expanding</enum>
      </property>
-     <property name="sizeHint" >
+     <property name="sizeHint" stdset="0" >
       <size>
        <width>341</width>
        <height>16</height>
Index: kopete/plugins/history/CMakeLists.txt
===================================================================
--- kopete/plugins/history/CMakeLists.txt	(revision 890701)
+++ kopete/plugins/history/CMakeLists.txt	(working copy)
@@ -28,7 +28,7 @@
 
 ########### next target ###############
 
-set(kcm_kopete_history_PART_SRCS historypreferences.cpp )
+set(kcm_kopete_history_PART_SRCS historypreferences.cpp historyimport.cpp \
historylogger.cpp )  
 kde4_add_ui_files(kcm_kopete_history_PART_SRCS historyprefsui.ui )
 



_______________________________________________
kopete-devel mailing list
kopete-devel@kde.org
https://mail.kde.org/mailman/listinfo/kopete-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic