mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 14:55:36 +08:00
Utility functions to sort text messages by timestamp (ascending/descending)
* compare function for text message * resort function * text message edit can display HTML text messages with ascending/descending timestamp * made CTextMessageListModel -> CListModelTimestampObject
This commit is contained in:
committed by
Mat Sutcliffe
parent
25eb13a83f
commit
e12dc3a73a
@@ -502,6 +502,13 @@ namespace BlackGui
|
||||
this->sort(this->getSortColumn(), this->getSortOrder());
|
||||
}
|
||||
|
||||
template<typename T, bool UseCompare>
|
||||
void CListModelBase<T, UseCompare>::resort()
|
||||
{
|
||||
// sort the values
|
||||
this->updateContainerMaybeAsync(m_container, true);
|
||||
}
|
||||
|
||||
template <typename T, bool UseCompare>
|
||||
void CListModelBase<T, UseCompare>::sort(int column, Qt::SortOrder order)
|
||||
{
|
||||
|
||||
@@ -107,6 +107,10 @@ namespace BlackGui
|
||||
//! Sort by given sort order \sa getSortColumn() \sa getSortOrder()
|
||||
void sort();
|
||||
|
||||
//! Sort by given sort order \sa getSortColumn() \sa getSortOrder()
|
||||
//! \remark always sorts, even if columns did no change
|
||||
void resort();
|
||||
|
||||
//! Truncate to given number
|
||||
void truncate(int maxNumber, bool forceSort = false);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace BlackGui
|
||||
// https://isocpp.org/wiki/faq/templates#separate-template-fn-defn-from-decl
|
||||
template class CListModelBase<BlackMisc::Network::CServerList, true>;
|
||||
template class CListModelBase<BlackMisc::Network::CUserList, true>;
|
||||
template class CListModelBase<BlackMisc::Network::CTextMessageList, false>;
|
||||
template class CListModelBase<BlackMisc::Network::CTextMessageList, true>;
|
||||
template class CListModelBase<BlackMisc::Network::CClientList, false>;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -19,11 +19,18 @@ namespace BlackGui
|
||||
{
|
||||
namespace Models
|
||||
{
|
||||
template <typename T, bool UseCompare>
|
||||
template<typename T, bool UseCompare>
|
||||
CListModelTimestampObjects<T, UseCompare>::CListModelTimestampObjects(const QString &translationContext, QObject *parent) :
|
||||
CListModelBase<ContainerType, UseCompare>(translationContext, parent)
|
||||
{ }
|
||||
|
||||
template<typename T, bool UseCompare>
|
||||
bool CListModelTimestampObjects<T, UseCompare>::isSortedByTimestampProperty() const
|
||||
{
|
||||
const CPropertyIndex pi = this->getSortProperty();
|
||||
return ITimestampBased::canHandleIndex(pi);
|
||||
}
|
||||
|
||||
template<typename T, bool UseCompare>
|
||||
void CListModelTimestampObjects<T, UseCompare>::addTimestampColumns()
|
||||
{
|
||||
@@ -32,6 +39,7 @@ namespace BlackGui
|
||||
}
|
||||
|
||||
template class CListModelTimestampObjects<BlackMisc::CStatusMessageList, true>;
|
||||
template class CListModelTimestampObjects<BlackMisc::Network::CTextMessageList, true>;
|
||||
template class CListModelTimestampObjects<BlackMisc::Aviation::CAircraftPartsList, true>;
|
||||
template class CListModelTimestampObjects<BlackMisc::Aviation::CAircraftSituationList, true>;
|
||||
template class CListModelTimestampObjects<BlackMisc::Aviation::CAircraftSituationChangeList, true>;
|
||||
|
||||
@@ -35,6 +35,9 @@ namespace BlackGui
|
||||
//! Container element type
|
||||
using ObjectType = typename T::value_type;
|
||||
|
||||
//! Sorted by one of the timestamp columns?
|
||||
bool isSortedByTimestampProperty() const;
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
CListModelTimestampObjects(const QString &translationContext, QObject *parent = nullptr);
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace BlackGui
|
||||
namespace Models
|
||||
{
|
||||
CTextMessageListModel::CTextMessageListModel(TextMessageMode mode, QObject *parent) :
|
||||
CListModelBase("ModelTextMessageList", parent), m_textMessageMode(NotSet)
|
||||
CListModelTimestampObjects("ModelTextMessageList", parent), m_textMessageMode(NotSet)
|
||||
{
|
||||
this->setTextMessageMode(mode);
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#ifndef BLACKGUI_MODELS_TEXTMESSAGELISTMODEL_H
|
||||
#define BLACKGUI_MODELS_TEXTMESSAGELISTMODEL_H
|
||||
|
||||
#include "blackgui/models/listmodeltimestampobjects.h"
|
||||
#include "blackgui/blackguiexport.h"
|
||||
#include "blackgui/models/listmodelbase.h"
|
||||
#include "blackmisc/network/textmessagelist.h"
|
||||
|
||||
class QObject;
|
||||
@@ -23,7 +23,8 @@ namespace BlackGui
|
||||
namespace Models
|
||||
{
|
||||
//! Text message list model
|
||||
class BLACKGUI_EXPORT CTextMessageListModel : public CListModelBase<BlackMisc::Network::CTextMessageList>
|
||||
class BLACKGUI_EXPORT CTextMessageListModel :
|
||||
public CListModelTimestampObjects<BlackMisc::Network::CTextMessageList, true>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -40,7 +41,7 @@ namespace BlackGui
|
||||
explicit CTextMessageListModel(TextMessageMode stationMode, QObject *parent = nullptr);
|
||||
|
||||
//! Destructor
|
||||
virtual ~CTextMessageListModel() {}
|
||||
virtual ~CTextMessageListModel() override {}
|
||||
|
||||
//! Set mode
|
||||
void setTextMessageMode(TextMessageMode mode);
|
||||
@@ -56,4 +57,5 @@ namespace BlackGui
|
||||
};
|
||||
} // ns
|
||||
} // ns
|
||||
|
||||
#endif // guard
|
||||
|
||||
@@ -45,12 +45,12 @@ namespace BlackGui
|
||||
m_actionWordWrap->setCheckable(true);
|
||||
|
||||
connect(m_actionClearTextEdit, &QAction::triggered, this, &CTextMessageTextEdit::clear);
|
||||
connect(m_actionAll, &QAction::triggered, this, &CTextMessageTextEdit::keepLastNMessages);
|
||||
connect(m_actionLast10, &QAction::triggered, this, &CTextMessageTextEdit::keepLastNMessages);
|
||||
connect(m_actionLast25, &QAction::triggered, this, &CTextMessageTextEdit::keepLastNMessages);
|
||||
connect(m_actionWithSender, &QAction::triggered, this, &CTextMessageTextEdit::setVisibleFields);
|
||||
connect(m_actionAll, &QAction::triggered, this, &CTextMessageTextEdit::keepLastNMessages);
|
||||
connect(m_actionLast10, &QAction::triggered, this, &CTextMessageTextEdit::keepLastNMessages);
|
||||
connect(m_actionLast25, &QAction::triggered, this, &CTextMessageTextEdit::keepLastNMessages);
|
||||
connect(m_actionWithSender, &QAction::triggered, this, &CTextMessageTextEdit::setVisibleFields);
|
||||
connect(m_actionWithRecipient, &QAction::triggered, this, &CTextMessageTextEdit::setVisibleFields);
|
||||
connect(m_actionWordWrap, &QAction::triggered, this, &CTextMessageTextEdit::setWordWrap);
|
||||
connect(m_actionWordWrap, &QAction::triggered, this, &CTextMessageTextEdit::setWordWrap);
|
||||
|
||||
connect(this, &QTextEdit::customContextMenuRequested, this, &CTextMessageTextEdit::showContextMenuForTextEdit);
|
||||
}
|
||||
@@ -63,14 +63,13 @@ namespace BlackGui
|
||||
if (maxMessages < 0 && m_keepMaxMessages >= 0) { maxMessages = m_keepMaxMessages; }
|
||||
if (maxMessages >= 0)
|
||||
{
|
||||
m_messages.push_frontMaxElements(textMessage, maxMessages);
|
||||
m_messages.push_backMaxElements(textMessage, maxMessages);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_messages.push_front(textMessage);
|
||||
m_messages.push_back(textMessage);
|
||||
}
|
||||
const QString html(toHtml(m_messages, m_withSender, m_withRecipient));
|
||||
m_textDocument.setHtml(html);
|
||||
this->redrawHtml();
|
||||
}
|
||||
|
||||
int CTextMessageTextEdit::count() const
|
||||
@@ -86,8 +85,14 @@ namespace BlackGui
|
||||
|
||||
void CTextMessageTextEdit::redrawHtml()
|
||||
{
|
||||
const QString html(toHtml(m_messages, m_withSender, m_withRecipient));
|
||||
const QString html(
|
||||
this->toHtml(
|
||||
m_latestFirst ? m_messages.reversed() : m_messages,
|
||||
m_withSender,
|
||||
m_withRecipient)
|
||||
);
|
||||
m_textDocument.setHtml(html);
|
||||
this->moveCursor(m_latestFirst ? QTextCursor::Start : QTextCursor::End);
|
||||
}
|
||||
|
||||
void CTextMessageTextEdit::setStyleSheetForContent(const QString &styleSheet)
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace BlackGui
|
||||
CTextMessageTextEdit(QWidget *parent = nullptr);
|
||||
|
||||
//! Destructor
|
||||
virtual ~CTextMessageTextEdit();
|
||||
virtual ~CTextMessageTextEdit() override;
|
||||
|
||||
//! Insert a message
|
||||
void insertTextMessage(const BlackMisc::Network::CTextMessage &textMessage, int maxMessages = -1);
|
||||
@@ -55,6 +55,12 @@ namespace BlackGui
|
||||
//! Redraw HTML
|
||||
void redrawHtml();
|
||||
|
||||
//! Order latest first/latest last
|
||||
void setLatestFirst(bool latestFirst) { m_latestFirst = latestFirst; }
|
||||
|
||||
//! Lastest first
|
||||
bool isLatestFirst() const { return m_latestFirst; }
|
||||
|
||||
private:
|
||||
//! Context menu
|
||||
void showContextMenuForTextEdit(const QPoint &pt);
|
||||
@@ -77,9 +83,10 @@ namespace BlackGui
|
||||
BlackMisc::Network::CTextMessageList m_messages;
|
||||
QTextDocument m_textDocument;
|
||||
int m_keepMaxMessages = -1; //!< max number of messages to keep, or -1 to keep all messages
|
||||
bool m_withSender = true;
|
||||
bool m_latestFirst = false;
|
||||
bool m_withSender = true;
|
||||
bool m_withRecipient = false;
|
||||
bool m_wordWrap = true;
|
||||
bool m_wordWrap = true;
|
||||
|
||||
QAction *m_actionClearTextEdit = nullptr;
|
||||
QAction *m_actionLast10 = nullptr;
|
||||
|
||||
@@ -21,15 +21,19 @@ namespace BlackGui
|
||||
CTextMessageView::CTextMessageView(QWidget *parent) : CViewBase(parent)
|
||||
{
|
||||
this->standardInit(new CTextMessageListModel(CTextMessageListModel::FromTo, this));
|
||||
this->m_menus |= MenuClear;
|
||||
m_menus |= MenuClear;
|
||||
}
|
||||
|
||||
void CTextMessageView::setTextMessageMode(CTextMessageListModel::TextMessageMode mode)
|
||||
{
|
||||
Q_ASSERT(this->m_model);
|
||||
this->m_model->setTextMessageMode(mode);
|
||||
Q_ASSERT(m_model);
|
||||
m_model->setTextMessageMode(mode);
|
||||
this->setSortIndicator();
|
||||
}
|
||||
|
||||
}
|
||||
bool CTextMessageView::isSortedByTimestampProperty() const
|
||||
{
|
||||
return m_model->isSortedByTimestampProperty();
|
||||
}
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -32,7 +32,11 @@ namespace BlackGui
|
||||
|
||||
//! Set display mode
|
||||
void setTextMessageMode(BlackGui::Models::CTextMessageListModel::TextMessageMode mode);
|
||||
|
||||
//! Sorted by a timestamp property
|
||||
bool isSortedByTimestampProperty() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
#endif // guard
|
||||
|
||||
@@ -107,8 +107,8 @@ namespace BlackGui
|
||||
|
||||
Q_UNUSED(sort);
|
||||
ModelClass *model = this->derivedModel();
|
||||
auto sortColumn = model->getSortColumn();
|
||||
auto sortOrder = model->getSortOrder();
|
||||
const auto sortColumn = model->getSortColumn();
|
||||
const auto sortOrder = model->getSortOrder();
|
||||
this->showLoadIndicator(container.size());
|
||||
CWorker *worker = CWorker::fromTask(this, "ViewSort", [model, container, sortColumn, sortOrder]()
|
||||
{
|
||||
@@ -300,7 +300,7 @@ namespace BlackGui
|
||||
if (!hasSelection()) { return 0; }
|
||||
int c = 0;
|
||||
|
||||
int lastUpdatedRow = -1;
|
||||
int lastUpdatedRow = -1;
|
||||
int firstUpdatedRow = -1;
|
||||
const CPropertyIndexList propertyIndexes(vm.indexes());
|
||||
const QModelIndexList indexes = this->selectedRows();
|
||||
@@ -503,6 +503,18 @@ namespace BlackGui
|
||||
m_model->sortByPropertyIndex(propertyIndex, order);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void CViewBase<T>::sort()
|
||||
{
|
||||
m_model->sort();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void CViewBase<T>::resort()
|
||||
{
|
||||
m_model->resort();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
QJsonObject CViewBase<T>::toJson(bool selectedOnly) const
|
||||
{
|
||||
|
||||
@@ -750,6 +750,12 @@ namespace BlackGui
|
||||
virtual Qt::SortOrder getSortOrder() const override { return m_model->getSortOrder(); }
|
||||
//! @}
|
||||
|
||||
//! Sort if columns or order changed
|
||||
void sort();
|
||||
|
||||
//! Resort ("forced sorting")
|
||||
void resort();
|
||||
|
||||
//! Column count
|
||||
int columnCount() const;
|
||||
|
||||
|
||||
@@ -277,7 +277,7 @@ namespace BlackMisc
|
||||
const ColumnIndex i = index.frontCasted<ColumnIndex>();
|
||||
switch (i)
|
||||
{
|
||||
case IndexSenderCallsign: return m_senderCallsign.propertyByIndex(index.copyFrontRemoved());
|
||||
case IndexSenderCallsign: return m_senderCallsign.propertyByIndex(index.copyFrontRemoved());
|
||||
case IndexRecipientCallsign: return m_recipientCallsign.propertyByIndex(index.copyFrontRemoved());
|
||||
case IndexRecipientCallsignOrFrequency: return CVariant::fromValue(this->getRecipientCallsignOrFrequency());
|
||||
case IndexMessage: return CVariant::fromValue(m_message);
|
||||
@@ -293,11 +293,28 @@ namespace BlackMisc
|
||||
const ColumnIndex i = index.frontCasted<ColumnIndex>();
|
||||
switch (i)
|
||||
{
|
||||
case IndexSenderCallsign: m_senderCallsign.setPropertyByIndex(index.copyFrontRemoved(), variant); break;
|
||||
case IndexSenderCallsign: m_senderCallsign.setPropertyByIndex(index.copyFrontRemoved(), variant); break;
|
||||
case IndexRecipientCallsign: m_recipientCallsign.setPropertyByIndex(index.copyFrontRemoved(), variant); break;
|
||||
case IndexMessage: m_message = variant.value<QString>(); break;
|
||||
default: CValueObject::setPropertyByIndex(index, variant); break;
|
||||
}
|
||||
}
|
||||
|
||||
int CTextMessage::comparePropertyByIndex(const CPropertyIndex &index, const CTextMessage &compareValue) const
|
||||
{
|
||||
if (ITimestampBased::canHandleIndex(index)) { return ITimestampBased::comparePropertyByIndex(index, compareValue); }
|
||||
const ColumnIndex i = index.frontCasted<ColumnIndex>();
|
||||
switch (i)
|
||||
{
|
||||
case IndexSenderCallsign: return m_senderCallsign.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getSenderCallsign());
|
||||
case IndexRecipientCallsign: return m_recipientCallsign.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getRecipientCallsign());
|
||||
case IndexRecipientCallsignOrFrequency:
|
||||
if (this->isRadioMessage()) { return this->getFrequency().compare(compareValue.getFrequency()); }
|
||||
return m_recipientCallsign.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getRecipientCallsign());
|
||||
default: return CValueObject::comparePropertyByIndex(index, *this);
|
||||
}
|
||||
Q_ASSERT_X(false, Q_FUNC_INFO, "No comparison");
|
||||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -180,6 +180,9 @@ namespace BlackMisc
|
||||
//! \copydoc BlackMisc::Mixin::Index::setPropertyByIndex
|
||||
void setPropertyByIndex(const BlackMisc::CPropertyIndex &index, const CVariant &variant);
|
||||
|
||||
//! \copydoc BlackMisc::Mixin::Index::comparePropertyByIndex
|
||||
int comparePropertyByIndex(const CPropertyIndex &index, const CTextMessage &compareValue) const;
|
||||
|
||||
//! \copydoc BlackMisc::Mixin::String::toQString
|
||||
QString convertToQString(bool i18n = false) const;
|
||||
|
||||
|
||||
@@ -138,10 +138,10 @@ namespace BlackMisc
|
||||
//! Any of the timestamp indexes
|
||||
static bool isAnyTimestampIndex(int index);
|
||||
|
||||
protected:
|
||||
//! Can given index be handled
|
||||
static bool canHandleIndex(const CPropertyIndex &index);
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
ITimestampBased();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user