Merge branch 'master' into context_driven_buttons, review context_driven_buttons
authorSami Rämö <sami.ramo@ixonos.com>
Fri, 3 Sep 2010 10:12:12 +0000 (13:12 +0300)
committerSami Rämö <sami.ramo@ixonos.com>
Fri, 3 Sep 2010 11:06:29 +0000 (14:06 +0300)
 - Reviewed by Jussi Laitinen

Conflicts:
images.qrc
src/src.pro
src/ui/friendlistpanel.cpp
src/ui/locationsearchpanel.cpp

35 files changed:
debian/control
images.qrc
res/images/clear_btn.png [new file with mode: 0644]
res/images/clear_btn_d.png [new file with mode: 0644]
res/images/clear_btn_s.png [new file with mode: 0644]
res/images/contact_btn.png [new file with mode: 0644]
res/images/contact_btn_d.png [new file with mode: 0644]
res/images/contact_btn_s.png [new file with mode: 0644]
res/images/search_history.png [new file with mode: 0644]
src/engine/contactmanager.cpp [new file with mode: 0644]
src/engine/contactmanager.h [new file with mode: 0644]
src/engine/contactmanagerprivate.cpp [new file with mode: 0644]
src/engine/contactmanagerprivate.h [new file with mode: 0644]
src/engine/contactmanagerprivatestub.cpp [new file with mode: 0644]
src/engine/contactmanagerprivatestub.h [new file with mode: 0644]
src/engine/engine.cpp
src/engine/engine.h
src/src.pro
src/ui/extendedlistitem.cpp
src/ui/friendlistitem.cpp
src/ui/friendlistitem.h
src/ui/friendlistpanel.cpp
src/ui/friendlistpanel.h
src/ui/listview.cpp
src/ui/listview.h
src/ui/locationsearchpanel.cpp
src/ui/locationsearchpanel.h
src/ui/mainwindow.cpp
src/ui/mainwindow.h
src/ui/ossoabookdialog.cpp [new file with mode: 0644]
src/ui/ossoabookdialog.h [new file with mode: 0644]
src/ui/searchhistorylistitem.cpp [new file with mode: 0644]
src/ui/searchhistorylistitem.h [new file with mode: 0644]
src/ui/searchhistorylistview.cpp [new file with mode: 0644]
src/ui/searchhistorylistview.h [new file with mode: 0644]

index a3082b5..0c29275 100644 (file)
@@ -2,7 +2,7 @@ Source: situare
 Section: user/navigation
 Priority: optional
 Maintainer: Jussi Laitinen <jussi.laitinen@ixonos.com>
-Build-Depends: debhelper, libdbus-1-dev, icd2-dev, libx11-dev, libqt4-dev, libqjson-dev, liblocation-dev, libqtm-dev, libgconf2-dev
+Build-Depends: debhelper, libdbus-1-dev, icd2-dev, libx11-dev, libqt4-dev, libqjson-dev, liblocation-dev, libqtm-dev, libgconf2-dev, libosso-abook-dev
 Standards-Version: 3.7.2
 
 Package: situare
@@ -17,7 +17,7 @@ Description: Locate and share your position with friends.
  Check also http://www.situare.net.
 XSBC-Bugtracker: https://garage.maemo.org/tracker/?atid=5192&group_id=1420&func=browse
 XB-Maemo-Display-Name: Situare
-XB-Maemo-Upgrade-Description: Alpha release
+XB-Maemo-Upgrade-Description: Beta release
 XB-Maemo-Icon-26:
  iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAA3X
  AAAN1wFCKJt4AAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNn
index 2325349..3dc6593 100644 (file)
         <file>res/images/list_item_context_button_bar_left.png</file>
         <file>res/images/list_item_context_button_bar_right.png</file>
         <file>res/images/list_item_context_button_bar_tile.png</file>
+        <file>res/images/search_history.png</file>
+        <file>res/images/clear_btn_d.png</file>
+        <file>res/images/clear_btn_s.png</file>
+        <file>res/images/clear_btn.png</file>
+        <file>res/images/contact_btn.png</file>
+        <file>res/images/contact_btn_d.png</file>
+        <file>res/images/contact_btn_s.png</file>
     </qresource>
 </RCC>
diff --git a/res/images/clear_btn.png b/res/images/clear_btn.png
new file mode 100644 (file)
index 0000000..6edb20d
Binary files /dev/null and b/res/images/clear_btn.png differ
diff --git a/res/images/clear_btn_d.png b/res/images/clear_btn_d.png
new file mode 100644 (file)
index 0000000..be1c3cd
Binary files /dev/null and b/res/images/clear_btn_d.png differ
diff --git a/res/images/clear_btn_s.png b/res/images/clear_btn_s.png
new file mode 100644 (file)
index 0000000..e237238
Binary files /dev/null and b/res/images/clear_btn_s.png differ
diff --git a/res/images/contact_btn.png b/res/images/contact_btn.png
new file mode 100644 (file)
index 0000000..026212c
Binary files /dev/null and b/res/images/contact_btn.png differ
diff --git a/res/images/contact_btn_d.png b/res/images/contact_btn_d.png
new file mode 100644 (file)
index 0000000..1ee74b2
Binary files /dev/null and b/res/images/contact_btn_d.png differ
diff --git a/res/images/contact_btn_s.png b/res/images/contact_btn_s.png
new file mode 100644 (file)
index 0000000..5738d33
Binary files /dev/null and b/res/images/contact_btn_s.png differ
diff --git a/res/images/search_history.png b/res/images/search_history.png
new file mode 100644 (file)
index 0000000..d96d329
Binary files /dev/null and b/res/images/search_history.png differ
diff --git a/src/engine/contactmanager.cpp b/src/engine/contactmanager.cpp
new file mode 100644 (file)
index 0000000..0e39bf3
--- /dev/null
@@ -0,0 +1,32 @@
+#include <QDebug>
+
+#if defined(Q_WS_MAEMO_5) & defined(ARMEL)
+#include "contactmanagerprivate.h"
+#else
+#include "contactmanagerprivatestub.h"
+#endif
+
+#include "contactmanager.h"
+
+ContactManager::ContactManager(QObject *parent)
+    : QObject(parent),
+      m_contactManagerPrivate(0)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    m_contactManagerPrivate = new ContactManagerPrivate(this);
+}
+
+QString ContactManager::contactGuid(const QString &facebookId) const
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    return m_contactManagerPrivate->contactGuid(facebookId);
+}
+
+void ContactManager::requestContactGuids()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    m_contactManagerPrivate->requestContactGuids();
+}
diff --git a/src/engine/contactmanager.h b/src/engine/contactmanager.h
new file mode 100644 (file)
index 0000000..97c1c96
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef CONTACTMANAGER_H
+#define CONTACTMANAGER_H
+
+#include <QObject>
+#include <QHash>
+
+class ContactManagerPrivate;
+
+/**
+* @brief Manages phone address book contacts.
+*/
+class ContactManager : public QObject
+{
+    Q_OBJECT
+public:
+    /**
+    * @brief Constructor
+    *
+    * @param parent QObject
+    */
+    ContactManager(QObject *parent = 0);
+
+/*******************************************************************************
+* MEMBER FUNCTIONS AND SLOTS
+******************************************************************************/
+    /**
+    * @brief Returns contact's guid from contact's facebook ID.
+    *
+    * @param facebookId contact's facebook ID
+    * @return contact guid
+    */
+    QString contactGuid(const QString &facebookId) const;
+
+    /**
+    * @brief Requests contact guids.
+    *
+    * Guid is a globally unique ID of a contact, which can be used with
+    * other datastores.
+    */
+    void requestContactGuids();
+
+/******************************************************************************
+* DATA MEMBERS
+******************************************************************************/
+private:
+    ContactManagerPrivate *m_contactManagerPrivate; ///< ContactManagerPrivate
+};
+
+#endif // CONTACTMANAGER_H
diff --git a/src/engine/contactmanagerprivate.cpp b/src/engine/contactmanagerprivate.cpp
new file mode 100644 (file)
index 0000000..96ac732
--- /dev/null
@@ -0,0 +1,82 @@
+#include <QContact>
+#include <QContactGuid>
+#include <QContactManager>
+#include <QContactOnlineAccount>
+#include <QDebug>
+#include <QHash>
+#include <QList>
+#include <QStringList>
+
+#include "contactmanager.h"
+
+#include "contactmanagerprivate.h"
+
+QTM_USE_NAMESPACE
+
+ContactManagerPrivate::ContactManagerPrivate(QObject *parent)
+    : QObject(parent),
+      m_manager(0)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    const QString MAEMO5_MANAGER_NAME = "maemo5";
+
+    QStringList availableManagers = QContactManager::availableManagers();
+
+    if (availableManagers.contains(MAEMO5_MANAGER_NAME)) {
+        QMap<QString, QString> params;
+        QString managerUri = QContactManager::buildUri(MAEMO5_MANAGER_NAME, params);
+        m_manager = QContactManager::fromUri(managerUri);
+    }
+}
+
+QString ContactManagerPrivate::parseFacebookId(const QString &accountUri) const
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    const QString FACEBOOK_CHAT_URL = "@chat.facebook.com";
+    int facebookChatUrlIndex = accountUri.indexOf(FACEBOOK_CHAT_URL);
+    QString facebookId;
+
+    if (facebookChatUrlIndex != -1) {
+        facebookId = accountUri.left(facebookChatUrlIndex);
+        facebookId.remove("-");
+    }
+
+    return facebookId;
+}
+
+QString ContactManagerPrivate::contactGuid(const QString &facebookId) const
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    if (!m_manager) {
+        qWarning() << "Manager is uninitialized";
+        return QString();
+    }
+
+    return m_contactGuids.value(facebookId);
+}
+
+void ContactManagerPrivate::requestContactGuids()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    if (!m_manager) {
+        qWarning() << "Manager is uninitialized";
+        return;
+    }
+
+    QHash<QString, QString> contactGuids;
+
+    foreach (QContact contact, m_manager->contacts()) {
+        QContactOnlineAccount account = contact.detail(QContactOnlineAccount::DefinitionName);
+        QString facebookId = parseFacebookId(account.accountUri());
+        QContactGuid contactGuid = contact.detail(QContactGuid::DefinitionName);
+
+        if (!facebookId.isEmpty())
+            contactGuids.insert(facebookId, contactGuid.guid());
+    }
+
+    m_contactGuids = contactGuids;
+}
diff --git a/src/engine/contactmanagerprivate.h b/src/engine/contactmanagerprivate.h
new file mode 100644 (file)
index 0000000..44f35d4
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef CONTACTMANAGERPRIVATE_H
+#define CONTACTMANAGERPRIVATE_H
+
+#include <QObject>
+
+#include <QContactManager>
+
+class ContactManager;
+
+QTM_USE_NAMESPACE
+
+/**
+* @brief Manages phone address book contacts.
+*/
+class ContactManagerPrivate : public QObject
+{
+    Q_OBJECT
+
+public:
+    /**
+    * @brief Constructor
+    *
+    * @param parent QObject
+    */
+    ContactManagerPrivate(QObject *parent = 0);
+
+/*******************************************************************************
+* MEMBER FUNCTIONS AND SLOTS
+******************************************************************************/
+public:
+    /**
+    * @brief Returns contact's guid from contact's facebook ID.
+    *
+    * @param facebookId contact's facebook ID
+    * @return contact guid
+    */
+    QString contactGuid(const QString &facebookId) const;
+
+    /**
+    * @brief Requests contact guids.
+    *
+    * Guid is a globally unique ID of a contact, which can be used with
+    * other datastores.
+    */
+    void requestContactGuids();
+
+private:
+    /**
+    * @brief Parses Facebook id from account URI.
+    *
+    * @param accountUri Accounts universal resource identifier.
+    * @return Facebook ID or empty if cannot parse the ID.
+    */
+    QString parseFacebookId(const QString &accountUri) const;
+
+/******************************************************************************
+* DATA MEMBERS
+******************************************************************************/
+private:
+    QContactManager *m_manager;             ///< Contact manager
+    QHash<QString, QString> m_contactGuids; ///< List of contact GUIDS
+};
+
+#endif // CONTACTMANAGERPRIVATE_H
diff --git a/src/engine/contactmanagerprivatestub.cpp b/src/engine/contactmanagerprivatestub.cpp
new file mode 100644 (file)
index 0000000..df142d2
--- /dev/null
@@ -0,0 +1,23 @@
+#include <QDebug>
+
+#include "contactmanagerprivatestub.h"
+
+ContactManagerPrivate::ContactManagerPrivate(QObject *parent) :
+    QObject(parent)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+}
+
+void ContactManagerPrivate::requestContactGuids()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+}
+
+QString ContactManagerPrivate::contactGuid(const QString &facebookId) const
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    Q_UNUSED(facebookId);
+
+    return QString();
+}
diff --git a/src/engine/contactmanagerprivatestub.h b/src/engine/contactmanagerprivatestub.h
new file mode 100644 (file)
index 0000000..191912c
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef CONTACTMANAGERPRIVATESTUB_H
+#define CONTACTMANAGERPRIVATESTUB_H
+
+#include <QObject>
+
+/**
+* @brief Manages phone address book contacts.
+*
+* STUB CLASS.
+*/
+class ContactManagerPrivate : public QObject
+{
+    Q_OBJECT
+public:
+    /**
+    * @brief Constructor
+    *
+    * @param parent QObject
+    */
+    ContactManagerPrivate(QObject *parent = 0);
+
+/*******************************************************************************
+* MEMBER FUNCTIONS AND SLOTS
+******************************************************************************/
+    /**
+    * @brief Returns contact's guid from contact's facebook ID.
+    *
+    * RETURNS empty QString.
+    *
+    * @param facebookId contact's facebook ID
+    * @return contact guid
+    */
+    QString contactGuid(const QString &facebookId) const;
+
+    /**
+    * @brief Requests contact guids.
+    *
+    * Guid is a globally unique ID of a contact, which can be used with
+    * other datastores.
+    *
+    * DOES NOTHING.
+    */
+    void requestContactGuids();
+};
+
+#endif // CONTACTMANAGERPRIVATESTUB_H
index 2883a50..d94ebfd 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "application.h"
 #include "common.h"
+#include "contactmanager.h"
 #include "../error.h"
 #include "facebookservice/facebookauthentication.h"
 #include "gps/gpsposition.h"
@@ -132,6 +133,9 @@ SituareEngine::SituareEngine()
 
     m_mce = new MCE(this);
     connect(m_mce, SIGNAL(displayOff(bool)), this, SLOT(setPowerSaving(bool)));
+    
+    m_contactManager = new ContactManager(this);
+    m_contactManager->requestContactGuids();
 }
 
 SituareEngine::~SituareEngine()
@@ -567,6 +571,19 @@ void SituareEngine::setPowerSaving(bool enabled)
         m_mapEngine->setAutoCentering(!enabled);
 }
 
+void SituareEngine::showContactDialog(const QString &facebookId)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    QString guid = m_contactManager->contactGuid(facebookId);
+
+    if (!guid.isEmpty())
+        m_ui->showContactDialog(guid);
+    else
+        m_ui->buildInformationBox(tr("Unable to find contact.\nYou must have Facebook "
+                                     "chat account to be able to open contact dialog."), true);
+}
+
 void SituareEngine::signalsFromFacebookAuthenticator()
 {
     qDebug() << __PRETTY_FUNCTION__;
@@ -685,6 +702,9 @@ void SituareEngine::signalsFromMainWindow()
             m_mapEngine,
             SLOT(showMapArea(const GeoCoordinate&, const GeoCoordinate&)));
 
+    connect(m_ui, SIGNAL(searchHistoryItemClicked(QString)),
+            this, SLOT(locationSearch(QString)));
+
     // signals from routing tab
     connect(m_ui, SIGNAL(clearRoute()),
             m_mapEngine, SLOT(clearRoute()));
@@ -702,6 +722,10 @@ void SituareEngine::signalsFromMainWindow()
     // signal from search location dialog
     connect(m_ui, SIGNAL(searchForLocation(QString)),
             this, SLOT(locationSearch(QString)));
+
+    // signal from friend list panel
+    connect(m_ui, SIGNAL(requestContactDialog(const QString &)),
+            this, SLOT(showContactDialog(const QString &)));
 }
 
 void SituareEngine::signalsFromMapEngine()
index 422e2f1..aacd9e5 100644 (file)
@@ -34,6 +34,7 @@
 class QTimer;
 
 class Application;
+class ContactManager;
 class FacebookAuthentication;
 class FacebookCredentials;
 class GeocodingService;
@@ -291,6 +292,14 @@ private slots:
     void setPowerSaving(bool enabled);
 
     /**
+    * @brief Shows contact dialog.
+    *
+    * Calls MainWindow showContactDialog with contact guid defined by contact's Facebook ID.
+    * @param facebookId contact's facebookId
+    */
+    void showContactDialog(const QString &facebookId);
+
+    /**
     * @brief Automatic update interval timer timeout.
     *
     * Requests update location if user has moved.
@@ -372,6 +381,7 @@ private:
 
     QTimer *m_automaticUpdateIntervalTimer; ///< Automatic update interval timer
 
+    ContactManager *m_contactManager;                ///< Instance of contact manager
     FacebookAuthentication *m_facebookAuthenticator; ///< Instance for facebook authenticator
     GeocodingService *m_geocodingService;            ///< Instance of the geocoding service
     GeoCoordinate m_lastUpdatedGPSPosition;          ///< Last updated GPS position
index e47c648..8cc801c 100644 (file)
@@ -12,6 +12,7 @@ SOURCES += main.cpp \
     application.cpp \
     coordinates/geocoordinate.cpp \
     coordinates/scenecoordinate.cpp \
+    engine/contactmanager.cpp \
     engine/engine.cpp \
     engine/mce.cpp \
     facebookservice/facebookauthentication.cpp \
@@ -61,33 +62,36 @@ SOURCES += main.cpp \
     ui/locationlistitem.cpp \
     ui/locationlistview.cpp \
     ui/indicatorbuttonpanel.cpp \
+    ui/locationsearchpanel.cpp \
     ui/logindialog.cpp \
     ui/mainwindow.cpp \
     ui/mapscale.cpp \
-    ui/settingsdialog.cpp \
-    ui/userinfo.cpp \
-    ui/userinfopanel.cpp \
-    ui/zoombutton.cpp \
-    ui/zoombuttonpanel.cpp \
-    ui/searchdialog.cpp \
     ui/panelbar.cpp \
     ui/panelbase.cpp \
     ui/panelcontentstack.cpp \
     ui/panelcontextbuttonbar.cpp \
     ui/paneltab.cpp \
     ui/paneltabbar.cpp \
-    ui/tabbedpanel.cpp \
     ui/routingpanel.cpp \
     ui/routewaypointlistitem.cpp \
-    ui/routewaypointlistview.cpp \
-    user/user.cpp \
-    ui/locationsearchpanel.cpp \
+    ui/routewaypointlistview.cpp \    
+    ui/searchdialog.cpp \
+    ui/searchhistorylistitem.cpp \
+    ui/searchhistorylistview.cpp \
+    ui/settingsdialog.cpp \
+    ui/tabbedpanel.cpp \
     ui/textmodifier.cpp \
+    ui/userinfo.cpp \
+    ui/userinfopanel.cpp \
+    ui/zoombutton.cpp \
+    ui/zoombuttonpanel.cpp \
+    user/user.cpp \
     ui/listitemcontextbuttonbar.cpp
 HEADERS += application.h \
     common.h \
     coordinates/geocoordinate.h \
     coordinates/scenecoordinate.h \
+    engine/contactmanager.h \
     engine/engine.h \
     engine/mce.h \
     error.h \
@@ -139,21 +143,16 @@ HEADERS += application.h \
     ui/imagebutton.h \
     ui/indicatorbutton.h \
     ui/indicatorbuttonpanel.h \
+    ui/listcommon.h \    
+    ui/listview.h \
+    ui/listitem.h \
+    ui/listitemdelegate.h \
     ui/logindialog.h \
     ui/locationlistitem.h \
     ui/locationlistview.h \
+    ui/locationsearchpanel.h \
     ui/mainwindow.h \
     ui/mapscale.h \
-    ui/settingsdialog.h \
-    ui/userinfo.h \
-    ui/userinfopanel.h \
-    ui/zoombutton.h \
-    ui/zoombuttonpanel.h \
-    ui/listcommon.h \    
-    ui/listview.h \
-    ui/listitem.h \
-    ui/listitemdelegate.h \
-    ui/searchdialog.h \
     ui/panelbar.h \
     ui/panelbase.h \
     ui/panelcommon.h \
@@ -161,13 +160,20 @@ HEADERS += application.h \
     ui/panelcontextbuttonbar.h \
     ui/paneltab.h \
     ui/paneltabbar.h \
-    ui/tabbedpanel.h \
     ui/routingpanel.h \
     ui/routewaypointlistitem.h \
     ui/routewaypointlistview.h \
-    user/user.h \
-    ui/locationsearchpanel.h \
+    ui/searchdialog.h \
+    ui/searchhistorylistitem.h \
+    ui/searchhistorylistview.h \
+    ui/settingsdialog.h \
+    ui/tabbedpanel.h \
     ui/textmodifier.h \
+    ui/userinfo.h \
+    ui/userinfopanel.h \
+    ui/zoombutton.h \
+    ui/zoombuttonpanel.h \
+    user/user.h \
     ui/listitemcontextbuttonbar.h
 QT += network \
     webkit
@@ -198,8 +204,14 @@ simulator {
                    gps/liblocationwrapper.h \
                    gps/geopositioninfo.h
         CONFIG += link_pkgconfig
-        PKGCONFIG += glib-2.0 liblocation mce
+        PKGCONFIG += glib-2.0 liblocation mce gtk+-2.0 libosso-abook-1.0
         LIBS += -llocation
+        SOURCES += engine/contactmanagerprivate.cpp \
+                   ui/ossoabookdialog.cpp
+        HEADERS += engine/contactmanagerprivate.h \
+                   ui/ossoabookdialog.h
+        CONFIG += mobility
+        MOBILITY += contacts
     } else {
         SOURCES += gps/gpspositionprivatestub.cpp \
                    network/networkhandlerprivatestub.cpp \
@@ -207,6 +219,8 @@ simulator {
         HEADERS += gps/gpspositionprivatestub.h \
                    network/networkhandlerprivatestub.h \
                    engine/mceprivatestub.h
+        SOURCES += engine/contactmanagerprivatestub.cpp
+        HEADERS += engine/contactmanagerprivatestub.h
     }
 
     QT += maemo5
@@ -227,6 +241,8 @@ simulator {
     HEADERS += gps/gpspositionprivatestub.h \
                network/networkhandlerprivatestub.h \
                engine/mceprivatestub.h
+    SOURCES += engine/contactmanagerprivatestub.cpp
+    HEADERS += engine/contactmanagerprivatestub.h
     message(QJson built in)
     message(Make sure you have QJson development headers installed)
     message(install headers with: sudo apt-get install libqjson-dev)
index 1ecb362..79da1bd 100644 (file)
@@ -34,7 +34,7 @@ ExtendedListItem::ExtendedListItem()
     : m_selected(false),
       m_expandedHeight(ITEM_MIN_HEIGHT),
       m_normalHeight(ITEM_MIN_HEIGHT),
-      m_subItemTextWidth(0)
+      m_subItemTextWidth(SUBITEM_TEXT_MAX_WIDTH)
 
 {
     qDebug() << __PRETTY_FUNCTION__;
index 395b9c1..9a8c67a 100644 (file)
@@ -48,6 +48,11 @@ GeoCoordinate FriendListItem::coordinates() const
     return m_coordinates;
 }
 
+QString FriendListItem::facebookId() const
+{
+    return m_facebookId;
+}
+
 void FriendListItem::setAvatarImage(const QPixmap &image)
 {
     qDebug() << __PRETTY_FUNCTION__;
@@ -85,6 +90,13 @@ void FriendListItem::setDistanceIcon(double value, const QString &unit)
     setData(DISTANCE_IMAGE_INDEX, distanceImage);
 }
 
+
+void FriendListItem::setFacebookId(const QString &facebookId)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    m_facebookId = facebookId;
+}
 void FriendListItem::setUserData(User *user)
 {
     qDebug() << __PRETTY_FUNCTION__;
@@ -96,6 +108,8 @@ void FriendListItem::setUserData(User *user)
     setData(DISTANCE_TEXT_DISPLAY_INDEX, distanceText);
     setDistanceIcon(value, unit);
 
+    setFacebookId(user->userId());
+
     //Dummy value to get painter font metrics.
     QPixmap p = QPixmap(ICON_WIDTH, ICON_HEIGHT);
     QPainter painter(&p);
index ed16e4a..b1aa1a7 100644 (file)
@@ -60,6 +60,13 @@ public:
     GeoCoordinate coordinates() const;
 
     /**
+    * @brief Return's item's Facebook ID
+    *
+    * @return item's Facebook ID
+    */
+    QString facebookId() const;
+
+    /**
     * @brief Sets avatar image for this item.
     *
     * @param image image
@@ -91,10 +98,19 @@ private:
     */
     void setDistanceIcon(double value, const QString &unit);
 
+    /**
+    * @brief Sets item's Facebook ID
+    *
+    * @param facebookId item's Facebook ID
+    */
+    void setFacebookId(const QString &facebookId);
+
 /******************************************************************************
 * DATA MEMBERS
 ******************************************************************************/
 private:
+    QString m_facebookId;           ///< User's Facebook ID
+
     GeoCoordinate m_coordinates;    ///< User coordinates
 };
 
index 3827746..99a2585 100644 (file)
@@ -6,6 +6,7 @@
         Henri Lampela - henri.lampela@ixonos.com
         Pekka Nissinen - pekka.nissinen@ixonos.com
         Sami Rämö - sami.ramo@ixonos.com
+        Jussi Laitinen - jussi.laitinen@ixonos.com
 
     Situare is free software; you can redistribute it and/or
     modify it under the terms of the GNU General Public License
@@ -124,6 +125,12 @@ FriendListPanel::FriendListPanel(QWidget *parent)
     connect(m_routeButton, SIGNAL(clicked()),
             this, SLOT(routeToSelectedFriend()));
 
+    m_showContactButton = new ImageButton(":res/images/contact_btn.png",
+                                          ":res/images/contact_btn_s.png",
+                                          ":res/images/contact_btn_d.png", this);
+    connect(m_showContactButton, SIGNAL(clicked()),
+            this, SLOT(requestSelectedFriendContactDialog()));
+
     m_clearGroupFilteringButton = new ImageButton(":res/images/filtered.png",
                                                   ":res/images/filtered_s.png",
                                                   ":res/images/filtered_d.png", this);
@@ -133,6 +140,7 @@ FriendListPanel::FriendListPanel(QWidget *parent)
             this, SLOT(clearFiltering()));
 
     m_itemButtonsLayout->addWidget(m_routeButton);
+    m_itemButtonsLayout->addWidget(m_showContactButton);
     m_genericButtonsLayout->addWidget(m_clearGroupFilteringButton);
 }
 
@@ -236,6 +244,19 @@ void FriendListPanel::hideEvent(QHideEvent *event)
     m_friendListView->clearItemSelection();
 }
 
+void FriendListPanel::requestSelectedFriendContactDialog()
+{
+     qDebug() << __PRETTY_FUNCTION__;
+
+     FriendListItem *item = dynamic_cast<FriendListItem *>(m_friendListView->selectedItem());
+
+     if (item) {
+         QString facebookId = item->facebookId();
+         if (!facebookId.isEmpty())
+             emit requestContactDialog(facebookId);
+     }
+}
+
 void FriendListPanel::routeToSelectedFriend()
 {
     qDebug() << __PRETTY_FUNCTION__;
index 6a2723e..43362a1 100644 (file)
@@ -162,6 +162,11 @@ private slots:
     void filterTextChanged(const QString &text);
 
     /**
+    * @brief Requests selected friend's contact dialog.
+    */
+    void requestSelectedFriendContactDialog();
+
+    /**
     * @brief Routes to selected friend.
     *
     * Emits routeToFriend if friend is selected from list.
@@ -197,6 +202,13 @@ signals:
     void findFriend(const GeoCoordinate &coordinates);
 
     /**
+    * @brief Requests contact dialog.
+    *
+    * @param facebookId contact's facebookId
+    */
+    void requestContactDialog(const QString &facebookId);
+
+    /**
     * @brief Signal for routing to friend.
     *
     * @param coordinates friend's geo coordinates
@@ -220,6 +232,7 @@ private:
 
     FriendListView *m_friendListView;           ///< Friend list view
     ImageButton *m_clearGroupFilteringButton;   ///< Button for clearing friend group filtering
+    ImageButton *m_showContactButton;           ///< Button for showing contact dialog    
     ImageButton *m_routeButton;                 ///< Button for routing to selected friend
 };
 
index fdcea75..c1e8617 100644 (file)
@@ -58,6 +58,8 @@ void ListView::addListItemToView(ListItem *item)
 
 void ListView::clearItemSelection()
 {
+    qDebug() << __PRETTY_FUNCTION__;
+
     clearSelection();
 
     if (m_currentItem)
@@ -206,20 +208,41 @@ ListItem *ListView::listItemAt(int index)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    QHashIterator<QString, ListItem*> itemIterator(m_listItems);
-    ListItem *item = 0;
-    int counter = 0;
+    ListItem *listItem = 0;
 
-    while (itemIterator.hasNext()) {
-        itemIterator.next();
-        if (index == counter) {
-            item = itemIterator.value();
-            break;
-        }
-        counter++;
+    if (index < count())
+        listItem = dynamic_cast<ListItem*>(item(index));
+
+    return listItem;
+}
+
+void ListView::prependListItem(const QString &key, ListItem *item)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    if (!m_listItems.contains(key)) {
+        insertItem(0, item);
+        m_listItems.insert(key, item);
     }
+}
 
-    return item;
+void ListView::removeLastItem()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    ListItem *item = listItemAt(count() - 1);
+
+    if (item) {
+        if (item) {
+            QString key = m_listItems.key(item);
+            m_listItems.remove(key);
+            takeItem(row(item));
+            if (m_currentItem == item)
+                m_currentItem = 0;
+            delete item;
+            item = 0;
+        }
+    }
 }
 
 ListItem *ListView::selectedItem()
index 417c5d1..eaf32fb 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef LISTVIEW_H
 #define LISTVIEW_H
 
+#include <QHash>
 #include <QListWidget>
 
 class GeoCoordinate;
@@ -154,6 +155,19 @@ public:
     ListItem *listItemAt(int index);
 
     /**
+    * @brief Prepends item to view and item list.
+    *
+    * @param key user ID
+    * @param item item to prepend to view and list
+    */
+    void prependListItem(const QString &key, ListItem *item);
+
+    /**
+    * @brief Removes last ListItem in list.
+    */
+    void removeLastItem();
+
+    /**
     * @brief Returns selected ListItem.
     *
     * @return ListItem if there is selected, 0 otherwise
index c0d53a8..63449a0 100644 (file)
     USA.
 */
 
+#include <QSettings>
+
+#include "avatarimage.h"
+#include "../common.h"
+#include "extendedlistitem.h"
 #include "extendedlistitemdelegate.h"
 #include "locationlistitem.h"
 #include "locationlistview.h"
 #include "imagebutton.h"
 #include "panelcommon.h"
 #include "routing/location.h"
+#include "searchhistorylistitem.h"
+#include "searchhistorylistview.h"
 
 #include "locationsearchpanel.h"
 
+const QString SETTINGS_SEARCH_HISTORY = "SEARCH_HISTORY";
+
 LocationSearchPanel::LocationSearchPanel(QWidget *parent)
     : PanelBase(parent)
 {
@@ -50,6 +59,13 @@ LocationSearchPanel::LocationSearchPanel(QWidget *parent)
     headerLayout->addWidget(m_resultsLabel, 0, Qt::AlignCenter);
     setHeaderText(0);
 
+    // --- SEARCH HISTORY LIST VIEW ---
+    m_searchHistoryListView = new SearchHistoryListView(this);
+    m_searchHistoryListView->setItemDelegate(new ExtendedListItemDelegate(this));
+
+    connect(m_searchHistoryListView, SIGNAL(searchHistoryItemClicked(QString)),
+            this, SIGNAL(searchHistoryItemClicked(QString)));
+
     // --- SEARCH RESULTS LIST VIEW ---
     m_locationListView = new LocationListView(this);
     m_locationListView->setItemDelegate(new ExtendedListItemDelegate(this));
@@ -65,6 +81,7 @@ LocationSearchPanel::LocationSearchPanel(QWidget *parent)
     QVBoxLayout *resultsListViewLayout = new QVBoxLayout;
     resultsListViewLayout->setContentsMargins(PANEL_MARGIN_LEFT, PANEL_MARGIN_TOP,
                                        PANEL_MARGIN_RIGHT, PANEL_MARGIN_BOTTOM);
+    resultsListViewLayout->addWidget(m_searchHistoryListView);
     resultsListViewLayout->addWidget(m_locationListView);
 
     // --- MAIN LAYOUT ---
@@ -86,11 +103,61 @@ LocationSearchPanel::LocationSearchPanel(QWidget *parent)
 
     ImageButton *searchLocationButton = new ImageButton(":/res/images/search.png",
                                                         ":/res/images/search_s.png", "", this);
+
     connect(searchLocationButton, SIGNAL(clicked()),
             this, SIGNAL(requestSearchLocation()));
 
+    m_clearLocationListButton = new ImageButton(":/res/images/clear_btn.png",
+                                                ":/res/images/clear_btn_s.png",
+                                                ":/res/images/clear_btn_d.png", this);
+    m_clearLocationListButton->setDisabled(true);
+
+    connect(m_clearLocationListButton, SIGNAL(clicked()),
+            this, SLOT(showSearchHistoryListView()));
+
     m_itemButtonsLayout->addWidget(m_routeButton);
     m_genericButtonsLayout->addWidget(searchLocationButton);
+    m_genericButtonsLayout->addWidget(m_clearLocationListButton);
+
+    readSettings();
+    showSearchHistoryListView();
+}
+
+LocationSearchPanel::~LocationSearchPanel()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    QSettings settings(DIRECTORY_NAME, FILE_NAME);
+    QList<QVariant> searchHistories;
+
+    for (int i = 0; i < m_searchHistoryListView->count(); ++i) {
+        SearchHistoryListItem *item = dynamic_cast<SearchHistoryListItem*>(
+                m_searchHistoryListView->listItemAt(i));
+
+        if (item) {
+            QList<QString> searchHistory;
+            searchHistory.append(item->title());
+            searchHistory.append(item->dateTime().toString());
+            searchHistories.append(QVariant(searchHistory));
+        }
+    }
+
+    settings.setValue(SETTINGS_SEARCH_HISTORY, searchHistories);
+}
+
+void LocationSearchPanel::prependSearchHistory(QString searchString, QDateTime dateTime)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    const int SEARCH_HISTORY_LIMIT = 10;
+    static int counter = 0;
+
+    if (m_searchHistoryListView->count() >= SEARCH_HISTORY_LIMIT)
+        m_searchHistoryListView->removeLastItem();
+
+    SearchHistoryListItem *item = new SearchHistoryListItem();
+    item->setSearchHistoryData(searchString, dateTime);
+    m_searchHistoryListView->prependListItem(QString::number(counter++), item);
 }
 
 void LocationSearchPanel::clearListsSelections()
@@ -98,6 +165,7 @@ void LocationSearchPanel::clearListsSelections()
     qDebug() << __PRETTY_FUNCTION__;
 
     m_locationListView->clearItemSelection();
+    m_searchHistoryListView->clearItemSelection();
 }
 
 void LocationSearchPanel::hideEvent(QHideEvent *event)
@@ -113,9 +181,8 @@ void LocationSearchPanel::populateLocationListView(const QList<Location> &locati
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    setHeaderText(locations.count());
-
     m_locationListView->clearList();
+    showLocationListView(locations.count());
 
     for (int i = 0; i < locations.size(); ++i) {
         LocationListItem *item = new LocationListItem();
@@ -136,6 +203,25 @@ void LocationSearchPanel::populateLocationListView(const QList<Location> &locati
     m_locationListView->scrollToTop();
 }
 
+void LocationSearchPanel::readSettings()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    const int SEARCH_HISTORY_LIST_ITEM_COUNT = 2;
+
+    QSettings settings(DIRECTORY_NAME, FILE_NAME);
+    QList<QVariant> searchHistories = settings.value(SETTINGS_SEARCH_HISTORY).toList();
+
+    //Read from end to begin so items are prepended in correct order
+    for (int i = searchHistories.count() - 1; i >= 0; --i) {
+        QList<QVariant> searchHistory = searchHistories.at(i).toList();
+        if (searchHistory.count() == SEARCH_HISTORY_LIST_ITEM_COUNT) {
+            prependSearchHistory(searchHistory.at(0).toString(),
+                                 QDateTime::fromString(searchHistory.at(1).toString()));
+        }
+    }
+}
+
 void LocationSearchPanel::routeToSelectedLocation()
 {
     qDebug() << __PRETTY_FUNCTION__;
@@ -153,3 +239,25 @@ void LocationSearchPanel::setHeaderText(int count)
 
     m_resultsLabel->setText(tr("Search results: %1").arg(count));
 }
+
+void LocationSearchPanel::showLocationListView(int locationItemsCount)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    m_searchHistoryListView->clearItemSelection();
+    m_searchHistoryListView->hide();
+    setHeaderText(locationItemsCount);
+    m_clearLocationListButton->setEnabled(true);
+    m_locationListView->show();
+}
+
+void LocationSearchPanel::showSearchHistoryListView()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    m_locationListView->clearList();
+    m_locationListView->hide();
+    m_resultsLabel->setText(tr("Search history:"));
+    m_clearLocationListButton->setDisabled(true);
+    m_searchHistoryListView->show();
+}
index 98b978d..e939db7 100644 (file)
@@ -32,6 +32,7 @@ class GeoCoordinate;
 class ImageButton;
 class Location;
 class LocationListView;
+class SearchHistoryListView;
 
 /**
  * @brief Location search panel
@@ -51,6 +52,13 @@ public:
      */
     LocationSearchPanel(QWidget *parent = 0);
 
+    /**
+     * @brief Destructor
+     *
+     * Writes search history to settings.
+     */
+    ~LocationSearchPanel();
+
 /*******************************************************************************
  * BASE CLASS INHERITED AND REIMPLEMENTED MEMBER FUNCTIONS
  ******************************************************************************/
@@ -69,6 +77,11 @@ protected:
  ******************************************************************************/
 private:
     /**
+    * @brief Reads search history from settings.
+    */
+    void readSettings();
+
+    /**
     * @brief Set text for header
     *
     * @param count Search result count
@@ -77,6 +90,16 @@ private:
 
 private slots:
     /**
+    * @brief Prepends search history list view with search.
+    *
+    * If search history limit is reached, oldest search is removed from list view.
+    *
+    * @param searchString search string to add
+    * @param dateTime date and time of search (if empty, current date and time is added)
+    */
+    void prependSearchHistory(QString searchString, QDateTime dateTime = QDateTime());
+
+    /**
     * @brief Clears lists' selections.
     *
     * Does call setRouteButtonDisabled().
@@ -84,6 +107,18 @@ private slots:
     void clearListsSelections();
 
     /**
+    * @brief Shows location list view.
+    *
+    * @param locationItemsCount location items count
+    */
+    void showLocationListView(int locationItemsCount);
+
+    /**
+    * @brief Shows search history list view.
+    */
+    void showSearchHistoryListView();
+
+    /**
     * @brief Populates location list view.
     *
     * @param locations list of Location objects
@@ -128,14 +163,23 @@ signals:
     */
     void routeWaypointItemClicked(const GeoCoordinate &coordinate);
 
+    /**
+    * @brief Signal is emitted when search history item is clicked.
+    *
+    * @param searchString search string used
+    */
+    void searchHistoryItemClicked(const QString &searchString);
+
 /*******************************************************************************
  * DATA MEMBERS
  ******************************************************************************/
 private:
-    QLabel *m_resultsLabel;                 ///< Location list label
+    QLabel *m_resultsLabel;                         ///< Location list label
 
-    ImageButton *m_routeButton;             ///< Route to location button
-    LocationListView *m_locationListView;   ///< Search results list view
+    ImageButton *m_clearLocationListButton;         ///< Clear location list button
+    ImageButton *m_routeButton;                     ///< Route to location button
+    SearchHistoryListView *m_searchHistoryListView; ///< Search history list view
+    LocationListView *m_locationListView;           ///< Search results list view
 };
 
 #endif // LOCATIONSEARCHPANEL_H
index cfba1f0..2ca83a8 100644 (file)
@@ -51,6 +51,7 @@
 #include "userinfopanel.h"
 #include "zoombuttonpanel.h"
 
+
 #include "mainwindow.h"
 
 // These MUST BE HERE, compiling for Maemo fails if moved
 #include <X11/Xlib.h>
 #endif // Q_WS_MAEMO_5
 
+#if defined(Q_WS_MAEMO_5) & defined(ARMEL)
+#include "ossoabookdialog.h"
+#endif
+
 MainWindow::MainWindow(QWidget *parent)
     : QMainWindow(parent),
       m_errorShown(false),
@@ -182,6 +187,9 @@ void MainWindow::buildFriendListPanel()
 
     connect(m_friendsListPanel, SIGNAL(routeToFriend(const GeoCoordinate&)),
             this, SIGNAL(routeTo(const GeoCoordinate&)));
+
+    connect(m_friendsListPanel, SIGNAL(requestContactDialog(const QString &)),
+            this, SIGNAL(requestContactDialog(const QString &)));
 }
 
 void MainWindow::buildFullScreenButton()
@@ -269,6 +277,12 @@ void MainWindow::buildLocationSearchPanel()
 
     connect(m_locationSearchPanel, SIGNAL(requestSearchLocation()),
             this, SLOT(startLocationSearch()));
+
+    connect(this, SIGNAL(searchForLocation(QString)),
+            m_locationSearchPanel, SLOT(prependSearchHistory(QString)));
+
+    connect(m_locationSearchPanel, SIGNAL(searchHistoryItemClicked(QString)),
+            this, SIGNAL(searchHistoryItemClicked(QString)));
 }
 
 void MainWindow::buildMap()
@@ -941,6 +955,18 @@ void MainWindow::setUsername(const QString &username)
     m_email = username;
 }
 
+void MainWindow::showContactDialog(const QString &guid)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+#if defined(Q_WS_MAEMO_5) & defined(ARMEL)
+    OssoABookDialog::showContactDialog(guid);
+#else
+    Q_UNUSED(guid);
+    buildInformationBox(tr("Contact dialog works only on phone!"), true);
+#endif
+}
+
 void MainWindow::showEnableAutomaticUpdateLocationDialog(const QString &text)
 {
     qDebug() << __PRETTY_FUNCTION__;
index 06acfae..b9e5604 100644 (file)
@@ -193,6 +193,14 @@ public slots:
     void setUsername(const QString &username);
 
     /**
+    * @brief Shows contact dialog.
+    *
+    * Shows contact dialog with contact's information.
+    * @param guid globally unique ID of a contact
+    */
+    void showContactDialog(const QString &guid);
+
+    /**
      * @brief Public slot to intercept signal when old cerdentials are invalid or credentials
      *        doesn't exist yet
      */
@@ -564,6 +572,13 @@ signals:
     void refreshUserData();
 
     /**
+    * @brief Requests contact dialog.
+    *
+    * @param facebookId contact's facebookId
+    */
+    void requestContactDialog(const QString &facebookId);
+
+    /**
      * @brief Signal for requesting reverseGeo from SituareEngine
      *
      */
@@ -610,6 +625,13 @@ signals:
     void searchForLocation(QString location);
 
     /**
+    * @brief Signal is emitted when search history item is clicked.
+    *
+    * @param searchString search string used
+    */
+    void searchHistoryItemClicked(const QString &searchString);
+
+    /**
      * @brief Signal for requestLocationUpdate from SituareEngine
      *
      * @param status Status message
diff --git a/src/ui/ossoabookdialog.cpp b/src/ui/ossoabookdialog.cpp
new file mode 100644 (file)
index 0000000..3c35c39
--- /dev/null
@@ -0,0 +1,44 @@
+#include "ossoabookdialog.h"
+#include <QDebug>
+
+OssoABookDialog::OssoABookDialog(QObject *parent) :
+    QObject(parent)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+}
+
+void OssoABookDialog::showContactDialog(const QString &id)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    OssoABookContact *contact = OssoABookDialog::lookup(id);
+    if (contact) {
+        GtkWidget *contactDialog = osso_abook_touch_contact_starter_dialog_new(NULL,
+        (OssoABookTouchContactStarter*)osso_abook_touch_contact_starter_new_with_contact(NULL,
+        contact));
+
+    gtk_widget_show_all(contactDialog);
+    gtk_dialog_run(GTK_DIALOG(contactDialog));
+    gtk_widget_destroy(contactDialog);
+    }
+}
+
+OssoABookContact* OssoABookDialog::lookup(const QString& id)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    GList* l = NULL; // Do not free
+    GError *error = NULL;
+    OssoABookAggregator* aggregator = NULL; // Do not free
+
+    aggregator = (OssoABookAggregator*) osso_abook_aggregator_get_default(&error);
+    if (error) {
+        qWarning() << "error opening addressbook" << error->message;
+        g_error_free (error);
+        return NULL;
+    }
+
+    l = osso_abook_aggregator_lookup(aggregator,qPrintable(id));
+
+    return (OssoABookContact*) l->data;
+}
diff --git a/src/ui/ossoabookdialog.h b/src/ui/ossoabookdialog.h
new file mode 100644 (file)
index 0000000..c3bf793
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef OSSOABOOKDIALOG_H
+#define OSSOABOOKDIALOG_H
+
+#include <QObject>
+#include <QStringList>
+
+#undef signals // Collides with GTK symbols
+#include <libosso-abook/osso-abook.h>
+
+/**
+* @brief Shows contact dialog.
+*/
+class OssoABookDialog : public QObject
+{
+    Q_OBJECT
+public:
+    /**
+    * @brief Constructor
+    *
+    * @param parent QObject
+    */
+    OssoABookDialog(QObject *parent = 0);
+
+/*******************************************************************************
+* MEMBER FUNCTIONS AND SLOTS
+******************************************************************************/
+    /**
+    * @brief Shows contact dialog.
+    *
+    * @param id contact ID
+    */
+    static void showContactDialog(const QString &id);
+
+private:
+    /**
+    * @brief Returns address book contact.
+    *
+    * @param id contact ID
+    * @return OssoABookContact
+    */
+    static OssoABookContact *lookup(const QString& id);
+};
+
+#endif // OSSOABOOKDIALOG_H
diff --git a/src/ui/searchhistorylistitem.cpp b/src/ui/searchhistorylistitem.cpp
new file mode 100644 (file)
index 0000000..53fd7a4
--- /dev/null
@@ -0,0 +1,49 @@
+#include <QDebug>
+
+#include "avatarimage.h"
+#include "../common.h"
+#include "listcommon.h"
+
+#include "searchhistorylistitem.h"
+
+const int SEARCH_HISTORY_SUBITEM_TEXT_MAX_WIDTH = SUBITEM_TEXT_MAX_WIDTH + MARGIN + IMAGE_WIDTH;
+
+SearchHistoryListItem::SearchHistoryListItem()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    setSubitemTextWidth(SEARCH_HISTORY_SUBITEM_TEXT_MAX_WIDTH);
+}
+
+SearchHistoryListItem::~SearchHistoryListItem()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+}
+
+QDateTime SearchHistoryListItem::dateTime() const
+{
+    return m_dateTime;
+}
+
+void SearchHistoryListItem::setDateTime(const QDateTime &dateTime)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    if (dateTime.isNull())
+        m_dateTime = QDateTime::currentDateTime();
+    else
+        m_dateTime = dateTime;
+}
+
+void SearchHistoryListItem::setSearchHistoryData(const QString &searchString,
+                                                 const QDateTime &dateTime)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    setDateTime(dateTime);
+    setTitle(shortenText(searchString, ITEM_WIDTH - 3 * MARGIN, ListItem::TEXT_SIZE_NORMAL));
+    setImage(AvatarImage::create(QPixmap(":/res/images/search_history.png"), AvatarImage::Small));
+
+    clearSubItems();
+    addSubItem(m_dateTime.toString(), QPixmap(":/res/images/clock.png"));
+}
diff --git a/src/ui/searchhistorylistitem.h b/src/ui/searchhistorylistitem.h
new file mode 100644 (file)
index 0000000..b6b877a
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+   Situare - A location system for Facebook
+   Copyright (C) 2010  Ixonos Plc. Authors:
+
+       Jussi Laitinen - jussi.laitinen@ixonos.com
+
+   Situare is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   version 2 as published by the Free Software Foundation.
+
+   Situare 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 Situare; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+   USA.
+*/
+
+#ifndef SEARCHHISTORYLISTITEM_H
+#define SEARCHHISTORYLISTITEM_H
+
+#include <QDateTime>
+
+#include "extendedlistitem.h"
+
+/**
+* @brief List item stores information about search history.
+*
+* @author Jussi Laitinen - jussi.laitinen (at) ixonos.com
+*/
+class SearchHistoryListItem : public ExtendedListItem
+{
+public:
+    /**
+    * @brief Constructor.
+    *
+    * Sets sub items' text width.
+    */
+    SearchHistoryListItem();
+
+    /**
+    * @brief Destructor.
+    */
+    ~SearchHistoryListItem();
+
+/******************************************************************************
+* MEMBER FUNCTIONS AND SLOTS
+******************************************************************************/
+public:
+    /**
+    * @brief Returns date and time.
+    *
+    * @return QDateTime
+    */
+    QDateTime dateTime() const;
+
+    /**
+    * @brief Sets search history data for this item.
+    *
+    * @param searchString search string
+    * @param dateTime date and time for search
+    */
+    void setSearchHistoryData(const QString &searchString, const QDateTime &dateTime);
+
+private:
+    /**
+    * @brief Sets date and time.
+    *
+    * @param dateTime QDateTime date and time
+    */
+    void setDateTime(const QDateTime &dateTime);
+
+/******************************************************************************
+* DATA MEMBERS
+******************************************************************************/
+private:
+    QDateTime m_dateTime;   ///< Date time
+};
+
+#endif // LOCATIONLISTITEM_H
diff --git a/src/ui/searchhistorylistview.cpp b/src/ui/searchhistorylistview.cpp
new file mode 100644 (file)
index 0000000..f6f7c80
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+   Situare - A location system for Facebook
+   Copyright (C) 2010  Ixonos Plc. Authors:
+
+       Jussi Laitinen - jussi.laitinen@ixonos.com
+
+   Situare is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   version 2 as published by the Free Software Foundation.
+
+   Situare 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 Situare; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+   USA.
+*/
+
+#include <QDebug>
+
+#include "listitem.h"
+
+#include "searchhistorylistview.h"
+
+SearchHistoryListView::SearchHistoryListView(QWidget *parent)
+    : ListView(parent)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+}
+
+bool SearchHistoryListView::listItemClicked(ListItem *item)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    bool selected = ListView::listItemClicked(item);
+
+    if (item && selected)
+        emit searchHistoryItemClicked(item->title());
+
+    return selected;
+}
diff --git a/src/ui/searchhistorylistview.h b/src/ui/searchhistorylistview.h
new file mode 100644 (file)
index 0000000..610df45
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+   Situare - A location system for Facebook
+   Copyright (C) 2010  Ixonos Plc. Authors:
+
+       Jussi Laitinen - jussi.laitinen@ixonos.com
+
+   Situare is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   version 2 as published by the Free Software Foundation.
+
+   Situare 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 Situare; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+   USA.
+*/
+
+#ifndef LOCATIONHISTORYLISTVIEW_H
+#define LOCATIONHISTORYLISTVIEW_H
+
+#include "listview.h"
+
+/**
+* @brief Shows search histroy in list view.
+*
+* @author Jussi Laitinen - jussi.laitinen (at) ixonos.com
+*/
+class SearchHistoryListView : public ListView
+{
+    Q_OBJECT
+
+public:
+    /**
+    * @brief Constructor.
+    *
+    * @param parent QWidget
+    */
+    SearchHistoryListView(QWidget *parent = 0);
+
+public slots:
+    /**
+    * @brief Slot for list item clicked.
+    *
+    * @param item ListItem
+    * @return true if item was selected, false otherwise
+    */
+    bool listItemClicked(ListItem *item);
+
+signals:
+    /**
+    * @brief Signal is emitted when search history item is clicked.
+    *
+    * @param searchString search string used
+    */
+    void searchHistoryItemClicked(const QString &searchString);
+};
+
+#endif // LOCATIONHISTORYLISTVIEW_H