_showSenderBrackets = defaultSettings.showSenderBrackets();
defaultSettings.notify("ShowSenderBrackets", this, SLOT(showSenderBracketsChanged()));
+ _useCustomTimestampFormat = defaultSettings.useCustomTimestampFormat();
+ defaultSettings.notify("UseCustomTimestampFormat", this, SLOT(useCustomTimestampFormatChanged()));
+
_timestampFormatString = defaultSettings.timestampFormatString();
defaultSettings.notify("TimestampFormat", this, SLOT(timestampFormatStringChanged()));
updateTimestampHasBrackets();
_showSenderBrackets = settings.showSenderBrackets();
}
+void ChatScene::useCustomTimestampFormatChanged()
+{
+ ChatViewSettings settings;
+ _useCustomTimestampFormat = settings.useCustomTimestampFormat();
+ updateTimestampHasBrackets();
+}
+
void ChatScene::timestampFormatStringChanged()
{
ChatViewSettings settings;
{
// Calculate these parameters only as needed, rather than on-demand
- // Does the timestamp format contain brackets? For example:
- // Classic: "[hh:mm:ss]"
- // Modern: " hh:mm:ss"
- //
- // Match groups of any opening or closing brackets - (), {}, [], <>, (>, {], etc:
- // ^\s*[({[<].+[)}\]>]\s*$
- // [...] is a character group containing ...
- // ^ matches start of string
- // \s* matches any amount of whitespace
- // [({[<] matches (, {, [, or <
- // .+ matches one or more characters
- // [)}\]>] matches ), }, ], or >, escaping the ]
- // $ matches end of string
- // Alternatively, if opening and closing brackets must be in pairs, use this:
- // (^\s*\(.+\)\s*$)|(^\s*\{.+\}\s*$)|(^\s*\[.+\]\s*$)|(^\s*<.+>\s*$)
- // Note that '\' must be escaped as '\\'
- // Helpful interactive website for debugging and explaining: https://regex101.com/
- const QRegExp regExpMatchBrackets("^\\s*[({[<].+[)}\\]>]\\s*$");
- _timestampHasBrackets = regExpMatchBrackets.exactMatch(_timestampFormatString);
+ if (!_useCustomTimestampFormat) {
+ // The default timestamp format string does not have brackets, no need to check.
+ // If UiStyle::updateSystemTimestampFormat() has brackets added, change this, too.
+ _timestampHasBrackets = false;
+ } else {
+ // Does the timestamp format contain brackets? For example:
+ // Classic: "[hh:mm:ss]"
+ // Modern: " hh:mm:ss"
+ //
+ // Match groups of any opening or closing brackets - (), {}, [], <>, (>, {], etc:
+ // ^\s*[({[<].+[)}\]>]\s*$
+ // [...] is a character group containing ...
+ // ^ matches start of string
+ // \s* matches any amount of whitespace
+ // [({[<] matches (, {, [, or <
+ // .+ matches one or more characters
+ // [)}\]>] matches ), }, ], or >, escaping the ]
+ // $ matches end of string
+ // Alternatively, if opening and closing brackets must be in pairs, use this:
+ // (^\s*\(.+\)\s*$)|(^\s*\{.+\}\s*$)|(^\s*\[.+\]\s*$)|(^\s*<.+>\s*$)
+ // Note that '\' must be escaped as '\\'
+ // Helpful interactive website for debugging and explaining: https://regex101.com/
+ const QRegExp regExpMatchBrackets("^\\s*[({[<].+[)}\\]>]\\s*$");
+ _timestampHasBrackets = regExpMatchBrackets.exactMatch(_timestampFormatString);
+ }
}
*/
void showSenderBracketsChanged();
+ /**
+ * Updates the local setting cache of whether or not to use the custom timestamp format
+ */
+ void useCustomTimestampFormatChanged();
+
/**
* Updates the local setting cache of the timestamp format string
*/
bool _showSenderBrackets; /// If true, show brackets around sender names
+ bool _useCustomTimestampFormat; /// If true, use the custom timestamp format
QString _timestampFormatString; /// Format of the timestamp string
bool _timestampHasBrackets; /// If true, timestamp format has [brackets] of some sort
inline void enableWebPreview(bool enabled) { setLocalValue("ShowWebPreview", enabled); }
/**
- * Gets the format string for chat log timestamps
+ * Gets if a custom timestamp format is used.
+ *
+ * @returns True if custom timestamp format used, otherwise false
+ */
+ inline bool useCustomTimestampFormat() { return localValue("UseCustomTimestampFormat", false).toBool(); }
+ /**
+ * Sets whether a custom timestamp format is used.
+ *
+ * @param[in] enabled True if custom timestamp format used, otherwise false
+ */
+ inline void setUseCustomTimestampFormat(bool enabled) { setLocalValue("UseCustomTimestampFormat", enabled); }
+
+ /**
+ * Gets the format string for chat log timestamps.
*
* @returns String representing timestamp format, e.g. "[hh:mm:ss]" or " hh:mm:ss"
*/
// --------
// Check minor settings version, handling upgrades/downgrades as needed
// Current minor version
- const uint VERSION_MINOR_CURRENT = 3;
+ const uint VERSION_MINOR_CURRENT = 4;
// Stored minor version
uint versionMinor = s.versionMinor();
// Each missed version will be called in sequence. E.g. to upgrade from '1' to '3', this
// function will be called with '2', then '3'.
// Use explicit scope via { ... } to avoid cross-initialization
+ //
+ // In most cases, the goal is to preserve the older default values for keys that haven't been
+ // saved. Exceptions will be noted below.
+ case 4:
+ {
+ // New default changes: system locale used to generate a timestamp format string, deciding
+ // 24-hour or 12-hour timestamp.
+
+ // --------
+ // ChatView settings
+ const QString useCustomTimestampFormatId = "ChatView/__default__/UseCustomTimestampFormat";
+ if (!settings.valueExists(useCustomTimestampFormatId)) {
+ // New default value is false, preserve previous behavior by setting to true
+ settings.setValue(useCustomTimestampFormatId, true);
+ }
+ // --------
+
+ // Migration complete!
+ return true;
+ }
case 3:
{
- // New default changes: per-chat history and line wrapping enabled by default. Preserve
- // the older default values for keys that haven't been saved.
+ // New default changes: per-chat history and line wrapping enabled by default.
// --------
// InputWidget settings
case 2:
{
// New default changes: sender <nick> brackets disabled, sender colors and sender CTCP
- // colors enabled. Preserve the older default values for keys that haven't been saved.
+ // colors enabled.
// --------
// ChatView settings
QtUiStyle::QtUiStyle(QObject *parent) : UiStyle(parent)
{
ChatViewSettings s;
+ s.notify("UseCustomTimestampFormat", this, SLOT(updateUseCustomTimestampFormat()));
+ updateUseCustomTimestampFormat();
s.notify("TimestampFormat", this, SLOT(updateTimestampFormatString()));
updateTimestampFormatString();
s.notify("ShowSenderBrackets", this, SLOT(updateShowSenderBrackets()));
QtUiStyle::~QtUiStyle() {}
+void QtUiStyle::updateUseCustomTimestampFormat()
+{
+ ChatViewSettings s;
+ setUseCustomTimestampFormat(s.useCustomTimestampFormat());
+}
+
void QtUiStyle::updateTimestampFormatString()
{
ChatViewSettings s;
void generateSettingsQss() const;
private slots:
+ /**
+ * Updates knowledge of whether or not to use the custom timestamp format
+ */
+ void updateUseCustomTimestampFormat();
+
+ /**
+ * Updates knowledge of the current timestamp format
+ */
void updateTimestampFormatString();
+
/**
* Updates knowledge of whether or not to show sender brackets
*/
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
- <widget class="QLabel" name="label_13">
+ <widget class="QCheckBox" name="customTimestampFormat">
+ <property name="toolTip">
+ <string>Use a custom format for the timestamp</string>
+ </property>
<property name="text">
- <string>Timestamp format:</string>
+ <string>Custom timestamp format:</string>
+ </property>
+ <property name="defaultValue" stdset="0">
+ <bool>false</bool>
+ </property>
+ <property name="settingsKey" stdset="0">
+ <string notr="true">UseCustomTimestampFormat</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="timestampFormat">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
<property name="toolTip">
<string><html><head/><body><p>Usage examples:</p>
<table cellpadding="2">
</customwidget>
</customwidgets>
<tabstops>
+ <tabstop>customTimestampFormat</tabstop>
<tabstop>timestampFormat</tabstop>
<tabstop>showSenderBrackets</tabstop>
<tabstop>customChatViewFont</tabstop>
</hint>
</hints>
</connection>
+ <connection>
+ <sender>customTimestampFormat</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>timestampFormat</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>116</x>
+ <y>22</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>301</x>
+ <y>23</y>
+ </hint>
+ </hints>
+ </connection>
</connections>
</ui>
#include "util.h"
QHash<QString, UiStyle::FormatType> UiStyle::_formatCodes;
-QString UiStyle::_timestampFormatString; /// Timestamp format
-bool UiStyle::_showSenderBrackets; /// If true, show brackets around sender names
+bool UiStyle::_useCustomTimestampFormat; /// If true, use the custom timestamp format
+QString UiStyle::_timestampFormatString; /// Timestamp format
+QString UiStyle::_systemTimestampFormatString; /// Cached copy of system locale timestamp format
+bool UiStyle::_showSenderBrackets; /// If true, show brackets around sender names
UiStyle::UiStyle(QObject *parent)
: QObject(parent),
// Initialize fallback defaults
// NOTE: If you change this, update qtui/chatviewsettings.h, too. More explanations available
// in there.
+ setUseCustomTimestampFormat(false);
setTimestampFormatString(" hh:mm:ss");
enableSenderBrackets(true);
return ss;
}
+
+void UiStyle::updateSystemTimestampFormat()
+{
+ // Does the system locale use AM/PM designators? For example:
+ // AM/PM: h:mm AP
+ // AM/PM: hh:mm a
+ // 24-hour: h:mm
+ // 24-hour: hh:mm ADD things
+ // For timestamp format, see https://doc.qt.io/qt-5/qdatetime.html#toString
+ // This won't update if the system locale is changed while Quassel is running. If need be,
+ // Quassel could hook into notifications of changing system locale to update this.
+ //
+ // Match any AP or A designation if on a word boundary, including underscores.
+ // .*(\b|_)(A|AP)(\b|_).*
+ // .* Match any number of characters
+ // \b Match a word boundary, i.e. "AAA.BBB", "." is matched
+ // _ Match the literal character '_' (not considered a word boundary)
+ // (X|Y) Match either X or Y, exactly
+ //
+ // Note that '\' must be escaped as '\\'
+ // QRegExp does not support (?> ...), so it's replaced with standard matching, (...)
+ // Helpful interactive website for debugging and explaining: https://regex101.com/
+ const QRegExp regExpMatchAMPM(".*(\\b|_)(A|AP)(\\b|_).*", Qt::CaseInsensitive);
+
+ if (regExpMatchAMPM.exactMatch(QLocale::system().timeFormat(QLocale::ShortFormat))) {
+ // AM/PM style used
+ _systemTimestampFormatString = " h:mm:ss ap";
+ } else {
+ // 24-hour style used
+ _systemTimestampFormatString = " hh:mm:ss";
+ }
+ // Include a space to give the timestamp a small bit of padding between the border of the chat
+ // buffer window and the numbers. Helps with readability.
+ // If you change this to include brackets, e.g. "[hh:mm:ss]", also update
+ // ChatScene::updateTimestampHasBrackets() to true or false as needed!
+}
+
+
// FIXME The following should trigger a reload/refresh of the chat view.
+void UiStyle::setUseCustomTimestampFormat(bool enabled)
+{
+ if (_useCustomTimestampFormat != enabled) {
+ _useCustomTimestampFormat = enabled;
+ }
+}
+
void UiStyle::setTimestampFormatString(const QString &format)
{
if (_timestampFormatString != format) {
}
+QString UiStyle::systemTimestampFormatString()
+{
+ if (_systemTimestampFormatString.isEmpty()) {
+ // Calculate and cache the system timestamp format string
+ updateSystemTimestampFormat();
+ }
+ return _systemTimestampFormatString;
+}
+
+
+QString UiStyle::timestampFormatString()
+{
+ if (useCustomTimestampFormat()) {
+ return _timestampFormatString;
+ } else {
+ return systemTimestampFormatString();
+ }
+}
+
+
/***********************************************************************************/
UiStyle::StyledMessage::StyledMessage(const Message &msg)
: Message(msg)
static FormatType formatType(Message::Type msgType);
static StyledString styleString(const QString &string, quint32 baseFormat = Base);
static QString mircToInternal(const QString &);
- static inline QString timestampFormatString() { return _timestampFormatString; }
+
+ /**
+ * Gets if a custom timestamp format is used.
+ *
+ * @return True if custom timestamp format used, otherwise false
+ */
+ static inline bool useCustomTimestampFormat() { return _useCustomTimestampFormat; }
+
+ /**
+ * Gets the format string for chat log timestamps according to the system locale.
+ *
+ * This will return " hh:mm:ss" for system locales with 24-hour time or " h:mm:ss AP" for
+ * systems with 12-hour time.
+ *
+ * @return String representing timestamp format according to system locale, e.g. " hh:mm:ss"
+ */
+ static QString systemTimestampFormatString();
+
+ /**
+ * Gets the format string for chat log timestamps, either system locale or custom.
+ *
+ * Depending on useCustomTimestampFormat(), this will return either the system locale based
+ * time format, or the custom user-specified string.
+ *
+ * @return String representing timestamp format, e.g. "[hh:mm:ss]" or " hh:mm:ss"
+ */
+ static QString timestampFormatString();
QTextCharFormat format(quint32 formatType, quint32 messageLabel) const;
QFontMetricsF *fontMetrics(quint32 formatType, quint32 messageLabel) const;
static FormatType formatType(const QString &code);
static QString formatCode(FormatType);
+
+ /**
+ * Cache the system locale timestamp format string
+ *
+ * Based on whether or not AM/PM designators are used in the QLocale::system().timeFormat(),
+ * this extends the system locale timestamp format string to include seconds.
+ *
+ * @see UiStyle::systemTimestampFormatString()
+ */
+ static void updateSystemTimestampFormat();
+
+ /**
+ * Updates the local setting cache of whether or not to use the custom timestamp format
+ *
+ * @param[in] enabled If true, custom timestamp format used, otherwise false
+ */
+ static void setUseCustomTimestampFormat(bool enabled);
+
+ /**
+ * Updates the local setting cache of the timestamp format string
+ *
+ * @param[in] format Timestamp format string
+ */
static void setTimestampFormatString(const QString &format);
+
/**
* Updates the local setting cache of whether or not to show sender brackets
*
mutable QHash<quint64, QFontMetricsF *> _metricsCache;
QHash<quint32, QTextCharFormat> _listItemFormats;
static QHash<QString, FormatType> _formatCodes;
- static QString _timestampFormatString;
- static bool _showSenderBrackets; /// If true, show brackets around sender names
+ static bool _useCustomTimestampFormat; /// If true, use the custom timestamp format
+ static QString _systemTimestampFormatString; /// Cached copy of system locale timestamp format
+ static QString _timestampFormatString; /// Timestamp format string
+ static bool _showSenderBrackets; /// If true, show brackets around sender names
QIcon _channelJoinedIcon;
QIcon _channelPartedIcon;