From 62b20e0c6c13ea7bfb713da68c85a5e94c951d1b Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Fri, 20 Mar 2009 22:01:36 +0100 Subject: [PATCH 1/1] Rework mergedFormats() to handle pre-set formats This allows us to seed the format cache with information from a stylesheet. mergedFormats() now handles sensible combinations of pre-set values in order to construct the requested format. For example, if the stylesheet sets a format for the sender column in a highlighted message, this is now used to construct derivations from that rather than using the hardcoded stock formats. --- src/uisupport/uistyle.cpp | 83 ++++++++++++++++++++++++++++++++------- src/uisupport/uistyle.h | 20 ++++++---- 2 files changed, 81 insertions(+), 22 deletions(-) diff --git a/src/uisupport/uistyle.cpp b/src/uisupport/uistyle.cpp index 19f9fd1b..84da3062 100644 --- a/src/uisupport/uistyle.cpp +++ b/src/uisupport/uistyle.cpp @@ -139,7 +139,7 @@ void UiStyle::setSenderAutoColor( bool state ) { QTextCharFormat UiStyle::format(FormatType ftype, Settings::Mode mode) const { // Check for enabled sender auto coloring if ( (ftype & 0x00000fff) == Sender && !_senderAutoColor ) { - // Just use the default sender style if auto coloring is disabled + // Just use the default sender style if auto coloring is disabled FIXME ftype = Sender; } @@ -150,23 +150,76 @@ QTextCharFormat UiStyle::format(FormatType ftype, Settings::Mode mode) const { // NOTE: This function is intimately tied to the values in FormatType. Don't change this // until you _really_ know what you do! QTextCharFormat UiStyle::mergedFormat(quint32 ftype) { - if(_cachedFormats.contains(ftype)) return _cachedFormats.value(ftype); - if(ftype == Invalid) return QTextCharFormat(); - // Now we construct the merged format, starting with the default - QTextCharFormat fmt = format(None); - // First: general message format - fmt.merge(format((FormatType)(ftype & 0x0f))); - // now more specific ones - for(quint32 mask = 0x0010; mask <= 0x2000; mask <<= 1) { - if(ftype & mask) fmt.merge(format((FormatType)mask)); + if(ftype == Invalid) + return QTextCharFormat(); + if(_cachedFormats.contains(ftype)) + return _cachedFormats.value(ftype); + + QTextCharFormat fmt; + + // Check if we have a special message format stored already sans color codes + if(_cachedFormats.contains(ftype & 0x1fffff)) + fmt = _cachedFormats.value(ftype &0x1fffff); + else { + // Nope, so we have to construct it... + // We assume that we don't mix mirc format codes and component codes, so at this point we know that it's either + // a stock (not stylesheeted) component, or mirc formats + // In both cases, we start off with the basic format for this message type and then merge the extra stuff + + // Check if we at least already have something stored for the message type first + if(_cachedFormats.contains(ftype & 0xf)) + fmt = _cachedFormats.value(ftype & 0xf); + else { + // Not being in the cache means it hasn't been preset via stylesheet (or used before) + // We might still have set something in code as a fallback, so merge + fmt = format(None); + fmt.merge(format((FormatType)(ftype & 0x0f))); + // This can be cached + _cachedFormats[ftype & 0x0f] = fmt; + } + // OK, at this point we have the message type format - now merge the rest + if((ftype & 0xf0)) { // mirc format + for(quint32 mask = 0x10; mask <= 0x80; mask <<= 1) { + if(!(ftype & mask)) + continue; + // We need to check for overrides in the cache + if(_cachedFormats.contains(mask | (ftype & 0x0f))) + fmt.merge(_cachedFormats.value(mask | (ftype & 0x0f))); + else if(_cachedFormats.contains(mask)) + fmt.merge(_cachedFormats.value(mask)); + else // nothing in cache, use stock format + fmt.merge(format((FormatType)mask)); + } + } else { // component + // We've already checked the cache for the combo of msgtype and component and failed, + // so we check if we defined a general format and merge this, or the stock format else + if(_cachedFormats.contains(ftype & 0xff00)) + fmt.merge(_cachedFormats.value(ftype & 0xff00)); + else + fmt.merge(format((FormatType)(ftype & 0xff00))); + } } - // color codes! - if(ftype & 0x00400000) fmt.merge(format((FormatType)(ftype & 0x0f400000))); // foreground - if(ftype & 0x00800000) fmt.merge(format((FormatType)(ftype & 0xf0800000))); // background + + // Now we handle color codes. We assume that those can't be combined with components + if(ftype & 0x00400000) + fmt.merge(format((FormatType)(ftype & 0x0f400000))); // foreground + if(ftype & 0x00800000) + fmt.merge(format((FormatType)(ftype & 0xf0800000))); // background + // Sender auto colors - if((ftype & 0xfff) == 0x200 && (ftype & 0xff000200) != 0x200) fmt.merge(format((FormatType)(ftype & 0xff000200))); + if(_senderAutoColor && (ftype & 0x200) && (ftype & 0xff000200) != 0x200) { + if(_cachedFormats.contains(ftype & 0xff00020f)) + fmt.merge(_cachedFormats.value(ftype & 0xff00020f)); + else if(_cachedFormats.contains(ftype & 0xff000200)) + fmt.merge(_cachedFormats.value(ftype & 0xff000200)); + else + fmt.merge(format((FormatType)(ftype & 0xff000200))); + } + // URL - if(ftype & Url) fmt.merge(format(Url)); + if(ftype & Url) + fmt.merge(format(Url)); // TODO handle this properly + return _cachedFormats[ftype] = fmt; } diff --git a/src/uisupport/uistyle.h b/src/uisupport/uistyle.h index 69947fc0..38d43f0d 100644 --- a/src/uisupport/uistyle.h +++ b/src/uisupport/uistyle.h @@ -49,6 +49,7 @@ public: enum FormatType { None = 0x00000000, Invalid = 0x11111111, + // Message Formats (mutually exclusive!) PlainMsg = 0x00000001, NoticeMsg = 0x00000002, @@ -61,11 +62,18 @@ public: RenameMsg = 0x00000009, ModeMsg = 0x0000000a, ActionMsg = 0x0000000b, + HighlightMsg = 0x0000000f, + + // Note: mergedFormat() assumes that 0x10 - 0x80 are *only* used within the message contents, + // e.g. not together with any of 0x0100-0x2000! + // If we happen to find a use case for that, we can see if/how to implement that though. + // Standard Formats Bold = 0x00000010, Italic = 0x00000020, Underline = 0x00000040, Reverse = 0x00000080, + // Individual parts of a message Timestamp = 0x00000100, Sender = 0x00000200, @@ -73,9 +81,11 @@ public: Hostmask = 0x00000800, ChannelName = 0x00001000, ModeFlags = 0x00002000, + // URL is special, we want that to take precedence over the rest... Url = 0x00100000, - // Colors + + // mIRC Colors - we assume those to be present only in plain contents FgCol00 = 0x00400000, FgCol01 = 0x01400000, FgCol02 = 0x02400000, @@ -132,13 +142,9 @@ public: SenderCol18 = 0x12000200, SenderCol19 = 0x13000200, SenderCol20 = 0x14000200, - SenderCol21 = 0x15000200 - - }; + SenderCol21 = 0x15000200, - struct UrlInfo { - int start, end; - QUrl url; + SenderColSelf = 0xff000200 }; struct StyledString { -- 2.20.1