I'm working on a Office add-in for PowerPoint. This is a modern 'add-in' for the Office store, not the old style add-in.
Is there a way to be notified when the active slide is changed?
My scenario is that I want to do something in my add-in code when the slide changes as a presentation is being given.
My app could be a content or task pane app at this stage.
There is no direct way to do this. The Office JS library does not have an event for slide transitions in PowerPoint.
However, there is a hacky way to do this which involves refreshing the web app on a periodic basis and using getSelectedDataAsync with the CoercionType of SlideRange. This gives you the full range of slides in the document and from that you can get the index of the current slide. You could store that index in a setting and check if it changes if it does you have your event.
Here is the basic code (refreshes every 1.5 seconds)
//Automatically refresh
window.setInterval(function () {
//get the current slide
Office.context.document.getSelectedDataAsync(Office.CoercionType.SlideRange, function (r) {
// null check
if (!r || !r.value || !r.value.slides) {
return;
}
//get current slides index
currentSlide = r.value.slides[0].index;
//get stored setting for current slide
var storedSlideIndex = Office.context.document.settings.get("CurrentSlide");
//check if current slide and stored setting are the same
if (currentSlide != storedSlideIndex) {
//the slide changed - do something
//update the stored setting for current slide
Office.context.document.settings.set("CurrentSlide", currentSlide);
Office.context.document.settings.saveAsync(function (asyncResult) { });
}
});
}, 1500);
Related
I'm working on a UWP app that hosts a WebView which runs in a separate process.
var webView = new Windows.UI.Xaml.Controls.WebView(WebViewExecutionMode.SeparateProcess)
This results in a behavior that if the WebView has the focus, the containing app can't regain the focus by itself by simply trying to focus on a UI element.
The app supports keyboard shortcuts which may result in different elements getting the focus, but it's not working correctly when the focus is captured by the WebView. The target element seems to be getting the focus but it seems as if the process itself is not activated (as the real focus resides in a different process I suppose...).
I'm currently trying to activate the app programmatically through protocol registration in an attempt to regain focus.
I added a declaration in the app manifest for a custom protocol mycustomprotocol coupled with the following activation overload
protected override void OnActivated(IActivatedEventArgs args)
{
if (eventArgs.Uri.Scheme == "mycustomprotocol")
{ }
}
And the following code to invoke the activation:
var result = await Windows.System.Launcher.LaunchUriAsync(new Uri("mycustomprotocol:"));
Seems to be working only on some computers, on others (not while debugging the app, only when executed unattached) instead of regaining focus the app's taskbar icon just flashes orange.
I've created a sample project showing the problem and the semi working solution here
Any insight on any of this would be great.
I can reproduce your issue. I found that when we switch the focus with the mouse, the focus can be transferred to the TextBlock. So you could solve this question through simulating mouse input.
Please use the following code to instead FocusTarget.Focus(FocusState.Programmatic).
As follows:
InputInjector inputInjector = InputInjector.TryCreate();
var infoDown = new InjectedInputMouseInfo();
// adjust your mouse position to the textbox through changing infoDown.DeltaX,infoDown.DeltaY
infoDown.DeltaX = 10; //change
infoDown.DeltaY = -150; //change
infoDown.MouseOptions = InjectedInputMouseOptions.LeftDown;
var infoUp = new InjectedInputMouseInfo();
infoUp.DeltaX = 0;
infoUp.DeltaY = 0;
infoUp.MouseOptions = InjectedInputMouseOptions.LeftUp;
inputInjector.InjectMouseInput(new[] { infoDown, infoUp });
Note: If you use the input injection APIs, you need to add inputInjectionBrokered Capabilitiy in your Package.appxmanifest.
But this Capabilitiy is a restricted Capabilitiy, you can’t publish this app in store, which can’t pass the verification.
I've been in discussions with a WebView software engineer. The problem is that the separate process still wants to own focus if you try to move the focus away from the webview. His solution is to ask the other process' web engine to give up focus with the following call:
_= webView.InvokeScriptAsync("eval", new string[] { "window.departFocus('up', { originLeft: 0, originTop: 0, originWidth: 0, originHeight: 0 });" });
You can call it before trying to change the focus to your target. I ran various tests and it works consistently.
I have a WebView that loads an URL (say login.salesforce.com) & asks the user to login to his instance.
Now, I want to get rid of the default login screen that it shows up & want to play around with the color of the login button.
Is it possible to change the color of a button inside a website that loads in UIWebView or WKWebView?
Absolutely Yes. For this you need to have little bit knowledge of html,css and java script.
Step 1. Prepare a java script as a string like below:
let changeHtmlbuttonScript = """
var property = document.getElementById(btn);
if (count == 0) {
property.style.backgroundColor = "#FFFFFF"
count = 1;
} else {
property.style.backgroundColor = "#7FFF00"
count = 0;
}
"""
Step 2: Evaluate java script on your current webview
self.webView.evaluateJavaScript(self.changeHtmlbuttonScript)
You can do it with UIWebView if you override the resource loading with a custom NSURLProtocol, and load your own CSS instead of theirs. "evaluateJavaScript" might work as well if you wait until the page is loaded somehow (see other reply).
Most likely what you ask violates the Salesforce's terms of service, so I wouldn't do it.
If they have a REST API for something that you try to achieve, then you can provide your own UI.
I have a Unity UI's input field and a text box. When I use Input.GetKeyDown (KeyCode.Return), it only works on the OS X and PC build and not on the iOS build. iOS keyboard's Return key does nothing. I have tried the events, too, but it doesn't work even then.
Somebody please tell me the solution to this problem if there is any?
While I can't think of a way to harness the return key directly on iOS, there is a way to do so with the "Submit" key using the TouchScreenKeyboard class in Unity
Specifically, it has a variable TouchScreenKeyboard.done to indicate whether the user has pressed the "Submit" (or equivalent) button on any mobile device (iOS, Android WP)
You can also check the wasCanceled variable to see whether the user canceled the input.
Example
public class TouchKeyboardExample : Monobehaviour {
private TouchScreenKeyboard touchScreenKeyboard;
private string inputText = string.Empty;
void Start () {
touchScreenKeyboard = TouchScreenKeyboard.Open(inputText, TouchScreenKeyboardType.Default);
}
void Update () {
if(touchScreenKeyboard == null)
return;
inputText = touchScreenKeyboard.text;
if(touchScreenKeyboard.done)
Debug.Log("User typed in "+inputText);
if(touchScreenKeyboard.wasCanceled)
Debug.Log("User canceled input");
}
}
I've never tried this on IOS, so I'll just guess here.
Are you using the new Unity UI that was introduced in Unity4.6 / Unity5? If so, you might want to use the UI EventSystem, which you probably have somewhere in scene already (it is being added automatically when you add new Canvas object). If you don't have it in scene, add it via menu GameObject->UI->Event System.
In the EventSystem game object, there's a component called Standalone Input Module, where you can then define Submit Button property - which is mapped to Unity's Input Manager (Edit->Project Settings->Input).
On the individual UI element (i.e. InputField in your case), you can now add EventTrigger component, which can listen to Submit event and call a custom method, even pass it some data (e.g. itself, as InputField parameter of the method).
You can also listen to many more events this way (select, hover, drag, etc).
this works fine for me (PC/Mobile), try it out
this.yourInput.onSubmit.AddListener(delegate {
if (this.yourInput.text.Length > 0)
// do something here after enter (PC) or done (mobile)
});
I don't know if the title say it properly but..
I have a cordova 1.9 app with push notifications using the PushNotification Plugin and UrbanAirship. Everything works fine.
Now I'd like to open a particular page of my app when I lauch/resume my app from a notification.
Is that possible using Javascript ?
I'm totally lost when reading objective-c.
Notifications causes problem to understand JSON structure.
It is not:
if(notifications.length > 0){
But:
if(notifications.notifications.length > 0){
Array is on: notifications.notifications[] structure.
I am not sure how you are trying to load the page but the simplest way would be to call for the pending notifications as it is in javascript and then use window.location.href to load the require page.
I am using this procedure to perform certain task when I have pending notification at application start:
function registerAirship() {
console.log("ready to register for airship");
window.plugins.pushNotification.registerDevice({alert:true, badge:true, sound:true},function(status) {
if (status.deviceToken) {
window.token = status.deviceToken;
if (status) {
registerUAPush(token, "https://go.urbanairship.com/", key, key1, function(){
window.plugins.pushNotification.getPendingNotifications(function(notifications) {
if(notifications.length > 0){
var note = notifications[0];
if(note.applicationLaunchNotification == "1"){
// use the note.aps and redirect to required page
}
}
});
});
} else {
alert("Registration Error: " + status);
}
}
});
}
I was in your position a few days ago. I decided it was easiest to hack objective-c.
So.
1) I found the function that handled my push notification (AppDelegate.m) and called a js function after objective-c had launched execution for handling the notification. After that line, I did this:
[viewController.webView stringByEvaluatingJavaScriptFromString:#"opensometab()"];
2) In the root of my web app application I added this to the pushnotification.js file (you should be able to put it anywhere but I wanted it here).
** My JS function was to activate a tab within the Viewport so yours may be different.
function opensometab(){
var tabPanel = Ext.Viewport.down('tabpanelname');
tabPanel.setActiveItem(3); //index number 3
}
Here's the issue:
I have a hook in IE that reacts on WebBrowser.OnNavigateComplete2 event to parse the content of the document for some precise info.
That document contains frames, so I look into the HTMLDocument.frames. For each one, I look into the document.body.outerHTML property to check for the content.
Problem is, the string I'm looking for never shows there, whereas it is displayed in the finale page. So, am I looking in the wrong place? If it is displayed when the page is fully loaded, then it's downloaded at some point, right? But in which object should I look ?
BTW, I Don't know if that is of any importance, but the page I'm searching into comes from a ASP.NET application.
public void OnNavigateComplete2(object pDisp, ref object url)
{
document = (HTMLDocument)webBrowser.Document;
mshtml.FramesCollection frames = document.frames;
for (int i = 0; i < frames.length; i++)
{
object refIdx = i;
IHTMLWindow2 frame = (IHTMLWindow2)frames.item(ref refIdx);
string frameContent = frame.document.body.outerHTML;
}
}
Thank your for your help.
#rams
This event is launched many times for each page, so I figured it was each time a framed is loaded, even if i don't get to catch the one I'm looking for. If not, what would be the event to catch the frames content?
What I want to do is detect some precise info on a precise frame, then save it. later, a web page is loaded triggered by some user action, where I need the info I got from parsing the frame.
Do you know the name/id of the frame you are looking for content? If so, in your navigateComplete2 event, can you get a reference to the frame like
iFrame frm = document.frames(<your frame id>);
int readyState=0;
while(frm.readystate !=4){
// do nothing. be careful to not create an endless loop
}
if(frm.readyState==4){
// get your content now
}
HTH
Are you using some kind of threading? Running the browser in a separate thread really messes up things. Try to execute it in an STAThread and check if you get the correct result.
The reason your string does not show is because of the frame. The web browser control fires the document navigate complete event after it has loaded the main document. At this point, the frames haven't yet requested their sources. After the document is parsed by the web browser control, requests for the frame sources are issues and downloaded.
Can you please describe what you are trying to accomplish?