Added call log and German translation.
authoreshe <jessehakanen@gmail.com>
Thu, 22 Jul 2010 15:49:00 +0000 (16:49 +0100)
committereshe <jessehakanen@gmail.com>
Thu, 22 Jul 2010 15:49:00 +0000 (16:49 +0100)
32 files changed:
src/common/cache.cpp
src/common/cache.h
src/common/dasoertliche.cpp [changed mode: 0755->0644]
src/common/dasoertliche.h [changed mode: 0755->0644]
src/common/dastelefonbuch.cpp [changed mode: 0755->0644]
src/common/dastelefonbuch.h [changed mode: 0755->0644]
src/common/db.cpp
src/common/db.h
src/common/settings.cpp
src/common/translations.grc [deleted file]
src/common/translations.qrc [new file with mode: 0644]
src/common/translations/de_DE.qm [new file with mode: 0644]
src/common/translations/de_DE.ts [new file with mode: 0644]
src/common/translations/fi_FI.qm
src/common/translations/fi_FI.ts
src/daemon/calllistener.cpp
src/daemon/calllistener.h
src/daemon/daemon.pro
src/daemon/main.cpp
src/gui/gui.pro
src/gui/icons.grc [deleted file]
src/gui/icons.qrc [new file with mode: 0644]
src/gui/listwidget.cpp [new file with mode: 0644]
src/gui/listwidget.h [new file with mode: 0644]
src/gui/logwindow.cpp [new file with mode: 0644]
src/gui/logwindow.h [new file with mode: 0644]
src/gui/main.cpp
src/gui/mainwindow.cpp
src/gui/mainwindow.h
src/gui/resultwindow.cpp
src/gui/searchdialog.cpp
src/gui/searchdialog.h

index fcbbcb5..b339d43 100644 (file)
@@ -54,6 +54,7 @@ int Cache::clear()
 
     return ret;
 }
+
 bool Cache::findItem(QString const& number, Source::Result& result)
 {
     bool connected = DB::connected();
@@ -63,13 +64,14 @@ bool Cache::findItem(QString const& number, Source::Result& result)
         DB::connect();
     }
 
-    QSqlQuery query;
-    query.prepare("SELECT name, street, city FROM cache WHERE number = :number");
-    query.bindValue(":number", number);
+    QSqlQuery query("SELECT name, street, city FROM cache WHERE number LIKE '%" + number.right(7) + "'");
+
+    //query.prepare("SELECT name, street, city FROM cache WHERE number = :number");
+    //query.bindValue(":number", number);
 
     bool ret = false;
 
-    if(query.exec() && query.next())
+    if(query.next())
     {
         result.number = number;
         result.name = query.value(0).toString();
@@ -155,6 +157,132 @@ bool Cache::addItem(Source::Result const& result)
 
 }
 
+bool Cache::logItem(Source::Result const& result, bool missed, unsigned int time)
+{
+    bool connected = DB::connected();
+
+    if(!connected)
+    {
+        DB::connect();
+    }
+
+    bool ret = true;
+
+    QSqlQuery query;
+
+    query.prepare("INSERT INTO log(number, name, street, city, time, missed) VALUES(:number, :name, :street, :city, :time, :missed)");
+    query.bindValue(":number", result.number);
+    query.bindValue(":name", result.name);
+    query.bindValue(":street", result.street);
+    query.bindValue(":city", result.city);
+    query.bindValue(":time", time);
+    int misVal = missed ? 1 : 0;
+
+    query.bindValue(":missed", misVal);
+
+    if(!query.exec())
+    {
+        ret = false;
+    }
+
+    query.clear();
+
+    // Delete old entries from cache
+    if(LOG_MAX_SIZE > 0)
+    {
+        if(query.exec("SELECT COUNT(*) FROM log") && query.next())
+        {
+            int itemsToDelete = query.value(0).toInt() - LOG_MAX_SIZE;
+
+            for(int i = 0; i < itemsToDelete; i++)
+            {
+                query.clear();
+
+                if(!query.exec("DELETE FROM cache WHERE id = (SELECT MIN(id) FROM cache)"))
+                {
+                    QSqlError error = query.lastError();
+                    qDebug() << "Unable to delete old cache entries: " << error.text();
+                    ret = false;
+                }
+            }
+        }
+        else
+        {
+            QSqlError error = query.lastError();
+            qDebug() << "Unable to get count for cache entries: " << error.text();
+            ret = false;
+        }
+
+    }
+
+    if(!connected)
+    {
+        DB::disconnect();
+    }
+
+    return ret;
+
+}
+
+void Cache::getLogItems(QList<Cache::LogDetails>& items, int limit)
+{
+    bool connected = DB::connected();
+
+    if(!connected)
+    {
+        DB::connect();
+    }
+
+    QSqlQuery query("SELECT number, name, street, city, time, missed FROM log ORDER BY time DESC LIMIT " + QString::number(limit));
+
+    while(query.next())
+    {
+        LogDetails details;
+        details.result.number = query.value(0).toString();
+        details.result.name = query.value(1).toString();
+        details.result.street = query.value(2).toString();
+        details.result.city = query.value(3).toString();
+        details.time = query.value(4).toInt();
+
+        int missed = query.value(5).toInt();
+
+        details.missed = missed ? true : false;
+
+        items.push_back(details);
+    }
+
+    if(!connected)
+    {
+        DB::disconnect();
+    }
+
+}
+
+int Cache::clearLog()
+{
+    bool connected = DB::connected();
+
+    if(!connected)
+    {
+        DB::connect();
+    }
+
+    QSqlQuery query;
+    int ret = -1;
+
+    if(query.exec("DELETE FROM log"))
+    {
+        ret = query.numRowsAffected();
+    }
+
+    if(!connected)
+    {
+        DB::disconnect();
+    }
+
+    return ret;
+}
+
 Cache& Cache::instance()
 {
     if(!instance_)
index f08b9d9..977159d 100644 (file)
 #ifndef CACHE_H
 #define CACHE_H
 
+#include <QtCore/QList>
+#include <QtCore/QPair>
 #include "source.h"
 
 class Cache
 {
 
 public:
+    struct LogDetails
+    {
+        Source::Result result;
+        int time;
+        bool missed;
+    };
+
+    static int const LOG_MAX_SIZE = 80;
+
     static Cache& instance();
     int clear();
     bool findItem(QString const& number, Source::Result& result);
     bool addItem(Source::Result const& result);
+    bool logItem(Source::Result const& result, bool missed, unsigned int time);
+    void getLogItems(QList<LogDetails>& items, int limit);
+    int clearLog();
 
 private:
     Cache();
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index ce0cf97..4028a74 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <QtCore/QDir>
 #include <QtCore/QDebug>
+#include <QtCore/QVariant>
 #include <QtSql/QSqlQuery>
 #include <QtSql/QSqlError>
 #include "db.h"
@@ -26,6 +27,7 @@ namespace
 {
     const QString SQL_DRIVER = "QSQLITE";
     const QString SQL_DATABASE = ".jenirok.db";
+    const int DB_VERSION = 2;
 }
 
 bool DB::initialized_ = false;
@@ -50,11 +52,20 @@ bool DB::connect()
 
     if(ret && !initialized_)
     {
-        QSqlQuery query("SELECT value FROM settings WHERE name = 'initialized'");
+        QSqlQuery query("SELECT value FROM settings WHERE name = 'db_version'");
 
-        if(!query.next())
+        if(query.next())
         {
-            ret = createTables();
+            int currentVersion = query.value(0).toString().toInt();
+
+            if(currentVersion < DB_VERSION)
+            {
+                ret = createTables(true);
+            }
+        }
+        else
+        {
+            ret = createTables(false);
         }
     }
 
@@ -94,15 +105,24 @@ QSqlDatabase& DB::instance()
     return db_;
 }
 
-bool DB::createTables()
+bool DB::createTables(bool update)
 {
     QSqlQuery query;
 
     bool ret = true;
 
-    ret = ret && query.exec("CREATE TABLE cache (id INTEGER PRIMARY KEY, number VARCHAR(32) NOT NULL UNIQUE, name VARCHAR(255) NOT NULL, street VARCHAR(255) NOT NULL, city VARCHAR(255) NOT NULL)");
-    ret = ret && query.exec("CREATE TABLE settings (name VARCHAR(255) NOT NULL PRIMARY KEY, value VARCHAR(255) NOT NULL)");
-    ret = ret && query.exec("INSERT INTO settings(name, value) VALUES('initialized', '1')");
+    ret = ret && query.exec("CREATE TABLE IF NOT EXISTS cache (id INTEGER PRIMARY KEY, number VARCHAR(32) NOT NULL UNIQUE, name VARCHAR(255) NOT NULL, street VARCHAR(255) NOT NULL, city VARCHAR(255) NOT NULL)");
+    ret = ret && query.exec("CREATE TABLE IF NOT EXISTS settings (name VARCHAR(255) NOT NULL PRIMARY KEY, value VARCHAR(255) NOT NULL)");
+    ret = ret && query.exec("CREATE TABLE IF NOT EXISTS log (id INTEGER PRIMARY KEY, number VARCHAR(32) NOT NULL, name VARCHAR(255), street VARCHAR(255), city VARCHAR(255), time INTEGER NOT NULL, missed INTEGER NOT NULL)");
+
+    if(update)
+    {
+        ret = ret && query.exec("UPDATE settings SET value = '" + QString::number(DB_VERSION) + "' WHERE name = 'db_version'");
+    }
+    else
+    {
+        ret = ret && query.exec("INSERT INTO settings(name, value) VALUES('db_version', '" + QString::number(DB_VERSION) + "')");
+    }
 
     return ret;
 }
index 0aa2490..6c1b989 100644 (file)
@@ -34,7 +34,7 @@ public:
 
 private:
     DB();
-    static bool createTables();
+    static bool createTables(bool update);
     static QSqlDatabase db_;
     static bool initialized_;
 };
index 182f0ab..21962d9 100644 (file)
 
 namespace
 {
-    static int const LANGUAGE_COUNT = 4;
+    static int const LANGUAGE_COUNT = 5;
 
     static QString const LANGUAGE_NAMES[LANGUAGE_COUNT] = {
        "English",
+       "Deutsch",
        "Norsk",
        "Suomi",
        "Svenska"
@@ -38,6 +39,7 @@ namespace
 
     static QString const LANGUAGE_IDS[LANGUAGE_COUNT] = {
        "en_US",
+       "de_DE",
        "nb_NO",
        "fi_FI",
        "sv_SE"
diff --git a/src/common/translations.grc b/src/common/translations.grc
deleted file mode 100644 (file)
index 974784d..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
-   <file>translations/fi_FI.qm</file>
-   <file>translations/nb_NO.qm</file>
-   <file>translations/sv_SE.qm</file>
-</qresource>
-</RCC>
diff --git a/src/common/translations.qrc b/src/common/translations.qrc
new file mode 100644 (file)
index 0000000..6bb133a
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+   <file>translations/fi_FI.qm</file>
+   <file>translations/nb_NO.qm</file>
+   <file>translations/sv_SE.qm</file>
+   <file>translations/de_DE.qm</file>
+</qresource>
+</RCC>
diff --git a/src/common/translations/de_DE.qm b/src/common/translations/de_DE.qm
new file mode 100644 (file)
index 0000000..f9f2113
Binary files /dev/null and b/src/common/translations/de_DE.qm differ
diff --git a/src/common/translations/de_DE.ts b/src/common/translations/de_DE.ts
new file mode 100644 (file)
index 0000000..9dcef5d
--- /dev/null
@@ -0,0 +1,459 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="de_DE">
+<context>
+    <name>AboutDialog</name>
+    <message>
+        <location filename="../../gui/aboutdialog.cpp" line="27"/>
+        <source>About</source>
+        <translation>Ãœber</translation>
+    </message>
+</context>
+<context>
+    <name>CallListener</name>
+    <message>
+        <source>Searching...</source>
+        <translation>Suche...</translation>
+    </message>
+    <message>
+        <source>Request timed out</source>
+        <translation>Server antwortet nicht</translation>
+    </message>
+    <message>
+        <source>Searching failed:</source>
+        <translation>Suche misslungen:</translation>
+    </message>
+    <message>
+        <source>Phone number was not found</source>
+        <translation>Telefonnummer nicht gefunden</translation>
+    </message>
+    <message>
+        <source>Automatic connecting is not allowed by settings.</source>
+        <translation>Einstellungen verbieten automatische Verbindung.</translation>
+    </message>
+    <message>
+        <source>Connecting...</source>
+        <translation>Verbinde...</translation>
+    </message>
+    <message>
+        <source>No available 3G or WLAN networks found.</source>
+        <translation>Keine 3G oder WLAN Verbindungen gefunden.</translation>
+    </message>
+    <message>
+        <source>Selected access point doesn&apos;t exist.</source>
+        <translation>Der gewählte Access-Point existiert nicht.</translation>
+    </message>
+    <message>
+        <source>Unable to connect to network.</source>
+        <translation>Netzwerkverbindung nicht möglich.</translation>
+    </message>
+</context>
+<context>
+    <name>ConnectionSelector</name>
+    <message>
+        <location filename="../../gui/connectionselector.cpp" line="69"/>
+        <source>Use global setting</source>
+        <translation>Globale Einstellung verwenden</translation>
+    </message>
+    <message>
+        <location filename="../../gui/connectionselector.cpp" line="70"/>
+        <source>WLAN connection</source>
+        <translation>WLAN-Verbindung</translation>
+    </message>
+    <message>
+        <location filename="../../gui/connectionselector.cpp" line="71"/>
+        <source>GPRS connection</source>
+        <translation>GPRS-Verbindung</translation>
+    </message>
+    <message>
+        <location filename="../../gui/connectionselector.cpp" line="72"/>
+        <source>Any connection</source>
+        <translation>Irgendeine Verbindung</translation>
+    </message>
+</context>
+<context>
+    <name>DetailWindow</name>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="42"/>
+        <location filename="../../gui/detailwindow.cpp" line="119"/>
+        <source>Add to contacts</source>
+        <translation>Zu Kontakten hinzufügen</translation>
+    </message>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="43"/>
+        <source>Copy number to clipboard</source>
+        <translation>Nummer kopieren</translation>
+    </message>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="44"/>
+        <source>Call</source>
+        <translation>Anruf</translation>
+    </message>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="45"/>
+        <source>Send SMS</source>
+        <translation>SMS senden</translation>
+    </message>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="53"/>
+        <location filename="../../gui/detailwindow.cpp" line="122"/>
+        <source>Name</source>
+        <translation>Name</translation>
+    </message>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="54"/>
+        <source>Street</source>
+        <translation>Straße</translation>
+    </message>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="55"/>
+        <source>City</source>
+        <translation>Stadt</translation>
+    </message>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="57"/>
+        <source>Phone number</source>
+        <translation>Telefonnummer</translation>
+    </message>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="109"/>
+        <source>Unable make call</source>
+        <translation>Anruf nicht möglich</translation>
+    </message>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="123"/>
+        <source>Add</source>
+        <translation>Hinzufügen</translation>
+    </message>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="156"/>
+        <source>Contact was successfully added to contacts.</source>
+        <translation>Kontakt erfolgreich hinzugefügt.</translation>
+    </message>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="194"/>
+        <source>Unable to open SMS application</source>
+        <translation>Kann SMS Anwendung nicht Ã¶ffnen</translation>
+    </message>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="109"/>
+        <location filename="../../gui/detailwindow.cpp" line="160"/>
+        <location filename="../../gui/detailwindow.cpp" line="194"/>
+        <source>Error</source>
+        <translation>Fehler</translation>
+    </message>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="160"/>
+        <source>Unable to add contact.</source>
+        <translation>Kann Kontakt nicht hinzufügen.</translation>
+    </message>
+    <message>
+        <location filename="../../gui/detailwindow.cpp" line="170"/>
+        <source>Number was successfully copied to clipboard.</source>
+        <translation>Telefonnummer kopiert.</translation>
+    </message>
+</context>
+<context>
+    <name>EmptyGuiConfig</name>
+    <message>
+        <location filename="../../gui/emptyguiconfig.cpp" line="27"/>
+        <source>Selected phonebook has no settings to configure.</source>
+        <translation>Kein Einstellungen für das gewählte Telefonbuch.</translation>
+    </message>
+</context>
+<context>
+    <name>EniroGuiConfig</name>
+    <message>
+        <location filename="../../gui/eniroguiconfig.cpp" line="36"/>
+        <source>Eniro username</source>
+        <translation>Eniro Benutzername</translation>
+    </message>
+    <message>
+        <location filename="../../gui/eniroguiconfig.cpp" line="39"/>
+        <source>Eniro password</source>
+        <translation>Eniro Passwort</translation>
+    </message>
+    <message>
+        <location filename="../../gui/eniroguiconfig.cpp" line="45"/>
+        <source>Eniro site</source>
+        <translation>Eniro Seite</translation>
+    </message>
+    <message>
+        <location filename="../../gui/eniroguiconfig.cpp" line="57"/>
+        <source>Finnish</source>
+        <translation>Finnisch</translation>
+    </message>
+    <message>
+        <location filename="../../gui/eniroguiconfig.cpp" line="60"/>
+        <source>Swedish</source>
+        <translation>Schwedisch</translation>
+    </message>
+    <message>
+        <location filename="../../gui/eniroguiconfig.cpp" line="63"/>
+        <source>Danish</source>
+        <translation>Dänisch</translation>
+    </message>
+</context>
+<context>
+    <name>MainWindow</name>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="48"/>
+        <source>Jenirok</source>
+        <translation>Jenirok</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="54"/>
+        <location filename="../../gui/mainwindow.cpp" line="151"/>
+        <source>Stop daemon</source>
+        <translation>Hintergrunddienst stoppen</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="60"/>
+        <location filename="../../gui/mainwindow.cpp" line="117"/>
+        <source>Start daemon</source>
+        <translation>Hintergrunddienst starten</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="65"/>
+        <source>Search</source>
+        <translation>Suchen</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="82"/>
+        <source>Settings</source>
+        <translation>Einstellungen</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="83"/>
+        <source>About</source>
+        <translation>Ãœber</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="115"/>
+        <source>Daemon was successfully stopped.</source>
+        <translation>Hintergrunddienst erfolgreich angehalten.</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="116"/>
+        <source>Unable to stop daemon.</source>
+        <translation>Kann Hintergrunddienst nicht anhalten.</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="127"/>
+        <source>Unable to start daemon</source>
+        <translation>Kann Hintergrunddienst nicht starten</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="129"/>
+        <source>Daemon cannot be started because it&apos;s not allowed to connect to the Internet. You have to either allow automatic Internet connection in Jenirok settings or in global Maemo settings.</source>
+        <translation>Der Hintergrunddienst kann nicht gestartet werden, da er keinen Internetzugriff erhält. Lösung: Entweder automatische Internetverbindung in Jenirok oder in den globalen Maemo Einstellungen erlauben.</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="133"/>
+        <source>Open settings</source>
+        <translation>Einstellungen Ã¶ffnen</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="135"/>
+        <source>Close</source>
+        <translation>Schliessen</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="149"/>
+        <source>Daemon was successfully started.</source>
+        <translation>Hintergrunddienst erfolgreich gestartet.</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="150"/>
+        <source>Unable to start daemon.</source>
+        <translation>Konnte Hintergrunddienst nicht starten.</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="157"/>
+        <source>Error</source>
+        <translation>Fehler</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="181"/>
+        <source>Info</source>
+        <translation>Info</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="181"/>
+        <source>You need to set login details or other options in settings before using this feature.</source>
+        <translation>Für diese Funktion müssen zuerst Anmeldedetails oder andere Einstellungen ausgefüllt sein.</translation>
+    </message>
+</context>
+<context>
+    <name>ResultWindow</name>
+    <message>
+        <location filename="../../gui/resultwindow.cpp" line="36"/>
+        <source>Search results</source>
+        <translation>Suchergebnisse</translation>
+    </message>
+    <message>
+        <location filename="../../gui/resultwindow.cpp" line="163"/>
+        <source>Connection to server failed</source>
+        <translation>Konnte nicht mit Server verbinden</translation>
+    </message>
+    <message>
+        <location filename="../../gui/resultwindow.cpp" line="166"/>
+        <source>Invalid login details</source>
+        <translation>Ungültige Anmeldedaten</translation>
+    </message>
+    <message>
+        <location filename="../../gui/resultwindow.cpp" line="169"/>
+        <source>Request timed out</source>
+        <translation>Server antwortet nicht</translation>
+    </message>
+    <message>
+        <location filename="../../gui/resultwindow.cpp" line="172"/>
+        <source>Searching failed:</source>
+        <translation>Suche fehlgeschlagen:</translation>
+    </message>
+    <message>
+        <location filename="../../gui/resultwindow.cpp" line="176"/>
+        <source>Error</source>
+        <translation>Fehler</translation>
+    </message>
+    <message>
+        <location filename="../../gui/resultwindow.cpp" line="181"/>
+        <source>No results found</source>
+        <translation>Keine Ergebnisse</translation>
+    </message>
+</context>
+<context>
+    <name>SearchDialog</name>
+    <message>
+        <location filename="../../gui/searchdialog.cpp" line="30"/>
+        <location filename="../../gui/searchdialog.cpp" line="55"/>
+        <source>Search</source>
+        <translation>Suche</translation>
+    </message>
+    <message>
+        <location filename="../../gui/searchdialog.cpp" line="33"/>
+        <source>Name/number</source>
+        <translation>Name/Nummer</translation>
+    </message>
+    <message>
+        <location filename="../../gui/searchdialog.cpp" line="39"/>
+        <source>Location</source>
+        <translation>Ort</translation>
+    </message>
+    <message>
+        <location filename="../../gui/searchdialog.cpp" line="44"/>
+        <source>Type</source>
+        <translation>Typ</translation>
+    </message>
+    <message>
+        <location filename="../../gui/searchdialog.cpp" line="45"/>
+        <source>Persons</source>
+        <translation>Personen</translation>
+    </message>
+    <message>
+        <location filename="../../gui/searchdialog.cpp" line="46"/>
+        <source>Companies</source>
+        <translation>Firmen</translation>
+    </message>
+</context>
+<context>
+    <name>Settings</name>
+    <message>
+        <location filename="../settings.cpp" line="168"/>
+        <source>fi</source>
+        <translation>fi</translation>
+    </message>
+</context>
+<context>
+    <name>SettingsDialog</name>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="44"/>
+        <source>Settings</source>
+        <translation>Einstellungen</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="58"/>
+        <source>Cache size (numbers)</source>
+        <translation>Programmspeicherplatz (Nummern)</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="61"/>
+        <source>Clear</source>
+        <translation>Leeren</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="64"/>
+        <source>Language</source>
+        <translation>Sprache</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="65"/>
+        <source>Automatic</source>
+        <translation>Automatisch</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="82"/>
+        <source>Phonebook</source>
+        <translation>Telefonbuch</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="102"/>
+        <source>Autostart</source>
+        <translation>Autostart</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="104"/>
+        <source>Enabled</source>
+        <translation>Aktiviert</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="105"/>
+        <source>Disabled</source>
+        <translation>Deaktiviert</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="108"/>
+        <source>Connect automatically on</source>
+        <translation>Automatisch verbinden bei</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="112"/>
+        <source>Save</source>
+        <translation>Speichern</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="137"/>
+        <source>General</source>
+        <translation>Allgemein</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="138"/>
+        <source>Daemon</source>
+        <translation>Hintergrunddienst</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="139"/>
+        <location filename="../../gui/settingsdialog.cpp" line="208"/>
+        <source>Phonebook settings</source>
+        <translation>Telefonbuch</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="170"/>
+        <source>Restarting daemon...</source>
+        <translation>Hintergrunddienst wird neu gestartet...</translation>
+    </message>
+    <message>
+        <location filename="../../gui/settingsdialog.cpp" line="176"/>
+        <source>You need to restart Jenirok for language change to take effect.</source>
+        <translation>Jenirok muss neu gestartet werden, damit die Spracheinstellungen aktiv werden.</translation>
+    </message>
+    <message numerus="yes">
+        <location filename="../../gui/settingsdialog.cpp" line="188"/>
+        <source>%n number(s) were deleted from cache</source>
+        <translation>
+            <numerusform>%n Telefonnummer aus Programmspeicher gelöscht</numerusform>
+            <numerusform>%n Telefonnummern aus Programmspeicher gelöscht</numerusform>
+        </translation>
+    </message>
+</context>
+</TS>
index 8c9f0c6..6440136 100644 (file)
Binary files a/src/common/translations/fi_FI.qm and b/src/common/translations/fi_FI.qm differ
index d9e26e2..c17a08b 100644 (file)
 <context>
     <name>ConnectionSelector</name>
     <message>
-        <location filename="../../gui/connectionselector.cpp" line="69"/>
+        <location filename="../../gui/connectionselector.cpp" line="71"/>
         <source>Use global setting</source>
         <translation>Käytä järj. asetusta</translation>
     </message>
     <message>
-        <location filename="../../gui/connectionselector.cpp" line="70"/>
+        <location filename="../../gui/connectionselector.cpp" line="72"/>
         <source>WLAN connection</source>
         <translation>WLAN-yhteys</translation>
     </message>
     <message>
-        <location filename="../../gui/connectionselector.cpp" line="71"/>
+        <location filename="../../gui/connectionselector.cpp" line="73"/>
         <source>GPRS connection</source>
         <translation>GPRS-yhteys</translation>
     </message>
     <message>
-        <location filename="../../gui/connectionselector.cpp" line="72"/>
+        <location filename="../../gui/connectionselector.cpp" line="74"/>
         <source>Any connection</source>
         <translation>Mikä tahansa yhteys</translation>
     </message>
 <context>
     <name>EniroGuiConfig</name>
     <message>
-        <location filename="../../gui/eniroguiconfig.cpp" line="36"/>
+        <location filename="../../gui/eniroguiconfig.cpp" line="123"/>
         <source>Eniro username</source>
         <translation>Eniro-tunnus</translation>
     </message>
     <message>
-        <location filename="../../gui/eniroguiconfig.cpp" line="39"/>
+        <location filename="../../gui/eniroguiconfig.cpp" line="126"/>
         <source>Eniro password</source>
         <translation>Eniro-salasana</translation>
     </message>
     <message>
-        <location filename="../../gui/eniroguiconfig.cpp" line="45"/>
+        <location filename="../../gui/eniroguiconfig.cpp" line="79"/>
         <source>Eniro site</source>
         <translation>Eniro-sivusto</translation>
     </message>
     <message>
-        <location filename="../../gui/eniroguiconfig.cpp" line="57"/>
+        <location filename="../../gui/eniroguiconfig.cpp" line="90"/>
         <source>Finnish</source>
         <translation>Suomi</translation>
     </message>
     <message>
-        <location filename="../../gui/eniroguiconfig.cpp" line="60"/>
+        <location filename="../../gui/eniroguiconfig.cpp" line="93"/>
         <source>Swedish</source>
         <translation>Ruotsi</translation>
     </message>
     <message>
-        <location filename="../../gui/eniroguiconfig.cpp" line="63"/>
+        <location filename="../../gui/eniroguiconfig.cpp" line="96"/>
         <source>Danish</source>
         <translation>Tanska</translation>
     </message>
 </context>
 <context>
+    <name>LogWindow</name>
+    <message>
+        <location filename="../../gui/logwindow.cpp" line="30"/>
+        <source>Incoming call log</source>
+        <translation>Puheluloki</translation>
+    </message>
+    <message>
+        <location filename="../../gui/logwindow.cpp" line="31"/>
+        <source>Clear log</source>
+        <translation>Tyhjennä loki</translation>
+    </message>
+    <message>
+        <location filename="../../gui/logwindow.cpp" line="64"/>
+        <source>There are currently no logged calls</source>
+        <translation>Ei kirjattuja puheluita</translation>
+    </message>
+    <message>
+        <location filename="../../gui/logwindow.cpp" line="134"/>
+        <source>%1 (no search results)</source>
+        <translation>%1 (ei hakutuloksia)</translation>
+    </message>
+</context>
+<context>
     <name>MainWindow</name>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="48"/>
+        <location filename="../../gui/mainwindow.cpp" line="49"/>
         <source>Jenirok</source>
         <translation>Jenirok</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="54"/>
-        <location filename="../../gui/mainwindow.cpp" line="151"/>
+        <location filename="../../gui/mainwindow.cpp" line="55"/>
+        <location filename="../../gui/mainwindow.cpp" line="171"/>
         <source>Stop daemon</source>
         <translation>Pysäytä</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="60"/>
-        <location filename="../../gui/mainwindow.cpp" line="117"/>
+        <location filename="../../gui/mainwindow.cpp" line="61"/>
+        <location filename="../../gui/mainwindow.cpp" line="137"/>
         <source>Start daemon</source>
         <translation>Käynnistä</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="65"/>
+        <location filename="../../gui/mainwindow.cpp" line="72"/>
         <source>Search</source>
         <translation>Hae</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="82"/>
+        <location filename="../../gui/mainwindow.cpp" line="76"/>
+        <source>Log</source>
+        <translation>Loki</translation>
+    </message>
+    <message>
+        <location filename="../../gui/mainwindow.cpp" line="97"/>
         <source>Settings</source>
         <translation>Asetukset</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="83"/>
+        <location filename="../../gui/mainwindow.cpp" line="98"/>
         <source>About</source>
         <translation>Tietoa</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="115"/>
+        <location filename="../../gui/mainwindow.cpp" line="135"/>
         <source>Daemon was successfully stopped.</source>
         <translation>Palvelu pysäytettiin onnistuneesti.</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="116"/>
+        <location filename="../../gui/mainwindow.cpp" line="136"/>
         <source>Unable to stop daemon.</source>
         <translation>Palvelun pysäyttäminen ei onnistunut.</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="127"/>
+        <location filename="../../gui/mainwindow.cpp" line="147"/>
         <source>Unable to start daemon</source>
         <translation>Palvelun käynnistäminen ei onnistunut</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="129"/>
+        <location filename="../../gui/mainwindow.cpp" line="149"/>
         <source>Daemon cannot be started because it&apos;s not allowed to connect to the Internet. You have to either allow automatic Internet connection in Jenirok settings or in global Maemo settings.</source>
         <translation>Palvelua ei voida käynnistää, koska sillä ei ole oikeutta yhdistää Internetiin. Sinun täytyy sallia automaattinen yhteyden muodostaminen joko Jenirokin asetuksista tai Maemon omista Internet-asetuksista.</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="133"/>
+        <location filename="../../gui/mainwindow.cpp" line="153"/>
         <source>Open settings</source>
         <translation>Avaa asetukset</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="135"/>
+        <location filename="../../gui/mainwindow.cpp" line="155"/>
         <source>Close</source>
         <translation>Sulje</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="149"/>
+        <location filename="../../gui/mainwindow.cpp" line="169"/>
         <source>Daemon was successfully started.</source>
         <translation>Palvelu käynnistettiin onnistuneesti.</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="150"/>
+        <location filename="../../gui/mainwindow.cpp" line="170"/>
         <source>Unable to start daemon.</source>
         <translation>Palvelun käynnistäminen ei onnistunut.</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="157"/>
+        <location filename="../../gui/mainwindow.cpp" line="177"/>
         <source>Error</source>
         <translation>Virhe</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="181"/>
+        <location filename="../../gui/mainwindow.cpp" line="201"/>
         <source>Info</source>
         <translation>Info</translation>
     </message>
     <message>
-        <location filename="../../gui/mainwindow.cpp" line="181"/>
+        <location filename="../../gui/mainwindow.cpp" line="201"/>
         <source>You need to set login details or other options in settings before using this feature.</source>
         <translation>Sinun täytyy asettaa kirjautumistiedot tai muita asetuksia ennen kuin voit käyttää tätä ominaisuutta.</translation>
     </message>
         <translation>Hakutulokset</translation>
     </message>
     <message>
-        <location filename="../../gui/resultwindow.cpp" line="163"/>
+        <location filename="../../gui/resultwindow.cpp" line="156"/>
         <source>Connection to server failed</source>
         <translation>Palvelimelle yhdistäminen epäonnistui</translation>
     </message>
     <message>
-        <location filename="../../gui/resultwindow.cpp" line="166"/>
+        <location filename="../../gui/resultwindow.cpp" line="159"/>
         <source>Invalid login details</source>
         <translation>Virheellinen tunnus tai salasana</translation>
     </message>
     <message>
-        <location filename="../../gui/resultwindow.cpp" line="169"/>
+        <location filename="../../gui/resultwindow.cpp" line="162"/>
         <source>Request timed out</source>
         <translation>Pyyntö aikakatkaistiin</translation>
     </message>
     <message>
-        <location filename="../../gui/resultwindow.cpp" line="172"/>
+        <location filename="../../gui/resultwindow.cpp" line="165"/>
         <source>Searching failed:</source>
         <translation>Haku epäonnistui:</translation>
     </message>
     <message>
-        <location filename="../../gui/resultwindow.cpp" line="176"/>
+        <location filename="../../gui/resultwindow.cpp" line="169"/>
         <source>Error</source>
         <translation>Virhe</translation>
     </message>
     <message>
-        <location filename="../../gui/resultwindow.cpp" line="181"/>
+        <location filename="../../gui/resultwindow.cpp" line="174"/>
         <source>No results found</source>
         <translation>Ei hakutuloksia</translation>
     </message>
 <context>
     <name>SearchDialog</name>
     <message>
-        <location filename="../../gui/searchdialog.cpp" line="30"/>
+        <location filename="../../gui/searchdialog.cpp" line="31"/>
         <location filename="../../gui/searchdialog.cpp" line="55"/>
         <source>Search</source>
         <translation>Hae</translation>
     </message>
     <message>
-        <location filename="../../gui/searchdialog.cpp" line="33"/>
+        <location filename="../../gui/searchdialog.cpp" line="34"/>
         <source>Name/number</source>
         <translation>Numero/nimi</translation>
     </message>
     <message>
-        <location filename="../../gui/searchdialog.cpp" line="39"/>
+        <location filename="../../gui/searchdialog.cpp" line="40"/>
         <source>Location</source>
         <translation>Sijainti</translation>
     </message>
     <message>
-        <location filename="../../gui/searchdialog.cpp" line="44"/>
+        <location filename="../../gui/searchdialog.cpp" line="45"/>
         <source>Type</source>
         <translation>Tyyppi</translation>
     </message>
     <message>
-        <location filename="../../gui/searchdialog.cpp" line="45"/>
+        <location filename="../../gui/searchdialog.cpp" line="118"/>
         <source>Persons</source>
         <translation>Henkilöt</translation>
     </message>
     <message>
-        <location filename="../../gui/searchdialog.cpp" line="46"/>
+        <location filename="../../gui/searchdialog.cpp" line="121"/>
         <source>Companies</source>
         <translation>Yritykset</translation>
     </message>
 <context>
     <name>Settings</name>
     <message>
-        <location filename="../settings.cpp" line="168"/>
+        <location filename="../settings.cpp" line="174"/>
         <source>fi</source>
         <translation>fi</translation>
     </message>
         <translation>Yhdistä automaattisesti</translation>
     </message>
     <message>
-        <location filename="../../gui/settingsdialog.cpp" line="112"/>
+        <location filename="../../gui/settingsdialog.cpp" line="117"/>
         <source>Save</source>
         <translation>Tallenna</translation>
     </message>
     <message>
-        <location filename="../../gui/settingsdialog.cpp" line="137"/>
+        <location filename="../../gui/settingsdialog.cpp" line="142"/>
         <source>General</source>
         <translation>Yleiset</translation>
     </message>
     <message>
-        <location filename="../../gui/settingsdialog.cpp" line="138"/>
+        <location filename="../../gui/settingsdialog.cpp" line="143"/>
         <source>Daemon</source>
         <translation>Taustaprosessi</translation>
     </message>
     <message>
-        <location filename="../../gui/settingsdialog.cpp" line="139"/>
-        <location filename="../../gui/settingsdialog.cpp" line="208"/>
+        <location filename="../../gui/settingsdialog.cpp" line="144"/>
+        <location filename="../../gui/settingsdialog.cpp" line="227"/>
         <source>Phonebook settings</source>
         <translation>Puhelinluettelo</translation>
     </message>
     <message>
-        <location filename="../../gui/settingsdialog.cpp" line="170"/>
+        <location filename="../../gui/settingsdialog.cpp" line="185"/>
         <source>Restarting daemon...</source>
         <translation>Käynnistetään palvelu uudelleen...</translation>
     </message>
         <translation>Jenirok täytyy käynnistää uudelleen, jotta uudet kieliasetukset tulevat voimaan.</translation>
     </message>
     <message numerus="yes">
-        <location filename="../../gui/settingsdialog.cpp" line="188"/>
+        <location filename="../../gui/settingsdialog.cpp" line="201"/>
         <source>%n number(s) were deleted from cache</source>
         <translation>
             <numerusform>Poistettiin %n numero välimuistista</numerusform>
index 78d5737..b4d80d4 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <QtCore/QDebug>
 #include <QtCore/QTimer>
+#include <QtCore/QDateTime>
 #include "calllistener.h"
 #include "settings.h"
 #include "cache.h"
@@ -35,13 +36,14 @@ namespace
     const QString CALL_SIGNAL_INCOMING = "Coming";
     const QString CALL_SIGNAL_RELEASE = "Release";
     const QString CALL_SIGNAL_TERMINATED = "Terminated";
+    const QString CALL_SIGNAL_ANSWERED = "AudioConnect";
 }
 
 QDBusConnection CallListener::systemBus_ = QDBusConnection::systemBus();
 
 CallListener::CallListener(): source_(0),
 closeConnection_(false), initialized_(false), box_(0), label_(0),
-retries_(-1), timer_(0)
+retries_(-1), timer_(0), currentCall_(0)
 {
 }
 
@@ -111,6 +113,16 @@ void CallListener::search(Source::SearchDetails const& details)
 {
     qDebug() << "Search called";
 
+    if(currentCall_)
+    {
+        delete currentCall_;
+    }
+
+    currentCall_ = new CallDetails;
+    currentCall_->number = details.query;
+    currentCall_->time = QDateTime::currentDateTime().toTime_t();
+    currentCall_->answered = false;
+
     searchInit();
 
     Source::Result result;
@@ -123,11 +135,12 @@ void CallListener::search(Source::SearchDetails const& details)
         showDelayedResult(createResult(result.name,
                                        result.street,
                                        result.city), BANNER_DELAY);
+
+        currentCall_->result = result;
     }
     else
     {
         retries_ = 0;
-        currentSearch_ = details.query;
 
         if(!handleConnection())
         {
@@ -156,7 +169,7 @@ void CallListener::requestFinished(QVector <Source::Result> const& results,
     }
 
     // If box is not visible, the call must have been terminated already
-    if(!initialized_ || !box_->isVisible())
+    if(!initialized_ || !box_->isVisible() || !currentCall_)
     {
         return;
     }
@@ -170,7 +183,7 @@ void CallListener::requestFinished(QVector <Source::Result> const& results,
         if(retries_ < SEARCH_RETRIES && retries_ >= 0)
         {
             retries_++;
-            source_->search(Source::SearchDetails(currentSearch_, "", Source::BOTH));
+            source_->search(Source::SearchDetails(currentCall_->number, "", Source::BOTH));
             return;
         }
         else
@@ -209,11 +222,11 @@ void CallListener::requestFinished(QVector <Source::Result> const& results,
             Source::Result result = results.at(0);
             result.number = details.query;
             Cache::instance().addItem(result);
+            currentCall_->result = results.at(0);
         }
     }
 
     retries_ = -1;
-    currentSearch_ = "";
 }
 
 QString CallListener::createResult(QString const& name, QString const& street, QString const& city)
@@ -273,6 +286,13 @@ void CallListener::incomingCall(QDBusObjectPath path, QString number)
                            this,
                            SLOT(callTerminate()));
 
+        systemBus_.connect(CALL_SERVICE_NAME,
+                           path.path(),
+                           CALL_SERVICE_INSTANCE_NAME,
+                           CALL_SIGNAL_ANSWERED,
+                           this,
+                           SLOT(handleAnswer()));
+
         search(Source::SearchDetails(number, "", Source::BOTH));
     }
     else
@@ -288,9 +308,27 @@ void CallListener::callTerminate()
         box_->hide();
     }
 
+    if(currentCall_)
+    {
+        currentCall_->result.number = currentCall_->number;
+        Cache::instance().logItem(currentCall_->result, !currentCall_->answered, currentCall_->time);
+        delete currentCall_;
+        currentCall_ = 0;
+    }
+
     searchClose();
 }
 
+void CallListener::handleAnswer()
+{
+    qDebug() << "Answered";
+
+    if(currentCall_)
+    {
+        currentCall_->answered = true;
+    }
+}
+
 void CallListener::showDelayedResult(QString const& text, int delay)
 {
     timedMessage_ = text;
index 682ea1b..5e1d18b 100644 (file)
@@ -54,10 +54,19 @@ private slots:
     void incomingCall(QDBusObjectPath path, QString numbe);
     void callTerminate();
     void showTimedMessage();
+    void handleAnswer();
 
 private:
     Q_DISABLE_COPY(CallListener);
 
+    struct CallDetails
+    {
+        QString number;
+        Source::Result result;
+        bool answered;
+        unsigned int time;
+    };
+
     void search(Source::SearchDetails const& details);
     void showResult(QString const& text);
     void showDelayedResult(QString const& text, int delay);
@@ -79,8 +88,8 @@ private:
     QLabel* label_;
     static QDBusConnection systemBus_;
     int retries_;
-    QString currentSearch_;
     int timer_;
+    CallDetails* currentCall_;
 };
 
 #endif // CALLLISTENER_H
index d9e3ccd..0987c0e 100644 (file)
@@ -31,8 +31,7 @@ HEADERS += calllistener.h \
     ../common/connectionmanager.h \
     ../common/cache.h \
     ../common/dastelefonbuch.h
-TRANSLATIONS = ../common/translations/fi_FI.ts
-RESOURCES = ../common/translations.grc
+RESOURCES = ../common/translations.qrc
 INCLUDEPATH += ../common
 CONFIG += link_pkgconfig
 PKGCONFIG += libebook-1.2 gconf-2.0
index 69964f3..d3b73a4 100644 (file)
 #include "calllistener.h"
 #include "settings.h"
 
+#include "source.h"
+#include "cache.h"
+#include <QtCore/QList>
+#include <QtCore/QPair>
+#include <QtCore/QDebug>
+#include <QtCore/QDateTime>
+
 
 int main(int argc, char *argv[])
 {
index 3492c0a..ce51464 100644 (file)
@@ -25,7 +25,9 @@ SOURCES += main.cpp \
     ../common/settings.cpp \
     ../common/connectionmanager.cpp \ 
     ../common/cache.cpp \
-    ../common/dastelefonbuch.cpp
+    ../common/dastelefonbuch.cpp \
+    logwindow.cpp \
+    listwidget.cpp
 HEADERS += mainwindow.h \
     searchdialog.h \
     resultwindow.h \
@@ -49,9 +51,11 @@ HEADERS += mainwindow.h \
     ../common/settings.h \
     ../common/connectionmanager.h \
     ../common/cache.h \
-    ../common/dastelefonbuch.h
+    ../common/dastelefonbuch.h \
+    logwindow.h \
+    listwidget.h
+RESOURCES = icons.qrc ../common/translations.qrc
 TRANSLATIONS = ../common/translations/fi_FI.ts
-RESOURCES = icons.grc ../common/translations.grc
 INCLUDEPATH += ../common
 CONFIG += link_pkgconfig
 PKGCONFIG += libebook-1.2 gconf-2.0
diff --git a/src/gui/icons.grc b/src/gui/icons.grc
deleted file mode 100644 (file)
index 68f3e89..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
-    <file>icons/start.png</file>
-    <file>icons/stop.png</file>
-    <file>icons/icon.png</file>
-</qresource>
-</RCC>
diff --git a/src/gui/icons.qrc b/src/gui/icons.qrc
new file mode 100644 (file)
index 0000000..68f3e89
--- /dev/null
@@ -0,0 +1,7 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+    <file>icons/start.png</file>
+    <file>icons/stop.png</file>
+    <file>icons/icon.png</file>
+</qresource>
+</RCC>
diff --git a/src/gui/listwidget.cpp b/src/gui/listwidget.cpp
new file mode 100644 (file)
index 0000000..39a6519
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * This file is part of Jenirok.
+ *
+ * Jenirok 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Jenirok 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 Jenirok.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <QtGui/QHeaderView>
+#include <QtCore/QDebug>
+#include "listwidget.h"
+
+ListWidget::ListWidget(QWidget* parent): QTableWidget(parent)
+{
+    connect(this, SIGNAL(cellClicked(int, int)), this, SLOT(handleClick(int)));
+    setColumnCount(1);
+    verticalHeader()->hide();
+    horizontalHeader()->hide();
+    setColumnWidth(0, 800);
+    setSelectionMode(QAbstractItemView::SingleSelection);
+}
+
+void ListWidget::addWidget(QWidget* widget, QVariant const& data)
+{
+    int row = rowCount();
+    setRowCount(row + 1);
+    setCellWidget(row, 0, widget);
+    data_[row] = data;
+    widgets_[row] = widget;
+    resizeRowToContents (row);
+}
+
+QVariant ListWidget::getData(int index) const
+{
+    if(data_.find(index) != data_.end())
+    {
+        return data_[index];
+    }
+
+    return QVariant();
+}
+
+QWidget* ListWidget::getWidget(int index) const
+{
+    if(widgets_.find(index) != widgets_.end())
+    {
+        return widgets_[index];
+    }
+
+    return 0;
+}
+
+void ListWidget::clear()
+{
+    QTableWidget::clear();
+    data_.clear();
+    widgets_.clear();
+    setRowCount(0);
+}
+
+void ListWidget::handleClick(int index)
+{
+    clearSelection();
+    emit itemClicked(index);
+}
diff --git a/src/gui/listwidget.h b/src/gui/listwidget.h
new file mode 100644 (file)
index 0000000..04db528
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * This file is part of Jenirok.
+ *
+ * Jenirok 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Jenirok 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 Jenirok.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef LISTWIDGET_H
+#define LISTWIDGET_H
+
+#include <QtGui/QTableWidget>
+#include <QtCore/QMap>
+#include <QtCore/QVariant>
+
+class ListWidget : public QTableWidget
+{
+    Q_OBJECT
+
+public:
+    ListWidget(QWidget* parent = 0);
+    void addWidget(QWidget* widget, QVariant const& data);
+    QVariant getData(int index) const;
+    QWidget* getWidget(int index) const;
+
+signals:
+    void itemClicked(int index);
+
+public slots:
+    void clear();
+
+private slots:
+    void handleClick(int index);
+
+private:
+    QTableWidget* widget_;
+    QMap<int, QVariant> data_;
+    QMap<int, QWidget*> widgets_;
+};
+
+#endif
diff --git a/src/gui/logwindow.cpp b/src/gui/logwindow.cpp
new file mode 100644 (file)
index 0000000..1fb8484
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * This file is part of Jenirok.
+ *
+ * Jenirok 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Jenirok 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 Jenirok.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <QtCore/QDateTime>
+#include <QtCore/QDebug>
+#include <QtGui/QLabel>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QMenuBar>
+#include "logwindow.h"
+
+LogWindow::LogWindow(QWidget* parent): QMainWindow(parent), list_(0)
+{
+    setAttribute(Qt::WA_Maemo5StackedWindow);
+    setWindowTitle(tr("Incoming call log"));
+    menuBar()->addAction(tr("Clear log"), this, SLOT(clearLog()));
+}
+
+void LogWindow::setVisible(bool visible)
+{
+    if(visible)
+    {
+        loadLogItems();
+    }
+
+    QMainWindow::setVisible(visible);
+}
+
+void LogWindow::loadLogItems()
+{
+    if(!list_)
+    {
+        list_ = new ListWidget(this);
+        setCentralWidget(list_);
+        connect(list_, SIGNAL(itemClicked(int)), this,
+                SLOT(itemClicked(int)));
+    }
+    else
+    {
+        list_->clear();
+    }
+
+    QList<Cache::LogDetails> logList;
+
+    Cache::instance().getLogItems(logList, LOG_MAX_ITEMS);
+
+    if(logList.size() == 0)
+    {
+        QLabel* info = new QLabel(tr("There are currently no logged calls"));
+        info->setAlignment(Qt::AlignCenter);
+        setCentralWidget(info);
+        list_ = 0;
+    }
+    else
+    {
+        for(int i = 0; i < logList.size(); i++)
+        {
+            QMap <QString, QVariant> data;
+            data["name"] = QVariant(logList.at(i).result.name);
+            data["street"] = QVariant(logList.at(i).result.street);
+            data["city"] = QVariant(logList.at(i).result.city);
+            data["number"] = QVariant(logList.at(i).result.number);
+
+            list_->addWidget(createWidget(logList.at(i)), data);
+        }
+    }
+}
+
+void LogWindow::itemClicked(int index)
+{
+    if(!list_)
+    {
+        return;
+    }
+
+    QMap <QString, QVariant> data = list_->getData(index).toMap();
+    Source::Result details;
+    details.name = data["name"].toString();
+
+    if(details.name.isEmpty())
+    {
+        return;
+    }
+
+    details.street = data["street"].toString();
+    details.city = data["city"].toString();
+    details.number = data["number"].toString();
+
+    emit logItemSelected(details);
+}
+
+QWidget* LogWindow::createWidget(Cache::LogDetails const& details)
+{
+    QWidget* widget = new QWidget;
+    QHBoxLayout* layout = new QHBoxLayout;
+
+    QIcon icon;
+
+    if(details.missed)
+    {
+        icon = QIcon::fromTheme("general_missed");
+    }
+    else
+    {
+        icon = QIcon::fromTheme("general_received");
+    }
+
+    QLabel* label = new QLabel;
+    label->setPixmap(icon.pixmap(48, 48));
+
+    layout->addWidget(label);
+
+    QVBoxLayout* content = new QVBoxLayout;
+
+    QString text;
+
+    if(details.result.name.isEmpty())
+    {
+        text = tr("%1 (no search results)").arg(details.result.number);
+    }
+    else
+    {
+        text = details.result.name;
+
+        if(!details.result.street.isEmpty())
+        {
+            text += ", " + details.result.street;
+        }
+
+        if(!details.result.city.isEmpty())
+        {
+            text += ", " + details.result.city;
+        }
+    }
+
+    QLabel* nameLabel = new QLabel(text);
+
+    QDateTime date = QDateTime::fromTime_t(details.time);
+    QLabel* dateLabel = new QLabel(date.toString(Qt::SystemLocaleShortDate));
+    QFont font;
+    font.setPointSize(11);
+    dateLabel->setFont(font);
+
+    content->addWidget(nameLabel);
+    content->addWidget(dateLabel);
+
+    layout->addLayout(content, Qt::AlignLeft);
+
+    widget->setLayout(layout);
+
+    return widget;
+}
+
+void LogWindow::clearLog()
+{
+    Cache::instance().clearLog();
+
+    loadLogItems();
+}
diff --git a/src/gui/logwindow.h b/src/gui/logwindow.h
new file mode 100644 (file)
index 0000000..2afe7e7
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * This file is part of Jenirok.
+ *
+ * Jenirok 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Jenirok 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 Jenirok.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef LOGWINDOW_H
+#define LOGWINDOW_H
+
+#include <QtGui/QMainWindow>
+#include <QtGui/QListWidget>
+#include "source.h"
+#include "listwidget.h"
+#include "cache.h"
+
+class LogWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    static int const LOG_MAX_ITEMS = 50;
+    LogWindow(QWidget* parent = 0);
+
+signals:
+    void logItemSelected(Source::Result const& result);
+
+protected:
+    void setVisible(bool visible);
+
+private slots:
+    void itemClicked(int index);
+    void clearLog();
+
+private:
+    QWidget* createWidget(Cache::LogDetails const& details);
+    void loadLogItems();
+    ListWidget* list_;
+};
+
+#endif
index 215c254..e642575 100644 (file)
@@ -43,5 +43,8 @@ int main(int argc, char *argv[])
     QObject::connect(&results, SIGNAL(itemSelected(Source::Result const&)),
                      &details, SLOT(loadData(Source::Result const&)));
 
+    QObject::connect(&window, SIGNAL(logItemSelected(Source::Result const&)),
+                     &details, SLOT(loadData(Source::Result const&)));
+
     return app.exec();
 }
index 2d4800d..3e62491 100644 (file)
@@ -43,7 +43,8 @@ namespace
 
 MainWindow::MainWindow(QWidget* parent): QMainWindow(parent),
 searchResults_(0), settingsDialog_(0), running_(false),
-toggleButton_(0), searchDialog_(0), aboutDialog_(0), warning_(0)
+toggleButton_(0), searchDialog_(0), aboutDialog_(0), warning_(0),
+logWindow_(0)
 {
     setWindowTitle(tr("Jenirok"));
     setAttribute(Qt::WA_Maemo5StackedWindow);
@@ -62,21 +63,35 @@ toggleButton_(0), searchDialog_(0), aboutDialog_(0), warning_(0)
         running_ = false;
     }
 
+    QSizePolicy policy;
+
+    policy.setHorizontalPolicy(QSizePolicy::Preferred);
+
+    toggleButton_->setSizePolicy(policy);
+
     QToolButton* searchButton = createButton(tr("Search"));
     searchButton->setIcon(QIcon::fromTheme("general_search"));
+    searchButton->setSizePolicy(policy);
+
+    QToolButton* logButton = createButton(tr("Log"));
+    logButton->setIcon(QIcon::fromTheme("general_call"));
+    logButton->setSizePolicy(policy);
 
     QSize size(64, 64);
     searchButton->setIconSize(size);
     toggleButton_->setIconSize(size);
+    logButton->setIconSize(size);
 
     QHBoxLayout *buttonLayout = new QHBoxLayout;
-    buttonLayout->addWidget(toggleButton_, Qt::AlignLeft);
-    buttonLayout->addWidget(searchButton, Qt::AlignRight);
+    buttonLayout->addWidget(toggleButton_, Qt::AlignHCenter);
+    buttonLayout->addWidget(searchButton, Qt::AlignHCenter);
+    buttonLayout->addWidget(logButton, Qt::AlignHCenter);
 
     mainWidget->setLayout(buttonLayout);
 
     connect(toggleButton_, SIGNAL(pressed()), this, SLOT(toggleDaemon()));
     connect(searchButton, SIGNAL(pressed()), this, SLOT(openSearch()));
+    connect(logButton, SIGNAL(pressed()), this, SLOT(openLog()));
 
     setCentralWidget(mainWidget);
     menuBar()->addAction(tr("Settings"), this, SLOT(showSettings()));
@@ -202,6 +217,17 @@ void MainWindow::openSearch()
     searchDialog_->show();
 }
 
+void MainWindow::openLog()
+{
+    if(!logWindow_)
+    {
+        logWindow_ = new LogWindow(this);
+        connect(logWindow_, SIGNAL(logItemSelected(Source::Result const&)), this, SIGNAL(logItemSelected(Source::Result const&)));
+    }
+
+    logWindow_->show();
+}
+
 QToolButton* MainWindow::createButton(QString const& text)
 {
     QToolButton* button = new QToolButton();
index b8e88aa..98ff0c6 100644 (file)
@@ -26,6 +26,8 @@
 #include "searchdialog.h"
 #include "settingsdialog.h"
 #include "aboutdialog.h"
+#include "source.h"
+#include "logwindow.h"
 
 class MainWindow : public QMainWindow
 {
@@ -37,12 +39,14 @@ public:
 
 signals:
     void search(SearchDialog::SearchDetails& details);
+    void logItemSelected(Source::Result const& result);
 
 public slots:
     void showSettings();
     void showAbout();
     void toggleDaemon();
     void openSearch();
+    void openLog();
     void handleSearch(SearchDialog::SearchDetails& details);
 
 private:
@@ -54,6 +58,7 @@ private:
     SearchDialog* searchDialog_;
     AboutDialog* aboutDialog_;
     QDialog* warning_;
+    LogWindow* logWindow_;
 
 };
 
index 5d04f03..adbd404 100644 (file)
@@ -90,21 +90,6 @@ void ResultWindow::search(SearchDialog::SearchDetails& details)
     config->apply(source_);
     delete config;
 
-    Source::SearchType type;
-
-    switch(details.type)
-    {
-    case 0:
-        type = Source::PERSONS;
-        break;
-    case 1:
-        type = Source::YELLOW_PAGES;
-        break;
-    default:
-        qDebug() << "Unknown search type: " << details.type;
-        return;
-    }
-
     show();
     setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true);
 
@@ -116,7 +101,7 @@ void ResultWindow::search(SearchDialog::SearchDetails& details)
     connectionManager_->connect();
 
     source_->abort();
-    source_->search(Source::SearchDetails(details.name, details.location, type));
+    source_->search(Source::SearchDetails(details.name, details.location, details.type));
 
 }
 
index 5ee806c..a6224cb 100644 (file)
@@ -23,7 +23,6 @@
 #include <QtGui/QDialogButtonBox>
 #include <QMaemo5ValueButton>
 #include "searchdialog.h"
-#include "source.h"
 #include "settings.h"
 
 SearchDialog::SearchDialog(QWidget* parent): QDialog(parent),
@@ -76,7 +75,16 @@ void SearchDialog::searchPressed()
     }
 
     details.location = locationInput_->text();
-    details.type = selector_->value().toInt();
+
+    int type = 0;
+
+    if(selector_->isVisible())
+    {
+        type = selector_->value().toInt();
+    }
+
+    details.type = static_cast<Source::SearchType>(type);
+
     emit search(details);
     hide();
 }
index 05c54c5..2f57a9b 100644 (file)
@@ -25,6 +25,7 @@
 #include <QtGui/QLineEdit>
 #include <QMaemo5ListPickSelector>
 #include "buttonselector.h"
+#include "source.h"
 
 class SearchDialog : public QDialog
 {
@@ -36,7 +37,7 @@ public:
     {
         QString name;
         QString location;
-        int type;
+        Source::SearchType type;
     };
 
     SearchDialog(QWidget* parent = 0);