2

I want to set the size of all elements as the size of the first selected element. but seems something wrong with my code , somehow first element size not working for others.

Please see attached script

/*
 * Make all elements same size
 */
function sameSizeElements() {
  var selection = SlidesApp.getActivePresentation().getSelection();
  var selectionType = selection.getSelectionType();
  var pageElements = selection.getPageElementRange().getPageElements();
  
  //iterate the selected page elements to grab the values of each positiion
  for (var i = 0; i < pageElements.length; i++) {
  
    if(i != 0){
      pageElements[i].setWidth(pageElements[0].getWidth());
      pageElements[i].setHeight(pageElements[0].getHeight());
    }
  }   
}

Here is the full code you can put in ScriptEditor > code.js default file and refresh slide. it will work as you want to debug.

Updated

We are in the discussion with Google App Script issue tracking team - https://issuetracker.google.com/issues/162545277

set this protity and check it works

Naresh
  • 2,761
  • 10
  • 45
  • 78
  • 2
    Can you share an example Presentation for testing? – Rafa Guillermo Jul 30 '20 at 11:42
  • https://docs.google.com/presentation/d/1v9AD_rmjmGUMaWoVmI5z_PM8rkG2boiCGpW4xJsx85A/edit?usp=sharing – Naresh Jul 30 '20 at 13:27
  • Here is the full code https://codeshare.io/29gWZM you can put in ScriptEditor -> code.js default file and refresh slide. it will work as you want to debug. thanks @RafaGuillermo – Naresh Jul 30 '20 at 13:29
  • @RafaGuillermo you can test with this priority https://imgur.com/a/y8Iesli – Naresh Jul 30 '20 at 13:42
  • @PuzzledBoy - hm, you should check if the elements returned by `getPageElements()` call are in the same order as you expect them to be in. I could not reproduce the error in my playground for Google Slides, your logic seems correct. And check if nothing interferes with `i` in the outer scope (using `let` instead will make sure of that) – Oleg Valter is with Ukraine Jul 30 '20 at 18:02
  • @PuzzledBoy - also, are you using the older Rhino runtime, does the issue persist if you switch to V8? – Oleg Valter is with Ukraine Jul 30 '20 at 18:21
  • Does this answer your question? [Google Slides Elements Selection Order Issue](https://stackoverflow.com/questions/62483449/google-slides-elements-selection-order-issue) – TheMaster Jul 30 '20 at 20:37
  • 1
    @OlegValter "This project is running on our new Apps Script runtime powered by Chrome V8." – Naresh Jul 31 '20 at 03:07
  • 1
    @PuzzledBoy - thank you, we discussed the issue with Tanaike earlier - this is an inconsistency common to both runtimes - there is something wrong in how selected elements are interpreted server-side, there is nothing you are doing wrong. I think we may open a bug issue or a FR for that – Oleg Valter is with Ukraine Jul 31 '20 at 03:10

2 Answers2

3

As the current workaround, how about this method?

Issue and workaround:

In the current stage, unfortunately, it seems that this bug is still not resolved. By this, in your case, the 1st selected image cannot be retrieved. I think that this is the current reason of your issue.

In order to achieve your goal, as the current workaround, I would like to propose the following flow.

  1. Select an image which is used as the basic size and script is run.
    • The object ID of image is saved to the PropertiesService.
  2. Select the images you want to resize and the script is run.

When your script is modified for this flow, it becomes as follows.

Modified script:

function allMenu(){
  var slideUi = SlidesApp.getUi();
  slideUi.createMenu('LAK')
      .addSeparator()
      .addSubMenu(slideUi.createMenu('Sizes')
      .addItem('Select base image', 'selectBaseImage')  // Added
      .addItem('Same Size', 'sameSizeElements'))
      .addToUi();
}

// 1. At first, it saves an image which is used as the base image.
function selectBaseImage() {
  var selection = SlidesApp.getActivePresentation().getSelection();
  var pageElements = selection.getPageElementRange().getPageElements();
  if (pageElements.length == 1) {
    PropertiesService.getScriptProperties().setProperty("baseImage", pageElements[0].getObjectId());
  } else {
    throw new Error("Select one image.");
  }
}

// 2. As the next step, the selected images are resized using the saved image.
function sameSizeElements() {
  var prop = PropertiesService.getScriptProperties();
  var objectId = prop.getProperty("baseImage");
  if (objectId != "") {
    var selection = SlidesApp.getActivePresentation().getSelection();
    var baseImage = selection.getCurrentPage().getPageElementById(objectId);
    var pageElements = selection.getPageElementRange().getPageElements();
    for (var i = 0; i < pageElements.length; i++) {
      pageElements[i].setWidth(baseImage.getWidth());
      pageElements[i].setHeight(baseImage.getHeight());
    }
    prop.deleteProperty("baseImage");
  } else {
    throw new Error("Base image was not found.");
  }
}

Result:

enter image description here

References:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Thank you for your best solution , sorry but i cant divide it in 2 steps. i will learn from your best practice. – Naresh Jul 31 '20 at 04:24
  • @Puzzled Boy Thank you for replying. I apologize that my proposal was different from the direction you expect. – Tanaike Jul 31 '20 at 07:57
3

Additional context to the issue:

when a server-side function is invoked, a ctx object is sent to the /invoke endpoint that, among other info (session id ssid, document id docId, revision number rev, and application type app), contains data about currently selected PageElements in property value with key sel.

The value is an array of arrays of strings and numbers, of which only one of the elements contains strings - if you look closely, these strings are object Ids (you can confirm with getObjectId method) in order of selection.

At least this confirms that the order of selection can be respected, but the way how the abovementioned list is managed server-side changes that order. Unfortunately, I could not confirm any particular order of how the elements (apart from grouping of Ids of form g8edc625556_0_0) are returned by .getSelection().getPageElementRange().getPageElements() chain of methods:

selection test animation

  • :Thank you. Is it possible that you can share your code with which you have given this strong technical answer. – Naresh Aug 03 '20 at 07:49