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
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
<file>res/images/zoom_in.png</file>
<file>res/images/zoom_out.png</file>
<file>res/images/location_search.png</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>
--- /dev/null
+#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();
+}
--- /dev/null
+#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
--- /dev/null
+#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;
+}
--- /dev/null
+#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
--- /dev/null
+#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();
+}
--- /dev/null
+#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
#include "application.h"
#include "common.h"
+#include "contactmanager.h"
#include "../error.h"
#include "facebookservice/facebookauthentication.h"
#include "gps/gpsposition.h"
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()
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__;
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()));
// 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()
class QTimer;
class Application;
+class ContactManager;
class FacebookAuthentication;
class FacebookCredentials;
class GeocodingService;
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.
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
application.cpp \
coordinates/geocoordinate.cpp \
coordinates/scenecoordinate.cpp \
+ engine/contactmanager.cpp \
engine/engine.cpp \
engine/mce.cpp \
facebookservice/facebookauthentication.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 \
+ 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/locationsearchpanel.cpp \
- ui/textmodifier.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 \
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 \
ui/panelcontextbuttonbar.h \
ui/paneltab.h \
ui/paneltabbar.h \
- ui/tabbedpanel.h \
ui/routingpanel.h \
ui/routewaypointlistitem.h \
ui/routewaypointlistview.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/locationsearchpanel.h \
- ui/textmodifier.h
+ ui/listitemcontextbuttonbar.h
QT += network \
webkit
DEFINES += QT_NO_DEBUG_OUTPUT
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 \
HEADERS += gps/gpspositionprivatestub.h \
network/networkhandlerprivatestub.h \
engine/mceprivatestub.h
+ SOURCES += engine/contactmanagerprivatestub.cpp
+ HEADERS += engine/contactmanagerprivatestub.h
}
QT += maemo5
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)
: 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__;
return m_coordinates;
}
+QString FriendListItem::facebookId() const
+{
+ return m_facebookId;
+}
+
void FriendListItem::setAvatarImage(const QPixmap &image)
{
qDebug() << __PRETTY_FUNCTION__;
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__;
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);
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
*/
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
};
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
this, SIGNAL(findFriend(GeoCoordinate)));
connect(m_friendListView, SIGNAL(listItemSelectionChanged()),
- this, SLOT(setRouteButtonDisabled()));
+ this, SLOT(onListItemSelectionChanged()));
// --- FOOTER, TEXT BASED FILTERING ---
QHBoxLayout *footerLayout = new QHBoxLayout();
m_routeButton = new ImageButton(":res/images/route_to_friend.png",
":res/images/route_to_friend_s.png",
":res/images/route_to_friend_d.png", this);
- m_routeButton->setDisabled(true);
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);
connect(m_clearGroupFilteringButton, SIGNAL(clicked()),
this, SLOT(clearFiltering()));
- m_contextButtonLayout->addWidget(m_routeButton);
- m_contextButtonLayout->addWidget(m_clearGroupFilteringButton);
+ m_itemButtonsLayout->addWidget(m_routeButton);
+ m_itemButtonsLayout->addWidget(m_showContactButton);
+ m_genericButtonsLayout->addWidget(m_clearGroupFilteringButton);
}
void FriendListPanel::anyPanelClosed()
clearFiltering();
m_friendListView->clearItemSelection();
- setRouteButtonDisabled();
}
void FriendListPanel::anyPanelOpened()
clearFiltering();
m_friendListView->clearItemSelection();
- setRouteButtonDisabled();
+}
+
+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()
}
}
-void FriendListPanel::setRouteButtonDisabled()
-{
- qDebug() << __PRETTY_FUNCTION__;
-
- m_routeButton->setDisabled(m_friendListView->selectedItems().isEmpty());
-}
-
void FriendListPanel::showEvent(QShowEvent *event)
{
qDebug() << __PRETTY_FUNCTION__;
void filterTextChanged(const QString &text);
/**
- * @brief Routes to selected friend.
- *
- * Emits routeToFriend if friend is selected from list.
+ * @brief Requests selected friend's contact dialog.
*/
- void routeToSelectedFriend();
+ void requestSelectedFriendContactDialog();
/**
- * @brief Sets route button disabled.
+ * @brief Routes to selected friend.
*
- * Disabled if there isn't any list item selected.
+ * Emits routeToFriend if friend is selected from list.
*/
- void setRouteButtonDisabled();
+ void routeToSelectedFriend();
/**
* @brief Slot to show friends in list.
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
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
};
--- /dev/null
+/*
+ Situare - A location system for Facebook
+ Copyright (C) 2010 Ixonos Plc. Authors:
+
+ Sami Rämö - sami.ramo@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 <QLayout>
+#include <QPainter>
+#include <QPropertyAnimation>
+#include <QStateMachine>
+
+#include "panelcommon.h"
+
+#include "listitemcontextbuttonbar.h"
+
+ListItemContextButtonBar::ListItemContextButtonBar(QWidget *parent) :
+ QWidget(parent),
+ m_waitForOpen(false),
+ m_contextButtons(0),
+ m_newContextButtons(0),
+ m_state(StateHidden)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ // --- BAR LOOK ---
+ const int BAR_HEIGHT = 78;
+ setFixedHeight(BAR_HEIGHT);
+
+ m_backgroundLeft = new QPixmap(":/res/images/list_item_context_button_bar_left.png");
+ m_backgroundMiddle = new QPixmap(":/res/images/list_item_context_button_bar_tile.png");
+ m_backgroundRight = new QPixmap(":/res/images/list_item_context_button_bar_right.png");
+
+ // --- ANIMATION ---
+ const int ANIMATION_DURATION_MS = 150;
+
+ m_animation = new QPropertyAnimation(this, "pos", this);
+ m_animation->setDuration(ANIMATION_DURATION_MS);
+
+ connect(m_animation, SIGNAL(finished()),
+ this, SLOT(onAnimationFinished()));
+}
+
+ListItemContextButtonBar::~ListItemContextButtonBar()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ if (m_backgroundLeft)
+ delete m_backgroundLeft;
+
+ if (m_backgroundMiddle)
+ delete m_backgroundMiddle;
+
+ if (m_backgroundRight)
+ delete m_backgroundRight;
+}
+
+void ListItemContextButtonBar::changeButtons()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ Q_ASSERT(m_animation->state() == QAbstractAnimation::Stopped);
+
+ if (!isVisible())
+ show();
+
+ // Hide previous buttons (if any)
+ if (m_contextButtons)
+ m_contextButtons->setParent(0);
+
+ m_contextButtons = m_newContextButtons;
+ m_newContextButtons = 0;
+ m_contextButtons->setParent(this);
+ m_contextButtons->show();
+ setFixedWidth(m_contextButtons->width());
+
+ // center this widget horizontally to middle of the panel contents area and set outside of
+ // the view
+ const int FROM_PANEL_CONTENTS_LEFT = PANEL_WIDTH / 2 - m_contextButtons->width() / 2;
+ move(PANEL_TAB_BAR_WIDTH + PANEL_BAR_WIDTH + FROM_PANEL_CONTENTS_LEFT, -size().height());
+
+ // update new target values for animations
+ m_animation->setStartValue(pos());
+ const int Y = 0;
+ m_animation->setEndValue(QPoint(pos().x(), Y));
+}
+
+void ListItemContextButtonBar::hideContextButtonBar()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ m_state = StateClosing;
+ m_animation->setDirection(QAbstractAnimation::Backward);
+ m_animation->start();
+}
+
+void ListItemContextButtonBar::onAnimationFinished()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ if (m_animation->direction() == QAbstractAnimation::Backward) {
+ m_state = StateHidden;
+ if (m_newContextButtons) {
+ changeButtons();
+ if (m_waitForOpen) {
+ m_waitForOpen = false;
+ showContextButtonBar();
+ }
+ }
+ } else {
+ m_state = StateVisible;
+ }
+}
+
+void ListItemContextButtonBar::onListItemSelectionChanged(bool itemIsSelected)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ if (itemIsSelected) {
+ if (m_newContextButtons)
+ m_waitForOpen = true;
+ else if (m_state != StateVisible)
+ showContextButtonBar();
+ } else {
+ if (m_newContextButtons)
+ m_waitForOpen = false;
+ else if (m_state != StateHidden)
+ hideContextButtonBar();
+ }
+}
+
+void ListItemContextButtonBar::paintEvent(QPaintEvent *event)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ Q_UNUSED(event);
+
+ QPainter painter(this);
+
+ const int TOP = 0;
+ const int LEFT = 0;
+ painter.drawPixmap(TOP, LEFT, *m_backgroundLeft);
+ painter.drawTiledPixmap(m_backgroundLeft->width(), TOP,
+ width() - m_backgroundLeft->width() - m_backgroundRight->width(),
+ height(),
+ *m_backgroundMiddle);
+ painter.drawPixmap(width() - m_backgroundRight->width(), TOP, *m_backgroundRight);
+}
+
+void ListItemContextButtonBar::setContextButtons(QWidget *contextButtons)
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ m_newContextButtons = contextButtons;
+ m_waitForOpen = false;
+
+ if (m_state != StateHidden)
+ hideContextButtonBar();
+ else
+ changeButtons();
+}
+
+void ListItemContextButtonBar::showContextButtonBar()
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ if (m_contextButtons->layout()->count() > 0) {
+ m_state = StateOpening;
+ m_animation->setDirection(QAbstractAnimation::Forward);
+ m_animation->start();
+ }
+}
--- /dev/null
+/*
+ Situare - A location system for Facebook
+ Copyright (C) 2010 Ixonos Plc. Authors:
+
+ Sami Rämö - sami.ramo@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 LISTITEMCONTEXTBUTTONBAR_H
+#define LISTITEMCONTEXTBUTTONBAR_H
+
+#include <QWidget>
+
+class QPropertyAnimation;
+
+/**
+ * @brief Button bar for list item relatex context buttons
+ *
+ * @author Sami Rämö - sami.ramo (at) ixonos.com
+ */
+class ListItemContextButtonBar : public QWidget
+{
+ Q_OBJECT
+public:
+ /**
+ * @brief Constructor
+ *
+ * @param parent Parent
+ */
+ explicit ListItemContextButtonBar(QWidget *parent = 0);
+
+ /**
+ * @brief Destructor
+ *
+ * Deletes images.
+ */
+ ~ListItemContextButtonBar();
+
+/*******************************************************************************
+ * BASE CLASS INHERITED AND REIMPLEMENTED MEMBER FUNCTIONS
+ ******************************************************************************/
+private:
+ /**
+ * @brief Paint the background of the item
+ *
+ * @param event Paint event
+ */
+ void paintEvent(QPaintEvent *event);
+
+/*******************************************************************************
+ * MEMBER FUNCTIONS AND SLOTS
+ ******************************************************************************/
+public:
+ /**
+ * @brief Start hiding animation
+ */
+ void hideContextButtonBar();
+
+ /**
+ * @brief Set new context buttons
+ *
+ * If bar is hidden, then changeButtons() is called. Otherwise pointer to new buttons is saved
+ * and hideContextButtonBar() is called.
+ *
+ * @param contextButtons Pointer to new context buttons
+ */
+ void setContextButtons(QWidget *contextButtons);
+
+ /**
+ * @brief Start showing animation
+ *
+ * Animation is started only if the bar contains buttons.
+ */
+ void showContextButtonBar();
+
+public slots:
+ /**
+ * @brief Shows and hides the bar when item selection is changed
+ *
+ * Calls showContextButtonBar() or hideContextButtonBar() if changing the state of the bar is
+ * required. If there is a pointer to new buttons, then request is remembered instead of
+ * changing the state immediately.
+ *
+ * @param itemIsSelected True is any item is selected
+ */
+ void onListItemSelectionChanged(bool itemIsSelected);
+
+private:
+ /**
+ * @brief Do the actual changing of the buttons
+ *
+ * Does also re-sizing and re-positioning of the bar and sets new values for animation.
+ */
+ void changeButtons();
+
+private slots:
+ /**
+ * @brief
+ *
+ * If bar was just hidden, then calls changeButtons() if there is a pointer to new buttons
+ * saved. If changing the buttons was done, then also checks if showing the bar was requested
+ * and calls showContextButtonBar() if needed.
+ */
+ void onAnimationFinished();
+
+/*******************************************************************************
+ * DATA MEMBERS
+ ******************************************************************************/
+private:
+ /**
+ * @brief States for the animation
+ *
+ * @enum AnimationState
+ */
+ enum AnimationState {
+ StateHidden,
+ StateOpening,
+ StateClosing,
+ StateVisible
+ };
+
+ bool m_waitForOpen; ///< Is showing requested while chaging buttons is not ready
+
+ QPixmap *m_backgroundLeft; ///< Background picture, left part
+ QPixmap *m_backgroundMiddle; ///< Background picture, center part
+ QPixmap *m_backgroundRight; ///< Background picture, right part
+
+ QPropertyAnimation *m_animation; ///< Sliding animation for show/hide
+
+ QWidget *m_contextButtons; ///< Widget for context buttons
+ QWidget *m_newContextButtons; ///< Temporary pointer for new context buttons
+
+ AnimationState m_state; ///< Current state of the animation
+};
+
+#endif // LISTITEMCONTEXTBUTTONBAR_H
void ListView::clearItemSelection()
{
+ qDebug() << __PRETTY_FUNCTION__;
+
clearSelection();
if (m_currentItem)
{
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()
#ifndef LISTVIEW_H
#define LISTVIEW_H
+#include <QHash>
#include <QListWidget>
class GeoCoordinate;
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
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)
{
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));
SIGNAL(locationItemClicked(const GeoCoordinate&, const GeoCoordinate&)));
connect(m_locationListView, SIGNAL(listItemSelectionChanged()),
- this, SLOT(setRouteButtonDisabled()));
+ this, SLOT(onListItemSelectionChanged()));
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 ---
panelLayout->addLayout(resultsListViewLayout);
// --- CONTEXT BUTTONS ---
- m_routeButton = new ImageButton(":res/images/compass.png", "", "", this);
- m_routeButton->setDisabled(true);
+ m_routeButton = new ImageButton(":res/images/routing.png", "", "", this);
connect(m_routeButton, SIGNAL(clicked()),
this, SLOT(routeToSelectedLocation()));
ImageButton *searchLocationButton = new ImageButton(":/res/images/search.png",
":/res/images/search_s.png", "", this);
+
connect(searchLocationButton, SIGNAL(clicked()),
this, SIGNAL(requestSearchLocation()));
- m_contextButtonLayout->addWidget(m_routeButton);
- m_contextButtonLayout->addWidget(searchLocationButton);
+ 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()
qDebug() << __PRETTY_FUNCTION__;
m_locationListView->clearItemSelection();
-
- setRouteButtonDisabled();
+ m_searchHistoryListView->clearItemSelection();
}
void LocationSearchPanel::hideEvent(QHideEvent *event)
{
qDebug() << __PRETTY_FUNCTION__;
- setHeaderText(locations.count());
-
m_locationListView->clearList();
+ showLocationListView(locations.count());
for (int i = 0; i < locations.size(); ++i) {
LocationListItem *item = new LocationListItem();
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__;
m_resultsLabel->setText(tr("Search results: %1").arg(count));
}
-void LocationSearchPanel::setRouteButtonDisabled()
+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_routeButton->setDisabled(m_locationListView->selectedItems().isEmpty());
+ m_locationListView->clearList();
+ m_locationListView->hide();
+ m_resultsLabel->setText(tr("Search history:"));
+ m_clearLocationListButton->setDisabled(true);
+ m_searchHistoryListView->show();
}
class ImageButton;
class Location;
class LocationListView;
+class SearchHistoryListView;
/**
* @brief Location search panel
*/
LocationSearchPanel(QWidget *parent = 0);
+ /**
+ * @brief Destructor
+ *
+ * Writes search history to settings.
+ */
+ ~LocationSearchPanel();
+
/*******************************************************************************
* BASE CLASS INHERITED AND REIMPLEMENTED MEMBER FUNCTIONS
******************************************************************************/
******************************************************************************/
private:
/**
+ * @brief Reads search history from settings.
+ */
+ void readSettings();
+
+ /**
* @brief Set text for header
*
* @param count Search result count
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().
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
*/
void routeToSelectedLocation();
- /**
- * @brief Sets route button disabled.
- *
- * Disabled if there isn't any list item selected.
- */
- void setRouteButtonDisabled();
-
/*******************************************************************************
* 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
#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),
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()
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()
buildRoutingPanel();
m_tabbedPanel = new TabbedPanel(this);
-
+
//Save Situare related tab indexes so tabs can be enabled/disabled when logged in/out
m_situareTabsIndexes.append(
m_tabbedPanel->addTab(m_userInfoPanel, QIcon(":/res/images/user_info.png")));
connect(m_tabbedPanel, SIGNAL(currentChanged(int)),
m_userInfoPanel, SIGNAL(collapse()));
+
+ // signals for showing and hiding list item context buttons
+ connect(m_friendsListPanel, SIGNAL(listItemSelectionChanged(bool)),
+ m_tabbedPanel, SIGNAL(listItemSelectionChanged(bool)));
+
+ connect(m_locationSearchPanel, SIGNAL(listItemSelectionChanged(bool)),
+ m_tabbedPanel, SIGNAL(listItemSelectionChanged(bool)));
+
+ connect(m_routingPanel, SIGNAL(listItemSelectionChanged(bool)),
+ m_tabbedPanel, SIGNAL(listItemSelectionChanged(bool)));
}
void MainWindow::buildRoutingPanel()
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__;
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
*/
void refreshUserData();
/**
+ * @brief Requests contact dialog.
+ *
+ * @param facebookId contact's facebookId
+ */
+ void requestContactDialog(const QString &facebookId);
+
+ /**
* @brief Signal for requesting reverseGeo from SituareEngine
*
*/
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
--- /dev/null
+#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;
+}
--- /dev/null
+#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
Copyright (C) 2010 Ixonos Plc. Authors:
Pekka Nissinen - pekka.nissinen@ixonos.com
+ Sami Rämö - sami.ramo@ixonos.com
Situare is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
*/
#include <QDebug>
+#include <QListWidget>
+#include <QResizeEvent>
#include <QVBoxLayout>
#include "panelbase.h"
{
qDebug() << __PRETTY_FUNCTION__;
+
+ // --- GENERIC BUTTONS ---
+ m_genericButtons = new QWidget;
+ m_genericButtonsLayout = new QVBoxLayout;
+
const int CONTEXT_BUTTON_MARGIN_LEFT = 2;
const int CONTEXT_BUTTON_MARGIN_TOP = 10;
const int CONTEXT_BUTTON_MARGIN_RIGHT = 0;
const int CONTEXT_BUTTON_MARGIN_BOTTOM = 0;
const int CONTEXT_BUTTON_SPACING = 0;
-
- m_contextButtons = new QWidget;
-
- m_contextButtonLayout = new QVBoxLayout;
- m_contextButtonLayout->setContentsMargins(CONTEXT_BUTTON_MARGIN_LEFT,
+ m_genericButtonsLayout->setContentsMargins(CONTEXT_BUTTON_MARGIN_LEFT,
CONTEXT_BUTTON_MARGIN_TOP,
CONTEXT_BUTTON_MARGIN_RIGHT,
CONTEXT_BUTTON_MARGIN_BOTTOM);
- m_contextButtonLayout->setSpacing(CONTEXT_BUTTON_SPACING);
+ m_genericButtonsLayout->setSpacing(CONTEXT_BUTTON_SPACING);
+
+ m_genericButtons->setLayout(m_genericButtonsLayout);
+
+ // --- ITEM RELATED BUTTONS ---
+ m_itemButtons = new QWidget(this);
+ m_itemButtonsLayout = new QHBoxLayout;
+
+ const int ITEM_CONTEXT_BUTTON_MARGIN_BOTTOM = 0;
+ const int ITEM_CONTEXT_BUTTON_MARGIN_LEFT = 2;
+ const int ITEM_CONTEXT_BUTTON_MARGIN_RIGHT = 2;
+ const int ITEM_CONTEXT_BUTTON_MARGIN_TOP = 2;
+ const int ITEM_CONTEXT_BUTTON_SPACING = 0;
+ m_itemButtonsLayout->setContentsMargins(ITEM_CONTEXT_BUTTON_MARGIN_LEFT,
+ ITEM_CONTEXT_BUTTON_MARGIN_TOP,
+ ITEM_CONTEXT_BUTTON_MARGIN_RIGHT,
+ ITEM_CONTEXT_BUTTON_MARGIN_BOTTOM);
+ m_itemButtonsLayout->setSpacing(ITEM_CONTEXT_BUTTON_SPACING);
+
+ m_itemButtons->setLayout(m_itemButtonsLayout);
+}
+
+QWidget* PanelBase::genericPanelButtons() const
+{
+ qDebug() << __PRETTY_FUNCTION__;
+
+ return m_genericButtons;
+}
+
+QWidget* PanelBase::itemButtons() const
+{
+ qDebug() << __PRETTY_FUNCTION__;
- m_contextButtons->setLayout(m_contextButtonLayout);
+ return m_itemButtons;
}
-QWidget* PanelBase::contextButtons() const
+void PanelBase::onListItemSelectionChanged()
{
qDebug() << __PRETTY_FUNCTION__;
- return m_contextButtons;
+ QListWidget *listWidget = dynamic_cast<QListWidget *>(sender());
+ if (listWidget && (listWidget->selectedItems().count() > 0))
+ emit listItemSelectionChanged(true);
+ else
+ emit listItemSelectionChanged(false);
}
Copyright (C) 2010 Ixonos Plc. Authors:
Pekka Nissinen - pekka.nissinen@ixonos.com
+ Sami Rämö - sami.ramo@ixonos.com
Situare is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
#include <QWidget>
+class QHBoxLayout;
+class QListWidgetItem;
class QVBoxLayout;
class ImageButton;
* @brief Base class for panels
*
* @author Pekka Nissinen - pekka.nissinen (at) ixonos.com
+ * @author Sami Rämö - sami.ramo (at) ixonos.com
*/
class PanelBase : public QWidget
{
******************************************************************************/
public:
/**
- * @brief Getter for the context buttons
+ * @brief Getter for the generic panel related context buttons
*
* @returns Pointer to context buttons widget
*/
- QWidget* contextButtons() const;
+ QWidget* genericPanelButtons() const;
+
+ /**
+ * @brief Getter for the list item related context buttons
+ *
+ * @returns Pointer to context buttons widget
+ */
+ QWidget* itemButtons() const;
+
+protected slots:
+ /**
+ * @brief Call when there is a change in list item selection
+ *
+ * Emits listItemSelectionChanged(bool). Parameter is true if any item is selected.
+ */
+ void onListItemSelectionChanged();
/*******************************************************************************
* SIGNALS
*/
void openPanelRequested(QWidget *widget);
+ /**
+ * @brief Emitted when there is a change in list item selection
+ *
+ * @param itemIsSelected True if any item is selected.
+ */
+ void listItemSelectionChanged(bool itemIsSelected);
+
/*******************************************************************************
* DATA MEMBERS
******************************************************************************/
protected:
- QVBoxLayout *m_contextButtonLayout; ///< Layout for context buttons
+ QVBoxLayout *m_genericButtonsLayout; ///< Layout for generic context buttons
+ QHBoxLayout *m_itemButtonsLayout; ///< Layout for item related context buttons
private:
- QWidget *m_contextButtons; ///< Widget for context buttons
+ QWidget *m_genericButtons; ///< Widget for generic context buttons
+ QWidget *m_itemButtons; ///< Widget for item related context buttons
};
#endif // PANELBASE_H
const int PANEL_BAR_WIDTH = 5; ///< Width of the slider bar
const int PANEL_TAB_BAR_WIDTH = 74; ///< Panel tab bar total width
const int PANEL_BAR_TABBED_WIDTH = PANEL_BAR_WIDTH + PANEL_TAB_BAR_WIDTH; ///< Width of the tabbed bar
-const int PANEL_WIDTH = 384; ///< Width of the panel
+const int PANEL_WIDTH = 384; ///< Width of the panel contents area
const int PANEL_HEIGHT = DEFAULT_SCREEN_HEIGHT - PANEL_TOP_PADDING
- PANEL_BOTTOM_PADDING; ///< Height of the panel
connect(m_routeWaypointListView, SIGNAL(routeWaypointItemClicked(GeoCoordinate)),
this, SIGNAL(routeWaypointItemClicked(GeoCoordinate)));
+ connect(m_routeWaypointListView, SIGNAL(listItemSelectionChanged()),
+ this, SLOT(onListItemSelectionChanged()));
+
QVBoxLayout *panelLayout = new QVBoxLayout;
panelLayout->setContentsMargins(PANEL_MARGIN_LEFT, PANEL_MARGIN_TOP,
PANEL_MARGIN_RIGHT, PANEL_MARGIN_BOTTOM);
this, SLOT(clearRouteButtonClicked()));
m_clearRouteButton->setDisabled(true);
- m_contextButtonLayout->addWidget(routeToCursorButton);
- m_contextButtonLayout->addWidget(m_clearRouteButton);
+ m_genericButtonsLayout->addWidget(routeToCursorButton);
+ m_genericButtonsLayout->addWidget(m_clearRouteButton);
}
void RoutingPanel::clearListsSelections()
--- /dev/null
+#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"));
+}
--- /dev/null
+/*
+ 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
--- /dev/null
+/*
+ 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;
+}
--- /dev/null
+/*
+ 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
#include <QStackedWidget>
#include <QStateMachine>
+#include "listitemcontextbuttonbar.h"
#include "panelbar.h"
#include "panelbase.h"
#include "panelcontentstack.h"
m_panelBar = new PanelBar(this);
m_panelBar->move(PANEL_TAB_BAR_WIDTH, PANEL_TOP_Y);
- // --- CONTEXT BUTTON BAR ---
+ // --- GENERIC PANEL CONTEXT BUTTON BAR ---
m_panelContextButtonBar = new PanelContextButtonBar(this);
m_panelContextButtonBar->move(PANEL_CONTEXT_BUTTON_BAR_LEFT_X, PANEL_HEIGHT);
connect(m_panelContextButtonBar, SIGNAL(positionChangeRequested()),
this, SLOT(repositionContextButtonBar()));
+ // --- LIST ITEM RELATED CONTEXT BUTTONS BAR ---
+ m_itemContextButtonBar = new ListItemContextButtonBar(this);
+ m_itemContextButtonBar->hide();
+
+ connect(this, SIGNAL(listItemSelectionChanged(bool)),
+ m_itemContextButtonBar, SLOT(onListItemSelectionChanged(bool)));
+
// --- PANEL CONTENT ---
m_panelContentStack = new PanelContentStack(this);
m_panelContentStack->move(PANEL_TAB_BAR_WIDTH + PANEL_BAR_WIDTH, PANEL_TOP_Y);
+ m_panelContentStack->stackUnder(m_itemContextButtonBar);
// --- PANEL ANIMATION ---
QStateMachine *panelStateMachine = new QStateMachine(this);
qDebug() << __PRETTY_FUNCTION__;
m_panelContextButtonBar->move(PANEL_CONTEXT_BUTTON_BAR_LEFT_X, height());
-
+
calculateMask();
}
openPanel();
m_panelContextButtonBar->setContextButtons(
- static_cast<PanelBase *>(m_panelContentStack->widget(index))->contextButtons());
+ static_cast<PanelBase *>(m_panelContentStack->widget(index))->genericPanelButtons());
+
+ QWidget *itemContextButtons = static_cast<PanelBase *>(m_panelContentStack->widget(index))->itemButtons();
+ m_itemContextButtonBar->setContextButtons(itemContextButtons);
emit currentChanged(index);
}
class QState;
class QStateMachine;
+class ListItemContextButtonBar;
class PanelBar;
class PanelContentStack;
class PanelContextButtonBar;
void currentChanged(int index);
/**
+ * @brief Emitted when there is a change in list item selection
+ *
+ * @param itemIsSelected True if any item is selected.
+ */
+ void listItemSelectionChanged(bool itemIsSelected);
+
+ /**
* @brief Signal that is sent when panel is closed
*
* @sa openPanel
QState *m_stateClosed; ///< State of the closed panel
QState *m_stateOpened; ///< State of the opened panel
+ ListItemContextButtonBar *m_itemContextButtonBar; ///< Widget for list item context button bar
PanelBar *m_panelBar; ///< Widget for panel bar
PanelContentStack *m_panelContentStack; ///< Stack for panel widgets
PanelContextButtonBar * m_panelContextButtonBar; ///< Widget for panel context button bar
":/res/images/send_position_s.png",
"", this);
- m_contextButtonLayout->addWidget(updateFriendsButton);
- m_contextButtonLayout->addWidget(updateStatusMessageButton);
+ m_genericButtonsLayout->addWidget(updateFriendsButton);
+ m_genericButtonsLayout->addWidget(updateStatusMessageButton);
connect(updateFriendsButton, SIGNAL(clicked()),
this, SIGNAL(refreshUserData()));
../../../src/ui/panelcontentstack.cpp \
../../../src/ui/panelcontextbuttonbar.cpp \
../../../src/ui/paneltab.cpp \
- ../../../src/ui/paneltabbar.cpp
+ ../../../src/ui/paneltabbar.cpp \
+ ../../../src/ui/listitemcontextbuttonbar.cpp
HEADERS += \
../../../src/ui/tabbedpanel.h \
../../../src/ui/panelbar.h \
../../../src/ui/panelcontextbuttonbar.h \
../../../src/ui/paneltab.h \
../../../src/ui/paneltabbar.h \
- ../../../src/ui/panelcommon.h
+ ../../../src/ui/panelcommon.h \
+ ../../../src/ui/listitemcontextbuttonbar.h
RESOURCES += ../../../images.qrc
DEFINES += QT_NO_DEBUG_OUTPUT