#!/usr/bin/python
"""
Step file creator/editor.

@copyright: Red Hat Inc 2009
@author: mgoldish@redhat.com (Michael Goldish)
@version: "20090401"
"""

import pygtk, gtk, os, glob, shutil, sys, logging
import common, ppm_utils
pygtk.require('2.0')


# General utilities

def corner_and_size_clipped(startpoint, endpoint, limits):
    c0 = startpoint[:]
    c1 = endpoint[:]
    if c0[0] < 0:
        c0[0] = 0
    if c0[1] < 0:
        c0[1] = 0
    if c1[0] < 0:
        c1[0] = 0
    if c1[1] < 0:
        c1[1] = 0
    if c0[0] > limits[0] - 1:
        c0[0] = limits[0] - 1
    if c0[1] > limits[1] - 1:
        c0[1] = limits[1] - 1
    if c1[0] > limits[0] - 1:
        c1[0] = limits[0] - 1
    if c1[1] > limits[1] - 1:
        c1[1] = limits[1] - 1
    return ([min(c0[0], c1[0]),
             min(c0[1], c1[1])],
            [abs(c1[0] - c0[0]) + 1,
             abs(c1[1] - c0[1]) + 1])


def key_event_to_qemu_string(event):
    keymap = gtk.gdk.keymap_get_default()
    keyvals = keymap.get_entries_for_keycode(event.hardware_keycode)
    keyval = keyvals[0][0]
    keyname = gtk.gdk.keyval_name(keyval)

    dict = { "Return": "ret",
             "Tab": "tab",
             "space": "spc",
             "Left": "left",
             "Right": "right",
             "Up": "up",
             "Down": "down",
             "F1": "f1",
             "F2": "f2",
             "F3": "f3",
             "F4": "f4",
             "F5": "f5",
             "F6": "f6",
             "F7": "f7",
             "F8": "f8",
             "F9": "f9",
             "F10": "f10",
             "F11": "f11",
             "F12": "f12",
             "Escape": "esc",
             "minus": "minus",
             "equal": "equal",
             "BackSpace": "backspace",
             "comma": "comma",
             "period": "dot",
             "slash": "slash",
             "Insert": "insert",
             "Delete": "delete",
             "Home": "home",
             "End": "end",
             "Page_Up": "pgup",
             "Page_Down": "pgdn",
             "Menu": "menu",
             "semicolon": "0x27",
             "backslash": "0x2b",
             "apostrophe": "0x28",
             "grave": "0x29",
             "less": "0x2b",
             "bracketleft": "0x1a",
             "bracketright": "0x1b",
             "Super_L": "0xdc",
             "Super_R": "0xdb",
             }

    if ord('a') <= keyval <= ord('z') or ord('0') <= keyval <= ord('9'):
        str = keyname
    elif keyname in dict.keys():
        str = dict[keyname]
    else:
        return ""

    if event.state & gtk.gdk.CONTROL_MASK:
        str = "ctrl-" + str
    if event.state & gtk.gdk.MOD1_MASK:
        str = "alt-" + str
    if event.state & gtk.gdk.SHIFT_MASK:
        str = "shift-" + str

    return str


class StepMakerWindow:

    # Constructor

    def __init__(self):
        # Window
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_title("Step Maker Window")
        self.window.connect("delete-event", self.delete_event)
        self.window.connect("destroy", self.destroy)
        self.window.set_default_size(600, 800)

        # Main box (inside a frame which is inside a VBox)
        self.menu_vbox = gtk.VBox()
        self.window.add(self.menu_vbox)
        self.menu_vbox.show()

        frame = gtk.Frame()
        frame.set_border_width(10)
        frame.set_shadow_type(gtk.SHADOW_NONE)
        self.menu_vbox.pack_end(frame)
        frame.show()

        self.main_vbox = gtk.VBox(spacing=10)
        frame.add(self.main_vbox)
        self.main_vbox.show()

        # EventBox
        self.scrolledwindow = gtk.ScrolledWindow()
        self.scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC,
                                       gtk.POLICY_AUTOMATIC)
        self.scrolledwindow.set_shadow_type(gtk.SHADOW_NONE)
        self.main_vbox.pack_start(self.scrolledwindow)
        self.scrolledwindow.show()

        table = gtk.Table(1, 1)
        self.scrolledwindow.add_with_viewport(table)
        table.show()
        table.realize()

        self.event_box = gtk.EventBox()
        table.attach(self.event_box, 0, 1, 0, 1, gtk.EXPAND, gtk.EXPAND)
        self.event_box.show()
        self.event_box.realize()

        # Image
        self.image = gtk.Image()
        self.event_box.add(self.image)
        self.image.show()

        # Data VBox
        self.data_vbox = gtk.VBox(spacing=10)
        self.main_vbox.pack_start(self.data_vbox, expand=False)
        self.data_vbox.show()

        # User VBox
        self.user_vbox = gtk.VBox(spacing=10)
        self.main_vbox.pack_start(self.user_vbox, expand=False)
        self.user_vbox.show()

        # Screendump ID HBox
        box = gtk.HBox(spacing=10)
        self.data_vbox.pack_start(box)
        box.show()

        label = gtk.Label("Screendump ID:")
        box.pack_start(label, False)
        label.show()

        self.entry_screendump = gtk.Entry()
        self.entry_screendump.set_editable(False)
        box.pack_start(self.entry_screendump)
        self.entry_screendump.show()

        label = gtk.Label("Time:")
        box.pack_start(label, False)
        label.show()

        self.entry_time = gtk.Entry()
        self.entry_time.set_editable(False)
        self.entry_time.set_width_chars(10)
        box.pack_start(self.entry_time, False)
        self.entry_time.show()

        # Comment HBox
        box = gtk.HBox(spacing=10)
        self.data_vbox.pack_start(box)
        box.show()

        label = gtk.Label("Comment:")
        box.pack_start(label, False)
        label.show()

        self.entry_comment = gtk.Entry()
        box.pack_start(self.entry_comment)
        self.entry_comment.show()

        # Sleep HBox
        box = gtk.HBox(spacing=10)
        self.data_vbox.pack_start(box)
        box.show()

        self.check_sleep = gtk.CheckButton("Sleep:")
        self.check_sleep.connect("toggled", self.event_check_sleep_toggled)
        box.pack_start(self.check_sleep, False)
        self.check_sleep.show()

        self.spin_sleep = gtk.SpinButton(gtk.Adjustment(0, 0, 50000, 1, 10, 0),
                                         climb_rate=0.0)
        box.pack_start(self.spin_sleep, False)
        self.spin_sleep.show()

        # Barrier HBox
        box = gtk.HBox(spacing=10)
        self.data_vbox.pack_start(box)
        box.show()

        self.check_barrier = gtk.CheckButton("Barrier:")
        self.check_barrier.connect("toggled", self.event_check_barrier_toggled)
        box.pack_start(self.check_barrier, False)
        self.check_barrier.show()

        vbox = gtk.VBox()
        box.pack_start(vbox)
        vbox.show()

        self.label_barrier_region = gtk.Label("Region:")
        self.label_barrier_region.set_alignment(0, 0.5)
        vbox.pack_start(self.label_barrier_region)
        self.label_barrier_region.show()

        self.label_barrier_md5sum = gtk.Label("MD5:")
        self.label_barrier_md5sum.set_alignment(0, 0.5)
        vbox.pack_start(self.label_barrier_md5sum)
        self.label_barrier_md5sum.show()

        self.label_barrier_timeout = gtk.Label("Timeout:")
        box.pack_start(self.label_barrier_timeout, False)
        self.label_barrier_timeout.show()

        self.spin_barrier_timeout = gtk.SpinButton(gtk.Adjustment(0, 0, 50000,
                                                                  1, 10, 0),
                                                                 climb_rate=0.0)
        box.pack_start(self.spin_barrier_timeout, False)
        self.spin_barrier_timeout.show()

        self.check_barrier_optional = gtk.CheckButton("Optional")
        box.pack_start(self.check_barrier_optional, False)
        self.check_barrier_optional.show()

        # Keystrokes HBox
        box = gtk.HBox(spacing=10)
        self.data_vbox.pack_start(box)
        box.show()

        label = gtk.Label("Keystrokes:")
        box.pack_start(label, False)
        label.show()

        frame = gtk.Frame()
        frame.set_shadow_type(gtk.SHADOW_IN)
        box.pack_start(frame)
        frame.show()

        self.text_buffer = gtk.TextBuffer()
        self.entry_keys = gtk.TextView(self.text_buffer)
        self.entry_keys.set_wrap_mode(gtk.WRAP_WORD)
        self.entry_keys.connect("key-press-event", self.event_key_press)
        frame.add(self.entry_keys)
        self.entry_keys.show()

        self.check_manual = gtk.CheckButton("Manual")
        self.check_manual.connect("toggled", self.event_manual_toggled)
        box.pack_start(self.check_manual, False)
        self.check_manual.show()

        button = gtk.Button("Clear")
        button.connect("clicked", self.event_clear_clicked)
        box.pack_start(button, False)
        button.show()

        # Mouse click HBox
        box = gtk.HBox(spacing=10)
        self.data_vbox.pack_start(box)
        box.show()

        label = gtk.Label("Mouse action:")
        box.pack_start(label, False)
        label.show()

        self.button_capture = gtk.Button("Capture")
        box.pack_start(self.button_capture, False)
        self.button_capture.show()

        self.check_mousemove = gtk.CheckButton("Move: ...")
        box.pack_start(self.check_mousemove, False)
        self.check_mousemove.show()

        self.check_mouseclick = gtk.CheckButton("Click: ...")
        box.pack_start(self.check_mouseclick, False)
        self.check_mouseclick.show()

        self.spin_sensitivity = gtk.SpinButton(gtk.Adjustment(1, 1, 100, 1, 10,
                                                              0),
                                                              climb_rate=0.0)
        box.pack_end(self.spin_sensitivity, False)
        self.spin_sensitivity.show()

        label = gtk.Label("Sensitivity:")
        box.pack_end(label, False)
        label.show()

        self.spin_latency = gtk.SpinButton(gtk.Adjustment(10, 1, 500, 1, 10, 0),
                                           climb_rate=0.0)
        box.pack_end(self.spin_latency, False)
        self.spin_latency.show()

        label = gtk.Label("Latency:")
        box.pack_end(label, False)
        label.show()

        self.handler_event_box_press = None
        self.handler_event_box_release = None
        self.handler_event_box_scroll = None
        self.handler_event_box_motion = None
        self.handler_event_box_expose = None

        self.window.realize()
        self.window.show()

        self.clear_state()

    # Utilities

    def message(self, text, title):
        dlg = gtk.MessageDialog(self.window,
                gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                gtk.MESSAGE_INFO,
                gtk.BUTTONS_CLOSE,
                title)
        dlg.set_title(title)
        dlg.format_secondary_text(text)
        response = dlg.run()
        dlg.destroy()


    def question_yes_no(self, text, title):
        dlg = gtk.MessageDialog(self.window,
                gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                gtk.MESSAGE_QUESTION,
                gtk.BUTTONS_YES_NO,
                title)
        dlg.set_title(title)
        dlg.format_secondary_text(text)
        response = dlg.run()
        dlg.destroy()
        if response == gtk.RESPONSE_YES:
            return True
        return False


    def inputdialog(self, text, title, default_response=""):
        # Define a little helper function
        def inputdialog_entry_activated(entry):
            dlg.response(gtk.RESPONSE_OK)

        # Create the dialog
        dlg = gtk.MessageDialog(self.window,
                gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                gtk.MESSAGE_QUESTION,
                gtk.BUTTONS_OK_CANCEL,
                title)
        dlg.set_title(title)
        dlg.format_secondary_text(text)

        # Create an entry widget
        entry = gtk.Entry()
        entry.set_text(default_response)
        entry.connect("activate", inputdialog_entry_activated)
        dlg.vbox.pack_start(entry)
        entry.show()

        # Run the dialog
        response = dlg.run()
        dlg.destroy()
        if response == gtk.RESPONSE_OK:
            return entry.get_text()
        return None


    def filedialog(self, title=None, default_filename=None):
        chooser = gtk.FileChooserDialog(title=title, parent=self.window,
                                        action=gtk.FILE_CHOOSER_ACTION_OPEN,
                buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN,
                         gtk.RESPONSE_OK))
        chooser.resize(700, 500)
        if default_filename:
            chooser.set_filename(os.path.abspath(default_filename))
        filename = None
        response = chooser.run()
        if response == gtk.RESPONSE_OK:
            filename = chooser.get_filename()
        chooser.destroy()
        return filename


    def redirect_event_box_input(self, press=None, release=None, scroll=None,
                                 motion=None, expose=None):
        if self.handler_event_box_press != None: \
        self.event_box.disconnect(self.handler_event_box_press)
        if self.handler_event_box_release != None: \
        self.event_box.disconnect(self.handler_event_box_release)
        if self.handler_event_box_scroll != None: \
        self.event_box.disconnect(self.handler_event_box_scroll)
        if self.handler_event_box_motion != None: \
        self.event_box.disconnect(self.handler_event_box_motion)
        if self.handler_event_box_expose != None: \
        self.event_box.disconnect(self.handler_event_box_expose)
        self.handler_event_box_press = None
        self.handler_event_box_release = None
        self.handler_event_box_scroll = None
        self.handler_event_box_motion = None
        self.handler_event_box_expose = None
        if press != None: self.handler_event_box_press = \
        self.event_box.connect("button-press-event", press)
        if release != None: self.handler_event_box_release = \
        self.event_box.connect("button-release-event", release)
        if scroll != None: self.handler_event_box_scroll = \
        self.event_box.connect("scroll-event", scroll)
        if motion != None: self.handler_event_box_motion = \
        self.event_box.connect("motion-notify-event", motion)
        if expose != None: self.handler_event_box_expose = \
        self.event_box.connect_after("expose-event", expose)


    def get_keys(self):
        return self.text_buffer.get_text(
                self.text_buffer.get_start_iter(),
                self.text_buffer.get_end_iter())


    def add_key(self, key):
        text = self.get_keys()
        if len(text) > 0 and text[-1] != ' ':
            text += " "
        text += key
        self.text_buffer.set_text(text)


    def clear_keys(self):
        self.text_buffer.set_text("")


    def update_barrier_info(self):
        if self.barrier_selected:
            self.label_barrier_region.set_text("Selected region: Corner: " + \
                                            str(tuple(self.barrier_corner)) + \
                                            " Size: " + \
                                            str(tuple(self.barrier_size)))
        else:
            self.label_barrier_region.set_text("No region selected.")
        self.label_barrier_md5sum.set_text("MD5: " + self.barrier_md5sum)


    def update_mouse_click_info(self):
        if self.mouse_click_captured:
            self.check_mousemove.set_label("Move: " + \
                                           str(tuple(self.mouse_click_coords)))
            self.check_mouseclick.set_label("Click: button %d" %
                                            self.mouse_click_button)
        else:
            self.check_mousemove.set_label("Move: ...")
            self.check_mouseclick.set_label("Click: ...")


    def clear_state(self, clear_screendump=True):
        # Recording time
        self.entry_time.set_text("unknown")
        if clear_screendump:
            # Screendump
            self.clear_image()
        # Screendump ID
        self.entry_screendump.set_text("")
        # Comment
        self.entry_comment.set_text("")
        # Sleep
        self.check_sleep.set_active(True)
        self.check_sleep.set_active(False)
        self.spin_sleep.set_value(10)
        # Barrier
        self.clear_barrier_state()
        # Keystrokes
        self.check_manual.set_active(False)
        self.clear_keys()
        # Mouse actions
        self.check_mousemove.set_sensitive(False)
        self.check_mouseclick.set_sensitive(False)
        self.check_mousemove.set_active(False)
        self.check_mouseclick.set_active(False)
        self.mouse_click_captured = False
        self.mouse_click_coords = [0, 0]
        self.mouse_click_button = 0
        self.update_mouse_click_info()


    def clear_barrier_state(self):
        self.check_barrier.set_active(True)
        self.check_barrier.set_active(False)
        self.check_barrier_optional.set_active(False)
        self.spin_barrier_timeout.set_value(10)
        self.barrier_selection_started = False
        self.barrier_selected = False
        self.barrier_corner0 = [0, 0]
        self.barrier_corner1 = [0, 0]
        self.barrier_corner = [0, 0]
        self.barrier_size = [0, 0]
        self.barrier_md5sum = ""
        self.update_barrier_info()


    def set_image(self, w, h, data):
        (self.image_width, self.image_height, self.image_data) = (w, h, data)
        self.image.set_from_pixbuf(gtk.gdk.pixbuf_new_from_data(
            data, gtk.gdk.COLORSPACE_RGB, False, 8,
            w, h, w*3))
        hscrollbar = self.scrolledwindow.get_hscrollbar()
        hscrollbar.set_range(0, w)
        vscrollbar = self.scrolledwindow.get_vscrollbar()
        vscrollbar.set_range(0, h)


    def set_image_from_file(self, filename):
        if not ppm_utils.image_verify_ppm_file(filename):
            logging.warning("set_image_from_file: Warning: received invalid"
                            "screendump file")
            return self.clear_image()
        (w, h, data) = ppm_utils.image_read_from_ppm_file(filename)
        self.set_image(w, h, data)


    def clear_image(self):
        self.image.clear()
        self.image_width = 0
        self.image_height = 0
        self.image_data = ""


    def update_screendump_id(self, data_dir):
        if not self.image_data:
            return
        # Find a proper ID for the screendump
        scrdump_md5sum = ppm_utils.image_md5sum(self.image_width,
                                                self.image_height,
                                                self.image_data)
        scrdump_id = ppm_utils.find_id_for_screendump(scrdump_md5sum, data_dir)
        if not scrdump_id:
            # Not found; generate one
            scrdump_id = ppm_utils.generate_id_for_screendump(scrdump_md5sum,
                                                              data_dir)
        self.entry_screendump.set_text(scrdump_id)


    def get_step_lines(self, data_dir=None):
        if self.check_barrier.get_active() and not self.barrier_selected:
            self.message("No barrier region selected.", "Error")
            return

        str = "step"

        # Add step recording time
        if self.entry_time.get_text():
            str += " " + self.entry_time.get_text()

        str += "\n"

        # Add screendump line
        if self.image_data:
            str += "screendump %s\n" % self.entry_screendump.get_text()

        # Add comment
        if self.entry_comment.get_text():
            str += "# %s\n" % self.entry_comment.get_text()

        # Add sleep line
        if self.check_sleep.get_active():
            str += "sleep %d\n" % self.spin_sleep.get_value()

        # Add barrier_2 line
        if self.check_barrier.get_active():
            str += "barrier_2 %d %d %d %d %s %d" % (
                    self.barrier_size[0], self.barrier_size[1],
                    self.barrier_corner[0], self.barrier_corner[1],
                    self.barrier_md5sum, self.spin_barrier_timeout.get_value())
            if self.check_barrier_optional.get_active():
                str += " optional"
            str += "\n"

        # Add "Sending keys" comment
        keys_to_send = self.get_keys().split()
        if keys_to_send:
            str += "# Sending keys: %s\n" % self.get_keys()

        # Add key and var lines
        for key in keys_to_send:
            if key.startswith("$"):
                varname = key[1:]
                str += "var %s\n" % varname
            else:
                str += "key %s\n" % key

        # Add mousemove line
        if self.check_mousemove.get_active():
            str += "mousemove %d %d\n" % (self.mouse_click_coords[0],
                                          self.mouse_click_coords[1])

        # Add mouseclick line
        if self.check_mouseclick.get_active():
            dict = { 1 : 1,
                     2 : 2,
                     3 : 4 }
            str += "mouseclick %d\n" % dict[self.mouse_click_button]

        # Write screendump and cropped screendump image files
        if data_dir and self.image_data:
            # Create the data dir if it doesn't exist
            if not os.path.exists(data_dir):
                os.makedirs(data_dir)
            # Get the full screendump filename
            scrdump_filename = os.path.join(data_dir,
                                            self.entry_screendump.get_text())
            # Write screendump file if it doesn't exist
            if not os.path.exists(scrdump_filename):
                try:
                    ppm_utils.image_write_to_ppm_file(scrdump_filename,
                                                      self.image_width,
                                                      self.image_height,
                                                      self.image_data)
                except IOError:
                    self.message("Could not write screendump file.", "Error")

            #if self.check_barrier.get_active():
            #    # Crop image to get the cropped screendump
            #    (cw, ch, cdata) = ppm_utils.image_crop(
            #            self.image_width, self.image_height, self.image_data,
            #            self.barrier_corner[0], self.barrier_corner[1],
            #            self.barrier_size[0], self.barrier_size[1])
            #    cropped_scrdump_md5sum = ppm_utils.image_md5sum(cw, ch, cdata)
            #    cropped_scrdump_filename = \
            #    ppm_utils.get_cropped_screendump_filename(scrdump_filename,
            #                                            cropped_scrdump_md5sum)
            #    # Write cropped screendump file
            #    try:
            #        ppm_utils.image_write_to_ppm_file(cropped_scrdump_filename,
            #                                          cw, ch, cdata)
            #    except IOError:
            #        self.message("Could not write cropped screendump file.",
            #                     "Error")

        return str

    def set_state_from_step_lines(self, str, data_dir, warn=True):
        self.clear_state()

        for line in str.splitlines():
            words = line.split()
            if not words:
                continue

            if line.startswith("#") \
                    and not self.entry_comment.get_text() \
                    and not line.startswith("# Sending keys:") \
                    and not line.startswith("# ----"):
                self.entry_comment.set_text(line.strip("#").strip())

            elif words[0] == "step":
                if len(words) >= 2:
                    self.entry_time.set_text(words[1])

            elif words[0] == "screendump":
                self.entry_screendump.set_text(words[1])
                self.set_image_from_file(os.path.join(data_dir, words[1]))

            elif words[0] == "sleep":
                self.spin_sleep.set_value(int(words[1]))
                self.check_sleep.set_active(True)

            elif words[0] == "key":
                self.add_key(words[1])

            elif words[0] == "var":
                self.add_key("$%s" % words[1])

            elif words[0] == "mousemove":
                self.mouse_click_captured = True
                self.mouse_click_coords = [int(words[1]), int(words[2])]
                self.update_mouse_click_info()

            elif words[0] == "mouseclick":
                self.mouse_click_captured = True
                self.mouse_click_button = int(words[1])
                self.update_mouse_click_info()

            elif words[0] == "barrier_2":
                # Get region corner and size from step lines
                self.barrier_corner = [int(words[3]), int(words[4])]
                self.barrier_size = [int(words[1]), int(words[2])]
                # Get corner0 and corner1 from step lines
                self.barrier_corner0 = self.barrier_corner
                self.barrier_corner1 = [self.barrier_corner[0] +
                                        self.barrier_size[0] - 1,
                                        self.barrier_corner[1] +
                                        self.barrier_size[1] - 1]
                # Get the md5sum
                self.barrier_md5sum = words[5]
                # Pretend the user selected the region with the mouse
                self.barrier_selection_started = True
                self.barrier_selected = True
                # Update label widgets according to region information
                self.update_barrier_info()
                # Check the barrier checkbutton
                self.check_barrier.set_active(True)
                # Set timeout value
                self.spin_barrier_timeout.set_value(int(words[6]))
                # Set 'optional' checkbutton state
                self.check_barrier_optional.set_active(words[-1] == "optional")
                # Update the image widget
                self.event_box.queue_draw()

                if warn:
                    # See if the computed md5sum matches the one recorded in
                    # the file
                    computed_md5sum = ppm_utils.get_region_md5sum(
                            self.image_width, self.image_height,
                            self.image_data, self.barrier_corner[0],
                            self.barrier_corner[1], self.barrier_size[0],
                            self.barrier_size[1])
                    if computed_md5sum != self.barrier_md5sum:
                        self.message("Computed MD5 sum (%s) differs from MD5"
                                     " sum recorded in steps file (%s)" %
                                     (computed_md5sum, self.barrier_md5sum),
                                     "Warning")

    # Events

    def delete_event(self, widget, event):
        pass

    def destroy(self, widget):
        gtk.main_quit()

    def event_check_barrier_toggled(self, widget):
        if self.check_barrier.get_active():
            self.redirect_event_box_input(
                    self.event_button_press,
                    self.event_button_release,
                    None,
                    None,
                    self.event_expose)
            self.event_box.queue_draw()
            self.event_box.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.CROSSHAIR))
            self.label_barrier_region.set_sensitive(True)
            self.label_barrier_md5sum.set_sensitive(True)
            self.label_barrier_timeout.set_sensitive(True)
            self.spin_barrier_timeout.set_sensitive(True)
            self.check_barrier_optional.set_sensitive(True)
        else:
            self.redirect_event_box_input()
            self.event_box.queue_draw()
            self.event_box.window.set_cursor(None)
            self.label_barrier_region.set_sensitive(False)
            self.label_barrier_md5sum.set_sensitive(False)
            self.label_barrier_timeout.set_sensitive(False)
            self.spin_barrier_timeout.set_sensitive(False)
            self.check_barrier_optional.set_sensitive(False)

    def event_check_sleep_toggled(self, widget):
        if self.check_sleep.get_active():
            self.spin_sleep.set_sensitive(True)
        else:
            self.spin_sleep.set_sensitive(False)

    def event_manual_toggled(self, widget):
        self.entry_keys.grab_focus()

    def event_clear_clicked(self, widget):
        self.clear_keys()
        self.entry_keys.grab_focus()

    def event_expose(self, widget, event):
        if not self.barrier_selection_started:
            return
        (corner, size) = corner_and_size_clipped(self.barrier_corner0,
                                                 self.barrier_corner1,
                                                 self.event_box.size_request())
        gc = self.event_box.window.new_gc(line_style=gtk.gdk.LINE_DOUBLE_DASH,
                                          line_width=1)
        gc.set_foreground(gc.get_colormap().alloc_color("red"))
        gc.set_background(gc.get_colormap().alloc_color("dark red"))
        gc.set_dashes(0, (4, 4))
        self.event_box.window.draw_rectangle(
                gc, False,
                corner[0], corner[1],
                size[0]-1, size[1]-1)

    def event_drag_motion(self, widget, event):
        old_corner1 = self.barrier_corner1
        self.barrier_corner1 = [int(event.x), int(event.y)]
        (corner, size) = corner_and_size_clipped(self.barrier_corner0,
                                                 self.barrier_corner1,
                                                 self.event_box.size_request())
        (old_corner, old_size) = corner_and_size_clipped(self.barrier_corner0,
                                                         old_corner1,
                                                  self.event_box.size_request())
        corner0 = [min(corner[0], old_corner[0]), min(corner[1], old_corner[1])]
        corner1 = [max(corner[0] + size[0], old_corner[0] + old_size[0]),
                   max(corner[1] + size[1], old_corner[1] + old_size[1])]
        size = [corner1[0] - corner0[0] + 1,
                corner1[1] - corner0[1] + 1]
        self.event_box.queue_draw_area(corner0[0], corner0[1], size[0], size[1])

    def event_button_press(self, widget, event):
        (corner, size) = corner_and_size_clipped(self.barrier_corner0,
                                                 self.barrier_corner1,
                                                 self.event_box.size_request())
        self.event_box.queue_draw_area(corner[0], corner[1], size[0], size[1])
        self.barrier_corner0 = [int(event.x), int(event.y)]
        self.barrier_corner1 = [int(event.x), int(event.y)]
        self.redirect_event_box_input(
                self.event_button_press,
                self.event_button_release,
                None,
                self.event_drag_motion,
                self.event_expose)
        self.barrier_selection_started = True

    def event_button_release(self, widget, event):
        self.redirect_event_box_input(
                self.event_button_press,
                self.event_button_release,
                None,
                None,
                self.event_expose)
        (self.barrier_corner, self.barrier_size) = \
        corner_and_size_clipped(self.barrier_corner0, self.barrier_corner1,
                                self.event_box.size_request())
        self.barrier_md5sum = ppm_utils.get_region_md5sum(
                self.image_width, self.image_height, self.image_data,
                self.barrier_corner[0], self.barrier_corner[1],
                self.barrier_size[0], self.barrier_size[1])
        self.barrier_selected = True
        self.update_barrier_info()

    def event_key_press(self, widget, event):
        if self.check_manual.get_active():
            return False
        str = key_event_to_qemu_string(event)
        self.add_key(str)
        return True


class StepEditor(StepMakerWindow):
    ui = '''<ui>
    <menubar name="MenuBar">
        <menu action="File">
            <menuitem action="Open"/>
            <separator/>
            <menuitem action="Quit"/>
        </menu>
        <menu action="Edit">
            <menuitem action="CopyStep"/>
            <menuitem action="DeleteStep"/>
        </menu>
        <menu action="Insert">
            <menuitem action="InsertNewBefore"/>
            <menuitem action="InsertNewAfter"/>
            <separator/>
            <menuitem action="InsertStepsBefore"/>
            <menuitem action="InsertStepsAfter"/>
        </menu>
        <menu action="Tools">
            <menuitem action="CleanUp"/>
        </menu>
    </menubar>
</ui>'''

    # Constructor

    def __init__(self, filename=None):
        StepMakerWindow.__init__(self)

        self.steps_filename = None
        self.steps = []

        # Create a UIManager instance
        uimanager = gtk.UIManager()

        # Add the accelerator group to the toplevel window
        accelgroup = uimanager.get_accel_group()
        self.window.add_accel_group(accelgroup)

        # Create an ActionGroup
        actiongroup = gtk.ActionGroup('StepEditor')

        # Create actions
        actiongroup.add_actions([
            ('Quit', gtk.STOCK_QUIT, '_Quit', None, 'Quit the Program',
             self.quit),
            ('Open', gtk.STOCK_OPEN, '_Open', None, 'Open steps file',
             self.open_steps_file),
            ('CopyStep', gtk.STOCK_COPY, '_Copy current step...', "",
             'Copy current step to user specified position', self.copy_step),
            ('DeleteStep', gtk.STOCK_DELETE, '_Delete current step', "",
             'Delete current step', self.event_remove_clicked),
            ('InsertNewBefore', gtk.STOCK_ADD, '_New step before current', "",
             'Insert new step before current step', self.insert_before),
            ('InsertNewAfter', gtk.STOCK_ADD, 'N_ew step after current', "",
             'Insert new step after current step', self.insert_after),
            ('InsertStepsBefore', gtk.STOCK_ADD, '_Steps before current...',
             "", 'Insert steps (from file) before current step',
             self.insert_steps_before),
            ('InsertStepsAfter', gtk.STOCK_ADD, 'Steps _after current...', "",
             'Insert steps (from file) after current step',
             self.insert_steps_after),
            ('CleanUp', gtk.STOCK_DELETE, '_Clean up data directory', "",
             'Move unused PPM files to a backup directory', self.cleanup),
            ('File', None, '_File'),
            ('Edit', None, '_Edit'),
            ('Insert', None, '_Insert'),
            ('Tools', None, '_Tools')
            ])

        def create_shortcut(name, callback, keyname):
            # Create an action
            action = gtk.Action(name, None, None, None)
            # Connect a callback to the action
            action.connect("activate", callback)
            actiongroup.add_action_with_accel(action, keyname)
            # Have the action use accelgroup
            action.set_accel_group(accelgroup)
            # Connect the accelerator to the action
            action.connect_accelerator()

        create_shortcut("Next", self.event_next_clicked, "Page_Down")
        create_shortcut("Previous", self.event_prev_clicked, "Page_Up")

        # Add the actiongroup to the uimanager
        uimanager.insert_action_group(actiongroup, 0)

        # Add a UI description
        uimanager.add_ui_from_string(self.ui)

        # Create a MenuBar
        menubar = uimanager.get_widget('/MenuBar')
        self.menu_vbox.pack_start(menubar, False)

        # Remember the Edit menu bar for future reference
        self.menu_edit = uimanager.get_widget('/MenuBar/Edit')
        self.menu_edit.set_sensitive(False)

        # Remember the Insert menu bar for future reference
        self.menu_insert = uimanager.get_widget('/MenuBar/Insert')
        self.menu_insert.set_sensitive(False)

        # Remember the Tools menu bar for future reference
        self.menu_tools = uimanager.get_widget('/MenuBar/Tools')
        self.menu_tools.set_sensitive(False)

        # Next/Previous HBox
        hbox = gtk.HBox(spacing=10)
        self.user_vbox.pack_start(hbox)
        hbox.show()

        self.button_first = gtk.Button(stock=gtk.STOCK_GOTO_FIRST)
        self.button_first.connect("clicked", self.event_first_clicked)
        hbox.pack_start(self.button_first)
        self.button_first.show()

        #self.button_prev = gtk.Button("<< Previous")
        self.button_prev = gtk.Button(stock=gtk.STOCK_GO_BACK)
        self.button_prev.connect("clicked", self.event_prev_clicked)
        hbox.pack_start(self.button_prev)
        self.button_prev.show()

        self.label_step = gtk.Label("Step:")
        hbox.pack_start(self.label_step, False)
        self.label_step.show()

        self.entry_step_num = gtk.Entry()
        self.entry_step_num.connect("activate", self.event_entry_step_activated)
        self.entry_step_num.set_width_chars(3)
        hbox.pack_start(self.entry_step_num, False)
        self.entry_step_num.show()

        #self.button_next = gtk.Button("Next >>")
        self.button_next = gtk.Button(stock=gtk.STOCK_GO_FORWARD)
        self.button_next.connect("clicked", self.event_next_clicked)
        hbox.pack_start(self.button_next)
        self.button_next.show()

        self.button_last = gtk.Button(stock=gtk.STOCK_GOTO_LAST)
        self.button_last.connect("clicked", self.event_last_clicked)
        hbox.pack_start(self.button_last)
        self.button_last.show()

        # Save HBox
        hbox = gtk.HBox(spacing=10)
        self.user_vbox.pack_start(hbox)
        hbox.show()

        self.button_save = gtk.Button("_Save current step")
        self.button_save.connect("clicked", self.event_save_clicked)
        hbox.pack_start(self.button_save)
        self.button_save.show()

        self.button_remove = gtk.Button("_Delete current step")
        self.button_remove.connect("clicked", self.event_remove_clicked)
        hbox.pack_start(self.button_remove)
        self.button_remove.show()

        self.button_replace = gtk.Button("_Replace screendump")
        self.button_replace.connect("clicked", self.event_replace_clicked)
        hbox.pack_start(self.button_replace)
        self.button_replace.show()

        # Disable unused widgets
        self.button_capture.set_sensitive(False)
        self.spin_latency.set_sensitive(False)
        self.spin_sensitivity.set_sensitive(False)

        # Disable main vbox because no steps file is loaded
        self.main_vbox.set_sensitive(False)

        # Set title
        self.window.set_title("Step Editor")

    # Events

    def delete_event(self, widget, event):
        # Make sure the step is saved (if the user wants it to be)
        self.verify_save()

    def event_first_clicked(self, widget):
        if not self.steps:
            return
        # Make sure the step is saved (if the user wants it to be)
        self.verify_save()
        # Go to first step
        self.set_step(0)

    def event_last_clicked(self, widget):
        if not self.steps:
            return
        # Make sure the step is saved (if the user wants it to be)
        self.verify_save()
        # Go to last step
        self.set_step(len(self.steps) - 1)

    def event_prev_clicked(self, widget):
        if not self.steps:
            return
        # Make sure the step is saved (if the user wants it to be)
        self.verify_save()
        # Go to previous step
        index = self.current_step_index - 1
        if self.steps:
            index = index % len(self.steps)
        self.set_step(index)

    def event_next_clicked(self, widget):
        if not self.steps:
            return
        # Make sure the step is saved (if the user wants it to be)
        self.verify_save()
        # Go to next step
        index = self.current_step_index + 1
        if self.steps:
            index = index % len(self.steps)
        self.set_step(index)

    def event_entry_step_activated(self, widget):
        if not self.steps:
            return
        step_index = self.entry_step_num.get_text()
        if not step_index.isdigit():
            return
        step_index = int(step_index) - 1
        if step_index == self.current_step_index:
            return
        self.verify_save()
        self.set_step(step_index)

    def event_save_clicked(self, widget):
        if not self.steps:
            return
        self.save_step()

    def event_remove_clicked(self, widget):
        if not self.steps:
            return
        if not self.question_yes_no("This will modify the steps file."
                                    " Are you sure?", "Remove step?"):
            return
        # Remove step
        del self.steps[self.current_step_index]
        # Write changes to file
        self.write_steps_file(self.steps_filename)
        # Move to previous step
        self.set_step(self.current_step_index)

    def event_replace_clicked(self, widget):
        if not self.steps:
            return
        # Let the user choose a screendump file
        current_filename = os.path.join(self.steps_data_dir,
                                        self.entry_screendump.get_text())
        filename = self.filedialog("Choose PPM image file",
                                   default_filename=current_filename)
        if not filename:
            return
        if not ppm_utils.image_verify_ppm_file(filename):
            self.message("Not a valid PPM image file.", "Error")
            return
        self.clear_image()
        self.clear_barrier_state()
        self.set_image_from_file(filename)
        self.update_screendump_id(self.steps_data_dir)

    # Menu actions

    def open_steps_file(self, action):
        # Make sure the step is saved (if the user wants it to be)
        self.verify_save()
        # Let the user choose a steps file
        current_filename = self.steps_filename
        filename = self.filedialog("Open steps file",
                                   default_filename=current_filename)
        if not filename:
            return
        self.set_steps_file(filename)

    def quit(self, action):
        # Make sure the step is saved (if the user wants it to be)
        self.verify_save()
        # Quit
        gtk.main_quit()

    def copy_step(self, action):
        if not self.steps:
            return
        self.verify_save()
        self.set_step(self.current_step_index)
        # Get the desired position
        step_index = self.inputdialog("Copy step to position:",
                                      "Copy step",
                                      str(self.current_step_index + 2))
        if not step_index:
            return
        step_index = int(step_index) - 1
        # Get the lines of the current step
        step = self.steps[self.current_step_index]
        # Insert new step at position step_index
        self.steps.insert(step_index, step)
        # Go to new step
        self.set_step(step_index)
        # Write changes to disk
        self.write_steps_file(self.steps_filename)

    def insert_before(self, action):
        if not self.steps_filename:
            return
        if not self.question_yes_no("This will modify the steps file."
                                    " Are you sure?", "Insert new step?"):
            return
        self.verify_save()
        step_index = self.current_step_index
        # Get the lines of a blank step
        self.clear_state()
        step = self.get_step_lines()
        # Insert new step at position step_index
        self.steps.insert(step_index, step)
        # Go to new step
        self.set_step(step_index)
        # Write changes to disk
        self.write_steps_file(self.steps_filename)

    def insert_after(self, action):
        if not self.steps_filename:
            return
        if not self.question_yes_no("This will modify the steps file."
                                    " Are you sure?", "Insert new step?"):
            return
        self.verify_save()
        step_index = self.current_step_index + 1
        # Get the lines of a blank step
        self.clear_state()
        step = self.get_step_lines()
        # Insert new step at position step_index
        self.steps.insert(step_index, step)
        # Go to new step
        self.set_step(step_index)
        # Write changes to disk
        self.write_steps_file(self.steps_filename)

    def insert_steps(self, filename, index):
        # Read the steps file
        (steps, header) = self.read_steps_file(filename)

        data_dir = ppm_utils.get_data_dir(filename)
        for step in steps:
            self.set_state_from_step_lines(step, data_dir, warn=False)
            step = self.get_step_lines(self.steps_data_dir)

        # Insert steps into self.steps
        self.steps[index:index] = steps
        # Write changes to disk
        self.write_steps_file(self.steps_filename)

    def insert_steps_before(self, action):
        if not self.steps_filename:
            return
        # Let the user choose a steps file
        current_filename = self.steps_filename
        filename = self.filedialog("Choose steps file",
                                   default_filename=current_filename)
        if not filename:
            return
        self.verify_save()

        step_index = self.current_step_index
        # Insert steps at position step_index
        self.insert_steps(filename, step_index)
        # Go to new steps
        self.set_step(step_index)

    def insert_steps_after(self, action):
        if not self.steps_filename:
            return
        # Let the user choose a steps file
        current_filename = self.steps_filename
        filename = self.filedialog("Choose steps file",
                                   default_filename=current_filename)
        if not filename:
            return
        self.verify_save()

        step_index = self.current_step_index + 1
        # Insert new steps at position step_index
        self.insert_steps(filename, step_index)
        # Go to new steps
        self.set_step(step_index)

    def cleanup(self, action):
        if not self.steps_filename:
            return
        if not self.question_yes_no("All unused PPM files will be moved to a"
                                    " backup directory. Are you sure?",
                                    "Clean up data directory?"):
            return
        # Remember the current step index
        current_step_index = self.current_step_index
        # Get the backup dir
        backup_dir = os.path.join(self.steps_data_dir, "backup")
        # Create it if it doesn't exist
        if not os.path.exists(backup_dir):
            os.makedirs(backup_dir)
        # Move all files to the backup dir
        for filename in glob.glob(os.path.join(self.steps_data_dir,
                                               "*.[Pp][Pp][Mm]")):
            shutil.move(filename, backup_dir)
        # Get the used files back
        for step in self.steps:
            self.set_state_from_step_lines(step, backup_dir, warn=False)
            self.get_step_lines(self.steps_data_dir)
        # Remove the used files from the backup dir
        used_files = os.listdir(self.steps_data_dir)
        for filename in os.listdir(backup_dir):
            if filename in used_files:
                os.unlink(os.path.join(backup_dir, filename))
        # Restore step index
        self.set_step(current_step_index)
        # Inform the user
        self.message("All unused PPM files may be found at %s." %
                     os.path.abspath(backup_dir),
                     "Clean up data directory")

    # Methods

    def read_steps_file(self, filename):
        steps = []
        header = ""

        file = open(filename, "r")
        for line in file.readlines():
            words = line.split()
            if not words:
                continue
            if line.startswith("# ----"):
                continue
            if words[0] == "step":
                steps.append("")
            if steps:
                steps[-1] += line
            else:
                header += line
        file.close()

        return (steps, header)

    def set_steps_file(self, filename):
        try:
            (self.steps, self.header) = self.read_steps_file(filename)
        except (TypeError, IOError):
            self.message("Cannot read file %s." % filename, "Error")
            return

        self.steps_filename = filename
        self.steps_data_dir = ppm_utils.get_data_dir(filename)
        # Go to step 0
        self.set_step(0)

    def set_step(self, index):
        # Limit index to legal boundaries
        if index < 0:
            index = 0
        if index > len(self.steps) - 1:
            index = len(self.steps) - 1

        # Enable the menus
        self.menu_edit.set_sensitive(True)
        self.menu_insert.set_sensitive(True)
        self.menu_tools.set_sensitive(True)

        # If no steps exist...
        if self.steps == []:
            self.current_step_index = index
            self.current_step = None
            # Set window title
            self.window.set_title("Step Editor -- %s" %
                                  os.path.basename(self.steps_filename))
            # Set step entry widget text
            self.entry_step_num.set_text("")
            # Clear the state of all widgets
            self.clear_state()
            # Disable the main vbox
            self.main_vbox.set_sensitive(False)
            return

        self.current_step_index = index
        self.current_step = self.steps[index]
        # Set window title
        self.window.set_title("Step Editor -- %s -- step %d" %
                              (os.path.basename(self.steps_filename),
                               index + 1))
        # Set step entry widget text
        self.entry_step_num.set_text(str(self.current_step_index + 1))
        # Load the state from the step lines
        self.set_state_from_step_lines(self.current_step, self.steps_data_dir)
        # Enable the main vbox
        self.main_vbox.set_sensitive(True)
        # Make sure the step lines in self.current_step are identical to the
        # output of self.get_step_lines
        self.current_step = self.get_step_lines()

    def verify_save(self):
        if not self.steps:
            return
        # See if the user changed anything
        if self.get_step_lines() != self.current_step:
            if self.question_yes_no("Step contents have been modified."
                                    " Save step?", "Save changes?"):
                self.save_step()

    def save_step(self):
        lines = self.get_step_lines(self.steps_data_dir)
        if lines != None:
            self.steps[self.current_step_index] = lines
            self.current_step = lines
            self.write_steps_file(self.steps_filename)

    def write_steps_file(self, filename):
        file = open(filename, "w")
        file.write(self.header)
        for step in self.steps:
            file.write("# " + "-" * 32 + "\n")
            file.write(step)
        file.close()


if __name__ == "__main__":
    se = StepEditor()
    if len(sys.argv) > 1:
        se.set_steps_file(sys.argv[1])
    gtk.main()
