Access Setting Theme VBA using MsoThemeColorSchemeIndex is off by 1 - vba

When setting a control/form theme, I often use VBA, as I can change the color on the fly. Works great. I have been trying to move my Database away from using hard-coded numbers, and built up a theme module that is included which has themes mapped so I could just change them there instead of everywhere else.
Then I realized, hey, there's an easier way to do this (or...so I thought).
Enter Enums MsoThemeColorIndex and MsoThemeColorSchemeIndex. This way, I can even do fancy things like decide that when I use myInternalTheme1 constant, I could just switch it out with MsoThemeColorSchemeIndex.msoThemeAccent1.
A long while back I noticed that if I used what is shown on the help docs (above), the themes were "off" by 1. Namely 5 (msoThemeAccent1 "Theme1"), instead of mapping to msoThemeAccent1 actually maps to "Theme2", and "Theme 2" Color is displayed. So, I just manually adjusted. But I'm wondering if I'm missing something here, and I'm using the value incorrectly?
I've used SaveAsText to export these forms after saving the values, and when I do, the field that's had "Theme 1" manually applied in Properties shows that the value 4 is used, which "should" map to msoThemeColorLight2, but doesn't.
Field's Backtheme setting:
BackThemeColorIndex =4
How I'm using this:
' In my "modColor"
Public Const MythemeAccent1 As Integer = 4 ' (help docs specify this as MsoThemeColorIndex.msoThemeColorLight2)
' This one colors the header in Theme2 "wrong color, correct enum value???"
' MsoThemeColorSchemeIndex.msoThemeAccent1 = 5 (as docs say)
Me.section(acHeader).BackThemeColorIndex = MsoThemeColorSchemeIndex.msoThemeAccent1
' This one colors the header with Theme1 "correct color, wrong enum value???"
' MsoThemeColorSchemeIndex.msoThemeLight2 = 4 (as docs say)
Me.section(acHeader).BackThemeColorIndex = MsoThemeColorSchemeIndex.msoThemeLight2
' my internal module, this works correctly (code looks correct, and correct color used).
Me.section(acHeader).BackThemeColorIndex = MythemeAccent1
If I assign the color in Design View via Form Properties > FormHeader > Format > Back Color > "Accent 1" it works correctly, and the theme is properly applied.
FormHeader Properties Format
I've verified the theme is correct, numerous times. I exported the theme, and verified that the XML for "Accent 1" is correct, and that "Accent2" is different. "Theme 1" is "Bluish" and "Theme 2" is "Redish" for reference, so it's not like my monitor rendering is just making me think it's different.
Excerpted XML from .Thmx file:
<a:accent1>
<a:srgbClr val="5C83B4"/>
</a:accent1>
<a:accent2>
<a:srgbClr val="E74B4B"/>
</a:accent2>

Related

Make a hotspot cell F4-enabled while insert. Possible?

My requirement is as follows:
I show records in an alv grid (CL_GUI_ALV_GRID), where the user can add new ones.
I have a keyfield, MATNR, which is disabled on existing records. This one does
not really need to have a working F4 SH icon. It must have a hotspot.
When the user decides to add a new record, I want to allow F4,make the field a
hotspot and enable it.
However, it turns out, that neither combining cellstyles 1-4 works (appearently there is no combining of their raws resulting in a multiple style) , nor does fieldcat-f4available = abap_true work together with fieldcat-hotspot = abap_true.
I must admit, that I do not come often over this kind of requirements... therefore I am asking in here, if anybody knows a way (best practice preferred).
Until now I set the cellstyles depending on row-contents, and the fieldcat is set up more or less statically.
So in the fieldcat, F4 is set up, and in the celltab style MC_HOTSPOT is set up.
However, this also forbids to entering values manually. Only the F4 value remapping works.
I have just had this problem and thought I'd share my solution.
Apparently the way to combine styles is with bitwise operations:
ls_style-style = cl_gui_alv_grid=>mc_style_hotspot BIT-OR
cl_gui_alv_grid=>mc_style_f4 BIT-OR
cl_gui_alv_grid=>mc_style_enabled.
Should create an editable field with hotspot and F4.
You should also mark edit and hotspot in the field catalog.
I needed to have: editable field with f4 and hotspot. My solutions:
I set in ls_fcat :
hotspot = abap_true, and f4avaliable = abap_true
In style of field, I set:
style = cl_gui_alv_grid=>mc_style_f4 BIT-OR cl_gui_alv_grid=>mc_style_enabled

Easeljs getBounds, when are dimensions set?

I'm importing someone's createjs application into an application loader which imports each developers application javascript to a global canvas. The application is working standalone but when I load the javascript dynamically I'm getting some strange behavior surrounding the getBounds() function.
I have some text created like this:
dialogText = new createjs.Text(text, 'bold ' + (28 * scale) + 'px Calibri', '#FFFFFF');
Then later on I use dialogText.getBounds() which returns null.
I try console logging dialogText and I can see that it is set and there is a value _bounds which reads null.
At what point do these values get set when the element in drawn to the canvas?
Note: I'm already adding the text to a createjs.Container() which has its bounds set before I run getBounds().
For a quick reference, I pasted EaselJS's update regarding getBounds():
(This dates back from "August 21, 2013", not sure if this is still necessary nowadays, but using setBounds(x, y, w, h) helped me with Shapes today [in 2017] actually!)
Source: http://blog.createjs.com/update-width-height-in-easeljs/
The _bounds property reflects a value that is manually set on the DisplayObject - which is helpful if you know the bounds of something that can't calculate it (like a Shape). It will always be null, unless you set it directly.
I tested your code, and it seems fine. Are you sure the scale or text values are not null? Maybe hard-code them to see if it works.
Do you have a sample somewhere? I noticed in the GitHub issue you posted that you mentioned it worked fine without RequireJS (though you don't mention that here). I would definitely ensure that the values are being set properly.
Here is the fiddle, as well as a simpler one with no EaselJS stage. Note that I have Calibri installed on my machine, so you might get different results if you are loading it in.
Sample code:
var dialogText = new createjs.Text("This is some text", 'bold ' + (28 * 1.5) + 'px Calibrix', '#FFFFFF');
console.log(">>",dialogText.getBounds());

Can I define a text property as rich text?

VS 2013, VB, EF6
I am creating an object that will keep user input in one of its properties. I would like that user input to be stored as rich text. What's involved to make that stored text be rich text format? So,
Public Property Text as <what?>
I thought I would post what was my answer for others who might ask the question the same way I did. I begin by stating that my question was poorly formed because I didn't understand I'm not really storing RTF, I'm storing WYSIWYG text with html tags. But I think the question as phrased is useful because that's how many people think until they are taught by others.
Ultimately this process opens a serious XSS vector, but first we have to at least collect the WYSIWYG text.
First step: using a script-based editor capture the text with html tags. I used CKEditor which is easy to download on NuGet. It comes in 3 flavors: basic, standard and full. Another popular one seems to be TinyMCE also available through NuGet.
CKEditor must be 'wired in' to replace the existing input element. I replaced #html.editorfor with a < textarea > directly as follows. Model.UserPost.Body is the property into which I want to place the WYSIWYG text. The Raw helper is required so the output is NOT encoded allowing us to see our WYSIWYG text.
<textarea name="model.UserPost.Body" id="model_UserPost_Body" class="form-control text-box multi-line">
#Html.Raw(Model.UserPost.Body)
</textarea>
CKEditor is 'wired in' using a script element to replace the < textarea > element.
#Section Scripts
<script src="~/scripts/ckeditor/ckeditor.js"></script>
<script>
CKEDITOR.replace('model.UserPost.Body');
</script>
End Section
The script above can be added to all pages via _layout.vbhtml, or just the target page via a #Section Scripts section as shown above, which is often recommended and what I did, but that may also require adding to the standard _Layout the following in the < head > section such as follows.
#RenderSection("Styles", False)
In the controller POST method for the view the following code is needed to capture the WYSIWYG text otherwise the default filter will raise an exception when it detects anything that looks like an html tag.
Dim rawBody = Request.Unvalidated.Form("model.UserPost.Body")
userPost.Body = rawBody
There are some possible gotcha's; The 'body' property has to be removed from the Include:= list of the < Bind > element in the method paramter list if < Bind > is being used. Also, although not directly related to this solution, you can't have a Data Annotation like < Required() > on this property in the model because background checking won't be able to confirm that condition so the ModelState.IsValid flag won't ever go true.
Second step: before saving the input it MUST be checked for XSS. Microsoft has a nice video explaining basic XSS that I recommend viewing; it's only 11 minutes.
Mikesdotnetting has a nice explaination for dealing with XSS and shows a whitelisting algorithm toward the bottom of this page. The following code is based on his work.
To create a white listing approach, the HTML Agility Pack is useful to catalogue the HTML nodes for review. This is easily loaded from Nu Get as well. This is the code I used in the POST method to invoke the white list methods (Yes, it could be more compact, but this is easier to read for us novices):
Dim tempDoc = New HtmlDocument()
tempDoc.LoadHtml(rawBody)
RemoveNodes(tempDoc.DocumentNode, allowedTags)
userPost.Body = tempDoc.DocumentNode.OuterHtml
The allowed tags are what you will allow, which means everything else is rejected, hence whitelisting. This is just a sample list:
Dim allowedTags As New List(Of String)() From {"p", "em", "s", "ol", "ul", "li", "h1", "h2", "h3", "h4", "h5", "h6", "strong"}
These are the methods based on Mikesdotnetting page:
Private Sub RemoveNodes(ByVal node As HtmlNode, allowedTags As List(Of String))
If (node.NodeType = HtmlNodeType.Element) Then
If Not allowedTags.Contains(node.Name) Then
node.ParentNode.RemoveChild(node)
Exit Sub
End If
End If
If (node.HasChildNodes) Then
RemoveChildren(node, allowedTags)
End If
End Sub
Private Sub RemoveChildren(ByVal parent As HtmlNode, allowedTags As List(Of String))
For i = parent.ChildNodes.Count() - 1 To 0 Step -1
RemoveNodes(parent.ChildNodes(i), allowedTags)
Next
End Sub
So basically, (1) CKEditor captures user input with html tags that looks nice, (2) the raw input is specially requested in the Controller POST method and then (3) cleaned using a white list. After that it can be output directly to the page using #Html.Raw() because it can be trusted.
That's it. I've not really posted solutions like this before, so if I've missed something let me know and I'll correct or add it.
Rich Text is stored in the Rich Text Format.
The Rich Text Format specifications can be found here:
http://www.microsoft.com/en-us/download/details.aspx?id=10725
It is just an ordinary string. You can extract the string from a RichTextBox using the SaveFile function:
Private Function GetRTF(ByRef Box As RichTextBox) As String
Using ms As New IO.MemoryStream
Box.SaveFile(ms, RichTextBoxStreamType.RichText)
Return System.Text.Encoding.ASCII.GetString(ms.ToArray)
End Using
End Function
You can load text in the Rich Text Format into a RichTextBox using the LoadFile method of the RichTextBox. The text needs to be in the correct format:
Dim rtf As String = "{\rtf1 {\colortbl;\red0\green0\blue255;\red255\green0\blue0;}Guten Tag!\line{\i Dies} ist ein\line formatierter {\b Text}.\line Das {\cf1 Ende}.}"
Using ms As New IO.MemoryStream(System.Text.Encoding.ASCII.GetBytes(rtf))
RichTextBox1.LoadFile(ms, RichTextBoxStreamType.RichText)
End Using
Ordinary controls usually will not interpret this format in their text property.

trac: modification roadmap thru style.css doesn't work

I'd like to add new group on the trac roadmap progress bar. To do this I've modified trac.ini file with:
# Definition of an 'rejected' group:
rejected = rejected
rejected.order = 2
rejected.css_class = my
rejected.label = rejected
where I've associated to css_class atribute value my.
Next I've created style.css file with one line only:
table.progress td.my { background: blue; }
The file style.css is read however the colour is not applied.
When I change back to the default one i.e.
rejected.css_class = new
the progress bar is updated and displaying yellow colour as expected.
However, it not displaying when I use
rejected.css_class = my
Any ides why?
First, for reference, the authoritative documentation on the subject is in trac.edgewall.org's wiki.
Now, did you try with other color expressions, like the common hex values, i.e. #BAE0BA (green Trac default for closed)? You could even try to set the full range of values for the background key like none repeat scroll 0 0 #BAE0BA.
Remember that CSS styles will override each other depending on the order in which they are encountered. The page may be loading your custom style correctly, but if another stylesheet is loaded after your style.css and that stylesheet includes any styles that conflict with yours, then the later stylesheet will override yours. Double-check that your custom stylesheet is being included and isn't being silently overridden by another stylesheet (I find the Firebug plugin for Firefox to be helpful in tracking down these sorts of issues).

Fixed text when scrolling

My program displays an ABAP list, I'm trying to show a header (some lines of text, nothing fancy) fixed when scrolling down in a report.
Is there some kind of tag or declaration that I have to use?
In SE38 you can define list heading with 'GOTO -> Text Elements -> List Headings`.
You can define a list header, and titles for your list (Columns heading).
One advantage: With GOTO -> Translations you can define different texts in different languages.
Another way to get this maintenance screen:
From your list, you can choose: System -> List -> List Header.
Another way:
You can use top-of-page to define your header text inside your report code.
top-of-page.
write 'My header'.
You can use the TOP OF PAGE event to write something that will stick at the top of the page while scrolling. You can find more info here.
You can also use the list headers from Text Elements menu. More info here.
Best regards,
Sergiu
One way is directly using top-of-page in your code.
Other way is calling reuse_alv_grid_display or reuse_alv_list_display (depending on your output type) and declaring "top-of-page" in the I_CALLBACK_TOP_OF_PAGE line. Then create a sub-routine with the same name as your "top-of-page". In that you can write
wa_list-typ = 'H'.
wa_list-info = ''.
APPEND wa_list to it_list.
clear wa_list.
OR
wa_list-typ = 'A'.
wa_list-info = 'Report Header'.
APPEND wa_list to it_list.
clear wa_list.
OR
wa_list-typ = 'S'.
wa_list-info = 'Report Header'.
APPEND wa_list to it_list.
clear wa_list.
depending on what you want (header, action or selection).
Finally you can use REUSE_ALV_COMMENTARY_WRITE function and call the table(in this example it_list).
Hope it helped.