text: # encoding: utf-8
  
  """
  Gherkin step implementations for placeholder-related features.
  """
  
  from __future__ import absolute_import
  
  import hashlib
  
  from behave import given, when, then
  
  from pptx import Presentation
  from pptx.chart.data import CategoryChartData
  from pptx.enum.chart import XL_CHART_TYPE
  from pptx.enum.shapes import MSO_SHAPE_TYPE, PP_PLACEHOLDER
  from pptx.shapes.base import _PlaceholderFormat
  
  from helpers import saved_pptx_path, test_file, test_pptx, test_text
  
  
  # given ===================================================
  
  
  @given("a bullet body placeholder")
  def given_a_bullet_body_placeholder(context):
      prs = Presentation(test_pptx("ph-unpopulated-placeholders"))
      context.prs = prs
      context.sld = prs.slides[2]
      context.body = prs.slides[2].shapes.placeholders[10]
  
  
  @given("a known {placeholder_type} placeholder shape")
  def given_a_known_placeholder_shape(context, placeholder_type):
      context.execute_steps(
          "given an unpopulated %s placeholder shape" % placeholder_type
      )
  
  
  @given("a layout placeholder having directly set position and size")
  def given_layout_placeholder_with_directly_set_pos_and_size(context):
      prs = Presentation(test_pptx("ph-inherit-props"))
      context.placeholder = prs.slide_layouts[0].placeholders[1]
  
  
  @given("a layout placeholder having no direct position or size settings")
  def given_layout_placeholder_with_no_direct_pos_or_size_settings(context):
      prs = Presentation(test_pptx("ph-inherit-props"))
      context.placeholder = prs.slide_layouts[0].placeholders[0]
  
  
  @given("a master placeholder")
  def given_a_master_placeholder(context):
      prs = Presentation(test_pptx("ph-inherit-props"))
      context.master_placeholder = prs.slide_master.placeholders[1]
  
  
  @given("a notes slide placeholder having directly set position and size")
  def given_notes_slide_placeholder_having_directly_set_pos_and_size(context):
      prs = Presentation(test_pptx("ph-inherit-props"))
      context.placeholder = prs.slides[1].notes_slide.placeholders[1]
  
  
  @given("a notes slide placeholder having no direct position or size settings")
  def given_notes_slide_placeholder_having_no_direct_pos_or_size(context):
      prs = Presentation(test_pptx("ph-inherit-props"))
      context.placeholder = prs.slides[0].notes_slide.placeholders[1]
  
  
  @given("a slide placeholder having directly set position and size")
  def given_slide_placeholder_with_directly_set_pos_and_size(context):
      prs = Presentation(test_pptx("ph-inherit-props"))
      context.placeholder = prs.slides[0].placeholders[10]
  
  
  @given("a slide placeholder having no direct position or size settings")
  def given_slide_placeholder_with_no_direct_pos_or_size_settings(context):
      prs = Presentation(test_pptx("ph-inherit-props"))
      context.placeholder = prs.slides[0].placeholders[0]
  
  
  @given("a slide with an unpopulated {type_} placeholder")
  def given_a_slide_with_an_unpopulated_type_placeholder(context, type_):
      slide_idx = [
          "title",
          "content",
          "text",
          "chart",
          "table",
          "smart art",
          "media",
          "clip art",
          "picture",
      ].index(type_)
      prs = Presentation(test_pptx("ph-unpopulated-placeholders"))
      context.shape = prs.slides[slide_idx].shapes[0]
  
  
  @given("a slide with a {type_} placeholder populated with {content}")
  def given_a_slide_with_a_type_ph_with_content(context, type_, content):
      slide_idx = [
          "picture",
          "clip art",
          "table",
          "chart",
          "title",
          "content",
          "text",
          "smart art",
          "media",
      ].index(type_)
      prs = Presentation(test_pptx("ph-populated-placeholders"))
      context.shape = prs.slides[slide_idx].shapes[0]
  
  
  @given("an unpopulated {placeholder_type} placeholder shape")
  def given_an_unpopulated_placeholder_shape(context, placeholder_type):
      slide_idx = [
          "title",
          "content",
          "text",
          "chart",
          "table",
          "smart art",
          "media",
          "clip art",
          "picture",
      ].index(placeholder_type)
      prs = Presentation(test_pptx("ph-unpopulated-placeholders"))
      context.shape = prs.slides[slide_idx].shapes[0]
  
  
  # when ====================================================
  
  
  @when("I call placeholder.insert_chart(XL_CHART_TYPE.PIE, chart_data)")
  def when_I_call_placeholder_insert_chart(context):
      chart_data = CategoryChartData()
      chart_data.categories = ["Yes", "No"]
      chart_data.add_series("Series 1", (42, 24))
      placeholder = context.shape
      context.placeholder = placeholder.insert_chart(XL_CHART_TYPE.PIE, chart_data)
  
  
  @when("I call placeholder.insert_picture('{filename}')")
  def when_I_call_placeholder_insert_picture(context, filename):
      placeholder = context.shape
      path = test_file(filename)
      with open(path, "rb") as f:
          context.image_sha1 = hashlib.sha1(f.read()).hexdigest()
      context.placeholder = placeholder.insert_picture(path)
  
  
  @when("I call placeholder.insert_table(rows=2, cols=3)")
  def when_I_call_placeholder_insert_table(context):
      placeholder = context.shape
      context.placeholder = placeholder.insert_table(2, 3)
  
  
  @when("I indent the first paragraph")
  def when_I_indent_the_first_paragraph(context):
      context.body.text_frame.paragraphs[0].level = 1
  
  
  @when("I set the title text of the slide")
  def step_when_set_slide_title_text(context):
      context.slide.shapes.title.text = test_text
  
  
  # then ====================================================
  
  
  @then("I can get the placeholder dimensions")
  def then_I_can_get_the_placeholder_dimensions(context):
      placeholder = context.master_placeholder
      assert placeholder.width == 6923112, "got %d" % placeholder.width
      assert placeholder.height == 3484984, "got %d" % placeholder.height
  
  
  @then("I can get the placeholder position")
  def then_I_can_get_the_placeholder_position(context):
      placeholder = context.master_placeholder
      assert placeholder.left == 1110444, "got %d" % placeholder.left
      assert placeholder.top == 1686508, "got %d" % placeholder.top
  
  
  @then("I get the direct settings when I query position and size")
  def then_I_get_direct_settings_when_query_pos_and_size(context):
      placeholder = context.placeholder
      assert placeholder.left == 468312, "got %s" % placeholder.left
      assert placeholder.top == 1700212, "got %s" % placeholder.top
      assert placeholder.width == 8208143, "got %s" % placeholder.width
      assert placeholder.height == 4537099, "got %s" % placeholder.height
  
  
  @then("I get inherited settings when I query position and size")
  def then_I_get_inherited_settings_when_I_query_position_and_size(context):
      placeholder = context.placeholder
      assert placeholder.left == 457200, "got %s" % placeholder.left
      assert placeholder.top == 274638, "got %s" % placeholder.top
      assert placeholder.width == 8229600, "got %s" % placeholder.width
      assert placeholder.height == 1143000, "got %s" % placeholder.height
  
  
  @then("placeholder_format.idx is {value}")
  def then_placeholder_format_idx_is_value(context, value):
      expected_value = int(value)
      placeholder_format = context.shape.placeholder_format
      assert placeholder_format.idx == expected_value
  
  
  @then("placeholder_format.type is {value}")
  def then_placeholder_format_type_is_value(context, value):
      expected_value = getattr(PP_PLACEHOLDER, value.split(".")[1])
      placeholder_format = context.shape.placeholder_format
      assert placeholder_format.type == expected_value
  
  
  @then("shape.placeholder_format is its _PlaceholderFormat object")
  def then_shape_placeholder_format_is_its_PlaceholderFormat_object(context):
      shape = context.shape
      placeholder_format = shape.placeholder_format
      assert isinstance(placeholder_format, _PlaceholderFormat)
      assert placeholder_format.element is shape.element.ph
  
  
  @then("shape.shape_type is MSO_SHAPE_TYPE.PLACEHOLDER")
  def then_shape_shape_type_is_PLACEHOLDER(context):
      shape = context.shape
      assert shape.shape_type == MSO_SHAPE_TYPE.PLACEHOLDER
  
  
  @then("slide.shapes[0] is a {cls} proxy object for that placeholder")
  def then_slide_shapes_0_is_a_cls_proxy_for_that_placeholder(context, cls):
      placeholder = context.shape
      clsname = placeholder.__class__.__name__
      assert clsname == cls, "got %s" % clsname
  
  
  @then("the chart is a pie chart")
  def then_the_chart_is_a_pie_chart(context):
      chart = context.chart
      assert chart.chart_type == XL_CHART_TYPE.PIE
  
  
  @then("the return value is a Placeholder{type} object")
  def then_the_return_value_is_a_PlaceholderType_object(context, type):
      expected_type_name = "Placeholder%s" % type
      placeholder_type_name = context.placeholder.__class__.__name__
      assert placeholder_type_name == expected_type_name
  
  
  @then("the paragraph is indented")
  def then_the_paragraph_is_indented(context):
      prs = Presentation(saved_pptx_path)
      p = prs.slides[2].shapes.placeholders[10].text_frame.paragraphs[0]
      assert p.level == 1
  
  
  @then("the placeholder contains the chart")
  def then_the_placeholder_contains_the_chart(context):
      placeholder_graphic_frame = context.placeholder
      assert placeholder_graphic_frame.has_chart
      context.chart = placeholder_graphic_frame.chart
  
  
  @then("the placeholder contains the image")
  def then_the_placeholder_contains_the_image(context):
      placeholder_picture = context.placeholder
      assert placeholder_picture.image.sha1 == context.image_sha1
  
  
  @then("the placeholder contains the table")
  def then_the_placeholder_contains_the_table(context):
      placeholder_graphic_frame = context.placeholder
      assert placeholder_graphic_frame.has_table
      context.table_ = placeholder_graphic_frame.table
  
  
  @then("the placeholder's position and size are inherited from its layout")
  def then_the_placeholders_position_and_size_are_inherited(context):
      placeholder = context.shape
      expected_values = (
          ("left", 2743200),
          ("top", 2057400),
          ("width", 3657600),
          ("height", 2743200),
      )
      for prop_name, expected_value in expected_values:
          value = getattr(placeholder, prop_name)
          assert value == expected_value, "got %s" % value
  
  
  @then("the {sides} crop is {value}")
  def then_the_sides_crop_is_value(context, sides, value):
      side_prop_names = {
          "top and bottom": ("crop_top", "crop_bottom"),
          "left and right": ("crop_left", "crop_right"),
      }[sides]
      expected_value = float(value)
      placeholder_picture = context.placeholder
      for prop_name in side_prop_names:
          value = getattr(placeholder_picture, prop_name)
          difference = abs(expected_value - value)
          assert difference < 0.000002, "got %s for %s" % (value, prop_name)
  
  
  @then("the table has 2 rows and 3 columns")
  def then_the_table_has_2_rows_and_3_columns(context):
      table = context.table_
      assert len(table.rows) == 2
      assert len(table.columns) == 3
  
  
  @then("the text appears in the title placeholder")
  def step_then_text_appears_in_title_placeholder(context):
      prs = Presentation(saved_pptx_path)
      title_shape = prs.slides[0].shapes.title
      title_text = title_shape.text_frame.paragraphs[0].runs[0].text
      assert title_text == test_text
  