diff --git a/icons/Filter.txt b/icons/Filter.txt
deleted file mode 100644
index 0fcf0fccc94..00000000000
--- a/icons/Filter.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-http://commons.wikimedia.org/wiki/File:Filter.svg
-
-
-I, the copyright holder of this work, hereby publish it under the following license:
-w:en:Creative Commons
-attribution share alike 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.
-
diff --git a/icons/Filter.svg b/icons/filter.svg
similarity index 100%
rename from icons/Filter.svg
rename to icons/filter.svg
diff --git a/icons/filter.txt b/icons/filter.txt
new file mode 100644
index 00000000000..be2a8a620aa
--- /dev/null
+++ b/icons/filter.txt
@@ -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)
\ No newline at end of file
diff --git a/scripts/mklic.pl b/scripts/mklic.pl
index c61cbcabb14..5b571d85118 100755
--- a/scripts/mklic.pl
+++ b/scripts/mklic.pl
@@ -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
diff --git a/src/mumble/UserModel.cpp b/src/mumble/UserModel.cpp
index 07970a64b24..498682f89fc 100644
--- a/src/mumble/UserModel.cpp
+++ b/src/mumble/UserModel.cpp
@@ -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"
"
").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")
);
}
diff --git a/src/mumble/UserView.cpp b/src/mumble/UserView.cpp
index a853bff1422..5c8d25fc3df 100644
--- a/src/mumble/UserView.cpp
+++ b/src/mumble/UserView.cpp
@@ -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(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 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 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(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(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;
}
diff --git a/src/mumble/UserView.h b/src/mumble/UserView.h
index b79791e4b96..a82c6d678bc 100644
--- a/src/mumble/UserView.h
+++ b/src/mumble/UserView.h
@@ -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);
};
diff --git a/src/mumble/licenses.h b/src/mumble/licenses.h
index f66448ffba7..aeb488c1666 100644
--- a/src/mumble/licenses.h
+++ b/src/mumble/licenses.h
@@ -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(),
};
diff --git a/src/mumble/mumble.qrc b/src/mumble/mumble.qrc
index e921c4a0a92..0cbb56d8d8d 100644
--- a/src/mumble/mumble.qrc
+++ b/src/mumble/mumble.qrc
@@ -51,7 +51,7 @@
../../samples/UserLeftChannel.ogg
../../samples/UserMutedYouOrByYou.ogg
../../samples/RecordingStateChanged.ogg
- ../../icons/Filter.svg
+ ../../icons/filter.svg
mumble_cs.qm
mumble_da.qm
mumble_de.qm