Skip to content
Permalink
Browse files

Fix channel flag handling with filter patch

- Channel comment flags were no longer clickable because
  filters weren't considered in offset calculation.
- What's this text didn't contain the flag icon
- Lowercased Flag.svg
- Magic numbers and abbreviation refactoring
- Lowercased Filter.svg and improved license display
  • Loading branch information...
hacst committed Sep 17, 2013
1 parent 8f30d0c commit 42d74df5ec4c14b3b1aad3db6581c7b2fa6d8204

This file was deleted.

File renamed without changes.
@@ -0,0 +1,18 @@
I, the copyright holder of this work, hereby publish it under the following
license:

This file is licensed under the Creative Commons Attribution-Share Alike 3.0
Unported license.

You are free:
to share � to copy, distribute and transmit the work
to remix � to adapt the work
Under the following conditions:
attribution � You must attribute the work in the manner specified by
the author or licensor (but not in any way that suggests that they
endorse you or your use of the work).
share alike � If you alter, transform, or build upon this work, you may
distribute the resulting work only under the same or similar license to
this one.

(Source: https://commons.wikimedia.org/wiki/File:Filter.svg#Licensing)
@@ -76,7 +76,7 @@ ($$$)
["licenseMachOverride", "../3rdPartyLicenses/mach_override_license.txt", "mach_override", "https://github.com/rentzsch/mach_star", "Q_OS_MAC"],
["licenseQtTranslations", "../src/mumble/qttranslations/LICENSE",
"Additional Qt translations", "https://www.virtualbox.org/ticket/2018", "USING_BUNDLED_QT_TRANSLATIONS"],
["licenseFilterSvg", "../icons/Filter.txt", "Filter.svg icon", "https://commons.wikimedia.org/wiki/File:Filter.svg"],
["licenseFilterSvg", "../icons/filter.txt", "filter.svg icon", "https://commons.wikimedia.org/wiki/File:Filter.svg"],
);

# Print 3rd party licenses
@@ -440,6 +440,7 @@ QVariant UserModel::data(const QModelIndex &idx, int role) const {
}
return qiChannel;
}
break;
case Qt::DisplayRole:
if (idx.column() == 0) {
if (! g.s.bShowUserCount || item->iUsers == 0)
@@ -449,8 +450,10 @@ QVariant UserModel::data(const QModelIndex &idx, int role) const {
}
if (! c->qbaDescHash.isEmpty())
l << (item->bCommentSeen ? qiCommentSeen : qiComment);

if (c->bFiltered)
l << (qiFilter);

return l;
case Qt::FontRole:
if (g.uiSession) {
@@ -634,20 +637,22 @@ QVariant UserModel::otherRoles(const QModelIndex &idx, int role) const {
tr("Muted (not allowed to speak in current channel)"),
tr("Muted (muted by you, only on your machine)")
).arg(
tr("Deafened (by self)"),
tr("Deafened (by admin)"),
tr("User has a new comment set (click to show)"),
tr("User has a comment set, which you've already seen. (click to show)"),
tr("Ignoring Text Messages")
);
tr("Deafened (by self)"),
tr("Deafened (by admin)"),
tr("User has a new comment set (click to show)"),
tr("User has a comment set, which you've already seen. (click to show)"),
tr("Ignoring Text Messages")
);
else
return QString::fromLatin1("%1"
"<table>"
"<tr><td><img src=\"skin:comment.svg\" width=64 /></td><td valign=\"middle\">%10</td></tr>"
"<tr><td><img src=\"skin:comment_seen.svg\" width=64 /></td><td valign=\"middle\">%11</td></tr>"
"<tr><td><img src=\"skin:filter.svg\" width=64 /></td><td valign=\"middle\">%12</td></tr>"
"</table>").arg(tr("This shows the flags the channel has, if any:"),
tr("Channel has a new comment set (click to show)"),
tr("Channel has a comment set, which you've already seen. (click to show)")
tr("Channel has a comment set, which you've already seen. (click to show)"),
tr("Channel will be hidden when filtering is enabled")
);

}
@@ -40,6 +40,10 @@
#include "ServerHandler.h"
#include "UserModel.h"

const int UserDelegate::FLAG_ICON_DIMENSION = 16;
const int UserDelegate::FLAG_ICON_PADDING = 1;
const int UserDelegate::FLAG_DIMENSION = 18;

UserDelegate::UserDelegate(QObject *p) : QStyledItemDelegate(p) {
}

@@ -75,7 +79,7 @@ void UserDelegate::paint(QPainter * painter, const QStyleOptionViewItem &option,
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &o, painter, o.widget);

// resize rect to exclude the flag icons
o.rect = option.rect.adjusted(0, 0, -18 * ql.count(), 0);
o.rect = option.rect.adjusted(0, 0, -FLAG_DIMENSION * ql.count(), 0);

// draw icon
QRect decorationRect = style->subElementRect(QStyle::SE_ItemViewItemDecoration, &o, o.widget);
@@ -88,11 +92,14 @@ void UserDelegate::paint(QPainter * painter, const QStyleOptionViewItem &option,
style->drawItemText(painter, textRect, o.displayAlignment, o.palette, true, itemText, colorRole);

// draw flag icons to original rect
QRect ps = QRect(option.rect.right() - (ql.size() * 18), option.rect.y(), ql.size() * 18, option.rect.height());
QRect ps = QRect(option.rect.right() - (ql.size() * FLAG_DIMENSION),
option.rect.y(), ql.size() * FLAG_DIMENSION,
option.rect.height());

for (int i = 0; i < ql.size(); ++i) {
QRect r = ps;
r.setSize(QSize(16, 16));
r.translate(i * 18 + 1, 1);
r.setSize(QSize(FLAG_ICON_DIMENSION, FLAG_ICON_DIMENSION));
r.translate(i * FLAG_DIMENSION + FLAG_ICON_PADDING, FLAG_ICON_PADDING);
QRect p = QStyle::alignedRect(option.direction, option.decorationAlignment, r.size(), r);
qvariant_cast<QIcon>(ql[i]).paint(painter, p, option.decorationAlignment, iconMode, QIcon::On);
}
@@ -103,15 +110,14 @@ void UserDelegate::paint(QPainter * painter, const QStyleOptionViewItem &option,
bool UserDelegate::helpEvent(QHelpEvent *evt, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index) {
if (index.isValid()) {
const QAbstractItemModel *m = index.model();
const QModelIndex idxc1 = index.sibling(index.row(), 1);
QVariant data = m->data(idxc1);
QList<QVariant> ql = data.toList();
int offset = 0;
offset = ql.size() * 18;
offset = option.rect.topRight().x() - offset;

if (evt->pos().x() >= offset) {
return QStyledItemDelegate::helpEvent(evt, view, option, idxc1);
const QModelIndex firstColumnIdx = index.sibling(index.row(), 1);
QVariant data = m->data(firstColumnIdx);
QList<QVariant> flagList = data.toList();
const int offset = flagList.size() * -FLAG_DIMENSION;
const int firstFlagPos = option.rect.topRight().x() + offset;

if (evt->pos().x() >= firstFlagPos) {
return QStyledItemDelegate::helpEvent(evt, view, option, firstColumnIdx);
}
}
return QStyledItemDelegate::helpEvent(evt, view, option, index);
@@ -149,54 +155,64 @@ bool UserView::event(QEvent *evt) {
* on user/channel flags (e.g. showing the comment)
*/
void UserView::mouseReleaseEvent(QMouseEvent *evt) {
QPoint qpos = evt->pos();
QPoint clickPosition = evt->pos();

QModelIndex idx = indexAt(qpos);
QModelIndex idx = indexAt(clickPosition);
if ((evt->button() == Qt::LeftButton) && idx.isValid()) {
UserModel *um = static_cast<UserModel *>(model());
ClientUser *cu = um->getUser(idx);
Channel * c = um->getChannel(idx);
if ((cu && ! cu->qbaCommentHash.isEmpty()) ||
(! cu && c && ! c->qbaDescHash.isEmpty())) {
QRect r = visualRect(idx);
UserModel *userModel = qobject_cast<UserModel *>(model());
ClientUser *clientUser = userModel->getUser(idx);
Channel *channel = userModel->getChannel(idx);

int commentFlagPxOffset = -UserDelegate::FLAG_DIMENSION;
bool hasComment = false;

if (clientUser && !clientUser->qbaCommentHash.isEmpty()) {
hasComment = true;

if (clientUser->bLocalIgnore)
commentFlagPxOffset -= UserDelegate::FLAG_DIMENSION;
if (clientUser->bRecording)
commentFlagPxOffset -= UserDelegate::FLAG_DIMENSION;
if (clientUser->bPrioritySpeaker)
commentFlagPxOffset -= UserDelegate::FLAG_DIMENSION;
if (clientUser->bMute)
commentFlagPxOffset -= UserDelegate::FLAG_DIMENSION;
if (clientUser->bSuppress)
commentFlagPxOffset -= UserDelegate::FLAG_DIMENSION;
if (clientUser->bSelfMute)
commentFlagPxOffset -= UserDelegate::FLAG_DIMENSION;
if (clientUser->bLocalMute)
commentFlagPxOffset -= UserDelegate::FLAG_DIMENSION;
if (clientUser->bSelfDeaf)
commentFlagPxOffset -= UserDelegate::FLAG_DIMENSION;
if (clientUser->bDeaf)
commentFlagPxOffset -= UserDelegate::FLAG_DIMENSION;
if (! clientUser->qsFriendName.isEmpty())
commentFlagPxOffset -= UserDelegate::FLAG_DIMENSION;
if (clientUser->iId >= 0)
commentFlagPxOffset -= UserDelegate::FLAG_DIMENSION;

} else if (channel && !channel->qbaDescHash.isEmpty()) {
hasComment = true;

if (channel->bFiltered)
commentFlagPxOffset -= UserDelegate::FLAG_DIMENSION;

int offset = 18;

if (cu) {
// Calculate pixel offset of comment flag
if (cu->bLocalIgnore)
offset += 18;
if (cu->bRecording)
offset += 18;
if (cu->bPrioritySpeaker)
offset += 18;
if (cu->bMute)
offset += 18;
if (cu->bSuppress)
offset += 18;
if (cu->bSelfMute)
offset += 18;
if (cu->bLocalMute)
offset += 18;
if (cu->bSelfDeaf)
offset += 18;
if (cu->bDeaf)
offset += 18;
if (! cu->qsFriendName.isEmpty())
offset += 18;
if (cu->iId >= 0)
offset += 18;
}
}

offset = r.topRight().x() - offset;
if (hasComment) {
QRect r = visualRect(idx);
const int commentFlagPxPos = r.topRight().x() + commentFlagPxOffset;

if ((qpos.x() >= offset) && (qpos.x() <= (offset+18))) {
QString str = um->data(idx, Qt::ToolTipRole).toString();
if ((clickPosition.x() >= commentFlagPxPos)
&& (clickPosition.x() <= (commentFlagPxPos + UserDelegate::FLAG_DIMENSION))) {
// Clicked comment icon
QString str = userModel->data(idx, Qt::ToolTipRole).toString();
if (str.isEmpty()) {
um->bClicked = true;
userModel->bClicked = true;
} else {
QWhatsThis::showText(viewport()->mapToGlobal(r.bottomRight()), str, this);
um->seenComment(idx);
userModel->seenComment(idx);
}
return;
}
@@ -49,6 +49,14 @@ class UserDelegate : public QStyledItemDelegate {
public:
UserDelegate(QObject *parent = NULL);
void paint(QPainter * painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

//! Width/height in px of user/channel flag icons
const static int FLAG_ICON_DIMENSION;
//! Padding in px around user/channel flag icons
const static int FLAG_ICON_PADDING;
//! Width/height in px of user/channel flags including padding
const static int FLAG_DIMENSION;

public slots:
bool helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index);
};
@@ -397,22 +397,24 @@ static const char *licenseQtTranslations =


static const char *licenseFilterSvg =
"http://commons.wikimedia.org/wiki/File:Filter.svg\n"
"I, the copyright holder of this work, hereby publish it under the following\n"
"license:\n"
"\n"
"\n"
"I, the copyright holder of this work, hereby publish it under the following license:\n"
"w:en:Creative Commons\n"
"attribution share alike This file is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license. \n"
"This file is licensed under the Creative Commons Attribution-Share Alike 3.0\n"
"Unported license.\n"
"\n"
" You are free:\n"
"\n"
" to share – to copy, distribute and transmit the work\n"
" to remix – to adapt the work\n"
"\n"
" Under the following conditions:\n"
"\n"
" attribution – You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work).\n"
" share alike – If you alter, transform, or build upon this work, you may distribute the resulting work only under the same or similar license to this one.";
" attribution – You must attribute the work in the manner specified by\n"
" the author or licensor (but not in any way that suggests that they\n"
" endorse you or your use of the work).\n"
" share alike – If you alter, transform, or build upon this work, you may\n"
" distribute the resulting work only under the same or similar license to\n"
" this one.\n"
"\n"
"(Source: https://commons.wikimedia.org/wiki/File:Filter.svg#Licensing)";


static const ThirdPartyLicense licenses3rdParties[] = {
@@ -430,7 +432,7 @@ static const ThirdPartyLicense licenses3rdParties[] = {
#ifdef USING_BUNDLED_QT_TRANSLATIONS
ThirdPartyLicense("Additional Qt translations", "https://www.virtualbox.org/ticket/2018", licenseQtTranslations),
#endif
ThirdPartyLicense("Filter.svg icon", "https://commons.wikimedia.org/wiki/File:Filter.svg", licenseFilterSvg),
ThirdPartyLicense("filter.svg icon", "https://commons.wikimedia.org/wiki/File:Filter.svg", licenseFilterSvg),
ThirdPartyLicense(),
};

@@ -51,7 +51,7 @@
<file alias="UserLeftChannel.ogg">../../samples/UserLeftChannel.ogg</file>
<file alias="UserMutedYouOrByYou.ogg">../../samples/UserMutedYouOrByYou.ogg</file>
<file alias="RecordingStateChanged.ogg">../../samples/RecordingStateChanged.ogg</file>
<file alias="filter.svg">../../icons/Filter.svg</file>
<file alias="filter.svg">../../icons/filter.svg</file>
<file>mumble_cs.qm</file>
<file>mumble_da.qm</file>
<file>mumble_de.qm</file>

0 comments on commit 42d74df

Please sign in to comment.
You can’t perform that action at this time.