QString QueryBufferItem::toolTip(int column) const { // pretty much code duplication of IrcUserItem::toolTip() but inheritance won't solve this... Q_UNUSED(column); QStringList toolTip; toolTip.append(tr("<b>Query with %1</b>").arg(bufferName())); if (_ircUser) { if (_ircUser->userModes() != "") toolTip[0].append(QString(" (+%1)").arg(_ircUser->userModes())); if (_ircUser->isAway()) { toolTip[0].append(QString(" (away%1)").arg(!_ircUser->awayMessage().isEmpty() ? (QString(" ") + _ircUser->awayMessage()) : QString())); } if (!_ircUser->realName().isEmpty()) toolTip.append(_ircUser->realName()); if (!_ircUser->ircOperator().isEmpty()) toolTip.append(QString("%1 %2").arg(_ircUser->nick()).arg(_ircUser->ircOperator())); if (!_ircUser->suserHost().isEmpty()) toolTip.append(_ircUser->suserHost()); if (!_ircUser->whoisServiceReply().isEmpty()) toolTip.append(_ircUser->whoisServiceReply()); toolTip.append(_ircUser->hostmask().remove(0, _ircUser->hostmask().indexOf("!")+1)); if (_ircUser->idleTime().isValid()) { QDateTime now = QDateTime::currentDateTime(); QDateTime idle = _ircUser->idleTime(); int idleTime = idle.secsTo(now); toolTip.append(tr("idling since %1").arg(secondsToString(idleTime))); } if (_ircUser->loginTime().isValid()) { toolTip.append(tr("login time: %1").arg(_ircUser->loginTime().toString())); } if (!_ircUser->server().isEmpty()) toolTip.append(tr("server: %1").arg(_ircUser->server())); } return QString("<p> %1 </p>").arg(toolTip.join("<br />")); }
QString ChannelBufferItem::toolTip(int column) const { Q_UNUSED(column); QStringList toolTip; toolTip.append(tr("<b>Channel %1</b>").arg(Qt::escape(bufferName()))); if (isActive()) { //TODO: add channel modes toolTip.append(tr("<b>Users:</b> %1").arg(nickCount())); if (_ircChannel) { QString channelMode = _ircChannel->channelModeString(); // channelModeString is compiled on the fly -> thus cache the result if (!channelMode.isEmpty()) toolTip.append(tr("<b>Mode:</b> %1").arg(channelMode)); } ItemViewSettings s; bool showTopic = s.displayTopicInTooltip(); if (showTopic) { QString _topic = topic(); if (_topic != "") { _topic = stripFormatCodes(_topic); _topic = Qt::escape(_topic); toolTip.append(QString("<font size='-2'> </font>")); toolTip.append(tr("<b>Topic:</b> %1").arg(_topic)); } } } else { toolTip.append(tr("Not active <br /> Double-click to join")); } return tr("<p> %1 </p>").arg(toolTip.join("<br />")); }
/** * Extract Shader Storage Buffer data from the shader */ void Program::ExtractStorageBlockData() { GLint numBlocks = 0; glGetProgramInterfaceiv(_program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &numBlocks); char tempNameAR[1024]; Log("\tBuffer :") for (int blockIdx = 0; blockIdx < numBlocks; blockIdx++) { std::vector<BufferVariableInfo> vars; glGetProgramResourceName(_program, GL_SHADER_STORAGE_BLOCK, blockIdx, 1024, NULL, tempNameAR); std::string bufferName(tempNameAR); GLint binding = 0; { GLenum prop[] = { GL_BUFFER_BINDING }; glGetProgramResourceiv(_program, GL_SHADER_STORAGE_BLOCK, blockIdx, 1, prop, 1, NULL, &binding); } Log("\t\t" + bufferName + " index " + ToString(blockIdx) + " binding " + ToString(binding)); GLint vcount = 0; { GLenum prop[] = { GL_NUM_ACTIVE_VARIABLES }; glGetProgramResourceiv(_program, GL_SHADER_STORAGE_BLOCK, blockIdx, 1, prop, 1, NULL, &vcount); } std::vector<GLint> variables(vcount); { GLenum prop[] = { GL_ACTIVE_VARIABLES }; glGetProgramResourceiv(_program, GL_SHADER_STORAGE_BLOCK, blockIdx, 1, prop, vcount, NULL, &variables.front()); } GLchar vnameAR[128] = { 0 }; for (int k = 0; k < vcount; k++) { GLenum propsAR[] = { GL_OFFSET, GL_TYPE, GL_ARRAY_STRIDE, GL_MATRIX_STRIDE, GL_IS_ROW_MAJOR, GL_TOP_LEVEL_ARRAY_STRIDE }; GLint paramsAR[sizeof(propsAR) / sizeof(GLenum)]; glGetProgramResourceiv(_program, GL_BUFFER_VARIABLE, variables[k], sizeof(propsAR) / sizeof(GLenum), propsAR, sizeof(paramsAR) / sizeof(GLenum), NULL, paramsAR); glGetProgramResourceName(_program, GL_BUFFER_VARIABLE, variables[k], sizeof(vnameAR), NULL, vnameAR); Log("\t\t\t" + std::string(vnameAR) + " offset " + ToString(paramsAR[0]) + " type " + GLUtil::GLSLTypeToStr(GLenum(paramsAR[1])) + " array stride " + ToString(paramsAR[2]) + " top level stride " + ToString(paramsAR[5])); vars.push_back(BufferVariableInfo(std::string(vnameAR), paramsAR[0], GLenum(paramsAR[1]), paramsAR[2], paramsAR[3], GLboolean(paramsAR[4]), paramsAR[5])); } _buffers.insert(std::make_pair(bufferName, BufferInfo(bufferName, blockIdx, vars))); } }
QString BufferItem::toolTip(int column) const { Q_UNUSED(column); return tr("<p> %1 - %2 </p>").arg(bufferInfo().bufferId().toInt()).arg(bufferName()); }
bool MessageFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { Q_UNUSED(sourceParent); QModelIndex sourceIdx = sourceModel()->index(sourceRow, 2); Message::Type messageType = (Message::Type)sourceIdx.data(MessageModel::TypeRole).toInt(); // apply message type filter if(_messageTypeFilter & messageType) return false; if(_validBuffers.isEmpty()) return true; BufferId bufferId = sourceIdx.data(MessageModel::BufferIdRole).value<BufferId>(); if(!bufferId.isValid()) { return true; } MsgId msgId = sourceIdx.data(MessageModel::MsgIdRole).value<MsgId>(); Message::Flags flags = (Message::Flags)sourceIdx.data(MessageModel::FlagsRole).toInt(); NetworkId myNetworkId = networkId(); NetworkId msgNetworkId = Client::networkModel()->networkId(bufferId); if(myNetworkId != msgNetworkId) return false; // ignorelist handling // only match if message is not flagged as server msg if(!(flags & Message::ServerMsg) && Client::ignoreListManager() && Client::ignoreListManager()->match(sourceIdx.data(MessageModel::MessageRole).value<Message>(), Client::networkModel()->networkName(bufferId))) return false; if(flags & Message::Redirected) { int redirectionTarget = 0; switch(messageType) { case Message::Notice: if(Client::networkModel()->bufferType(bufferId) != BufferInfo::ChannelBuffer) { if(flags & Message::ServerMsg) { // server notice redirectionTarget = _serverNoticesTarget; } else { redirectionTarget = _userNoticesTarget; } } break; case Message::Error: redirectionTarget = _errorMsgsTarget; break; default: break; } if(redirectionTarget & BufferSettings::DefaultBuffer && _validBuffers.contains(bufferId)) return true; if(redirectionTarget & BufferSettings::CurrentBuffer && !(flags & Message::Backlog)) { BufferId redirectedTo = sourceModel()->data(sourceIdx, MessageModel::RedirectedToRole).value<BufferId>(); if(!redirectedTo.isValid()) { BufferId redirectedTo = Client::bufferModel()->currentIndex().data(NetworkModel::BufferIdRole).value<BufferId>(); if(redirectedTo.isValid()) sourceModel()->setData(sourceIdx, QVariant::fromValue<BufferId>(redirectedTo), MessageModel::RedirectedToRole); } if(_validBuffers.contains(redirectedTo)) return true; } if(redirectionTarget & BufferSettings::StatusBuffer) { QSet<BufferId>::const_iterator idIter = _validBuffers.constBegin(); while(idIter != _validBuffers.constEnd()) { if(Client::networkModel()->bufferType(*idIter) == BufferInfo::StatusBuffer) return true; idIter++; } } return false; } if(_validBuffers.contains(bufferId)) { return true; } else { // show Quit messages in Query buffers: if(bufferType() != BufferInfo::QueryBuffer) return false; if(!(messageType & Message::Quit)) return false; if(myNetworkId != msgNetworkId) return false; uint messageTimestamp = sourceModel()->data(sourceIdx, MessageModel::TimestampRole).value<QDateTime>().toTime_t(); QString quiter = sourceModel()->data(sourceIdx, Qt::DisplayRole).toString().section(' ', 0, 0, QString::SectionSkipEmpty).toLower(); if(quiter != bufferName().toLower()) return false; if(_filteredQuitMsgs.contains(quiter, messageTimestamp)) return false; MessageFilter *that = const_cast<MessageFilter *>(this); that->_filteredQuitMsgs.insert(quiter, messageTimestamp); return true; } }
bool MessageFilter::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const { Q_UNUSED(sourceParent); QModelIndex sourceIdx = sourceModel()->index(sourceRow, 2); Message::Type messageType = (Message::Type)sourceIdx.data(MessageModel::TypeRole).toInt(); // apply message type filter if (_messageTypeFilter & messageType) return false; if (_validBuffers.isEmpty()) return true; BufferId bufferId = sourceIdx.data(MessageModel::BufferIdRole).value<BufferId>(); if (!bufferId.isValid()) { return true; } // MsgId msgId = sourceIdx.data(MessageModel::MsgIdRole).value<MsgId>(); Message::Flags flags = (Message::Flags)sourceIdx.data(MessageModel::FlagsRole).toInt(); NetworkId myNetworkId = networkId(); NetworkId msgNetworkId = Client::networkModel()->networkId(bufferId); if (myNetworkId != msgNetworkId) return false; // ignorelist handling // only match if message is not flagged as server msg if (!(flags & Message::ServerMsg) && Client::ignoreListManager() && Client::ignoreListManager()->match(sourceIdx.data(MessageModel::MessageRole).value<Message>(), Client::networkModel()->networkName(bufferId))) return false; if (flags & Message::Redirected) { int redirectionTarget = 0; switch (messageType) { case Message::Notice: if (Client::networkModel()->bufferType(bufferId) != BufferInfo::ChannelBuffer) { if (flags & Message::ServerMsg) { // server notice redirectionTarget = _serverNoticesTarget; } else { redirectionTarget = _userNoticesTarget; } } break; case Message::Error: redirectionTarget = _errorMsgsTarget; break; default: break; } if (redirectionTarget & BufferSettings::DefaultBuffer && _validBuffers.contains(bufferId)) return true; if (redirectionTarget & BufferSettings::CurrentBuffer && !(flags & Message::Backlog)) { BufferId redirectedTo = sourceModel()->data(sourceIdx, MessageModel::RedirectedToRole).value<BufferId>(); if (!redirectedTo.isValid()) { BufferId redirectedTo = Client::bufferModel()->currentIndex().data(NetworkModel::BufferIdRole).value<BufferId>(); if (redirectedTo.isValid()) sourceModel()->setData(sourceIdx, QVariant::fromValue<BufferId>(redirectedTo), MessageModel::RedirectedToRole); } if (_validBuffers.contains(redirectedTo)) return true; } if (redirectionTarget & BufferSettings::StatusBuffer) { QSet<BufferId>::const_iterator idIter = _validBuffers.constBegin(); while (idIter != _validBuffers.constEnd()) { if (Client::networkModel()->bufferType(*idIter) == BufferInfo::StatusBuffer) return true; ++idIter; } } return false; } if (_validBuffers.contains(bufferId)) { return true; } else { // show Quit messages in Query buffers: if (bufferType() != BufferInfo::QueryBuffer) return false; if (!(messageType & Message::Quit)) return false; if (myNetworkId != msgNetworkId) return false; // Extract timestamp and nickname from the new quit message qint64 messageTimestamp = sourceModel()->data(sourceIdx, MessageModel::TimestampRole).value<QDateTime>().toMSecsSinceEpoch(); QString quiter = nickFromMask(sourceModel()->data(sourceIdx, MessageModel::MessageRole).value<Message>().sender()).toLower(); // Check that nickname matches query name if (quiter != bufferName().toLower()) return false; // Check if a quit message was already forwarded within +/- 1000 ms static constexpr qint64 MAX_QUIT_DELTA_MS = 1 * 1000; // No need to check if it's the appropriate buffer, each query has a unique message filter if (std::binary_search(_filteredQuitMsgTime.begin(), _filteredQuitMsgTime.end(), messageTimestamp, [](qint64 a, qint64 b) { return ((a + MAX_QUIT_DELTA_MS) < b); })) { // New element is less than if at least 1000 ms older/newer // Match found, no need to forward another quit message return false; } // Mark query as having a quit message inserted auto* that = const_cast<MessageFilter*>(this); that->_filteredQuitMsgTime.insert(messageTimestamp); return true; } }