diff --git a/plugins/highlight/highlightconfig.cpp b/plugins/highlight/highlightconfig.cpp index 707983cdf..ff78da872 100644 --- a/plugins/highlight/highlightconfig.cpp +++ b/plugins/highlight/highlightconfig.cpp @@ -1,180 +1,180 @@ /* highlightconfig.cpp Copyright (c) 2003 by Olivier Goffart Copyright (c) 2003 by Matt Rogers Kopete (c) 2002-2003 by the Kopete developers ************************************************************************* * * * 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 "highlightconfig.h" #include #include #include #include #include #include #include #include #include #include "filter.h" HighlightConfig::HighlightConfig() { } HighlightConfig::~HighlightConfig() { qDeleteAll(m_filters); m_filters.clear(); } void HighlightConfig::removeFilter(Filter *f) { m_filters.removeAll(f); delete f; } void HighlightConfig::appendFilter(Filter *f) { m_filters.append(f); } QList HighlightConfig::filters() const { return m_filters; } Filter *HighlightConfig::newFilter() { Filter *filtre = new Filter(); filtre->caseSensitive = false; filtre->isRegExp = false; filtre->setImportance = false; filtre->importance = 1; filtre->setBG = false; filtre->setFG = false; filtre->raiseView = false; filtre->displayName = i18n("-New filter-"); m_filters.append(filtre); return filtre; } void HighlightConfig::load() { m_filters.clear(); //clear filters - const QString filename = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') + QStringLiteral("highlight.xml"); + const QString filename = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QLatin1Char('/') + QStringLiteral("highlight.xml"); if (filename.isEmpty()) { return; } QDomDocument filterList(QLatin1String("highlight-plugin")); QFile filterListFile(filename); filterListFile.open(QIODevice::ReadOnly); filterList.setContent(&filterListFile); QDomElement list = filterList.documentElement(); QDomNode node = list.firstChild(); while (!node.isNull()) { QDomElement element = node.toElement(); if (!element.isNull()) { // if( element.tagName() == QString::fromLatin1("filter") // { Filter *filtre = newFilter(); QDomNode filterNode = node.firstChild(); while (!filterNode.isNull()) { QDomElement filterElement = filterNode.toElement(); if (!filterElement.isNull()) { if (filterElement.tagName() == QLatin1String("display-name")) { filtre->displayName = filterElement.text(); } else if (filterElement.tagName() == QLatin1String("search")) { filtre->search = filterElement.text(); filtre->caseSensitive = (filterElement.attribute(QStringLiteral("caseSensitive"), QStringLiteral("1")) == QLatin1String("1")); filtre->isRegExp = (filterElement.attribute(QStringLiteral("regExp"), QStringLiteral("0")) == QLatin1String("1")); } else if (filterElement.tagName() == QLatin1String("FG")) { filtre->FG = filterElement.text(); filtre->setFG = (filterElement.attribute(QStringLiteral("set"), QStringLiteral("0")) == QLatin1String("1")); } else if (filterElement.tagName() == QLatin1String("BG")) { filtre->BG = filterElement.text(); filtre->setBG = (filterElement.attribute(QStringLiteral("set"), QStringLiteral("0")) == QLatin1String("1")); } else if (filterElement.tagName() == QLatin1String("importance")) { filtre->importance = filterElement.text().toUInt(); filtre->setImportance = (filterElement.attribute(QStringLiteral("set"), QStringLiteral("0")) == QLatin1String("1")); } else if (filterElement.tagName() == QLatin1String("raise")) { filtre->raiseView = (filterElement.attribute(QStringLiteral("set"), QStringLiteral("0")) == QLatin1String("1")); } } filterNode = filterNode.nextSibling(); } // } } node = node.nextSibling(); } filterListFile.close(); } void HighlightConfig::save() { - const QString fileName = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') + QStringLiteral("highlight.xml"); + const QString fileName = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QLatin1Char('/') + QStringLiteral("highlight.xml"); QSaveFile file(fileName); if (file.open(QIODevice::WriteOnly)) { QTextStream stream(&file); stream.setCodec(QTextCodec::codecForName("UTF-8")); QString xml = QString::fromLatin1( "\n" "\n" "\n"); // Save metafilter information. foreach (Filter *filtre, m_filters) { xml += QLatin1String(" \n ") + filtre->displayName.toHtmlEscaped() + QLatin1String("\n"); xml += QLatin1String(" (filtre->caseSensitive)) +QLatin1String("\" regExp=\"") + QString::number(static_cast(filtre->isRegExp)) +QLatin1String("\">") + filtre->search.toHtmlEscaped() + QLatin1String("\n"); xml += QLatin1String(" (filtre->setBG)) +QLatin1String("\">") + filtre->BG.name().toHtmlEscaped() + QLatin1String("\n"); xml += QLatin1String(" (filtre->setFG)) +QLatin1String("\">") + filtre->FG.name().toHtmlEscaped() + QLatin1String("\n"); xml += QLatin1String(" (filtre->setImportance)) +QLatin1String("\">") + QString::number(filtre->importance) + QLatin1String("\n"); xml += QLatin1String(" (filtre->raiseView)) +QLatin1String("\">\n"); xml += QLatin1String(" \n"); } xml += QLatin1String("\n"); stream << xml; } } // vim: set noet ts=4 sts=4 sw=4: diff --git a/plugins/statistics/statisticsdialog.cpp b/plugins/statistics/statisticsdialog.cpp index 4075ebd58..01ec6376b 100644 --- a/plugins/statistics/statisticsdialog.cpp +++ b/plugins/statistics/statisticsdialog.cpp @@ -1,670 +1,670 @@ /* statisticsdialog.cpp - Kopete Statistics Dialog Copyright (c) 2003-2004 by Marc Cramdal Copyright (c) 2007 by the Kopete Developers ************************************************************************* * * * 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 "statisticsdialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "kopetemetacontact.h" #include "kopeteonlinestatus.h" #include "statisticscontact.h" #include "ui_statisticswidgetbase.h" #include "statisticsplugin.h" #include "statisticsdb.h" StatisticsDialog::StatisticsDialog (StatisticsContact *contact, StatisticsDB *db, QWidget *parent) : KDialog(parent) , m_db(db) , m_contact(contact) { setAttribute(Qt::WA_DeleteOnClose, true); setButtons(KDialog::Close); setDefaultButton(KDialog::Close); setCaption(i18n("Statistics for %1", contact->metaContact()->displayName())); QWidget *w = new QWidget(this); dialogUi = new Ui::StatisticsWidgetUI(); dialogUi->setupUi(w); setMainWidget(w); KHBox *generalHBox = new KHBox(this); generalHTMLPart = new KHTMLPart(generalHBox); connect(generalHTMLPart->browserExtension(), SIGNAL(openUrlRequestDelayed(KUrl,KParts::OpenUrlArguments,KParts::BrowserArguments)), this, SLOT(slotOpenURLRequest(KUrl,KParts::OpenUrlArguments,KParts::BrowserArguments))); generalHTMLPart->setJScriptEnabled(false); generalHTMLPart->setJavaEnabled(false); generalHTMLPart->setMetaRefreshEnabled(false); generalHTMLPart->setPluginsEnabled(false); generalHTMLPart->setOnlyLocalReferences(true); dialogUi->tabWidget->insertTab(0, generalHBox, i18n("General")); dialogUi->tabWidget->setCurrentIndex(0); KColorScheme scheme(QPalette::Active, KColorScheme::View); m_onlineColor = scheme.background(KColorScheme::ActiveBackground).color().darker(130); m_awayColor = scheme.background(KColorScheme::NeutralBackground).color().darker(130); m_offlineColor = scheme.background(KColorScheme::AlternateBackground).color().darker(130); m_backgroundColor = scheme.background(KColorScheme::NormalBackground).color().darker(130); m_textColor = scheme.foreground(KColorScheme::NormalText).color(); calendarHTMLPart = new KHTMLPart(dialogUi->calendarHBox); calendarHTMLPart->setJScriptEnabled(false); calendarHTMLPart->setJavaEnabled(false); calendarHTMLPart->setMetaRefreshEnabled(false); calendarHTMLPart->setPluginsEnabled(false); calendarHTMLPart->setOnlyLocalReferences(true); dialogUi->calendarKey->setTextFormat(Qt::RichText); dialogUi->calendarKey->setText(i18n("Key: " "Online " "Away " "Offline", m_onlineColor.name(), m_awayColor.name(), m_offlineColor.name())); dialogUi->datePicker->setDate(QDate::currentDate()); - connect(dialogUi->datePicker, SIGNAL(dateChanged(QDate)), this, SLOT(fillCalendarCells())); - connect(dialogUi->datePicker, SIGNAL(dateChanged(QDate)), this, SLOT(generateOneDayStats())); + connect(dialogUi->datePicker, &KDatePicker::dateChanged, this, &StatisticsDialog::fillCalendarCells); + connect(dialogUi->datePicker, &KDatePicker::dateChanged, this, &StatisticsDialog::generateOneDayStats); setFocus(); setEscapeButton(Close); generatePageGeneral(); fillCalendarCells(); generateOneDayStats(); } StatisticsDialog::~StatisticsDialog() { delete dialogUi; } // We only generate pages when the user clicks on a link void StatisticsDialog::slotOpenURLRequest(const KUrl &url, const KParts::OpenUrlArguments &, const KParts::BrowserArguments &) { if (url.protocol() == QLatin1String("main")) { generatePageGeneral(); } else if (url.protocol() == QLatin1String("dayofweek")) { generatePageForDay(url.path().toInt()); } else if (url.protocol() == QLatin1String("monthofyear")) { generatePageForMonth(url.path().toInt()); } } /*void StatisticsDialog::parseTemplate(QString Template) { QString fileString = ::locate("appdata", "kopete_statistics.template.html"); QString templateString; QFile file(file); if (file.open(QIODevice::ReadOnly)) { QTextStream stream(&file); templateString = stream.read(); file.close(); } // The template is loaded in templateString now. templateString.strReplace( }*/ void StatisticsDialog::generatePageForMonth(const int monthOfYear) { QStringList values = m_db->query(QString("SELECT status, datetimebegin, datetimeend " "FROM contactstatus WHERE metacontactid LIKE '%1' ORDER BY datetimebegin;").arg(m_contact->metaContactId())); QStringList values2; for (int i = 0; i < values.count(); i += 3) { QDateTime dateTimeBegin; dateTimeBegin.setTime_t(values[i+1].toInt()); /// @todo Same as for Day, check if second datetime is on the same month if (dateTimeBegin.date().month() == monthOfYear) { values2.push_back(values[i]); values2.push_back(values[i+1]); values2.push_back(values[i+2]); } } generatePageFromQStringList(values2, QDate::longMonthName(monthOfYear)); } void StatisticsDialog::generatePageForDay(const int dayOfWeek) { QStringList values = m_db->query(QString("SELECT status, datetimebegin, datetimeend " "FROM contactstatus WHERE metacontactid LIKE '%1' ORDER BY datetimebegin;").arg(m_contact->metaContactId())); QStringList values2; for (int i = 0; i < values.count(); i += 3) { QDateTime dateTimeBegin; dateTimeBegin.setTime_t(values[i+1].toInt()); QDateTime dateTimeEnd; dateTimeEnd.setTime_t(values[i+2].toInt()); if (dateTimeBegin.date().dayOfWeek() == dayOfWeek) { if (dateTimeEnd.date().dayOfWeek() != dayOfWeek) { // Day of week is not the same at beginning and at end of the event values2.push_back(values[i]); values2.push_back(values[i+1]); // datetime from value[i+1] dateTimeBegin = QDateTime(dateTimeBegin.date(), QTime(0, 0, 0)); dateTimeBegin.addSecs(dateTimeBegin.time().secsTo(QTime(23, 59, 59))); values2.push_back(QString::number(dateTimeBegin.toTime_t())); } else { values2.push_back(values[i]); values2.push_back(values[i+1]); values2.push_back(values[i+2]); } } } generatePageFromQStringList(values2, QDate::longDayName(dayOfWeek)); } /// @todo chart problem at midnight. void StatisticsDialog::generatePageFromQStringList(QStringList values, const QString &subTitle) { KColorScheme colorScheme(QPalette::Active, KColorScheme::View); generalHTMLPart->begin(); generalHTMLPart->write(QString("" +i18n("

Statistics for %1

", m_contact->metaContact()->displayName()) +"

%1


").arg(subTitle)); generalHTMLPart->write(i18n("
General
" "Days: " "Monday " "Tuesday " "Wednesday " "Thursday " "Friday " "Saturday " "Sunday
" "Months: " "January " "February " "March " "April " "May " "June " "July " "August " "September " "October " "November " "December " "

")); // dialogUi->listView->addColumn(i18n("Status")); // dialogUi->listView->addColumn(i18n("Start Date")); // dialogUi->listView->addColumn(i18n("End Date")); // dialogUi->listView->addColumn(i18n("Start Date")); // dialogUi->listView->addColumn(i18n("End Date")); QString todayString; todayString.append(i18n("

Today

")); bool today; int totalTime = 0; // this is in seconds int totalAwayTime = 0; // this is in seconds int totalOnlineTime = 0; // this is in seconds int totalOfflineTime = 0; // idem int hours[24]; // in seconds, too int iMaxHours = 0; int hoursOnline[24]; // this is in seconds int iMaxHoursOnline = 0; int hoursAway[24]; // this is in seconds int iMaxHoursAway = 0; int hoursOffline[24]; // this is in seconds. Hours where we are sure contact is offline int iMaxHoursOffline = 0; for (uint i = 0; i < 24; i++) { hours[i] = 0; hoursOnline[i] = 0; hoursAway[i] = 0; hoursOffline[i] = 0; } for (int i = 0; i < values.count(); i += 3 /* because SELECT 3 columns */) { /* Here we try to interpret one database entry... What's important here, is to not count two times the same hour for instance This is why there are some if in all this stuff ;-) */ // it is the STARTDATE from the database QDateTime dateTime1; dateTime1.setTime_t(values[i+1].toInt()); // it is the ENDDATE from the database QDateTime dateTime2; dateTime2.setTime_t(values[i+2].toInt()); if (dateTime1.date() == QDate::currentDate() || dateTime2.date() == QDate::currentDate()) { today = true; } else { today = false; } totalTime += dateTime1.secsTo(dateTime2); if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Online) { totalOnlineTime += dateTime1.secsTo(dateTime2); } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Away) { totalAwayTime += dateTime1.secsTo(dateTime2); } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Busy) { totalAwayTime += dateTime1.secsTo(dateTime2); } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Offline) { totalOfflineTime += dateTime1.secsTo(dateTime2); } /* * To build the chart/hours */ // Number of hours between dateTime1 and dateTime2 int nbHours = (int)(dateTime1.secsTo(dateTime2) /3600.0); uint tempHour = dateTime1.time().hour() == dateTime2.time().hour() ? dateTime1.secsTo(dateTime2) // (*) : 3600 - dateTime1.time().minute() *60 - dateTime1.time().second(); hours[dateTime1.time().hour() ] += tempHour; if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Online) { hoursOnline[dateTime1.time().hour() ] += tempHour; } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Away) { hoursAway[dateTime1.time().hour() ] += tempHour; } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Busy) { hoursAway[dateTime1.time().hour() ] += tempHour; } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Offline) { hoursOffline[dateTime1.time().hour() ] += tempHour; } for (int j = dateTime1.time().hour() +1; j < dateTime1.time().hour() + nbHours - 1; j++) { hours[j%24] += 3600; if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Online) { hoursOnline[j%24] += 3600; } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Away) { hoursAway[j%24] += 3600; } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Busy) { hoursAway[j%24] += 3600; } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Offline) { hoursOffline[j%24] += 3600; } } if (dateTime1.time().hour() != dateTime2.time().hour()) { // We don't want to count this if the hour from dateTime2 is the same than the one from dateTime1 // since it as already been taken in account in the (*) instruction tempHour = dateTime2.time().minute() *60 +dateTime2.time().second(); hours[dateTime2.time().hour() ] += tempHour; if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Online) { hoursOnline[dateTime2.time().hour() ] += tempHour; } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Away) { hoursAway[dateTime2.time().hour() ] += tempHour; } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Busy) { hoursAway[dateTime2.time().hour() ] += tempHour; } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Offline) { hoursOffline[dateTime2.time().hour() ] += tempHour; } } if (today) { QString status; if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Online) { status = i18n("Online"); } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Away) { status = i18n("Away"); } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Busy) { status = i18n("Busy"); } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Offline) { status = i18n("Offline"); } todayString.append(QStringLiteral("").arg(status, dateTime1.time().toString(), dateTime2.time().toString())); } // We add a listview item to the log list // QDateTime listViewDT1, listViewDT2; // listViewDT1.setTime_t(values[i+1].toInt()); // listViewDT2.setTime_t(values[i+2].toInt()); // new K3ListViewItem(dialogUi->listView, values[i], values[i+1], values[i+2], listViewDT1.toString(), listViewDT2.toString()); } todayString.append("
StatusFromTo
%2%3%4
"); // Get the max from the hours* for (uint i = 1; i < 24; i++) { if (hours[iMaxHours] < hours[i]) { iMaxHours = i; } if (hoursOnline[iMaxHoursOnline] < hoursOnline[i]) { iMaxHoursOnline = i; } if (hoursOffline[iMaxHoursOffline] < hoursOffline[i]) { iMaxHoursOffline = i; } if (hoursAway[iMaxHoursAway] < hoursAway[i]) { iMaxHoursAway = i; } } // /* * Here we really generate the page */ // Some "total times" generalHTMLPart->write(i18n("
")); generalHTMLPart->write(i18n("" "Total visible time : %2
", m_contact->metaContact()->displayName(), stringFromSeconds(totalOnlineTime + totalAwayTime))); generalHTMLPart->write(i18n("" "Total online time : %2
", m_contact->metaContact()->displayName(), stringFromSeconds(totalOnlineTime))); generalHTMLPart->write(i18n("Total busy time : %2
", m_contact->metaContact()->displayName(), stringFromSeconds(totalAwayTime))); generalHTMLPart->write(i18n("Total offline time : %2", m_contact->metaContact()->displayName(), stringFromSeconds(totalOfflineTime))); generalHTMLPart->write(QStringLiteral("
")); if (subTitle == i18n("General information")) { /* * General stats that should not be shown on "day" or "month" pages */ generalHTMLPart->write(QStringLiteral("
")); generalHTMLPart->write(i18np("Average message length: %1 character
", "Average message length: %1 characters
", m_contact->messageLength())); generalHTMLPart->write(i18np("Time between two messages: %1 second", "Time between two messages: %1 seconds", m_contact->timeBetweenTwoMessages())); generalHTMLPart->write(QStringLiteral("
")); generalHTMLPart->write(QStringLiteral("
")); generalHTMLPart->write(i18n("Last talk : %2
", m_contact->metaContact()->displayName(), QLocale().toString(m_contact->lastTalk()))); generalHTMLPart->write(i18n("Last time present : %2", m_contact->metaContact()->displayName(), QLocale().toString( m_contact->lastPresent()))); generalHTMLPart->write(QStringLiteral("
")); //generalHTMLPart->write(QString("
")); //generalHTMLPart->write(i18n("Main online events :
").arg(m_contact->metaContact()->displayName())); //QValueList mainEvents = m_contact->mainEvents(Kopete::OnlineStatus::Online); //for (uint i=0; iwrite(QString("%1
").arg(mainEvents[i].toString())); //generalHTMLPart->write(QString("
")); generalHTMLPart->write("
"); generalHTMLPart->write(i18n("Is %1 since %2", Kopete::OnlineStatus(m_contact->oldStatus()).description(), QLocale().toString(m_contact->oldStatusDateTime()))); generalHTMLPart->write(QStringLiteral("
")); } /* * Chart which shows the hours where plugin has seen this contact online */ generalHTMLPart->write(QStringLiteral("
")); generalHTMLPart->write(QStringLiteral("")); generalHTMLPart->write(QStringLiteral("")); generalHTMLPart->write(QStringLiteral("
") + i18nc("TRANSLATOR: please reverse 'left' and 'right' as appropriate for your language", "When was this contact visible?
All charts are in 24 blocks, " "one per hour, encompassing one day. %1 is on the left, " "and %2 is on the right.", QLocale().toString(QTime(0, 0)), QLocale().toString(QTime(23, 59))) + QStringLiteral("
")); QString chartString; QByteArray colorPath; QPixmap pixmap(1, 1); pixmap.fill(Qt::black); // Generate base64 picture. QByteArray tempArray; QBuffer tempBuffer(&tempArray); tempBuffer.open(QIODevice::WriteOnly); if (pixmap.save(&tempBuffer, "PNG")) { colorPath = tempArray.toBase64(); } for (uint i = 0; i < 24; i++) { int hrWidth = qRound((double)(hoursOnline[i] + hoursAway[i]) / (double)hours[iMaxHours]*100.); chartString += QStringLiteral("metaContact()->displayName(), hrWidth) + QStringLiteral("\">"); } generalHTMLPart->write(chartString); generalHTMLPart->write(QStringLiteral("
") +i18n("Online time") +QStringLiteral("") +i18n("Away time") +QStringLiteral("") +i18n("Offline time") +QStringLiteral("
")); generalHTMLPart->write(generateHTMLChart(hoursOnline, hoursAway, hoursOffline, i18n("online"), m_onlineColor)); generalHTMLPart->write(QStringLiteral("")); generalHTMLPart->write(generateHTMLChart(hoursAway, hoursOnline, hoursOffline, i18n("away"), m_awayColor)); generalHTMLPart->write(QStringLiteral("")); generalHTMLPart->write(generateHTMLChart(hoursOffline, hoursAway, hoursOnline, i18n("offline"), m_offlineColor)); generalHTMLPart->write(QStringLiteral("
")); if (subTitle == i18n("General information")) { /* On main page, show the different status of the contact today */ generalHTMLPart->write(QString(todayString)); } generalHTMLPart->write(QStringLiteral("")); generalHTMLPart->end(); } void StatisticsDialog::generatePageGeneral() { QStringList values; values = m_db->query(QString("SELECT status, datetimebegin, datetimeend " "FROM contactstatus WHERE metacontactid LIKE '%1' ORDER BY datetimebegin;") .arg(m_contact->metaContactId())); generatePageFromQStringList(values, i18n("General information")); } QString StatisticsDialog::generateHTMLChart(const int *hours, const int *hours2, const int *hours3, const QString &caption, const QColor &color) { QString chartString; QByteArray colorPath; QPixmap pixmap(1, 1); pixmap.fill(color); // Generate base64 picture. QByteArray tempArray; QBuffer tempBuffer(&tempArray); tempBuffer.open(QIODevice::WriteOnly); if (pixmap.save(&tempBuffer, "PNG")) { colorPath = tempArray.toBase64(); } for (uint i = 0; i < 24; i++) { int totalTime = hours[i] + hours2[i] + hours3[i]; int hrWidth = qRound((double)hours[i]/ (double)totalTime*100.); chartString += QStringLiteral("metaContact()->displayName(), hrWidth, caption) +"\">"; } return chartString; } QString StatisticsDialog::stringFromSeconds(const int seconds) { return KFormat().formatDuration((unsigned long)seconds * 1000); } void StatisticsDialog::fillCalendarCells() { QDateTime firstOfMonth(dialogUi->datePicker->date()); QDateTime lastOfMonth(dialogUi->datePicker->date()); firstOfMonth.setDate(QDate(firstOfMonth.date().year(), firstOfMonth.date().month(), 1)); lastOfMonth.setDate(QDate(lastOfMonth.date().year(), lastOfMonth.date().month(), lastOfMonth.date().daysInMonth())); QStringList values = m_db->query(QString("SELECT status, datetimebegin, datetimeend " "FROM contactstatus WHERE metacontactid LIKE '%1' AND " "datetimebegin BETWEEN '%2' AND '%3' " "AND datetimeend BETWEEN '%4' AND '%5';") .arg(m_contact->metaContactId()) .arg(firstOfMonth.toTime_t()) .arg(lastOfMonth.toTime_t()) .arg(firstOfMonth.toTime_t()) .arg(lastOfMonth.toTime_t())); QVector statuses(32, Kopete::OnlineStatus::Unknown); // list of dates and statuses using begintimes for (int i = 0; i < values.count(); i += 3) { QDate date(QDateTime::fromTime_t(values.at(i+1).toUInt()).date()); Kopete::OnlineStatus status = Kopete::OnlineStatus::statusStringToType(values.at(i)); if (status > statuses.at(date.day())) { statuses[date.day() ] = status; } } // list of dates and statuses using endtimes for (int i = 0; i < values.count(); i += 3) { QDate date(QDateTime::fromTime_t(values.at(i+2).toUInt()).date()); Kopete::OnlineStatus status = Kopete::OnlineStatus::statusStringToType(values.at(i)); if (status > statuses.at(date.day())) { statuses[date.day() ] = status; } } for (int i = 0; i < statuses.count(); i++) { QColor color(m_backgroundColor); if (statuses.at(i) == Kopete::OnlineStatus::Online) { color = m_onlineColor; } else if (statuses.at(i) == Kopete::OnlineStatus::Away) { color = m_awayColor; } else if (statuses.at(i) == Kopete::OnlineStatus::Busy) { color = m_awayColor; } else if (statuses.at(i) == Kopete::OnlineStatus::Offline) { color = m_offlineColor; } // dialogUi->datePicker->dateTable()->setCustomDatePainting ( // QDate ( firstOfMonth.date().year(), firstOfMonth.date().month(), i ), // m_textColor, KDateTable::RectangleMode, color ); } dialogUi->datePicker->update(); } void StatisticsDialog::generateOneDayStats() { QDate day = dialogUi->datePicker->date(); QDateTime topOfDay = QDateTime(day); QDateTime endOfDay = topOfDay.addDays(1); QStringList values = m_db->query(QString("SELECT status, datetimebegin, datetimeend " "FROM contactstatus WHERE metacontactid LIKE '%1' AND " "datetimebegin BETWEEN '%2' AND '%3' " "AND datetimeend BETWEEN '%4' AND '%5';") .arg(m_contact->metaContactId()) .arg(topOfDay.toTime_t()) .arg(endOfDay.toTime_t()) .arg(topOfDay.toTime_t()) .arg(endOfDay.toTime_t())); QString todayString; todayString.append(i18n("

%1

", QLocale().toString(topOfDay.date()))); for (int i = 0; i < values.count(); i += 3) { // it is the STARTDATE from the database QDateTime dateTime1; dateTime1.setTime_t(values[i+1].toInt()); // it is the ENDDATE from the database QDateTime dateTime2; dateTime2.setTime_t(values[i+2].toInt()); QString status; if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Online) { status = i18n("Online"); } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Away) { status = i18n("Away"); } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Busy) { status = i18n("Busy"); } else if (Kopete::OnlineStatus::statusStringToType(values[i]) == Kopete::OnlineStatus::Offline) { status = i18n("Offline"); } todayString.append(QStringLiteral("").arg(status, dateTime1.time().toString(), dateTime2.time().toString())); } todayString.append("
StatusFromTo
%2%3%4
"); calendarHTMLPart->begin(); calendarHTMLPart->write(QString("")); calendarHTMLPart->write(todayString); calendarHTMLPart->write(QStringLiteral("")); calendarHTMLPart->end(); } diff --git a/plugins/statistics/statisticsplugin.cpp b/plugins/statistics/statisticsplugin.cpp index a0e097149..b25a09474 100644 --- a/plugins/statistics/statisticsplugin.cpp +++ b/plugins/statistics/statisticsplugin.cpp @@ -1,348 +1,340 @@ /* statisticsplugin.cpp Copyright (c) 2003-2004 by Marc Cramdal Copyright (c) 2007 by the Kopete Developers ************************************************************************* * * * 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 "statisticsplugin.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "kopetechatsessionmanager.h" #include "kopetemetacontact.h" #include "kopeteview.h" #include "kopetecontactlist.h" #include "kopeteuiglobal.h" #include "kopetemessageevent.h" #include "kopeteonlinestatus.h" #include "kopeteaccountmanager.h" #include "kopeteaccount.h" #include "kopetecontact.h" #include "statisticscontact.h" #include "statisticsdialog.h" #include "statisticsadaptor.h" #include "statisticsdb.h" K_PLUGIN_FACTORY(StatisticsPluginFactory, registerPlugin(); ) K_EXPORT_PLUGIN(StatisticsPluginFactory("kopete_statistics")) StatisticsPlugin::StatisticsPlugin(QObject *parent, const QVariantList & /*args*/) : Kopete::Plugin(parent) { m_db = nullptr; QAction *viewMetaContactStatistics = new QAction(QIcon::fromTheme(QStringLiteral("view-statistics")), i18n("View &Statistics"), this); actionCollection()->addAction(QStringLiteral("viewMetaContactStatistics"), viewMetaContactStatistics); - connect(viewMetaContactStatistics, SIGNAL(triggered(bool)), this, SLOT(slotViewStatistics())); + connect(viewMetaContactStatistics, &QAction::triggered, this, &StatisticsPlugin::slotViewStatistics); viewMetaContactStatistics->setEnabled(Kopete::ContactList::self()->selectedMetaContacts().count() == 1); - connect(Kopete::ChatSessionManager::self(), SIGNAL(chatSessionCreated(Kopete::ChatSession *)), - this, SLOT(slotViewCreated(Kopete::ChatSession *))); - connect(Kopete::ChatSessionManager::self(), SIGNAL(aboutToReceive(Kopete::Message&)), - this, SLOT(slotAboutToReceive(Kopete::Message&))); + connect(Kopete::ChatSessionManager::self(), &Kopete::ChatSessionManager::chatSessionCreated, this, &StatisticsPlugin::slotViewCreated); + connect(Kopete::ChatSessionManager::self(), &Kopete::ChatSessionManager::aboutToReceive, this, &StatisticsPlugin::slotAboutToReceive); - connect(Kopete::ContactList::self(), SIGNAL(metaContactSelected(bool)), - viewMetaContactStatistics, SLOT(setEnabled(bool))); - connect(Kopete::ContactList::self(), SIGNAL(metaContactAdded(Kopete::MetaContact *)), - this, SLOT(slotMetaContactAdded(Kopete::MetaContact *))); - connect(Kopete::ContactList::self(), SIGNAL(metaContactRemoved(Kopete::MetaContact *)), - this, SLOT(slotMetaContactRemoved(Kopete::MetaContact *))); + connect(Kopete::ContactList::self(), &Kopete::ContactList::metaContactSelected, viewMetaContactStatistics, &QAction::setEnabled); + connect(Kopete::ContactList::self(), &Kopete::ContactList::metaContactAdded, this, &StatisticsPlugin::slotMetaContactAdded); + connect(Kopete::ContactList::self(), &Kopete::ContactList::metaContactRemoved, this, &StatisticsPlugin::slotMetaContactRemoved); setComponentName(QStringLiteral("kopete_statistics"), i18n("Kopete")); setXMLFile(QStringLiteral("statisticsui.rc")); /* Initialization reads the database, so it could be a bit time-consuming due to disk access. This should overcome the problem and makes it non-blocking. */ QTimer::singleShot(0, this, SLOT(slotInitialize())); QTimer::singleShot(20000, this, SLOT(slotInitialize2())); new StatisticsAdaptor(this); QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.registerObject(QStringLiteral("/Statistics"), this); } void StatisticsPlugin::slotInitialize() { // Initializes the database m_db = new StatisticsDB(); QList list = Kopete::ContactList::self()->metaContacts(); foreach (Kopete::MetaContact *metaContact, list) { if (metaContact->isOnline()) { slotMetaContactAdded(metaContact); slotOnlineStatusChanged(metaContact, metaContact->status()); } else { - connect(metaContact, SIGNAL(onlineStatusChanged(Kopete::MetaContact *,Kopete::OnlineStatus::StatusType)), this, - SLOT(slotDelayedMetaContactAdded(Kopete::MetaContact *,Kopete::OnlineStatus::StatusType))); + connect(metaContact, SIGNAL(onlineStatusChanged(Kopete::MetaContact *,Kopete::OnlineStatus::StatusType)), this, SLOT(slotDelayedMetaContactAdded(Kopete::MetaContact *,Kopete::OnlineStatus::StatusType))); } } } void StatisticsPlugin::slotInitialize2() { QList list = Kopete::ContactList::self()->metaContacts(); foreach (Kopete::MetaContact *metaContact, list) { if (metaContact->status() != Kopete::OnlineStatus::Unknown && !statisticsContactMap.value(metaContact)) { slotDelayedMetaContactAdded(metaContact, metaContact->status()); } } } StatisticsPlugin::~StatisticsPlugin() { qDeleteAll(statisticsContactMap); statisticsContactMap.clear(); delete m_db; m_db = nullptr; } void StatisticsPlugin::slotAboutToReceive(Kopete::Message &m) { if (!m.from()) { return; } StatisticsContact *sc = statisticsContactMap.value(m.from()->metaContact()); if (sc) { sc->newMessageReceived(m); } } void StatisticsPlugin::slotViewCreated(Kopete::ChatSession *session) { connect(session, SIGNAL(closing(Kopete::ChatSession *)), this, SLOT(slotViewClosed(Kopete::ChatSession *))); } void StatisticsPlugin::slotViewClosed(Kopete::ChatSession *session) { QList list = session->members(); foreach (Kopete::Contact *contact, list) { // If this contact is not in other chat sessions if (!contact->manager()) { StatisticsContact *sc = statisticsContactMap.value(contact->metaContact()); if (sc) { sc->setIsChatWindowOpen(false); } } } } void StatisticsPlugin::slotViewStatistics() { Kopete::MetaContact *mc = Kopete::ContactList::self()->selectedMetaContacts().first(); kDebug(14315) << "statistics - dialog: " + mc->displayName(); StatisticsContact *sc = statisticsContactMap.value(mc); if (!sc) { slotMetaContactAdded(mc); sc = statisticsContactMap.value(mc); } if (sc) { StatisticsDialog *dialog = new StatisticsDialog(sc, db()); dialog->setObjectName(QStringLiteral("StatisticsDialog")); dialog->show(); } } void StatisticsPlugin::slotOnlineStatusChanged(Kopete::MetaContact *metaContact, Kopete::OnlineStatus::StatusType status) { StatisticsContact *sc = statisticsContactMap.value(metaContact); if (sc) { sc->onlineStatusChanged(status); } } void StatisticsPlugin::slotMetaContactAdded(Kopete::MetaContact *mc) { - connect(mc, SIGNAL(onlineStatusChanged(Kopete::MetaContact *,Kopete::OnlineStatus::StatusType)), this, - SLOT(slotOnlineStatusChanged(Kopete::MetaContact *,Kopete::OnlineStatus::StatusType))); + connect(mc, &Kopete::MetaContact::onlineStatusChanged, this, &StatisticsPlugin::slotOnlineStatusChanged); if (!statisticsContactMap.contains(mc)) { statisticsContactMap[mc] = new StatisticsContact(mc, db()); } } void StatisticsPlugin::slotDelayedMetaContactAdded(Kopete::MetaContact *mc, Kopete::OnlineStatus::StatusType status) { if (status != Kopete::OnlineStatus::Unknown) { - disconnect(mc, SIGNAL(onlineStatusChanged(Kopete::MetaContact *,Kopete::OnlineStatus::StatusType)), this, - SLOT(slotDelayedMetaContactAdded(Kopete::MetaContact *,Kopete::OnlineStatus::StatusType))); + disconnect(mc, &Kopete::MetaContact::onlineStatusChanged, this, &StatisticsPlugin::slotDelayedMetaContactAdded); slotMetaContactAdded(mc); slotOnlineStatusChanged(mc, status); } } void StatisticsPlugin::slotMetaContactRemoved(Kopete::MetaContact *mc) { disconnect(mc, 0, this, 0); StatisticsContact *sc = statisticsContactMap.value(mc); if (sc) { statisticsContactMap.remove(mc); delete sc; } } StatisticsContact *StatisticsPlugin::findStatisticsContact(QString id) const { QMapIterator it(statisticsContactMap); while (it.hasNext()) { it.next(); if (it.key()->metaContactId() == id) { return it.value(); } } return 0; } void StatisticsPlugin::dbusStatisticsDialog(QString id) { kDebug(14315) << "statistics - DBus dialog :" << id; StatisticsContact *sc = findStatisticsContact(id); if (sc) { StatisticsDialog *dialog = new StatisticsDialog(sc, db()); dialog->setObjectName(QStringLiteral("StatisticsDialog")); dialog->show(); } } bool StatisticsPlugin::dbusWasOnline(QString id, int timeStamp) { QDateTime dt; dt.setTime_t(timeStamp); return dbusWasStatus(id, dt, Kopete::OnlineStatus::Online); } bool StatisticsPlugin::dbusWasOnline(QString id, QString dateTime) { return dbusWasStatus(id, QDateTime::fromString(dateTime), Kopete::OnlineStatus::Online); } bool StatisticsPlugin::dbusWasAway(QString id, int timeStamp) { QDateTime dt; dt.setTime_t(timeStamp); return dbusWasStatus(id, dt, Kopete::OnlineStatus::Away); } bool StatisticsPlugin::dbusWasAway(QString id, QString dateTime) { return dbusWasStatus(id, QDateTime::fromString(dateTime), Kopete::OnlineStatus::Away); } bool StatisticsPlugin::dbusWasOffline(QString id, int timeStamp) { QDateTime dt; dt.setTime_t(timeStamp); return dbusWasStatus(id, dt, Kopete::OnlineStatus::Offline); } bool StatisticsPlugin::dbusWasOffline(QString id, QString dateTime) { return dbusWasStatus(id, QDateTime::fromString(dateTime), Kopete::OnlineStatus::Offline); } bool StatisticsPlugin::dbusWasStatus(QString id, QDateTime dateTime, Kopete::OnlineStatus::StatusType status) { kDebug(14315) << "statistics - DBus wasOnline :" << id; if (dateTime.isValid()) { StatisticsContact *sc = findStatisticsContact(id); if (sc) { return sc->wasStatus(dateTime, status); } } return false; } QString StatisticsPlugin::dbusStatus(QString id, int timeStamp) { QDateTime dt; dt.setTime_t(timeStamp); return dbusStatus(id, dt.toString()); } QString StatisticsPlugin::dbusStatus(QString id, QString dateTime) { QDateTime dt = QDateTime::fromString(dateTime); if (dt.isValid()) { StatisticsContact *sc = findStatisticsContact(id); if (sc) { return sc->statusAt(dt); } } return QLatin1String(""); } QString StatisticsPlugin::dbusMainStatus(QString id, int timeStamp) { QDateTime dt; dt.setTime_t(timeStamp); if (dt.isValid()) { StatisticsContact *sc = findStatisticsContact(id); if (sc) { return sc->mainStatusDate(dt.date()); } } return QLatin1String(""); } void StatisticsPlugin::aboutToUnload() { /* Upon exit kopete will set the online status of each metacontact to * "unknown", causing a storm of synchronous writes to the DB. * Disconnect the signal and batch a single transaction. */ m_db->transaction(); QMap::iterator it; for (it = statisticsContactMap.begin(); it != statisticsContactMap.end(); ++it) { Kopete::MetaContact *mc = it.key(); StatisticsContact *sc = it.value(); disconnect(mc, 0, this, 0); sc->onlineStatusChanged(Kopete::OnlineStatus::Unknown); } m_db->commit(); /* Report ready for unload */ emit readyForUnload(); } #include "statisticsplugin.moc"