How to get selected image - office-addins

I have a Word 2016 Add-in that creates images using graphviz and stores the corresponding dot code in the altdescription of the image.
I can select the image and load the dot code back to the editor in the add-in. But this only works in my current implementation for inlinePictures.
function getDataFromSelection() {
Word.run(function (context) {
var range = context.document.getSelection();
var paragraphs = range.paragraphs;
context.load(paragraphs);
return context.sync().then(function () {
var pictures = paragraphs.items[0].inlinePictures;
context.load(pictures);
return context.sync().then(function () {
var picture = pictures.items[0];
editor.getSession().getDocument().setValue(picture.altTextDescription);
});
});
})
}
How can I obtain the selected picture if it is free floating in the document?
The Goal of the add in is to create and edit already created graphs using dot. But the editing part is currently the problem.

great question. as you properly deduced the inlinePictures collection only includes, excuse the redundance, inlinePicture images. Floating images are not included in that collection, something we will add in future iterations of the API.
There is a workaround that I suggest you to do to check if there are floating images in the selection.
you can get and analyze the OOXML from the selection and find out of there are any floating images in the selection.
this code shows how to get the OOXML from the selection:
// Run a batch operation against the Word object model.
Word.run(function (context) {
// Queue a command to get the current selection and then
// create a proxy range object with the results.
var range = context.document.getSelection();
// Queue a commmand to get the OOXML of the current selection.
var ooxml = range.getOoxml();
// Synchronize the document state by executing the queued-up commands,
// and return a promise to indicate task completion.
return context.sync().then(function () {
console.log('The OOXML read from the document was: ' + ooxml.value);
});
}).catch(function (error) {
console.log('Error: ' + JSON.stringify(error));
if (error instanceof OfficeExtension.Error) {
console.log('Debug info: ' + JSON.stringify(error.debugInfo));
}
});
Once you have the OOXML you can actually get (with string search or XML editors) what's within in the of if look for something like this element, you will know there is a floating image there. you can also get the alt text and description as you can see. if so needed you can use that string replace the alt text properties you need and can write back the OOXML to update that floating image. its a bit painful but doable and hopefully we can ship the floating images collection soon! thanks and happy coding!!!
<w:drawing>
<wp:anchor allowOverlap="1" layoutInCell="1" locked="0" behindDoc="0" relativeHeight="251659264" simplePos="1" distR="114300" distL="114300" distB="0" distT="0">
<wp:simplePos y="3710305" x="1729105"/>
<wp:positionH relativeFrom="margin">
<wp:posOffset>1729105</wp:posOffset>
</wp:positionH>
<wp:positionV relativeFrom="margin">
<wp:posOffset>3710305</wp:posOffset>
</wp:positionV>
<wp:extent cx="2847975" cy="2133600"/>
<wp:effectExtent r="9525" b="0" t="0" l="0"/>
<wp:wrapSquare wrapText="bothSides"/>
<wp:docPr title="alt text sample" name="Picture 1" descr="alt test description!!" id="1"/>
<wp:cNvGraphicFramePr>
<a:graphicFrameLocks noChangeAspect="1" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"/>
</wp:cNvGraphicFramePr>
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr name="stratus2.jpg" id="1"/>
<pic:cNvPicPr/>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="rId4">
<a:extLst>
<a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
<a14:useLocalDpi val="0" xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main"/>
</a:ext>
</a:extLst>
</a:blip>
<a:stretch>
<a:fillRect/>
</a:stretch>
</pic:blipFill>
<pic:spPr>
<a:xfrm>
<a:off y="0" x="0"/>
<a:ext cx="2847975" cy="2133600"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
</pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:anchor>
</w:drawing>

Related

Create drop down menu from external JSON in Javascript

I am using an external JSON to retrieve the name of the volcano and put all names into a drop down menu to be selected and shown on my map. Currently, I have no errors on my webpage console but I am not getting any names inside the dropdown. I am very new to coding and I am blank on what is wrong. Any advice?
'''
//Call JSON for map latitude and longitude, showing volcaones locations
// with last eruption in a hover feature
var data = {};
d3.json("./Graphs/Vol_cleaned.json").then(function (data) {
console.log(data);
// Once we get a response, send the data.features object to the createFeatures function
makeMap(data);
makeDrop();
});
//MAKE DROP DOWN MENU TO SELECT VOLCANO NAME
function makeDrop(){
for (var i = 0; i < data.Volcano_Name; i++){
let name = data.Volcano_Name[i];
d3.select("#arr").append("option").text(name);
}
}
function optionChanged() {
makeMap(data);
}
function makeMap(data) {
'''
JSON
I have tried several ways to call the data, I don't think I will be able to describe them correctly being that I am new to the coding world. My current code in the picture provide is working with no errors but nothing is populated in the drop down.

SwiftUI FireStore - Get Field from Document and display as Text()

I'm very new to SwiftUI so bare with me - it's for a project.
I have stored user's details into my Firestore database which looks like this:
image of database
I want to take the name from the database and display it in a Text("Hello" [name])
I have been able to fetch the name from the database and append it into an array. This function is run when the 'Log in' button is clicked.
The code is as follows:
func getData(){
let docRef = db.collection(FStore.collectionName).document(userID)
docRef.getDocument { (document, error) in
if let document = document, document.exists {
if let fetchedName = document.get("name") as? String {
userArray.append(fetchedName)
print(userArray)
}
}
}
}
When printing userArray, the correct name does print.
However I am struggling to display the name outside of the console and on my Text UI field. When I attempt the code below, it gives me an index out of range error.
Text("Hello: \(userArray[0])")
Any help is appreciated / any other methods of retrieving field data from a specific document.
Thanks to #Steve M , it ended up being a kind of silly mistake.
He was right, the display was attempting to read the array before the array had even been populated.
As described in my comments, I called the getData() function then ran code to display the next screen. I wrapped the "display next screen code" in a DispatchQueue to delay the next screen being displayed
DispatchQueue.main.asyncAfter(deadline# .now() + 1){
nextView = true
}
This ran a 1-second delay before displaying the next screen and successfully displayed the name from the database.

Check if the new element has been added to the table in Protractor

In my Angular app I have a table (ng-grid to be precise) and I have a procedure to add the a new element to it. I spare you the details, but the procedure is multi-step, involves talking to the server and results in a new item in the ng-grid table. I know the name of the new item and I want to check in my protractor test that this item has indeed be added. This is how I'm trying to do it:
var nameTestItem="mySuperItem";
//... some actions to add the element, and going back to the page with the table
browser.get('#/resTable');
//checking if there is new item with this title
var element_added=false;
//picking the cell of the table with css selector and searching for the text
element.all(by.css('div.ui-grid-cell-contents')).then(function(elements) {
_.forEach(elements, function(el) {
el.getText().then(function(text){
console.log(text);
element_added= element_added || (nameTestItem==text);
});
});
});
browser.sleep(1000);
browser.pause();
expect(element_added).toBeTruthy();
apparently my problem is that I'm dealing with a lot of promises. How would you tackle this problem? I really don't want to rely on count() because I don't want collisions when several people execute the test.
I'd use filter() instead:
var results = element.all(by.css('div.ui-grid-cell-contents')).filter(function(elm) {
return elm.getText().then(function(text) {
return nameTestItem === text;
});
});
expect(results.count()).toEqual(1);
And, if you are using jasmine-matchers, a bit more readable way:
expect(results).toBeNonEmptyArray();

AngularFire - manage child_added and other events on $asArray

Hello guys !
I wanted to do something pretty simple : display the last 10 posts with the newer at the top, and when someone posts a new one, display a bar "click here to see x new posts" that when clicked displays the new ones.
My problem : when a new posts enters Firebase, it immediately displays on screen (using the ng-repeat on the array of the scope linked to the array from Firebase), and takes the older of the 10 elements out.
$firebase(ref.limitToLast(10)).$asArray().$loaded().then(function(messagesData) { ... }
I can detect the change using
messagesData.$watch(function(data) {
console.log("data changed!", data, messagesData);
if(data.event == "child_added") {
// work here
}
});
But I can't figure out how to do what I'm trying to, nor did I find it in the doc. Thanks for any help !
Okay, so, there is a solution. It's possible not to have everything in sync while still enjoying the use of AngularFire for the current elements. Here is how.
Start by getting the messages you want to display at the beginning :
$firebase(ref.orderByKey().limitToLast(nbMessages)).$asArray().$loaded().then(function(messagesData) { ......
Then link them to another array one by one using foreach :
angular.forEach(messagesData, function(value, key) {
messagesDataReturn[key] = value;
// get any other data you need for that message (user name, etc...
});
This will keep every element iterated in sync. So if there is something like a counter of likes, they will be updated live.
Finally add a watcher :
messagesData.$watch(function(data) {
if(data.event == "child_added") {
var newLine = messagesData.filter(function ( obj ) {
return obj.$id === data.key;
})[0];
// add any needed data for this new line
$rootScope.$broadcast('list:updated', newLine);
}
});
In your controller you just have to listen to the broadcast :
$scope.newData = [];
$scope.$on('list:updated', function (event, data) {
$scope.newData.push(data);
});
You can then use $scope.newData to display the way to show the new messages and onclick merge this array with your main one on the scope, so the new messages appears.
Hope this helps someone !

Removing a fMath image properties dialog in ckeditor

I am a bit stuck with this so it would be great if you could help.
I am using Drupal 7 and Ckeditor 4.3. I am developing a site which has fmath equation editor integrated.
I have disabled the image button, as I don't want end users being able to upload their own images. On the other hand, users can use fMath to insert equations. The way fMath handles equation insertion is by inserting a img tag.
When users double click this image or when they right click over the image, they access the image properties dialog, where they can change source url of the image and few other things. On the url input text, they could change the source of the image so that they could insert their own images on the page, which is something I don't want.
The have been working with two different unsuccessful approaches until now trying to solve this problem:
Removing elements from the dialog, as the URL input text on the dialog (and the alt text as well).
Trying to disable the dialog itself.
I'd like to use a custom plugin to accomplish the desired behavior as I have different CKeditor profiles in Drupal.
I haven't been successful. Do you know how could I handle this undesirable behavior?
Ok, I ended up with something like this in the plugin.js file:
CKEDITOR.plugins.add( 'custom_doubleclick',
{
init: function( editor )
{
// First part, dialogDefinition allow us to remove the
// "Link" and "Advanced" tabs on the dialog
CKEDITOR.on( 'dialogDefinition', function( ev ) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if ( dialogName == 'image' ) {
dialogDefinition.removeContents( 'Link' );
dialogDefinition.removeContents( 'advanced' );
}
});
// Second part, it disables the textUrl and txtAlt input text boxes
editor.on( 'dialogShow', function( ev ) {
var dialog = ev.data;
var dialogName = dialog.getName();
if ( dialogName == 'image' ) {
//var dialog = CKEDITOR.dialog.getCurrent();
// Get a reference to the Link Info tab.
console.log(dialog)
dialog.getContentElement( 'info','txtUrl' ).disable();
dialog.getContentElement( 'info','txtAlt' ).disable();
}
});
}
});
As you can see I didn't disable the dialog itself, but the non useful elements. I hope this can help to someone else.

Resources