OS X, Why is Help NSMenuItem in NSMenu disabled after registering the Help Book? - osx-lion

OS X, Why is Help NSMenuItem in mainMenu disabled after registering the Help Book
Tags: OSX, HelpBook, NSMenuItem, AHRegisterHelpBookWithURL
The HelpBook is unusable because the Help menu is disabled.
When the Help Menu is selected, the Help sub menu appears this way:
Spotlight Search searchBar here - BLUE
HungryMe Help - GREYED OUT
The MainWindow.nib contains the Menu. The Help Menu Item is enabled in Xcode.
THE HELP BOOK
The HelpBook Info.plist follows;
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en_US</string>
<key>CFBundleIdentifier</key>
<string>com.DrummingGrouse.HungryMe.help</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>HungryMe</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>hbwr</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>HPDBookAccessPath</key>
<string></string>
<key>HPDBookIconPath</key>
<string>shrd/EyeOnly.png</string>
<key>HPDBookIndexPath</key>
<string></string>
<key>HPDBookKBProduct</key>
<string></string>
<key>HPDBookKBURL</key>
<string></string>
<key>HPDBookRemoteURL</key>
<string></string>
<key>HPDBookTitle</key>
<string>HungryMe Help</string>
<key>HPDBookType</key>
<string>3</string>
</dict>
</plist>
The test Title Page, HungryMe.html, follows:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" AppleTitle="com.DrummingGrouse.HungryMe.help" />
<title>HungryMe</title>
</head>
<body>
<a name="hungryme_page"></a>
<div class="container">
<p>This is some text. <img src="../shrd/EyeOnly.png" align="middle"> This is some more text.</p>
<div class="content">
<h1>Getting Started - Cooking with HungryMe</h1>
<p>HungryMe has a main window with Category elements on the left and Recipe elements on the right.</p>
<p>The display of a recipe's details is done as follows:</p>
<p> 1. Select a recipe Category in the left table of the main window. Select "Browse All" if you wish to have all recipes to be listed.</p>
<p>2. Double click the desired recipe and a separate window will appear displaying the details for the selected recipe. Multiple recipes can be displayed simultaneously.</p>
<!-- end .content --></div>
<!-- end .container --></div>
</body>
</html>
The App's Info.plist has:
CFBundleHelpBookFolder HungryMe.help
CFBundleHelpBookName com.DrummingGrouse.HungryMe.help
The Apple Help Programming Guide has:
The CFBundleHelpBookName key identifies the help book. The value associated with this key
should be a string specifying the help book title, as defined by the AppleTitle tag in the
title page of the book. For example, here is how you would enter the title
of the SurfWriter Help book:
<key>CFBundleHelpBookName</key>
<string>com.mycompany.surfwriter.help</string>
The Help Book bundle, HungryMe.help, is added to the Xcode project's Resources/ folder.
The Bundle is structured this way:
HungryMe.help/
Contents/
Info.plist
Resources/
shrd/ <shared artwork>
English.lproj/
HungryMe.html <title page>
pgs/ <the rest of the content pages>
gfx/ <localized artwork>
sty/ <style sheets, generated list template>
scrpt/ <scripts>
The Help Menu Item that would display the HelpBook is greyed out whether or not the
Help Book is registered using AHRegisterHelpBookWithURL.
If AHRegisterHelpBookWithURL is used, the err returned in code below is Zero.
OSStatus RegisterMyHelpBook(void)
{
CFBundleRef myApplicationBundle;
CFURLRef myBundleURL;
OSStatus err = noErr;
myApplicationBundle = NULL;
myBundleURL = NULL;
myApplicationBundle = CFBundleGetMainBundle();// 1
if (myApplicationBundle == NULL) {err = fnfErr; return err;}
myBundleURL = CFBundleCopyBundleURL(myApplicationBundle);// 2
if (myBundleURL == NULL) {err = fnfErr; return err;}
if (err == noErr){
err = AHRegisterHelpBookWithURL(myBundleURL);// 3
}
return err;
}
The following code, executed at launch time,
NSMenu *mainMenu = [[NSApplication sharedApplication] mainMenu];
NSMenuItem *menuItemHelp = [mainMenu itemWithTitle:#"Help"];
NSMenu *menuHelp = [menuItemHelp submenu];
NSMenuItem *menuItemHelpHungryMe = [menuHelp itemAtIndex:0];
DLog(#"menuItemHelpHungryMe=%#",menuItemHelpHungryMe);
DLog(#"menuHelp=%#",menuHelp);
Produces the following output.
2012-11-16 11:30:03.167 HungryMe[62153:303] -[AppDelegate applicationDidFinishLaunching:]
menuItemHelpHungryMe=<NSMenuItem: 0x1b6e3c0 HungryMe Help>
2012-11-16 11:30:03.168 HungryMe[62153:303] -[AppDelegate applicationDidFinishLaunching:]
menuHelp=<NSMenu: 0x1b6e3a0>
Title: Help
Supermenu: 0x1b6c8e0 (MainMenu), autoenable: YES
Items: (
"<NSMenuItem: 0x1b6e3c0 HungryMe Help>"
)
I observed that menuHelp above has only one item.
The Help Menu Item titled "HungryMe Help" is greyed out regardless of whether or not the Help Menu
is enabled in the NIB .

I deleted the Help Menu Item from the NIB file and then re-added it in Xcode. The Help Menu then became enabled for reasons I don't understand. The following code made the Help Viewer appear:
- (IBAction) showHelp:(id)sender {
int status = MyGotoHelpPage();
DLog(#"status for HelpBook load is %d",status);
}
OSStatus MyGotoHelpPage (void)
{
CFBundleRef myApplicationBundle = NULL;
CFStringRef myBookName = NULL;
OSStatus err = noErr;
myApplicationBundle = CFBundleGetMainBundle();// 1
//if (myApplicationBundle == NULL) {err = fnfErr; goto bail;}// 2
myBookName =
CFBundleGetValueForInfoDictionaryKey( myApplicationBundle, CFSTR("CFBundleHelpBookName"));
if (myBookName == NULL) {err = fnfErr; return err;}
if (CFGetTypeID(myBookName) != CFStringGetTypeID()) {// 4
err = paramErr;
}
err = AHGotoPage (myBookName, NULL,NULL);// load title page
return err;
}
The Help Viewer appears with a message: "The selected topic is currently unavailable."
This is progress.

Related

How to adress a button on a DevExpress Popup edit form

I have 2 buttons on my Pop-up Edit form. I want to play with visibility of them - so that only 1 button is shown at a time.
I have done it many times on usual forms (not pop-up) and it worked.
it was just as easy as :
ID_NameOfMyButton.Visible = false;
However when i address the button on my pop-up form it doesnt find it:
"CS0103: The name 'ID_NameOfMyButton' does not exist in the current context"
Tried also this:
grid.EditForm.getElementById("ID_NameOfMyButton").style.display = "none";
-also get error:
"CS1061: 'DevExpress.Web.ASPxGridView' does not contain a definition for 'EditForm' and no extension method 'EditForm' accepting a first argument of type 'DevExpress.Web.ASPxGridView' could be found (are you missing a using directive or an assembly reference?)"
i am lost.... please anybody can advise me anything?
here is my code reflecting the location of the button on my Pop-up edit form:
<Templates>
<EditForm >
//// my 2 buttons in the header of the Popup Form /////
<dx:ASPxButton ID="ID_NameOfMyButton" runat="server" Text="Publish" Width="100px"
OnClick="MyButton_OnClick" Visible="True"> </dx:ASPxButton>
<dx:ASPxButton ID="ID_NameOfMyButton2" runat="server" Text="Withdraw" Width="100px"
OnClick="MyButton2_OnClick" Visible="True"> </dx:ASPxButton>
//// 2 Tabs of the Popup Form: /////
<dx:ASPxPageControl runat="server" ID="pageControl_1" Width="100%">
<TabPages>
<dx:TabPage Text="Part 1" Visible="true">
<ContentCollection>
<dx:ContentControl runat="server">
//// here are my controls on Tab 1 of the Popup Form /////
</dx:ContentControl>
</ContentCollection>
</dx:TabPage>
<dx:TabPage Text="Part 2" Visible="true">
<ContentCollection>
<dx:ContentControl runat="server">
//// here are my controls on Tab 2 of the Popup Form ////
</dx:ContentControl>
</ContentCollection>
</dx:TabPage>
</TabPages>
</dx:ASPxPageControl>
</EditForm>
</Templates>

After a user is redirected to a page in my quick app from a card, how can my app directly take them back to the card?

In my Huawei quick app, when I have opened page A in a quick app, and then taps a card or other media to proceed to page B, tapping the back button in the upper left corner redirects them to page A first. But it is expected to be redirected directly to the card after tapping the back button. How does it occur?
The problem is caused by the default startup mode standard, which the page adopts. In this mode, every new page started by the user will be cached in the page stack, so a page that is opened for multiple times will be cached repeatedly. As a result, the user can only close one page at a time. To solve this problem, you are advised to set the startup mode of page B to clearTask using the dynamic declaration when the user taps a card to go to a quick app. In this case, page A closes when page B opens, meaning only page B exists in the page stack. When the user taps the back button, they will directly exit the quick app.
You can use the following sample code for redirecting a user from a card to a quick app using deep links:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Quick app test</title>
</head>
<body>
Open through hwfastapp.
<br>
<br>
Open through hap.
</body>
</html>
Target page of the quick app to which the card is redirected (There is always only one page based on the number of current page stacks.)
<template>
<div class="container">
<text>___PARAM_LAUNCH_FLAG___=</text>
<text>{{taskflag}}</text>
<text>Number of current page stacks.</text>
<text>{{length}}</text>
</div>
</template>
<style>
.container {
flex-direction: column;
align-content: center;
align-items: center;
justify-content: center;
}
text {
margin-bottom: 50px;
}
</style>
<script>
import router from '#system.router';
export default {
data: {
// The default is the local app internal image
photoUri: '/Common/logo.png',
taskflag:'',
PARAM_LAUNCH_FLAG:'',
length:''
},
onInit() {
this.$page.setTitleBar({ text: 'deepLink' })
var that=this;
that.taskflag=this.PARAM_LAUNCH_FLAG;
// Call the getPages method.
let pages = router.getPages()
// The obtained value is a JSON array. Therefore, the value cannot be displayed directly. You can use the following method to display the value:
console.log("tag", this.printJSONArray(router.getPages()));
that.length= router.getLength();
console.log("pages' length = "+that.length);
},
printJSONArray(array) {
let result = ""
const suffix = ", "
Array.isArray(array) && array.forEach((element, index) => {
result = result + JSON.stringify(element) + (index === array.length-1 ? "" : ", ")
})
return result
}
}
</script>
The page launch mode can be configured in two modes: static declaration in the manifest file and dynamic parameter pass declaration, of which the latter is recommended. The static declaration mode applies to scenarios with fixed settings which cannot be flexibly adjusted.
For more details,you can refer to this Docs and deep link documentation.

flutter_inappwebview - no html-video

I'm using flutter_inappwebview in a Flutter-app to display local html (from assets). (I know: not ideal. I would prefer to program the whole thing in Dart, but that is not an option right now). It works great..apart from one thing. Can't get the video in html to work.
Problem
The video works fine when I open the html in any browser (directly from assets folder). So the html should be ok. All other html works fine in the app. So files and pubspec-import should be ok. In the app, the page shows a video-player, but no content on both iOS-sim and iOS device. In the Android-sim it works.
Code
I'm using:
flutter_inappwebview: ^3.2.0
sdk: ">=2.7.0 <3.0.0"
I use the inappview like this, after the imports. Server is already running (flutter reports: flutter: Server running on http://localhost:8080)
InAppWebViewController webViewController;
InAppWebView webView;
class OfflineViewer extends StatefulWidget {
#override
_ViewerState createState() => _ViewerState();
}
class _ViewerState extends State<OfflineViewer> {
#override
Widget build(BuildContext context) {
return InAppWebView(
initialUrl: "http://localhost:8080/assets/source/intro.html",
onWebViewCreated: (InAppWebViewController controller) {
webViewController = controller;
},
);
}
}
The video-tag in the loaded intro.html is:
<video height="600" controls>
<source src="intro.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
Things I tried:
Different video-formats (webm, ogg) > no difference.
Loading an online video into the html instead of local > works. Video loads and plays.
Different methods of embedding video (video-tag, iframe, video.js) > no difference.
Setting InAppWebViewOptions, like:
cacheEnabled: true,
javaScriptCanOpenWindowsAutomatically: true,
useOnLoadResource: true,
javaScriptEnabled: true,
mediaPlaybackRequiresUserGesture: false,
What makes this hard to solve (for me) is that I can't catch the html-errors once it's embedded in the app, whereas the standalone html doesn't give an error. Any ideas on how to solve or even troubleshoot this are highly appreciated.
Greetings,
Mark
Got it sorted. Just posting this in case anyone else has the same problem. Cause of the problem was: the HTTPServer-class creates a blob-server. It returns a video in one chunk (status 200). iOS doesn't accept that and wants status 206 (parts).
Based on https://stackoverflow.com/a/54004600/6007404 I created a JS-file which converts all the video's in the document. Just add it to any html-file with video:
if(navigator.platform && /iPad|iPhone|iPod|Mac/.test(navigator.platform)){
window.addEventListener("load", streamVideoBlobs);
}
function streamVideoBlobs(){
var allVideos = document.getElementsByTagName("video");
for(var i = 0, max = allVideos.length; i < max; i++)
{
iOSVideoConvert(allVideos[i]);
}
}
async function iOSVideoConvert(video){
let blob = await fetch(video.src).then(r => r.blob());
var videoUrl=createObjectURL(blob);
video.src = videoUrl;
}
function createObjectURL(object) {
return (window.URL) ? window.URL.createObjectURL(object) : window.webkitURL.createObjectURL(object);
}
Apart from that, you'll have to set
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
in your info.plist. (You can also use NSAllowsArbitraryLoads, but that's more allowance then needed and Apple might flag it down when submitting the app).
Not sure but you may be missing the NSAppTransportSecurity setting in your Info.plist. This allows you to load unsafe content which http://localhost:8080 is.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
https://stackoverflow.com/a/61999847/15258962
this make me realized ,the problem is not the WebView, its the LocalServer side.
I change the localServer logic to serve basic64 encoded video source when a video tag appeared ,and its worked for me

Line comment format in Visual Studio Code

Is there a way to remove the space inserted after the line comment character(s), and to start the comment at the start of the line in Visual Studio Code? (thus being able to use the commented-out-code comment style)
Before:
void fn() {
code();
}
After (applying Toggle Line Comment command):
void fn() {
// code();
}
Desired:
void fn() {
// code();
}
I would prefer either a global switch or a per language configuration.
E.g. in Sublime Text 3 you can achieve this by copying the Comments.tmPreferences file from the package of a given language to into the user packages, and changing the value of the TM_COMMENT_START and TM_COMMENT_DISABLE_INDENT settings shell variables. E.g. the original Groovy.sublime-package\Comments.tmPreferences:
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>name</key>
<string>Comments</string>
<key>scope</key>
<string>source.groovy</string>
<key>settings</key>
<dict>
<key>shellVariables</key>
<array>
<dict>
<key>name</key>
<string>TM_COMMENT_START</string>
<key>value</key>
<string>// </string>
</dict>
...
On the other hand in Visual Studio Code in the language-configuration.json file of a given language the comments.lineComment values already lack the extra space, so they are inserted somewhere else. E.g. the original groovy\language-configuration.json:
{
"comments": {
"lineComment": "//",
"blockComment": [ "/*", "*/" ]
},
...

Embed google-plus in GWT

I am trying to embed Google-Plus into my GWT Application. I would like it to be embedded into a HorizontalPanel. I did read +1button developers google. I didn't find any post about this particular problem in stackoverflow. My problem might be that I don't understand how to include the js into a GUI component. I would appreciate an Example of how to add the Google+ code into a Panel.
Here is how to do it:
Documentation:
<!-- Place this tag in your head or just before your close body tag -->
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
<!-- Place this tag where you want the +1 button to render -->
<g:plusone></g:plusone>
in GWT:
private void drawPlusOne() {
String s = "<g:plusone href=\"http://urltoplusone.com\"></g:plusone>";
HTML h = new HTML(s);
somePanel.add(h);
// You can insert a script tag this way or via your .gwt.xml
Document doc = Document.get();
ScriptElement script = doc.createScriptElement();
script.setSrc("https://apis.google.com/js/plusone.js");
script.setType("text/javascript");
script.setLang("javascript");
doc.getBody().appendChild(script);
}
I've personally never embedded the +1 button in GWT, but the linked article seems pretty self explanatory.
In the section "A Simple Button", it indicates that the simplest way of implementing GooglePlus integration is to add this:
<script src="https://apis.google.com/js/plusone.js" />
<g:plusone></g:plusone>
First, the <script> tag should be included in your .gwt.xml file.
Then I'd implement the <g:plusone></g:plusone> like this:
public class GPlusOne extends SimplePanel {
public GPlusOne () {
super((Element)Document.get().createElement("g:plusone").cast());
}
}
(Note that this code is untested, but it's based on the simple concept that a SimplePanel can be extended to compile as any HTML element.)
Then you'd use the new GPlusOne element wherever you'd want the button to show.
I found a better way to do it:
Follow this example to have the button work on invocation on a normal html page (you can try one here http://jsfiddle.net/JQAdc/)
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script src="https://apis.google.com/js/plusone.js">
{"parsetags": "explicit"}
</script>
<script type="text/javascript">
function gPlusBtn(id, params) {
/* window.alert("searching for "+ id +" with params: "+ params) */
paramsObj = eval( '('+params+')' );
gapi.plusone.render(id, paramsObj );
}
// params is here just for a reference to simulate what will come from gwt
params = '{href:"http://1vu.fr", size:"tall"}';
</script>
</head>
<body>
taken from http://jsfiddle.net/JQAdc/
<div id="gplus" />
<button onclick="gPlusBtn('gplus', params)">show!</button>
</body>
</html>
Then you can call a native method to trigger the button display on Activity start (if you're using MVP).
protected native void plusOneButton(String id, String params) /*-{
$wnd.gPlusBtn(id, params);
}-*/;
You can have multiple buttons with different urls, that's why id is left as a parameter.
NOTE: for me the raw HTML works on localhost, but the GWT version. I have to deploy to the server to be able to see the results