summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Maudsley <richard.maudsley@isode.com>2014-04-17 08:20:32 (GMT)
committerSwift Review <review@swift.im>2014-05-27 13:56:47 (GMT)
commit67cc8dff4e80344c2d10e2691c562c2440fd8c1c (patch)
treeab06eb839c422e8c28f0324b934614f112537fba
parent8930bbfd434468a4f2c601400705e8a545310c6c (diff)
downloadswift-contrib-67cc8dff4e80344c2d10e2691c562c2440fd8c1c.zip
swift-contrib-67cc8dff4e80344c2d10e2691c562c2440fd8c1c.tar.bz2
Fix QtTreeWidget compiler warnings.
Change-Id: Ib15a950faca1d0fcc9c20809e63b531160995247
-rw-r--r--Swift/QtUI/Roster/QtTreeWidget.cpp23
-rw-r--r--Swift/QtUI/Roster/RosterModel.cpp6
2 files changed, 13 insertions, 16 deletions
diff --git a/Swift/QtUI/Roster/QtTreeWidget.cpp b/Swift/QtUI/Roster/QtTreeWidget.cpp
index 325edef..fbe85de 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidget.cpp
@@ -1,249 +1,242 @@
/*
* Copyright (c) 2010-2012 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swift/QtUI/Roster/QtTreeWidget.h>
#include <boost/smart_ptr/make_shared.hpp>
#include <boost/bind.hpp>
#include <QUrl>
#include <QMimeData>
#include <QObject>
#include <QLabel>
#include <QTimer>
#include <QToolTip>
#include <Swiften/Base/Platform.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
#include <Swift/Controllers/UIEvents/SendFileUIEvent.h>
#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <Swift/QtUI/QtUISettingConstants.h>
#include <Swift/QtUI/Roster/RosterModel.h>
#include <QtSwiftUtil.h>
namespace Swift {
QtTreeWidget::QtTreeWidget(UIEventStream* eventStream, SettingsProvider* settings, MessageTarget messageTarget, QWidget* parent) : QTreeView(parent), tooltipShown_(false), messageTarget_(messageTarget) {
eventStream_ = eventStream;
settings_ = settings;
model_ = new RosterModel(this, settings_->getSetting(QtUISettingConstants::USE_SCREENREADER));
setModel(model_);
delegate_ = new RosterDelegate(this, settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
setItemDelegate(delegate_);
setHeaderHidden(true);
#ifdef SWIFT_PLATFORM_MACOSX
setAlternatingRowColors(true);
#endif
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
expandAll();
setAnimated(true);
setIndentation(0);
#ifdef SWIFT_EXPERIMENTAL_FT
setAcceptDrops(true);
#endif
setDragEnabled(true);
setRootIsDecorated(true);
connect(this, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleItemActivated(const QModelIndex&)));
connect(model_, SIGNAL(itemExpanded(const QModelIndex&, bool)), this, SLOT(handleModelItemExpanded(const QModelIndex&, bool)));
connect(this, SIGNAL(expanded(const QModelIndex&)), this, SLOT(handleExpanded(const QModelIndex&)));
connect(this, SIGNAL(collapsed(const QModelIndex&)), this, SLOT(handleCollapsed(const QModelIndex&)));
connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(handleClicked(const QModelIndex&)));
settings_->onSettingChanged.connect(boost::bind(&QtTreeWidget::handleSettingChanged, this, _1));
}
QtTreeWidget::~QtTreeWidget() {
settings_->onSettingChanged.disconnect(boost::bind(&QtTreeWidget::handleSettingChanged, this, _1));
delete model_;
delete delegate_;
}
void QtTreeWidget::handleSettingChanged(const std::string& setting) {
if (setting == QtUISettingConstants::COMPACT_ROSTER.getKey()) {
delegate_->setCompact(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
repaint();
}
}
void QtTreeWidget::handleRefreshTooltip() {
if (tooltipShown_) {
QPoint position = QCursor::pos();
QModelIndex index = indexAt(mapFromGlobal(position));
QToolTip::showText(position, model_->data(index, Qt::ToolTipRole).toString());
}
}
void QtTreeWidget::setRosterModel(Roster* roster) {
roster_ = roster;
model_->setRoster(roster);
expandAll();
}
void QtTreeWidget::refreshTooltip() {
// Qt needs some time to emit the events we need to detect tooltip's visibility correctly; 20 ms should be enough
QTimer::singleShot(20, this, SLOT(handleRefreshTooltip()));
}
QtTreeWidgetItem* QtTreeWidget::getRoot() {
return treeRoot_;
}
void QtTreeWidget::handleClicked(const QModelIndex& index) {
GroupRosterItem* item = dynamic_cast<GroupRosterItem*>(static_cast<RosterItem*>(index.internalPointer()));
if (item) {
setExpanded(index, !isExpanded(index));
}
currentChanged(index, QModelIndex());
}
QModelIndexList QtTreeWidget::getSelectedIndexes() const {
// Not using selectedIndexes(), because this seems to cause a crash in Qt (4.7.0) in the
// QModelIndexList destructor.
// This is a workaround posted in http://www.qtcentre.org/threads/16933 (although this case
// was resolved by linking against the debug libs, ours isn't, and we're not alone)
QItemSelection ranges = selectionModel()->selection();
QModelIndexList selectedIndexList;
for (int i = 0; i < ranges.count(); ++i) {
QModelIndex parent = ranges.at(i).parent();
int right = ranges.at(i).model()->columnCount(parent) - 1;
if (ranges.at(i).left() == 0 && ranges.at(i).right() == right) {
for (int r = ranges.at(i).top(); r <= ranges.at(i).bottom(); ++r) {
selectedIndexList.append(ranges.at(i).model()->index(r, 0, parent));
}
}
}
return selectedIndexList;
}
void QtTreeWidget::currentChanged(const QModelIndex& current, const QModelIndex& previous) {
RosterItem* item = NULL;
QModelIndexList selectedIndexList = getSelectedIndexes();
if (selectedIndexList.empty() || !selectedIndexList[0].isValid()) {
/* I didn't quite understand why using current didn't seem to work here.*/
}
else if (current.isValid()) {
item = static_cast<RosterItem*>(current.internalPointer());
item = dynamic_cast<ContactRosterItem*>(item);
}
onSomethingSelectedChanged(item);
QTreeView::currentChanged(current, previous);
}
void QtTreeWidget::handleItemActivated(const QModelIndex& index) {
- switch (messageTarget_) {
- case MessageDisplayJID: {
- QString indexJID = index.data(DisplayJIDRole).toString();
- if (!indexJID.isEmpty()) {
- JID target = JID(Q2PSTRING(indexJID)).toBare();
- eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(target)));
- break;
- }
+ JID target;
+ if (messageTarget_ == MessageDisplayJID) {
+ target = JID(Q2PSTRING(index.data(DisplayJIDRole).toString()));
+ target = target.toBare();
}
- case MessageDefaultJID: {
- QString indexJID = index.data(JIDRole).toString();
- if (!indexJID.isEmpty()) {
- JID target = JID(Q2PSTRING(indexJID));
- eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(target)));
- }
- break;
+ if (!target.isValid()) {
+ target = JID(Q2PSTRING(index.data(JIDRole).toString()));
}
+ if (target.isValid()) {
+ eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(target)));
}
}
void QtTreeWidget::dragEnterEvent(QDragEnterEvent *event) {
if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) {
event->acceptProposedAction();
}
}
void QtTreeWidget::dropEvent(QDropEvent *event) {
QModelIndex index = indexAt(event->pos());
if (index.isValid()) {
RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
if (ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item)) {
if (contact->supportsFeature(ContactRosterItem::FileTransferFeature)) {
QString filename = event->mimeData()->urls().at(0).toLocalFile();
if (!filename.isEmpty()) {
eventStream_->send(boost::make_shared<SendFileUIEvent>(contact->getJID(), Q2PSTRING(filename)));
}
}
}
}
}
void QtTreeWidget::dragMoveEvent(QDragMoveEvent* event) {
QModelIndex index = indexAt(event->pos());
if (index.isValid()) {
RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
if (ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item)) {
if (contact->supportsFeature(ContactRosterItem::FileTransferFeature)) {
event->accept();
return;
}
}
}
QTreeView::dragMoveEvent(event);
}
bool QtTreeWidget::event(QEvent* event) {
QChildEvent* childEvent = NULL;
if ((childEvent = dynamic_cast<QChildEvent*>(event))) {
if (childEvent->polished()) {
if (dynamic_cast<QLabel*>(childEvent->child())) {
tooltipShown_ = true;
}
}
else if (childEvent->removed()) {
if (childEvent->child()->objectName() == "qtooltip_label") {
tooltipShown_ = false;
}
}
}
return QAbstractItemView::event(event);
}
void QtTreeWidget::handleExpanded(const QModelIndex& index) {
GroupRosterItem* item = dynamic_cast<GroupRosterItem*>(static_cast<RosterItem*>(index.internalPointer()));
if (item) {
item->setExpanded(true);
}
}
void QtTreeWidget::handleCollapsed(const QModelIndex& index) {
GroupRosterItem* item = dynamic_cast<GroupRosterItem*>(static_cast<RosterItem*>(index.internalPointer()));
if (item) {
item->setExpanded(false);
}
}
void QtTreeWidget::handleModelItemExpanded(const QModelIndex& index, bool shouldExpand) {
if (!index.isValid()) {
return;
}
bool alreadyRight = this->isExpanded(index) == shouldExpand;
if (alreadyRight) {
return;
}
setExpanded(index, shouldExpand);
}
void QtTreeWidget::drawBranches(QPainter*, const QRect&, const QModelIndex&) const {
}
void QtTreeWidget::show() {
QWidget::show();
}
void QtTreeWidget::setMessageTarget(MessageTarget messageTarget) {
messageTarget_ = messageTarget;
}
}
diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp
index d8108ba..730ffbb 100644
--- a/Swift/QtUI/Roster/RosterModel.cpp
+++ b/Swift/QtUI/Roster/RosterModel.cpp
@@ -1,274 +1,278 @@
/*
* Copyright (c) 2010-2014 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swift/QtUI/Roster/RosterModel.h>
#include <boost/bind.hpp>
#include <QColor>
#include <QIcon>
#include <QMimeData>
#include <qdebug.h>
#include <Swiften/Elements/StatusShow.h>
#include <Swiften/Base/Path.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/StatusUtil.h>
#include <Swift/QtUI/Roster/QtTreeWidget.h>
#include <Swift/QtUI/Roster/RosterTooltip.h>
#include <Swift/QtUI/QtResourceHelper.h>
#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
RosterModel::RosterModel(QtTreeWidget* view, bool screenReaderMode) : roster_(NULL), view_(view), screenReader_(screenReaderMode) {
const int tooltipAvatarSize = 96; // maximal suggested size according to XEP-0153
cachedImageScaler_ = new QtScaledAvatarCache(tooltipAvatarSize);
}
RosterModel::~RosterModel() {
delete cachedImageScaler_;
}
void RosterModel::setRoster(Roster* roster) {
roster_ = roster;
if (roster_) {
roster->onChildrenChanged.connect(boost::bind(&RosterModel::handleChildrenChanged, this, _1));
roster->onDataChanged.connect(boost::bind(&RosterModel::handleDataChanged, this, _1));
}
reLayout();
}
void RosterModel::reLayout() {
//emit layoutChanged();
beginResetModel();
endResetModel(); // TODO: Not sure if this isn't too early?
if (!roster_) {
return;
}
foreach (RosterItem* item, roster_->getRoot()->getDisplayedChildren()) {
GroupRosterItem* child = dynamic_cast<GroupRosterItem*>(item);
if (!child) continue;
emit itemExpanded(index(child), child->isExpanded());
}
}
void RosterModel::handleChildrenChanged(GroupRosterItem* /*group*/) {
reLayout();
}
void RosterModel::handleDataChanged(RosterItem* item) {
Q_ASSERT(item);
QModelIndex modelIndex = index(item);
if (modelIndex.isValid()) {
emit dataChanged(modelIndex, modelIndex);
view_->refreshTooltip();
}
}
Qt::ItemFlags RosterModel::flags(const QModelIndex& index) const {
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
if (dynamic_cast<GroupRosterItem*>(getItem(index)) == NULL) {
flags |= Qt::ItemIsDragEnabled;
}
return flags;
}
int RosterModel::columnCount(const QModelIndex& /*parent*/) const {
return 1;
}
RosterItem* RosterModel::getItem(const QModelIndex& index) const {
return index.isValid() ? static_cast<RosterItem*>(index.internalPointer()) : NULL;
}
QVariant RosterModel::data(const QModelIndex& index, int role) const {
RosterItem* item = getItem(index);
if (!item) return QVariant();
switch (role) {
case Qt::DisplayRole: return getScreenReaderTextOr(item, P2QSTRING(item->getDisplayName()));
case Qt::TextColorRole: return getTextColor(item);
case Qt::BackgroundColorRole: return getBackgroundColor(item);
case Qt::ToolTipRole: return getToolTip(item);
case StatusTextRole: return getStatusText(item);
case AvatarRole: return getAvatar(item);
case PresenceIconRole: return getPresenceIcon(item);
case ChildCountRole: return getChildCount(item);
case IdleRole: return getIsIdle(item);
case JIDRole: return getJID(item);
case DisplayJIDRole: return getDisplayJID(item);
default: return QVariant();
}
}
QString RosterModel::getScreenReaderTextOr(RosterItem* item, const QString& alternative) const {
QString name = P2QSTRING(item->getDisplayName());
ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
if (contact && screenReader_) {
name += ": " + P2QSTRING(statusShowTypeToFriendlyName(contact->getStatusShow()));
if (!contact->getStatusText().empty()) {
name += " (" + P2QSTRING(contact->getStatusText()) + ")";
}
return name;
}
else {
return alternative;
}
}
int RosterModel::getChildCount(RosterItem* item) const {
GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
return group ? group->getDisplayedChildren().size() : 0;
}
bool RosterModel::getIsIdle(RosterItem* item) const {
ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
return contact ? !contact->getIdleText().empty() : false;
}
QColor RosterModel::intToColor(int color) const {
return QColor(
((color & 0xFF0000)>>16),
((color & 0xFF00)>>8),
(color & 0xFF));
}
QColor RosterModel::getTextColor(RosterItem* item) const {
ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
int color = 0;
if (contact) {
switch (contact->getStatusShow()) {
case StatusShow::Online: color = 0x000000; break;
case StatusShow::Away: color = 0x336699; break;
case StatusShow::XA: color = 0x336699; break;
case StatusShow::FFC: color = 0x000000; break;
case StatusShow::DND: color = 0x990000; break;
case StatusShow::None: color = 0x7F7F7F;break;
}
}
return intToColor(color);
}
QColor RosterModel::getBackgroundColor(RosterItem* item) const {
return dynamic_cast<ContactRosterItem*>(item) ? intToColor(0xFFFFFF) : intToColor(0x969696);
}
QString RosterModel::getToolTip(RosterItem* item) const {
QString tip(P2QSTRING(item->getDisplayName()));
ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
if (contact) {
return RosterTooltip::buildDetailedTooltip(contact, cachedImageScaler_);
}
return tip;
}
QString RosterModel::getAvatar(RosterItem* item) const {
ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
if (!contact) {
return "";
}
return P2QSTRING(pathToString(contact->getAvatarPath()));
}
QString RosterModel::getStatusText(RosterItem* item) const {
ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
if (!contact) return "";
return P2QSTRING(contact->getStatusText());
}
QString RosterModel::getJID(RosterItem* item) const {
ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
return contact ? P2QSTRING(contact->getJID().toString()) : QString();
}
QString RosterModel::getDisplayJID(RosterItem* item) const {
ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- return contact ? P2QSTRING(contact->getDisplayJID().toString()) : QString();
+ QString result = contact ? P2QSTRING(contact->getDisplayJID().toString()) : QString();
+ if (result.isEmpty()) {
+ result = getJID(item);
+ }
+ return result;
}
QIcon RosterModel::getPresenceIcon(RosterItem* item) const {
ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
if (!contact) return QIcon();
if (contact->blockState() == ContactRosterItem::IsBlocked ||
contact->blockState() == ContactRosterItem::IsDomainBlocked) {
return QIcon(":/icons/stop.png");
}
return QIcon(statusShowTypeToIconPath(contact->getStatusShow()));
}
QModelIndex RosterModel::index(int row, int column, const QModelIndex& parent) const {
if (!roster_) {
return QModelIndex();
}
GroupRosterItem* parentItem;
if (!parent.isValid()) {
//top level
parentItem = roster_->getRoot();
} else {
parentItem = dynamic_cast<GroupRosterItem*>(getItem(parent));
if (!parentItem) return QModelIndex();
}
return static_cast<size_t>(row) < parentItem->getDisplayedChildren().size() ? createIndex(row, column, parentItem->getDisplayedChildren()[row]) : QModelIndex();
}
QModelIndex RosterModel::index(RosterItem* item) const {
GroupRosterItem* parent = item->getParent();
/* Recursive check that it's ok to create such an item
Assuming there are more contacts in a group than groups in a
group, this could save a decent chunk of search time at startup.*/
if (parent == NULL || roster_ == NULL || (parent != roster_->getRoot() && !index(parent).isValid())) {
return QModelIndex();
}
for (size_t i = 0; i < parent->getDisplayedChildren().size(); i++) {
if (parent->getDisplayedChildren()[i] == item) {
return createIndex(i, 0, item);
}
}
return QModelIndex();
}
QModelIndex RosterModel::parent(const QModelIndex& child) const {
if (!roster_ || !child.isValid()) {
return QModelIndex();
}
GroupRosterItem* parent = getItem(child)->getParent();
return (parent != roster_->getRoot()) ? index(parent) : QModelIndex();
}
int RosterModel::rowCount(const QModelIndex& parent) const {
if (!roster_) return 0;
RosterItem* item = parent.isValid() ? static_cast<RosterItem*>(parent.internalPointer()) : roster_->getRoot();
Q_ASSERT(item);
GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
int count = group ? group->getDisplayedChildren().size() : 0;
// qDebug() << "rowCount = " << count << " where parent.isValid() == " << parent.isValid() << ", group == " << (group ? P2QSTRING(group->getDisplayName()) : "*contact*");
return count;
}
QMimeData* RosterModel::mimeData(const QModelIndexList& indexes) const {
QMimeData* data = QAbstractItemModel::mimeData(indexes);
ContactRosterItem *item = dynamic_cast<ContactRosterItem*>(getItem(indexes.first()));
if (item == NULL) {
return data;
}
/* only a single JID in this list */
QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << P2QSTRING(item->getJID().toString());
data->setData("application/vnd.swift.contact-jid-list", itemData);
return data;
}
}