1# -*- coding: utf-8 -*-
2import os
3import sys
4import argparse
5import ctypes
6import time
7import test_utils
8from   subprocess import Popen
9import winreg
10import logging
11import test_constants
12import filecmp
13import shutil
14from io import StringIO
15try:
16    from junit_xml import TestCase
17except ImportError:
18    print("junit_xml module not found. Please install it by running 'pip install junit_xml' if you want to generate JUnit XML report.")
19
20user32 = ctypes.windll.user32
21
22studio_exe_path = "../../../guix_studio/build/vs_2019/Release/guix_studio.exe"
23top_windows = []
24WM_CLOSE = 0x0010
25reset_map_format = False
26change_color_table = False
27Debug = False
28
29props_ctrl_ids = {}
30widget_types = {}
31color_formats = {}
32font_formats = {}
33group_ids = {}
34folder_ids = {}
35resource_item_types = {}
36palette_types = {}
37border_types = {}
38trigger_types = {}
39animation_param_ids = {}
40
41#dictionary of studio window name : handle
42studio_windows = {
43    'main_frame':0,
44    'Properties Win':0,
45    'Project View':0,
46    'Target Screen':0,
47    'Target View':0,
48    'Resource View':0,
49    }
50
51CREATE_NEW_PROJECT_DIALOG = 'Create New Project'
52CONFIGURE_PROJECT_DIALOG = 'Configure Project'
53SYNERGY_SETTINGS_DIALOG = 'Renesas Graphics Advanced Settings'
54CONFIGURE_THEME_DIALOG = 'Configure Themes'
55CONFIGURE_LANGUAGE_DIALOG = 'Configure Languages'
56EDIT_FONT_DIALOG = 'Edit Font'
57EDIT_COLOR_DIALOG = 'Edit Color'
58EDIT_PIXELMAP_DIALOG = 'Edit Pixelmap(s)'
59STRING_TABLE_EDITOR_DIALOG = 'String Table Editor'
60STRING_EXPORT_CONTROL_DIALOG = 'XLIFF/CSV Export Control'
61NOTIFICATION_DIALOG = 'Notification'
62ERROR_DIALOG = 'Error'
63PLEASE_CONFIRM_DIALOG = 'Please Confirm'
64RECORD_MACRO_DIALOG = 'Record Macro'
65PLAYBACK_MACRO_DIALOG = 'Playback Macro'
66EDIT_FOLDER_NAME_DIALOG = 'Edit Folder Name'
67GRID_SNAP_SETTING_DIALOG = 'Grid and Snap Settings'
68RESOURCE_EXPORT_DIALOG = 'Select Export Resources'
69STRING_SCROLL_WHEEL_EDIT_DIALOG = 'String Scroll Wheel Edit'
70IMPORT_PROJECT_DIALOG = 'Import Project'
71OPTION_DIALOG='Warning'
72WAIT_DIALOG='Please Wait...'
73EDIT_PALETTE_DIALOG='Edit Palette'
74SCREEN_FLOW_EDIT_DIALOG='Edit Screen Flow'
75TRIGGER_LIST_EDIT_DIALOG='Edit Trigger List'
76TRIGGER_EDIT_DIALOG='trigger edit dialog'
77TRIGGER_ACTION_EDIT_DIALOG='trigger action edit dialog'
78TRIGGER_ACTION_SELECT_DIALOG='Select Action'
79EASING_FUNCTION_SELECT_DIALOG='Select Easing Function'
80RICH_TEXT_EDIT_DIALOG='Edit Rich Text'
81SPRITE_FRAME_EDIT_DIALOG='Edit Sprite Frames'
82SPRITE_FRAME_IMPORT_DIALOG='Import Sprite Frames'
83APP_EXECUTION_WINDOW='GUIX'
84
85GW_CHILD = 5
86GW_HWNDNEXT = 2
87
88active_dialog_stack = []
89
90#dictionary of studio dialog name: handle
91studio_dialogs = {
92    CREATE_NEW_PROJECT_DIALOG:0,
93    CONFIGURE_PROJECT_DIALOG:0,
94    SYNERGY_SETTINGS_DIALOG:0,
95    CONFIGURE_THEME_DIALOG:0,
96    CONFIGURE_LANGUAGE_DIALOG:0,
97    EDIT_FONT_DIALOG:0,
98    EDIT_COLOR_DIALOG:0,
99    EDIT_PIXELMAP_DIALOG:0,
100    STRING_TABLE_EDITOR_DIALOG:0,
101    STRING_EXPORT_CONTROL_DIALOG:0,
102    NOTIFICATION_DIALOG:0,
103    ERROR_DIALOG:0,
104    PLEASE_CONFIRM_DIALOG:0,
105    RECORD_MACRO_DIALOG:0,
106    PLAYBACK_MACRO_DIALOG:0,
107    EDIT_FOLDER_NAME_DIALOG:0,
108    GRID_SNAP_SETTING_DIALOG:0,
109    RESOURCE_EXPORT_DIALOG:0,
110    STRING_SCROLL_WHEEL_EDIT_DIALOG:0,
111    IMPORT_PROJECT_DIALOG:0,
112    OPTION_DIALOG:0,
113    WAIT_DIALOG:0,
114    EDIT_PALETTE_DIALOG:0,
115    SCREEN_FLOW_EDIT_DIALOG:0,
116    TRIGGER_LIST_EDIT_DIALOG:0,
117    TRIGGER_EDIT_DIALOG:0,
118    TRIGGER_ACTION_EDIT_DIALOG:0,
119    TRIGGER_ACTION_SELECT_DIALOG:0,
120    EASING_FUNCTION_SELECT_DIALOG:0,
121    RICH_TEXT_EDIT_DIALOG:0,
122    SPRITE_FRAME_EDIT_DIALOG:0,
123    SPRITE_FRAME_IMPORT_DIALOG:0,
124    APP_EXECUTION_WINDOW:0
125}
126
127STUDIO_TEST_MESG = 0x0402
128studio_test_index = 0
129DEFAULT_TEST_FAILURE_PATH = 'test_failures/'
130DEFAULT_OUTPUT_FILE_PATH = "output_files/"
131DEFAULT_GOLDEN_FILE_PATH = 'golden_files/'
132gen_golden_file_pathname = ""
133test_name = ""
134gen_golden_file = False
135gen_screenshot = False
136good_results = []
137result_count = [0, 0]
138total_failures = 0
139CLOSE_WAIT = 0
140CLOSE_NO_WAIT = 1
141CLOSE_NOTIFICATION_MSG = True
142CLOSE_ERROR_MSG = True
143selected_screen_name = ""
144test_start_time = 0
145test_cases = []
146test_log_stream = StringIO()
147test_log_txt = None
148test_log_xml = None
149
150def get_total_failures():
151    global total_failures
152    return total_failures
153
154#Compile studio
155def studio_compile(msbuild_exe_path, project_sln_path):
156    #Ensure msbuild exists
157    if not os.path.isfile(msbuild_exe_path):
158        raise Exception('Msbuild.exe not found. path=' + msbuild_exe_path)
159
160    #Ensure solution file exists
161    if not os.path.isfile(msbuild_exe_path):
162        raise Exception('studiox.sln not found. path=' + project_sln_path)
163
164    os.system("msbuild " + project_sln_path + " /p:Configuration=Release")
165
166#generate resource files
167def generate(gxp_project, studio_release):
168    path = os.path.realpath(DEFAULT_OUTPUT_FILE_PATH)
169
170    if os.path.exists(path) == False:
171        os.makedirs(path)
172
173    if not os.path.isfile(gxp_project):
174        raise Exception('gxp project not found. path=' + studio_release)
175
176    if not os.path.isfile(studio_release):
177        raise Exception('guix_studio.exe not found. path=' + studio_release)
178
179    absolute_path = os.path.abspath(gxp_project)
180    os.system(os.path.abspath(studio_release) + " -p " + absolute_path + " -n")
181
182#compare two resource files
183def compare_file(pathname_1, pathname_2, encoding = "", compare_start_string = "", skip_line = ""):
184    logging.info('Comparing: %s and %s', pathname_1, pathname_2)
185
186    # check if files exist
187    if not os.path.isfile(pathname_1):
188        logging.error("** ERROR ** %s does not exist", pathname_1)
189        return False
190
191    if not os.path.isfile(pathname_2):
192        logging.error("** ERROR ** %s does not exist", pathname_2)
193        return False
194
195    # open comparing files
196    if encoding != "":
197        file_1 = open(pathname_1,'r', encoding=encoding)
198        file_2 = open(pathname_2, 'r', encoding=encoding)
199    else:
200        file_1 = open(pathname_1,'r')
201        file_2 = open(pathname_2, 'r')
202
203    # read files into lists
204    list_1 = file_1.readlines()
205    list_2 = file_2.readlines()
206
207    start_row_1 = 0
208    start_row_2 = 0
209
210    if compare_start_string != "":
211        # find the line where comparing starts
212        for line in list_1:
213            if compare_start_string in line:
214                start_row_1 = list_1.index(line)
215                break;
216
217        for line in list_2:
218            if compare_start_string in line:
219                start_row_2 = list_1.index(line)
220                break;
221
222    # compare from the start line
223    list_1 = list_1[start_row_1:]
224    list_2 = list_2[start_row_2:]
225
226    for line_1,line_2 in zip(list_1,list_2):
227        # If the skip line string is not empty, skip the line if it contains the skip_line string
228        if skip_line != "" and skip_line in line_1:
229            continue
230
231        if line_1 != line_2:
232            logging.error("** ERROR ** Does Not Match:\n%s\n%s" %(line_1, line_2))
233            return False
234
235    logging.info("Match success.")
236    return True
237
238def compare_output_file(pathname_1, pathname_2):
239    return compare_file(pathname_1, pathname_2, '', '#include')
240
241def compare_xliff_file(pathname_1, pathname_2):
242    return compare_file(pathname_1, pathname_2, 'utf-8', '', '<file')
243
244def compare_xml_file(pathname_1, pathname_2):
245    return compare_file(pathname_1, pathname_2, 'utf-8', '', '<studio_version>')
246
247def compare_normal_file(pathname_1, pathname_2):
248    return compare_file(pathname_1, pathname_2, 'utf-8')
249
250def cmp_files(output_file_lists, compare_func, output_file_path = DEFAULT_OUTPUT_FILE_PATH, golden_file_path = DEFAULT_GOLDEN_FILE_PATH):
251    global studio_test_index
252
253    if gen_golden_file == True:
254        golden_file = open(gen_golden_file_pathname, "a+")
255        if studio_test_index == 0:
256            golden_file.write("good_results = [\n")
257
258        #save golden values
259        golden_file.write("    0, #test %d, comparing files\n" %(studio_test_index))
260
261    else:
262        result = True
263        for file in output_file_lists:
264            golden_file = golden_file_path + file
265            output_file = output_file_path + file
266            if compare_func(output_file, golden_file) == False:
267                result = False
268
269        if result == True:
270            print('Test %d passed' %studio_test_index)
271            logging.info("Test #%d, compare output files- Passed." %studio_test_index)
272            result_count[0] += 1
273        else:
274            print('** Test %d failed **' %studio_test_index)
275            logging.info("Test #%d, compare output files- Failed." %studio_test_index)
276            result_count[1] += 1
277
278    studio_test_index += 1
279
280def cmp_output_files(output_file_lists, output_file_path = DEFAULT_OUTPUT_FILE_PATH, golden_file_path = DEFAULT_GOLDEN_FILE_PATH):
281    cmp_files(output_file_lists, compare_output_file, output_file_path, golden_file_path)
282
283def cmp_normal_files(normal_file_lists, output_file_path = DEFAULT_OUTPUT_FILE_PATH, golden_file_path = DEFAULT_GOLDEN_FILE_PATH):
284    cmp_files(normal_file_lists, compare_normal_file, output_file_path, golden_file_path)
285
286def cmp_xml_files(xml_file_lists, output_file_path = DEFAULT_OUTPUT_FILE_PATH, golden_file_path = DEFAULT_GOLDEN_FILE_PATH):
287    cmp_files(xml_file_lists, compare_xml_file, output_file_path, golden_file_path)
288
289# run the Studio executable
290def run_studio():
291    absolute_path = os.path.abspath(studio_exe_path)
292    if not os.path.isfile(absolute_path):
293        raise Exception("Unable to locate Studio executable.")
294    Popen(os.path.abspath(absolute_path))
295    time.sleep(5)
296
297def wait_for_key(prompt = ''):
298     if Debug:
299        if prompt:
300             print('%s' %prompt)
301
302        input("\nPress Enter to continue")
303
304
305def enum_callback(hwnd, lParam):
306    if user32.IsWindowVisible(hwnd):
307        length = user32.GetWindowTextLengthW(hwnd) + 1
308
309        if length > 1:
310            buffer = ctypes.create_unicode_buffer(length)
311            user32.GetWindowTextW(hwnd, buffer, length)
312            top_windows.append((hwnd, buffer.value))
313    return True
314
315# search for named child windows, save handles for those that we want to send
316# test events
317
318def get_window_tree(hwnd):
319    # get the first child window
320    child = user32.GetWindow(hwnd, GW_CHILD)
321
322    while child:
323        length = user32.GetWindowTextLengthW(child) + 1
324        if length > 1:
325            buffer = ctypes.create_unicode_buffer(length)
326            user32.GetWindowTextW(child, buffer, length)
327
328            if buffer.value in studio_windows:
329                studio_windows[buffer.value] = child
330
331        get_window_tree(child)
332
333        # get the next child window
334        child = user32.GetWindow(child, GW_HWNDNEXT)
335
336#send a test event to the requested Studio window
337def send_to_studio(handle, cmd, param):
338    result = 0
339
340    if type(param) == str:
341        with open('c:\\temp\\guix_param0.txt', 'w', encoding="utf-8") as fparam:
342            fparam.write(param)
343            fparam.close()
344
345        result = user32.SendMessageA(handle, STUDIO_TEST_MESG, cmd, None)
346    else:
347        result = user32.SendMessageA(handle, STUDIO_TEST_MESG, cmd, param)
348    return result
349
350def post_to_studio(handle, cmd, param):
351    result = 0
352
353    if type(param) == str:
354        with open('c:\\temp\\guix_param1.txt', 'w', encoding="utf-8") as fparam:
355            fparam.write(param)
356            fparam.close()
357
358        result = user32.PostMessageA(handle, STUDIO_TEST_MESG, cmd, None)
359    else:
360        result = user32.PostMessageA(handle, STUDIO_TEST_MESG, cmd, param)
361    return result
362
363def delete_temp_files():
364    if (os.path.exists("c:\\temp\\guix_param1.txt")):
365        os.remove("c:\\temp\\guix_param1.txt")
366
367    if (os.path.exists("c:\\temp\\guix_param0.txt")):
368        os.remove("c:\\temp\\guix_param0.txt")
369
370# locate the Studio windows and store handles
371def find_studio_handles():
372    a = ctypes.WINFUNCTYPE(ctypes.c_bool,
373                       ctypes.POINTER(ctypes.c_int),
374                       ctypes.POINTER(ctypes.c_int))(enum_callback)
375    user32.EnumWindows(a, 0)
376
377    found_studio = False
378
379    for hwnd, name in top_windows:
380        if 'GUIX Studio' in name:
381            found_studio = True
382            studio_windows['main_frame'] = ctypes.c_void_p.from_buffer(hwnd).value
383            get_window_tree(hwnd)
384
385    if found_studio:
386        for name in studio_windows:
387            if studio_windows[name] == 0:
388                print('Unable to find Studio window named: %s' %name)
389                return False
390            else:
391                print('Found Studio Window: %s' %name)
392    return found_studio
393
394# find dialog handle
395def find_dialog(name, owner = 0, class_name = '#32770'):
396    if class_name == 'GUIX':
397        owner = 0
398    elif owner == 0:
399        owner = studio_windows['main_frame']
400
401    param = class_name + ';'
402    param += name + ';'
403    param += str(owner)
404
405    studio_dialogs[name] = send_to_main_frame('CMD_FIND_DIALOG', param)
406
407    return studio_dialogs[name]
408
409def close_dialog(name, owner = 0):
410    retries = 0
411    wait_dialog_open(name, owner)
412
413    while retries < 3:
414        user32.PostMessageA(studio_dialogs[name], WM_CLOSE, None, None)
415        if wait_dialog_close(name, owner) is True:
416            return
417        retries += 1
418
419    raise Exception('Unable to close %s dialog' %name)
420
421def close_window(name, owner = 0):
422    user32.PostMessageA(studio_windows[name], WM_CLOSE, None, None)
423
424def wait_dialog_open(name, owner = 0, class_name = '#32770'):
425    time_start = time.time()
426
427    logging.debug("wait dialog open: %s", name)
428    if owner == 0 and len(active_dialog_stack) > 0:
429        logging.debug("dialog parent: %s", active_dialog_stack[-1])
430        owner = studio_dialogs[active_dialog_stack[-1]]
431
432    while find_dialog(name, owner, class_name) == 0:
433        time.sleep(1)
434        interval = time.time() - time_start
435        if interval > 300:
436            raise Exception('Unable to open %s dialog' %name)
437            break
438    active_dialog_stack.append(name)
439    logging.debug("push active dialog: %s", name)
440    logging.debug("active dialog list: %s", active_dialog_stack)
441    time.sleep(1)
442
443def wait_dialog_close(name, owner = 0, class_name = '#32770'):
444    #wait popup dialog close
445    time_start = time.time()
446
447    if owner == 0 and len(active_dialog_stack) > 1:
448        owner = studio_dialogs[active_dialog_stack[-2]]
449
450    while find_dialog(name, owner, class_name) != studio_dialogs[name]:
451        time.sleep(1)
452        interval = time.time() - time_start
453        if interval > 300:
454            return False
455    time.sleep(1)
456    active_dialog_stack.pop()
457    logging.debug("pop active dialog: %s", name)
458    logging.debug("active dialog list: %s", active_dialog_stack)
459    return True
460
461# compare canvas crc32 value with known good value, or
462# print value if it's a new index
463def compare_result():
464    global studio_test_index
465    result = get_result()
466
467    if result == 0:
468        return True
469
470    while is_wait_dialog_running() == True:
471        time.sleep(5)
472
473    #generate screen shot
474    if gen_screenshot == True:
475        path = os.path.realpath(DEFAULT_OUTPUT_FILE_PATH + "/" + test_name)
476        if os.path.exists(path) == False:
477            os.makedirs(path)
478        filename = path + "/test_" + str(studio_test_index) + ".bmp"
479        generate_screenshot(filename)
480
481    if gen_golden_file == True:
482        golden_file = open(gen_golden_file_pathname, "a+")
483        if studio_test_index == 0:
484            golden_file.write("good_results = [\n")
485
486        #save golden values
487        golden_file.write("    %#x, #test %d\n" %(result, studio_test_index))
488
489        print('Generate CRC32 for test %d' %studio_test_index)
490        logging.info("test %d. Golden value: %#x.\n" %(studio_test_index, result)) #print golden values
491        studio_test_index += 1
492    else:
493        if len(good_results) > studio_test_index and good_results[studio_test_index] != 0:
494            if good_results[studio_test_index] == result:
495                print('Test %d passed' %studio_test_index)
496                logging.info("Test #%d, compute CRC32 on canvas memory- Passed.\n" %studio_test_index)
497                result_count[0] += 1
498                studio_test_index += 1
499                return True
500            else:
501                #generate failure screen shots
502                path = os.path.realpath(DEFAULT_TEST_FAILURE_PATH)
503                if os.path.exists(path) == False:
504                    os.makedirs(path)
505                filename = path + "/" + test_name +"_" + str(studio_test_index) + ".bmp"
506                generate_screenshot(filename)
507
508                print('** Test %d failed **' %studio_test_index)
509                logging.error("CRC32 failure on test %d. Golden value: %#x  Result Value: %#x\n" %(studio_test_index, good_results[studio_test_index], result))
510                result_count[1] += 1
511                studio_test_index += 1
512
513                #this will make the script wait here until the user inputs a CR key
514                #input()
515                return False
516        else:
517            logging.info('Result for index %d is %#x' %(studio_test_index, result))
518            studio_test_index += 1
519            return True
520
521
522def set_test_results(passed, test_type, error_msg):
523    global studio_test_index
524
525    if gen_golden_file == True:
526        golden_file = open(gen_golden_file_pathname, "a+")
527        if studio_test_index == 0:
528            golden_file.write("good_results = [\n")
529
530        golden_file.write("    0, #test %d, %s\n" %(studio_test_index, test_type))
531    else:
532        if passed == True:
533            print('Test %d passed' %studio_test_index)
534            logging.info("Test #%d, %s- Passed.\n", studio_test_index, test_type)
535            result_count[0] += 1
536        else:
537            print('** Test %d failed **' %studio_test_index)
538            logging.info("Test #%d, %s- Failed.\n", studio_test_index, test_type)
539            logging.info(error_msg)
540            result_count[1] += 1
541
542    studio_test_index += 1
543
544def output_test_header(header_notes):
545    global test_start_time
546    test_start_time = time.time()
547    global test_log_stream
548    test_log_stream.truncate(0)
549    test_log_stream.seek(0)
550
551    logging.info("*******************************************************")
552    logging.info(header_notes)
553    logging.info("*                                                     *")
554    logging.info("*******************************************************")
555    logging.info("Test date: %s\n", time.asctime())
556
557def clean_up():
558    path = os.path.realpath(DEFAULT_TEST_FAILURE_PATH)
559    print(path)
560    if os.path.exists(path):
561        shutil.rmtree(path)
562
563    path = os.path.realpath(DEFAULT_OUTPUT_FILE_PATH)
564    print(path)
565    if os.path.exists(path):
566        shutil.rmtree(path)
567
568def setup(generate, screenshot, golden_file):
569    test_utils.gen_golden_file = generate
570    test_utils.gen_screenshot = screenshot
571
572    global studio_test_index
573    studio_test_index = 0;
574
575    global test_name
576    test_name = golden_file.replace("_golden_file", "")
577
578    if os.path.exists(DEFAULT_OUTPUT_FILE_PATH) == False:
579        os.makedirs(DEFAULT_OUTPUT_FILE_PATH)
580
581    if generate:
582        global gen_golden_file_pathname
583
584        if golden_file is not None:
585            gen_golden_file_pathname = DEFAULT_OUTPUT_FILE_PATH + golden_file + ".py"
586
587        #delete old golden file
588        if os.path.exists(gen_golden_file_pathname):
589            os.remove(gen_golden_file_pathname)
590
591        print("golden file path: %s" %gen_golden_file_pathname)
592    else:
593        module = __import__("golden_files.%s" %(golden_file), fromlist=["golden_files"])
594        global good_results
595        good_results = module.good_results
596    global active_dialog_stack
597    active_dialog_stack = []
598
599def write_end(test_name):
600    global good_results
601    global total_failures
602    global test_log_xml
603    global test_cases
604
605    if gen_golden_file == True:
606        golden_file = open(gen_golden_file_pathname, "a+")
607        golden_file.write("]")
608    else:
609        if len(good_results):
610            failures = len(good_results) - result_count[0]
611        else:
612            failures = result_count[1]
613
614        total_failures += failures
615        logging.info("********************************************************************")
616        logging.info("** Test %s completed." %test_name)
617        logging.info('** Tests Passed: %d  Tests Failed %d' %(result_count[0], failures))
618        logging.info("********************************************************************")
619        logging.info("Total Faiures: %d\n", total_failures)
620        logging.info("\n\n\n")
621
622        print('\nTest %s completed. \nTests Passed: %d\nTests Failed: %d\n' %(test_name, result_count[0], failures))
623        print('Total Failures: %d\n' %(total_failures))
624
625        result_count[0] = 0
626        result_count[1] = 0
627        studio_test_index = 0
628        good_results = []
629
630    test_time = time.time() - test_start_time
631    test_log_txt.write(test_log_stream.getvalue())
632
633    if test_log_xml is not None:
634        test = TestCase(test_name, "", test_time, test_log_stream.getvalue(), None)
635        if failures:
636            test.add_failure_info("Failed.")
637        test_cases.append(test)
638
639# read c++ type defines into a python dictionary
640def read_defines(file_path, prefix):
641    if os.path.exists(file_path) is False:
642        print("** ERROR ** %s does not exist" %file_path)
643        return False
644
645    logging.info("read '%s' defines from %s", prefix, file_path)
646
647    file = open(file_path, 'r')
648    lines = file.readlines()
649
650    # read defines into string
651    defines = {}
652    for line in lines:
653        if '#define' in line and prefix in line:
654            line = ' '.join(line.split())
655            list = line.split()
656            defines[list[1]] = int(list[2], 0)
657
658    return defines
659
660# read c++ type enum structure into a python dictionary
661def read_enum(file_path, variable_name):
662    if os.path.exists(file_path) is False:
663        print("** ERROR ** %s does not exist" %file_path)
664        return False
665
666    logging.info("read '%s' enum structure from %s", variable_name, file_path)
667
668    file = open(file_path, 'r')
669    lines = file.readlines()
670
671    start_read = False
672
673    # read enum structure into string
674    enum_str = ''
675    for line in lines:
676        if 'enum' in line and variable_name in line:
677            start_read = True
678
679        if start_read:
680            enum_str += line
681
682            index = line.find('}')
683            if index >= 0:
684                break
685
686    # remove braces
687    index = enum_str.find('{')
688    if index >= 0:
689        enum_str = enum_str[index + 1:]
690
691    index = enum_str.find('}')
692    if index >= 0:
693        enum_str = enum_str[:index - 1]
694
695    # remove line breaks
696    enum_str = enum_str.replace('\n', '')
697    enum_str = enum_str.replace('\r', '')
698
699    # read enums into a dictionary of {"ID", value} pair
700    enum = {}
701    enum_index = 0
702    index = enum_str.find(',')
703    while len(enum_str) > 0:
704
705        if index == -1:
706            temp = enum_str
707            enum_str =  ''
708        else:
709            temp = enum_str[0:index]
710            enum_str = enum_str[index + 1:]
711
712        index = temp.find('=')
713        if index >= 0:
714            if index == 0:
715                temp = ''
716            else:
717                enum_index = int(temp[index + 1:])
718                temp = temp[0:index - 1]
719
720        temp = temp.replace(' ', '')
721
722        if len(temp) > 0:
723            enum[temp] = enum_index
724            enum_index += 1
725
726        index = enum_str.find(',')
727
728    return enum
729
730def read_constants():
731    logging.info("*******************************************************")
732    logging.info("*                Reading Constants                    *")
733    logging.info("*                                                     *")
734    logging.info("*******************************************************")
735    print('Reading Constants')
736
737    gx_api_h = '..//..//..//common//inc//gx_api.h'
738    studioxproject_h = '..//..//..//guix_studio//StudioXProject.h'
739    properties_win_cpp = '..//..//..//guix_studio//properties_win.cpp'
740    trigger_edit_dlg_h = '..//..//..//guix_studio//trigger_edit_dlg.h'
741    trigger_action_edit_dlg_h = '..//..//..//guix_studio//trigger_action_edit_dlg.h'
742
743    # read property control ids
744    global props_ctrl_ids
745    props_ctrl_ids = read_enum(properties_win_cpp, 'CONTROL_IDS')
746
747    # read widget types
748    global widget_types
749    widget_types = read_defines(gx_api_h, 'GX_TYPE')
750
751    # read color formats
752    global color_formats
753    color_formats = read_defines(gx_api_h, 'GX_COLOR_FORMAT')
754
755    # read font formats
756    global font_formats
757    font_formats = read_defines(gx_api_h, 'GX_FONT_FORMAT')
758
759    global resource_item_types
760    resource_item_types = read_enum(studioxproject_h, 'resource_item_types')
761
762    global group_ids
763    group_ids = read_enum(studioxproject_h, 'GROUP_IDS')
764
765    global folder_ids
766    folder_ids = read_enum(studioxproject_h, 'FolderIds')
767
768    global palette_types
769    palette_types = read_enum(studioxproject_h, 'PALETTE_TYPES')
770
771    global trigger_types
772    trigger_types = read_enum(trigger_edit_dlg_h, 'TRIGGER_TYPE')
773
774    global animation_param_ids
775    animation_param_ids = read_enum(trigger_action_edit_dlg_h, 'TRIGGER_ACTION_EDIT_CONTROL_IDS')
776
777    logging.info("\n")
778
779#================================================================#
780#           Send Commands to Main Frame                          #
781#================================================================#
782main_frame_test_commands=[
783    '',
784    'CMD_ZOOM_IN',
785    'CMD_TOOLBAR_CREATE',
786    'CMD_TOOLBAR_OPEN',
787    'CMD_TOOLBAR_SAVE',
788    'CMD_TOOLBAR_CUT',
789    'CMD_TOOLBAR_COPY',
790    'CMD_TOOLBAR_PASTE',
791    'CMD_TOOLBAR_ALIGN_LEFT',
792    'CMD_TOOLBAR_ALIGN_RIGHT',
793    'CMD_TOOLBAR_ALIGN_TOP',
794    'CMD_TOOLBAR_ALIGN_BOTTOM',
795    'CMD_TOOLBAR_VSPACE_EQUALLY',
796    'CMD_TOOLBAR_HSPACE_EQUALLY',
797    'CMD_TOOLBAR_EQUAL_WIDTH',
798    'CMD_TOOLBAR_EQUAL_HEIGHT',
799    'CMD_TOOLBAR_MOVE_TO_FRONT',
800    'CMD_TOOLBAR_MOVE_TO_BACK',
801    'CMD_TOOLBAR_SIZE_TO_FIT',
802    'CMD_TOOLBAR_ZOOM_IN',
803    'CMD_TOOLBAR_ZOOM_OUT',
804    'CMD_TOOLBAR_RECORD_MACRO',
805    'CMD_TOOLBAR_PLAYBACK_MACRO',
806    'CMD_TOOLBAR_ABOUT',
807    'CMD_UNDO',
808    'CMD_CONFIGURE_LANGUAGES',
809    'CMD_CONFIGURE_PROJECT',
810    'CMD_CONFIGURE_THEMES',
811    'CMD_CONFIGURE_SCREEN_FLOW',
812    'CMD_GENERATE_ALL',
813    'CMD_GENERATE_RESOURCES',
814    'CMD_GET_MENU_STATUS',
815    'CMD_GRID_SNAP_SETTING',
816    'CMD_FIND_DIALOG',
817    'CMD_LOCK_UNLOCK_WIDGET_POSITIONS',
818    'CMD_RUN_APPLICATION',
819    'CMD_IS_WAIT_DIALOG_RUNNING'
820]
821
822#send a test command to the main frame
823def send_to_main_frame(cmd, param):
824    handle = studio_windows['main_frame']
825    command = main_frame_test_commands.index(cmd)
826    return(send_to_studio(handle,command, param))
827
828#post a test command to the main frame
829def post_to_main_frame(cmd, param):
830    handle = studio_windows['main_frame']
831    command = main_frame_test_commands.index(cmd)
832    return(post_to_studio(handle, command, param))
833
834# command the main frame to click toolbar button
835def toolbar_create():
836    logging.info('create new project')
837    post_to_main_frame('CMD_TOOLBAR_CREATE', 0)
838    wait_dialog_open(CREATE_NEW_PROJECT_DIALOG)
839
840def toolbar_save():
841    logging.info('save project')
842    send_to_main_frame('CMD_TOOLBAR_SAVE', 0)
843
844def toolbar_cut():
845    logging.info('click toolbar button: cut')
846    send_to_main_frame('CMD_TOOLBAR_CUT', 0)
847    compare_result()
848    time.sleep(1)
849
850def toolbar_copy():
851    logging.info('click toolbar button: copy')
852    send_to_main_frame('CMD_TOOLBAR_COPY', 0)
853    compare_result()
854    time.sleep(1)
855
856def toolbar_paste(do_deselect = 1):
857    logging.info('click toolbar button: paste')
858    send_to_main_frame('CMD_TOOLBAR_PASTE', 0)
859
860    if do_deselect:
861        deselect()
862        dirty_root_window()
863        compare_result()
864
865
866def toolbar_paste_no_wait():
867    logging.info('click toolbar button: paste')
868    post_to_main_frame('CMD_TOOLBAR_PASTE', 0)
869
870def toolbar_align_left():
871    logging.info('click toolbar button: align left')
872    send_to_main_frame('CMD_TOOLBAR_ALIGN_LEFT', 0)
873    compare_result()
874    time.sleep(1)
875
876def toolbar_align_right():
877    logging.info('click toolbar button: align right')
878    send_to_main_frame('CMD_TOOLBAR_ALIGN_RIGHT', 0)
879    compare_result()
880    time.sleep(1)
881
882def toolbar_align_top():
883    logging.info('click toolbar button: align top')
884    send_to_main_frame('CMD_TOOLBAR_ALIGN_TOP', 0)
885    compare_result()
886    time.sleep(1)
887
888def toolbar_align_bottom():
889    logging.info('click toolbar button: align bottom')
890    send_to_main_frame('CMD_TOOLBAR_ALIGN_BOTTOM', 0)
891    compare_result()
892    time.sleep(1)
893
894def toolbar_vspace_equally():
895    logging.info('click toolbar button: vertical space equally')
896    send_to_main_frame('CMD_TOOLBAR_VSPACE_EQUALLY', 0)
897    compare_result()
898    time.sleep(1)
899
900def toolbar_hspace_equally():
901    logging.info('click toolbar button: horizontal space equally')
902    send_to_main_frame('CMD_TOOLBAR_HSPACE_EQUALLY', 0)
903    compare_result()
904    time.sleep(1)
905
906def toolbar_equal_width():
907    logging.info('click toolbar button: equal width')
908    send_to_main_frame('CMD_TOOLBAR_EQUAL_WIDTH', 0)
909    compare_result()
910    time.sleep(1)
911
912def toolbar_equal_height():
913    logging.info('click toolbar button: equal height')
914    send_to_main_frame('CMD_TOOLBAR_EQUAL_HEIGHT', 0)
915    compare_result()
916    time.sleep(1)
917
918def toolbar_move_to_front():
919    logging.info('click toolbar button: move to front')
920    send_to_main_frame('CMD_TOOLBAR_MOVE_TO_FRONT', 0)
921    compare_result()
922    time.sleep(1)
923
924def toolbar_move_to_back():
925    logging.info('click toolbar button: move to back')
926    send_to_main_frame('CMD_TOOLBAR_MOVE_TO_BACK', 0)
927    compare_result()
928    time.sleep(1)
929
930def toolbar_size_to_fit():
931    logging.info('click toolbar button: size to fit')
932    send_to_main_frame('CMD_TOOLBAR_SIZE_TO_FIT', 0)
933    compare_result()
934    time.sleep(1)
935
936def toolbar_zoom_in():
937    logging.info('click toolbar button: zoom in')
938    send_to_main_frame('CMD_TOOLBAR_ZOOM_IN', 0)
939    compare_result()
940    time.sleep(1)
941
942def toolbar_zoom_out():
943    logging.info('click toolbar button: zoom out')
944    send_to_main_frame('CMD_TOOLBAR_ZOOM_OUT', 0)
945    compare_result()
946    time.sleep(1)
947
948def toolbar_record_macro():
949    logging.info('click toolbar button: record macro')
950    post_to_main_frame('CMD_TOOLBAR_RECORD_MACRO', 0)
951
952def toolbar_playback_macro():
953    logging.info('click toolbar button: playback macro')
954    post_to_main_frame('CMD_TOOLBAR_PLAYBACK_MACRO', 0)
955
956def toolbar_about():
957    logging.info('click toolbar button: about')
958    post_to_main_frame('CMD_TOOLBAR_ABOUT', 0)
959
960def undo():
961    logging.info('click edit menu: undo')
962    send_to_main_frame('CMD_UNDO', 0)
963    time.sleep(1)
964    compare_result()
965
966# command to main frame to generate all output files
967def generate_all():
968    logging.info("generate all output files.")
969    post_to_main_frame('CMD_GENERATE_ALL', 0)
970    wait_dialog_open(RESOURCE_EXPORT_DIALOG)
971
972def generate_resources():
973    logging.info("generate resources")
974    post_to_main_frame('CMD_GENERATE_RESOURCES', 0)
975    wait_dialog_open(RESOURCE_EXPORT_DIALOG)
976
977def configure_project():
978    logging.info('configure project')
979    post_to_main_frame('CMD_CONFIGURE_PROJECT', 0)
980    wait_dialog_open(CONFIGURE_PROJECT_DIALOG)
981
982def configure_themes():
983    logging.info('configure themes')
984    post_to_main_frame('CMD_CONFIGURE_THEMES', 0)
985    wait_dialog_open(CONFIGURE_THEME_DIALOG)
986
987# command the main frame to popup language configure dialog
988def configure_languages():
989    logging.info('configure languages')
990    post_to_main_frame('CMD_CONFIGURE_LANGUAGES', 0)
991    wait_dialog_open(CONFIGURE_LANGUAGE_DIALOG)
992
993def configure_screen_flow():
994    logging.info('configure screen flow')
995    post_to_main_frame('CMD_CONFIGURE_SCREEN_FLOW', 0)
996    wait_dialog_open(SCREEN_FLOW_EDIT_DIALOG)
997
998def get_menu_status(string):
999    return send_to_main_frame('CMD_GET_MENU_STATUS', string)
1000
1001def grid_snap_setting():
1002    logging.info('grid and snap setting')
1003    post_to_main_frame('CMD_GRID_SNAP_SETTING', 0)
1004    wait_dialog_open(GRID_SNAP_SETTING_DIALOG)
1005
1006def lock_unlock_widget_positions(lock):
1007    if lock:
1008        logging.info('lock widget positions')
1009    else:
1010        logging.info('unlock widget positions')
1011
1012    send_to_main_frame('CMD_LOCK_UNLOCK_WIDGET_POSITIONS', lock)
1013
1014def run_application():
1015    logging.info('run application')
1016    send_to_main_frame('CMD_RUN_APPLICATION', 0)
1017    wait_dialog_open('GUIX', 0, 'GUIX')
1018
1019def is_wait_dialog_running():
1020    logging.info('check if wait dialog is running')
1021    return send_to_main_frame('CMD_IS_WAIT_DIALOG_RUNNING', 0)
1022
1023#================================================================#
1024#           Send Commands to Target Screen                       #
1025#================================================================#
1026target_screen_test_commands = [
1027'',
1028'CMD_GENERATE_CHECKSUM',
1029'CMD_GENERATE_SCREENSHOT',
1030'CMD_DESELECT',
1031'CMD_DIRTY_ROOT_WINDOW',
1032'CMD_MOVE_WINDOW',
1033'CMD_MOVE_SELECTED',
1034'CMD_ADD_WIDGET',
1035'CMD_ADD_TEMPLATE',
1036'CMD_ZOOM_IN',
1037'CMD_LBUTTON_DOWN',
1038'CMD_LBUTTON_UP',
1039'CMD_MOUSEMOVE',
1040'CMD_MOUSEMOVE_POST'
1041]
1042
1043#send a test command to the target screen
1044def send_to_target_screen(cmd, param):
1045    handle = studio_windows['Target Screen']
1046    command = target_screen_test_commands.index(cmd)
1047    return(send_to_studio(handle, command, param))
1048
1049def post_to_target_screen(cmd, param):
1050    handle = studio_windows['Target Screen']
1051    command = target_screen_test_commands.index(cmd)
1052    return(post_to_studio(handle, command, param))
1053
1054#ask the target screen for current canvas crc32 value
1055def get_result():
1056    result= send_to_target_screen('CMD_GENERATE_CHECKSUM', None)
1057    return result
1058
1059def generate_screenshot(filename):
1060    logging.info('generate screen shot, image file name = %s', filename)
1061    send_to_target_screen('CMD_GENERATE_SCREENSHOT', filename);
1062
1063def deselect():
1064    logging.info('Deselect')
1065    send_to_target_screen('CMD_DESELECT', 0)
1066
1067def dirty_root_window():
1068    logging.info('dirty root window')
1069    send_to_target_screen('CMD_DIRTY_ROOT_WINDOW', 0)
1070
1071# command the target screen to shift the main window
1072def move_window(shift):
1073    logging.info('move top-level window to force redraw')
1074    send_to_target_screen('CMD_MOVE_WINDOW', shift)
1075    compare_result()
1076    time.sleep(1)
1077
1078# command the target screen to shift the selected widget
1079def move_selected(shift):
1080    logging.info('move the selected widget')
1081    send_to_target_screen('CMD_MOVE_SELECTED', shift)
1082    compare_result()
1083    time.sleep(1)
1084
1085# command the target screen to add widget
1086def add_widget(typename):
1087    if typename in widget_types:
1088        logging.info('add a widget, type = %s' %typename)
1089        send_to_target_screen('CMD_ADD_WIDGET', widget_types[typename])
1090    else:
1091        raise Exception("Invalid widget type: %s" %typename)
1092
1093    time.sleep(1)
1094
1095# command to target screen to add template
1096def add_template(base_name, display = 0):
1097    param = str(base_name) + ',' + str(display)
1098    send_to_target_screen('CMD_ADD_TEMPLATE', param)
1099    logging.info('add a widget using template %s' %base_name)
1100    time.sleep(1)
1101
1102def zoom_in(scale):
1103    send_to_target_screen('CMD_ZOOM_IN', scale)
1104    logging.info('zoom in target view by %d percent' %scale)
1105    compare_result()
1106
1107def left_button_down(x, y):
1108    param = str(x) + ',' + str(y)
1109    send_to_target_screen('CMD_LBUTTON_DOWN', param)
1110    logging.info('simulate left button down on (%d, %d)', x, y)
1111
1112def left_button_up(x, y):
1113    param = str(x) + ',' + str(y)
1114    send_to_target_screen('CMD_LBUTTON_UP', param)
1115    logging.info('simulate left button up on (%d, %d)', x, y)
1116
1117def mousemove(x, y, close_notification = False):
1118    param = str(x) + ',' + str(y)
1119
1120    if close_notification == False:
1121        send_to_target_screen('CMD_MOUSEMOVE', param)
1122        logging.info('simulate mousemove on (%d, %d)', x, y)
1123    else:
1124        post_to_target_screen('CMD_MOUSEMOVE_POST', param)
1125        logging.info('simulate mousemove on (%d, %d)', x, y)
1126        close_message_dialog()
1127
1128#================================================================#
1129#           Send Commands to Properties Screen                   #
1130#================================================================#
1131properties_win_test_commands = [
1132'',
1133'CMD_EDIT_WIDGET_PROPS',
1134'CMD_EDIT_WIDGET_PROPS_POST'
1135]
1136
1137#send a test command to the properties view
1138def send_to_properties_screen(cmd, param):
1139    handle = studio_windows['Properties Win']
1140    command = properties_win_test_commands.index(cmd)
1141    return(send_to_studio(handle, command, param))
1142
1143def post_to_properties_screen(cmd, param):
1144    handle = studio_windows['Properties Win']
1145    command = properties_win_test_commands.index(cmd)
1146    return(post_to_studio(handle, command, param))
1147
1148def edit_widget_props(id_str, prop_val):
1149    control_id = props_ctrl_ids[id_str];
1150    param = str(control_id) + "," + str(prop_val)
1151    prop_string = str(prop_val)
1152    logging.info("editing property: %s, control_id = %d, val = %s" %(id_str, control_id, prop_string.encode(sys.stdout.encoding, 'replace')))
1153    send_to_properties_screen('CMD_EDIT_WIDGET_PROPS', param)
1154
1155def edit_widget_props_post(id_str, prop_val):
1156    control_id = props_ctrl_ids[id_str];
1157    param = str(control_id) + "," + str(prop_val)
1158    prop_string = str(prop_val)
1159    logging.info("editing property: %s, control_id = %d, val = %s" %(id_str, control_id, prop_string.encode(sys.stdout.encoding, 'replace')))
1160    post_to_properties_screen('CMD_EDIT_WIDGET_PROPS_POST', param)
1161
1162#================================================================#
1163#           Send Commands to Project View                        #
1164#================================================================#
1165project_view_test_commands = [
1166'',
1167'CMD_OPEN_PROJECT',
1168'CMD_CLOSE_PROJECT',
1169'CMD_IMPORT_PROJECT',
1170'CMD_SELECT_PROJECT_TREE_NODE',
1171'CMD_SELECT_PROJECT_TREE_FOLDER',
1172'CMD_SELECT_CHILD_WIDGET',
1173'CMD_SELECT_MULTI_WIDGETS',
1174'CMD_DELETE_WIDGET',
1175'CMD_GET_WIDGET_LEFT',
1176'CMD_GET_WIDGET_TOP',
1177'CMD_GET_WIDGET_RIGHT',
1178'CMD_GET_WIDGET_BOTTOM',
1179'CMD_INSERT_FOLDER',
1180'CMD_EDIT_FOLDER_PROPERTIES',
1181'CMD_DELETE_FOLDER',
1182'CMD_TERMINATE_APP_EXECUTION'
1183]
1184
1185#send a test command to the project view
1186def send_to_project_view(cmd, param):
1187    handle = studio_windows['Project View']
1188    command = project_view_test_commands.index(cmd)
1189    return(send_to_studio(handle, command, param))
1190
1191def post_to_project_view(cmd, param):
1192    handle = studio_windows['Project View']
1193    command = project_view_test_commands.index(cmd)
1194    return(post_to_studio(handle, command, param))
1195
1196# tell the Studio project view to open a project
1197def open_project(path, compare = 1):
1198    if not os.path.isfile(path):
1199        raise Exception('Test project is missing: %s' %path)
1200    abs_path = os.path.abspath(path)
1201    logging.info("open project: %s", abs_path)
1202    global default_map
1203    send_to_project_view('CMD_OPEN_PROJECT', abs_path)
1204
1205    if compare == 1:
1206        compare_result()
1207
1208def import_project(pathname):
1209    logging.info("import project:%s", pathname)
1210    post_to_project_view('CMD_IMPORT_PROJECT', pathname)
1211    wait_dialog_open(IMPORT_PROJECT_DIALOG)
1212
1213# tell the Studio project view to close a project
1214def close_project(save_change = 0):
1215    logging.info('close current project')
1216    if save_change == 1:
1217        post_to_project_view('CMD_CLOSE_PROJECT', save_change)
1218    else:
1219        send_to_project_view('CMD_CLOSE_PROJECT', save_change)
1220
1221# command the project view to select a widget
1222def select_project_tree_node(name):
1223    while is_wait_dialog_running() == True:
1224        time.sleep(5)
1225
1226    logging.info('select "%s"' %name)
1227    result = send_to_project_view('CMD_SELECT_PROJECT_TREE_NODE', name)
1228    time.sleep(1)
1229    return result
1230
1231# command the project view to select a folder
1232def select_project_tree_folder(display_name, folder_name):
1233    logging.info('select display, folder "%s", "%s"' %(display_name, folder_name))
1234    param = display_name + ',' + folder_name
1235    result = send_to_project_view('CMD_SELECT_PROJECT_TREE_FOLDER', param)
1236
1237def select_project_tree_child():
1238    logging.info('select project tree child widget')
1239    result = send_to_project_view('CMD_SELECT_CHILD_WIDGET')
1240
1241# command the project view to select multiple widgets
1242def select_multi_widgets(name):
1243    logging.info('select "%s" with Shift-Key down' %name)
1244    send_to_project_view('CMD_SELECT_MULTI_WIDGETS', name)
1245    time.sleep(1)
1246
1247# command the project view to delete a widget
1248def delete_widget(do_compare = 1):
1249    logging.info('delete current selected widget')
1250    send_to_project_view('CMD_DELETE_WIDGET', 0)
1251
1252    if do_compare:
1253        compare_result()
1254
1255    time.sleep(1)
1256
1257def post_delete_widget():
1258    logging.info('post delete widget message')
1259    post_to_project_view('CMD_DELETE_WIDGET', 0)
1260
1261def get_widget_left(widget_name):
1262    return send_to_project_view('CMD_GET_WIDGET_LEFT', widget_name)
1263
1264def get_widget_top(widget_name):
1265    return send_to_project_view('CMD_GET_WIDGET_TOP', widget_name)
1266
1267def get_widget_right(widget_name):
1268    return send_to_project_view('CMD_GET_WIDGET_RIGHT', widget_name)
1269
1270def get_widget_bottom(widget_name):
1271    return send_to_project_view('CMD_GET_WIDGET_BOTTOM', widget_name)
1272
1273def drag_left(widget_name, delta_x, close_notification = False):
1274    logging.info('drag left of widget "%s"', widget_name)
1275    left = get_widget_left(widget_name) - 1
1276    top = get_widget_top(widget_name) - 1
1277    bottom = get_widget_bottom(widget_name) + 1
1278
1279    y = (top + bottom) / 2
1280    left_button_down(left, y)
1281    mousemove(left + delta_x, y, close_notification)
1282    left_button_up(left + delta_x, y)
1283
1284def drag_right(widget_name, delta_x, close_notification = False):
1285    logging.info('drag right of widget "%s"', widget_name)
1286    right = get_widget_right(widget_name) + 1
1287    top = get_widget_top(widget_name) - 1
1288    bottom = get_widget_bottom(widget_name) + 1
1289
1290    y = (top + bottom) / 2
1291    left_button_down(right, y)
1292    mousemove(right + delta_x, y, close_notification)
1293    left_button_up(right + delta_x, y)
1294
1295def drag_top(widget_name, delta_y, close_notification = False):
1296    logging.info('drag top of widget "%s"', widget_name)
1297    left = get_widget_left(widget_name) - 1
1298    right = get_widget_right(widget_name) + 1
1299    top = get_widget_top(widget_name) - 1
1300
1301    x = (left + right) / 2
1302    left_button_down(x, top)
1303    mousemove(x, top + delta_y, close_notification)
1304    left_button_up(x, top + delta_y)
1305
1306def drag_bottom(widget_name, delta_y, close_notification = False):
1307    logging.info('drag bottom of widget "%s"', widget_name)
1308    left = get_widget_left(widget_name) - 1
1309    right = get_widget_right(widget_name) + 1
1310    bottom = get_widget_bottom(widget_name) + 1
1311
1312    x = (left + right) / 2
1313    left_button_down(x, bottom)
1314    mousemove(x, bottom + delta_y, close_notification)
1315    left_button_up(x, bottom + delta_y)
1316
1317def drag_left_top(widget_name, delta_x, delta_y, close_notification = False):
1318    logging.info('drag left top of widget "%s"', widget_name)
1319    left = get_widget_left(widget_name) - 1
1320    top = get_widget_top(widget_name) - 1
1321
1322    left_button_down(left, top)
1323    mousemove(left + delta_x, top + delta_y, close_notification)
1324    left_button_up(left + delta_x, top + delta_y)
1325
1326def drag_right_top(widget_name, delta_x, delta_y, close_notification = False):
1327    logging.info('drag right top of widget "%s"', widget_name)
1328    right = get_widget_right(widget_name) + 1
1329    top = get_widget_top(widget_name) - 1
1330
1331    left_button_down(right, top)
1332    mousemove(right + delta_x, top + delta_y, close_notification)
1333    left_button_up(right + delta_x, top + delta_y)
1334
1335def drag_left_bottom(widget_name, delta_x, delta_y, close_notification = False):
1336    logging.info('drag left bottom of widget "%s"', widget_name)
1337    left = get_widget_left(widget_name) - 1
1338    bottom = get_widget_bottom(widget_name) + 1
1339
1340    left_button_down(left, bottom)
1341    mousemove(left + delta_x, bottom + delta_y, close_notification)
1342    left_button_up(left + delta_x, bottom + delta_y)
1343
1344def drag_right_bottom(widget_name, delta_x, delta_y, close_notification = False):
1345    logging.info('drag right bottom of widget "%s"', widget_name)
1346    right = get_widget_right(widget_name) + 1
1347    bottom = get_widget_bottom(widget_name) + 1
1348
1349    left_button_down(right, bottom)
1350    mousemove(right + delta_x, bottom + delta_y, close_notification)
1351    left_button_up(right + delta_x, bottom + delta_y)
1352
1353def drag_move(widget_name, delta_x, delta_y, close_notification = False):
1354    logging.info('move widget "%s"', widget_name)
1355    left = get_widget_left(widget_name)
1356    right = get_widget_right(widget_name)
1357    top = get_widget_top(widget_name)
1358    bottom = get_widget_bottom(widget_name)
1359
1360    x = (left + right) / 2
1361    y = (top + bottom) / 2
1362
1363    left_button_down(x, y)
1364    mousemove(x + delta_x, y + delta_y, close_notification)
1365    left_button_up(x + delta_x, y + delta_y)
1366
1367def insert_folder():
1368    send_to_project_view('CMD_INSERT_FOLDER',0)
1369
1370def edit_folder_properties():
1371    post_to_project_view('CMD_EDIT_FOLDER_PROPERTIES', 0)
1372    wait_dialog_open(EDIT_FOLDER_NAME_DIALOG)
1373
1374def rename_folder(new_name):
1375    edit_folder_properties()
1376    set_folder_name(new_name)
1377    save_folder_name_edit()
1378
1379def delete_folder(do_compare = 1):
1380    logging.info('delete selected folder')
1381    send_to_project_view('CMD_DELETE_FOLDER', 0)
1382
1383    if do_compare:
1384        compare_result()
1385
1386def post_delete_folder():
1387    logging.info('post delete folder message')
1388    post_to_project_view('CMD_DELETE_FOLDER', 0)
1389
1390
1391def terminate_app_execution():
1392    logging.info('terminate app execution')
1393    send_to_project_view('CMD_TERMINATE_APP_EXECUTION', 0)
1394    active_dialog_stack.pop()
1395    logging.debug("pop active dialog: %s", APP_EXECUTION_WINDOW)
1396
1397#================================================================#
1398#           Send Commands to Resource View                       #
1399#================================================================#
1400resource_view_test_commands = [
1401'',
1402'CMD_CLICK_RESOURCE_GROUP',
1403'CMD_CLICK_PIXELMAP_FOLDER',
1404'CMD_CLICK_RESOURCE_ITEM',
1405'CMD_ADD_COLOR',
1406'CMD_EDIT_COLOR',
1407'CMD_DELETE_COLOR',
1408'CMD_ADD_FONT',
1409'CMD_EDIT_FONT',
1410'CMD_DELETE_FONT',
1411'CMD_ADD_PIXELMAPS',
1412'CMD_EDIT_PIXELMAP',
1413'CMD_EDIT_PIXELMAPS',
1414'CMD_DELETE_PIXELMAP',
1415'CMD_ENABLE_PIXELMAP',
1416'CMD_DISABLE_PIXELMAP',
1417'CMD_ADD_PIXELMAP_FOLDER',
1418'CMD_REMOVE_PIXELMAP_FOLDER',
1419'CMD_ENABLE_PIXELMAP_FOLDER',
1420'CMD_DISABLE_PIXELMAP_FOLDER',
1421'CMD_SET_FOLDER_NAME',
1422'CMD_SAVE_FOLDER_NAME_EDIT',
1423'CMD_EDIT_STRING',
1424'CMD_INCREMENT_ACTIVE_LANGUAGE_INDEX',
1425'CMD_DECREMENT_ACTIVE_LANGUAGE_INDEX',
1426'CMD_GENERATE_XML'
1427]
1428
1429#send a test command to resource view
1430def send_to_resource_view(cmd, param):
1431    handle = studio_windows['Resource View']
1432    command = resource_view_test_commands.index(cmd)
1433    return(send_to_studio(handle, command, param))
1434
1435#post a test command to resource view
1436def post_to_resource_view(cmd, param):
1437    handle = studio_windows['Resource View']
1438    command = resource_view_test_commands.index(cmd)
1439    return(post_to_studio(handle, command, param))
1440
1441def click_resource_group(name):
1442    logging.info('click resource group: %s', name)
1443    send_to_resource_view('CMD_CLICK_RESOURCE_GROUP', group_ids[name])
1444
1445def click_pixelmap_folder(folder_id, name):
1446    logging.info('click resource folder: %s', name)
1447    param = str(folder_ids[folder_id]) + ',' + name
1448    send_to_resource_view('CMD_CLICK_PIXELMAP_FOLDER', param)
1449
1450# command the resource view to open color resource folder
1451def click_resource_item(type, name):
1452    param = str(resource_item_types[type]) + ',' + name
1453    send_to_resource_view('CMD_CLICK_RESOURCE_ITEM', param)
1454
1455# command the resource view to open font edit dialog
1456def add_font():
1457    logging.info('add a font')
1458    post_to_resource_view('CMD_ADD_FONT', 0)
1459    wait_dialog_open(EDIT_FONT_DIALOG)
1460
1461def edit_font(id_name):
1462    click_resource_item('RES_TYPE_FONT', id_name)
1463
1464    logging.info('edit font: %s', id_name)
1465    post_to_resource_view('CMD_EDIT_FONT', 0)
1466    wait_dialog_open(EDIT_FONT_DIALOG)
1467
1468def delete_font(id_name):
1469    click_resource_item('RES_TYPE_FONT', id_name)
1470
1471    logging.info('delete font: %s', id_name)
1472    send_to_resource_view('CMD_DELETE_FONT', 0)
1473
1474# command the resource view to open color edit dialog
1475def add_color():
1476    logging.info('add a color')
1477    post_to_resource_view('CMD_ADD_COLOR', 0)
1478    wait_dialog_open(EDIT_COLOR_DIALOG)
1479
1480def edit_color(id_name):
1481    click_resource_item('RES_TYPE_COLOR', id_name)
1482
1483    logging.info('edit color: %s', id_name)
1484    post_to_resource_view('CMD_EDIT_COLOR', 0)
1485    wait_dialog_open(EDIT_COLOR_DIALOG)
1486
1487def delete_color(id_name):
1488    click_resource_item('RES_TYPE_COLOR', id_name)
1489
1490    logging.info('delete color: %s', id_name)
1491    send_to_resource_view('CMD_DELETE_COLOR', 0)
1492
1493# command the resource view to add images
1494def add_pixelmaps(folder_name, path, name_array, wait = CLOSE_WAIT):
1495    while is_wait_dialog_running() == True:
1496        time.sleep(5)
1497
1498    path = os.path.realpath(path) + '\\'
1499    logging.info("add pixelmaps, folder name = %s, path = %s, names = %s", folder_name, path, name_array)
1500
1501    param = folder_name + ','
1502    param += path + ','
1503    param += name_array
1504
1505    post_to_resource_view('CMD_ADD_PIXELMAPS', param)
1506
1507    time.sleep(1)
1508    if wait == CLOSE_WAIT and find_dialog(WAIT_DIALOG):
1509        wait_dialog_close(WAIT_DIALOG)
1510
1511    click_pixelmap_folder('CUSTOM_PIXELMAP_FOLDER', folder_name)
1512
1513def delete_pixelmap(id_name):
1514    click_resource_item('RES_TYPE_PIXELMAP', id_name)
1515    logging.info('delete pixelmap: %s', id_name)
1516    send_to_resource_view('CMD_DELETE_PIXELMAP', 0)
1517
1518def enable_pixelmap(id_name):
1519    click_resource_item('RES_TYPE_PIXELMAP', id_name)
1520    logging.info('enable pixelmap: %s', id_name)
1521    send_to_resource_view('CMD_ENABLE_PIXELMAP', 0)
1522
1523def disable_pixelmap(id_name):
1524    click_resource_item('RES_TYPE_PIXELMAP', id_name)
1525    logging.info('disable pixelmap: %s', id_name)
1526    send_to_resource_view('CMD_DISABLE_PIXELMAP', 0)
1527
1528# command the resoruce view to edit a pixelmap
1529def edit_pixelmap(id_name):
1530    click_resource_item('RES_TYPE_PIXELMAP', id_name)
1531
1532    logging.info('edit pixelmap: %s', id_name)
1533    post_to_resource_view('CMD_EDIT_PIXELMAP', 0)
1534    wait_dialog_open(EDIT_PIXELMAP_DIALOG)
1535
1536# command the resoruce view to edit pixelmaps under pixelmap group/folder
1537def edit_pixelmaps():
1538    logging.info('edit pixelmaps')
1539    post_to_resource_view('CMD_EDIT_PIXELMAPS', 0)
1540    wait_dialog_open(EDIT_PIXELMAP_DIALOG)
1541
1542
1543# command the resource view to show string edit dialog
1544def edit_string():
1545    logging.info("edit string table")
1546    post_to_resource_view('CMD_EDIT_STRING', 0)
1547
1548    wait_dialog_open(STRING_TABLE_EDITOR_DIALOG)
1549
1550def add_pixelmap_folder():
1551    logging.info('add a pixelmap folder')
1552    test_utils.click_resource_group('PIXELMAP_GROUP')
1553    post_to_resource_view('CMD_ADD_PIXELMAP_FOLDER', 0)
1554    wait_dialog_open(EDIT_FOLDER_NAME_DIALOG)
1555    test_utils.click_resource_group('PIXELMAP_GROUP')
1556
1557def remove_pixelmap_folder(name):
1558    click_pixelmap_folder('CUSTOM_PIXELMAP_FOLDER', name)
1559    logging.info('remove pixelmap folder: %s', name)
1560    send_to_resource_view('CMD_REMOVE_PIXELMAP_FOLDER', 0)
1561
1562def enable_pixelmap_folder():
1563    logging.info('enable pixelmap folder')
1564    send_to_resource_view('CMD_ENABLE_PIXELMAP_FOLDER', 0)
1565
1566def disable_pixelmap_folder():
1567    logging.info('disable pixelmap folder')
1568    send_to_resource_view('CMD_DISABLE_PIXELMAP_FOLDER', 0)
1569
1570def increment_active_language_index():
1571    logging.info('increase active language index')
1572    send_to_resource_view('CMD_INCREMENT_ACTIVE_LANGUAGE_INDEX', 0)
1573
1574def decrement_active_language_index():
1575    logging.info('decrease active language index')
1576    send_to_resource_view('CMD_DECREMENT_ACTIVE_LANGUAGE_INDEX', 0)
1577
1578def generate_xml(name):
1579    logging.info('generate xml file: %s', name)
1580    name = os.path.abspath(name)
1581    send_to_resource_view('CMD_GENERATE_XML', name)
1582
1583#================================================================#
1584#           Send Commands to Message Dialog                      #
1585#================================================================#
1586message_dialog_commands = [
1587'',
1588'CMD_YES_TO_MESSAGE_DIALOG',
1589'CMD_NO_TO_MESSAGE_DIALOG',
1590'CMD_CLOSE_MESSAGE_DIALOG'
1591]
1592
1593def post_to_message_dialog(cmd, param):
1594    handle = studio_dialogs[NOTIFICATION_DIALOG]
1595    command = message_dialog_commands.index(cmd)
1596    return(post_to_studio(handle, command, param))
1597
1598def click_yes_to_message_dialog():
1599    wait_dialog_open(NOTIFICATION_DIALOG)
1600    logging.info('click yes button of message dialog.')
1601    post_to_message_dialog('CMD_YES_TO_MESSAGE_DIALOG', 0)
1602    wait_dialog_close(NOTIFICATION_DIALOG)
1603
1604def click_no_to_message_dialog():
1605    wait_dialog_open(NOTIFICATION_DIALOG)
1606    logging.info('click no button of message dialog.')
1607    post_to_message_dialog('CMD_NO_TO_MESSAGE_DIALOG', 0)
1608    wait_dialog_close(NOTIFICATION_DIALOG)
1609
1610def close_message_dialog(owner = 0):
1611    retries = 0
1612
1613    wait_dialog_open(NOTIFICATION_DIALOG, owner)
1614    logging.info('close notification dialog.')
1615
1616    while retries < 3:
1617        post_to_message_dialog('CMD_CLOSE_MESSAGE_DIALOG', 0)
1618        if wait_dialog_close(NOTIFICATION_DIALOG) is True:
1619            return;
1620        retries += 1
1621
1622def post_to_error_dialog(cmd, param):
1623    handle = studio_dialogs[ERROR_DIALOG]
1624    command = message_dialog_commands.index(cmd)
1625    return(post_to_studio(handle, command, param))
1626
1627
1628def close_error_dialog(owner = 0):
1629    retries = 0
1630
1631    logging.info('close error dialog.')
1632    wait_dialog_open(ERROR_DIALOG, owner)
1633
1634    while retries < 3:
1635        post_to_error_dialog('CMD_CLOSE_MESSAGE_DIALOG', 0)
1636        if wait_dialog_close(ERROR_DIALOG) is True:
1637            return;
1638        retries += 1
1639
1640def post_to_please_confirm_dialog(cmd, param):
1641    handle = studio_dialogs[PLEASE_CONFIRM_DIALOG]
1642    command = message_dialog_commands.index(cmd)
1643    return(post_to_studio(handle, command, param))
1644
1645
1646def click_yes_to_please_confirm_dialog():
1647    wait_dialog_open(PLEASE_CONFIRM_DIALOG)
1648    logging.info('click yes button of please confirm dialog.')
1649    post_to_please_confirm_dialog('CMD_YES_TO_MESSAGE_DIALOG', 0)
1650    wait_dialog_close(PLEASE_CONFIRM_DIALOG)
1651
1652def click_no_to_please_confirm_dialog():
1653    wait_dialog_open(PLEASE_CONFIRM_DIALOG)
1654    logging.info('click no button of please confirm dialog.')
1655    post_to_please_confirm_dialog('CMD_NO_TO_MESSAGE_DIALOG', 0)
1656    wait_dialog_close(PLEASE_CONFIRM_DIALOG)
1657
1658#================================================================#
1659#           Send Commands to Language Configure Dialog           #
1660#================================================================#
1661
1662language_configure_commands = [
1663'',
1664'CMD_ADD_LANGUAGE',
1665'CMD_DELETE_LANGUAGE',
1666'CMD_SELECT_LANGUAGE_INDEX',
1667'CMD_SELECT_LANGUAGE_ID',
1668'CMD_CHECK_SUPPORT_BIDI_TEXT',
1669'CMD_CHECK_REORDER_BIDI_TEXT',
1670'CMD_CHECK_SUPPORT_THAI_SHAPING',
1671'CMD_CHECK_GEN_ADJUSTED_THAI',
1672'CMD_SAVE_LANGUAGE_CONFIGURE',
1673'CMD_CANCEL_LANGUAGE_CONFIGURE'
1674]
1675
1676def send_to_language_configure_dialog(cmd, param):
1677    handle = studio_dialogs[CONFIGURE_LANGUAGE_DIALOG]
1678    command = language_configure_commands.index(cmd)
1679    return(send_to_studio(handle, command, param))
1680
1681def post_to_language_configure_dialog(cmd, param):
1682    handle = studio_dialogs[CONFIGURE_LANGUAGE_DIALOG]
1683    command = language_configure_commands.index(cmd)
1684    return(post_to_studio(handle, command, param))
1685
1686# command the language configure dialog to add a language
1687def add_language():
1688    logging.info('add a language')
1689    send_to_language_configure_dialog('CMD_ADD_LANGUAGE', 0)
1690
1691# command the language configure dialog to delete a language
1692def delete_language():
1693    logging.info('delete a language')
1694    send_to_language_configure_dialog('CMD_DELETE_LANGUAGE', 0)
1695
1696# command the languge configure dialog to select a language index
1697def select_language_index(language_index):
1698    logging.info('select language index: %d', language_index)
1699    send_to_language_configure_dialog('CMD_SELECT_LANGUAGE_INDEX', language_index)
1700
1701# command the language configure dialog to select a language id
1702def select_language_id(language):
1703    logging.info('select language id: %s', language)
1704    send_to_language_configure_dialog('CMD_SELECT_LANGUAGE_ID', language)
1705
1706def check_support_bidi_text(check):
1707    if check:
1708        logging.info('check on support bidi text box')
1709    else:
1710        logging.info('check off support bidi text box')
1711    send_to_language_configure_dialog('CMD_CHECK_SUPPORT_BIDI_TEXT', check)
1712
1713def check_reorder_bidi_text(check):
1714    if check:
1715        logging.info('check on reorder bidi text box')
1716    else:
1717        logging.info('check off reorder bidi text box')
1718    send_to_language_configure_dialog('CMD_CHECK_REORDER_BIDI_TEXT', check)
1719
1720def check_support_thai_glyph_shapping(check):
1721    if check:
1722        logging.debug('check on support support thai glyph shaping box')
1723    else:
1724        logging.debug('check off support support thai glyph shaping box')
1725    send_to_language_configure_dialog('CMD_CHECK_SUPPORT_THAI_SHAPING', check)
1726
1727def check_gen_adjusted_thai_string(check):
1728    if check:
1729        logging.debug('check on generate adjusted thai string box')
1730    else:
1731        logging.debug('check off generate adjusted thai string box')
1732    send_to_language_configure_dialog('CMD_CHECK_GEN_ADJUSTED_THAI', check)
1733
1734# command the languge configure dialog to save the changes
1735def save_language_configure():
1736    logging.info('save language configuration')
1737    post_to_language_configure_dialog('CMD_SAVE_LANGUAGE_CONFIGURE', 0)
1738    wait_dialog_close(CONFIGURE_LANGUAGE_DIALOG)
1739
1740# command the language configure dialog to cancel the changes
1741def cancel_language_configure():
1742    logging.info('cancel language configuration')
1743    post_to_language_configure_dialog('CMD_CANCEL_LANGUAGE_CONFIGURE', 0)
1744    wait_dialog_close(CONFIGURE_LANGUAGE_DIALOG)
1745
1746#================================================================#
1747#           Send Commands to Project Configure Dialog            #
1748#================================================================#
1749
1750project_configure_commands  = [
1751'',
1752'CMD_CONFIGURE_SOURCE_PATH',
1753'CMD_CONFIGURE_HEADER_PATH',
1754'CMD_CONFIGURE_RESOURCE_PATH',
1755'CMD_CONFIGURE_X_RES',
1756'CMD_CONFIGURE_Y_RES',
1757'CMD_CONFIGURE_DISPLAY_NUM',
1758'CMD_SELECT_DISPLAY_INDEX',
1759'CMD_CONFIGURE_DISPLAY_NAME',
1760'CMD_CONFIGURE_DISPLAY_COLOR_FORMAT',
1761'CMD_CONFIGURE_DISPLAY_COLOR_DEPTH',
1762'CMD_CONFIGURE_DISPLAY_RGB_BITS',
1763'CMD_CONFIGURE_MINOR_VERSION',
1764'CMD_CONFIGURE_SERVICE_PACK',
1765'CMD_CONFIGURE_CANVAS_ALLOCATE',
1766'CMD_CONFIGURE_CPU_TYPE',
1767'CMD_CONFIGURE_BIG_ENDIAN',
1768'CMD_SAVE_PROJECT_CONFIGURE',
1769'CMD_CANCEL_PROJECT_CONFIGURE',
1770'CMD_IS_DEFAULT_MAP_FORMAT',
1771'CMD_GET_CPU_TYPE',
1772'CMD_GET_DISPLAY_COLOR_FORMAT',
1773'CMD_GET_DISPLAY_COLOR_DEPTH',
1774'CMD_IS_1555_FORMAT',
1775'CMD_IS_4444_FORAMT',
1776'CMD_IS_332_FORMAT',
1777'CMD_IS_NEW_PROJECT',
1778'CMD_OPEN_ADVANCED_SETTINGS',
1779'CMD_SET_AA_TEXT_COLORS'
1780]
1781
1782def send_to_project_configure_dialog(cmd, param):
1783    handle = studio_dialogs[CONFIGURE_PROJECT_DIALOG]
1784    command = project_configure_commands.index(cmd)
1785    return(send_to_studio(handle, command, param))
1786
1787def post_to_project_configure_dialog(cmd, param):
1788    handle = studio_dialogs[CONFIGURE_PROJECT_DIALOG]
1789    command = project_configure_commands.index(cmd)
1790    return(post_to_studio(handle, command, param))
1791
1792def is_default_map_format():
1793    return send_to_project_configure_dialog('CMD_IS_DEFAULT_MAP_FORMAT', 0)
1794
1795def get_cpu_type():
1796    return send_to_project_configure_dialog('CMD_GET_CPU_TYPE', 0)
1797
1798def get_display_color_format():
1799    return send_to_project_configure_dialog('CMD_GET_DISPLAY_COLOR_FORMAT', 0)
1800
1801def get_display_color_depth():
1802    return send_to_project_configure_dialog('CMD_GET_DISPLAY_COLOR_DEPTH', 0)
1803
1804def is_1555_format():
1805    return  send_to_project_configure_dialog('CMD_IS_1555_FORMAT', 0)
1806
1807def is_4444_format():
1808    return  send_to_project_configure_dialog('CMD_IS_4444_FORAMT', 0)
1809
1810def is_332_format():
1811    return  send_to_project_configure_dialog('CMD_IS_332_FORMAT', 0)
1812
1813def is_new_project():
1814    return send_to_project_configure_dialog('CMD_IS_NEW_PROJECT', 0)
1815
1816def set_aa_text_colors(count):
1817    param = str(count)
1818    logging.info('set palette mode aa text colors = %d', count)
1819    send_to_project_configure_dialog('CMD_SET_AA_TEXT_COLORS', param)
1820
1821def configure_source_path(path):
1822    path = os.path.realpath(path)
1823
1824    if os.path.exists(path) == False:
1825        os.makedirs(path)
1826
1827    logging.info('set source files path: %s', path)
1828    send_to_project_configure_dialog('CMD_CONFIGURE_SOURCE_PATH', path)
1829
1830def configure_header_path(path):
1831    path = os.path.realpath(path)
1832
1833    if os.path.exists(path) == False:
1834        os.makedirs(path)
1835
1836    logging.info('set header files path: %s', path)
1837    send_to_project_configure_dialog('CMD_CONFIGURE_HEADER_PATH', path)
1838
1839def configure_resource_path(path):
1840    path = os.path.realpath(path)
1841
1842    if os.path.exists(path) == False:
1843        os.makedirs(path)
1844
1845    logging.info('set resource files path: %s', path)
1846    send_to_project_configure_dialog('CMD_CONFIGURE_RESOURCE_PATH', path)
1847
1848def configure_x_res(x_res):
1849    logging.info('set x resolution to "%d"' %x_res)
1850    send_to_project_configure_dialog('CMD_CONFIGURE_X_RES', str(x_res))
1851
1852def configure_y_res(y_res):
1853    logging.info('set y resolution to "%d"' %y_res)
1854    send_to_project_configure_dialog('CMD_CONFIGURE_Y_RES', str(y_res))
1855
1856def configure_display_num(display_num):
1857    logging.info('set display num: %d', display_num)
1858    send_to_project_configure_dialog('CMD_CONFIGURE_DISPLAY_NUM', display_num)
1859
1860def select_display_index(display_index):
1861    logging.info('select display index: %d', display_index)
1862    send_to_project_configure_dialog('CMD_SELECT_DISPLAY_INDEX', display_index)
1863
1864def configure_display_name(name):
1865    logging.info('set display name to "%s"' %name)
1866    send_to_project_configure_dialog('CMD_CONFIGURE_DISPLAY_NAME', name)
1867
1868def configure_display_color_format(format):
1869    global reset_map_format
1870    global change_color_table
1871
1872    if (get_display_color_format() != color_formats[format]) and (not is_new_project()):
1873        reset_map_format = True
1874        change_color_table = True
1875    else:
1876        reset_map_format = False
1877        change_color_table = False
1878
1879    logging.info('set display color format to "%s"' %format)
1880    send_to_project_configure_dialog('CMD_CONFIGURE_DISPLAY_COLOR_FORMAT', color_formats[format])
1881
1882def configure_display_color_depth(color_depth):
1883    logging.info('set display color depth to "%s"' %color_depth)
1884    status = send_to_project_configure_dialog('CMD_CONFIGURE_DISPLAY_COLOR_DEPTH', color_depth)
1885
1886    if (status == 0) and (not is_new_project()): #means set color depth success
1887        logging.info('set display color depth to "%s" successfully.' %color_depth)
1888        global reset_map_format
1889        global change_color_table
1890        reset_map_format = True
1891        change_color_table = True
1892
1893def configure_display_rgb_bits(rgb_bits):
1894    logging.info('set checkbox rgb bits to "%s"' %rgb_bits)
1895    send_to_project_configure_dialog('CMD_CONFIGURE_DISPLAY_RGB_BITS', rgb_bits)
1896
1897def configure_minor_version(minor_version):
1898    logging.info('set minor version to "%d"' %minor_version)
1899    send_to_project_configure_dialog('CMD_CONFIGURE_MINOR_VERSION', minor_version)
1900
1901def configure_service_pack(service_pack):
1902    logging.info('set service pack to "%d"' %service_pack)
1903    send_to_project_configure_dialog('CMD_CONFIGURE_SERVICE_PACK', service_pack)
1904
1905def configure_canvas_allocate(check):
1906    if check:
1907        logging.info('check on "Allocate Canvas"')
1908    else:
1909        logging.info('check off "Allocate Canvas"')
1910
1911    send_to_project_configure_dialog('CMD_CONFIGURE_CANVAS_ALLOCATE', check)
1912
1913def configure_cpu_type(type):
1914    global reset_map_format
1915    if get_cpu_type() != test_constants.cpu_types[type]:
1916        reset_map_format = True
1917    else:
1918        reset_map_format = False
1919
1920    logging.info('set cpu type: %s', type)
1921    send_to_project_configure_dialog('CMD_CONFIGURE_CPU_TYPE', test_constants.cpu_types[type])
1922
1923def configure_big_endian(check):
1924    if check:
1925        logging.info('check on "big endian"')
1926    else:
1927        logging.info('check off "big endian"')
1928
1929    send_to_project_configure_dialog('CMD_CONFIGURE_BIG_ENDIAN', check)
1930
1931def open_advanced_settings():
1932    logging.info('open synergy advanced settings dialog')
1933    post_to_project_configure_dialog('CMD_OPEN_ADVANCED_SETTINGS', 0)
1934    wait_dialog_open(SYNERGY_SETTINGS_DIALOG, studio_dialogs[CONFIGURE_PROJECT_DIALOG])
1935
1936def save_project_configure(wait_close = CLOSE_WAIT):
1937    logging.info("save project configure")
1938
1939    # check if all pixelmaps are default color format
1940    is_default_map = is_default_map_format()
1941    post_to_project_configure_dialog('CMD_SAVE_PROJECT_CONFIGURE', 0)
1942
1943    global reset_map_format
1944    global change_color_table
1945
1946    if change_color_table == True:
1947        logging.info('Close warning dialog about reset color table')
1948        close_message_dialog(studio_dialogs[CONFIGURE_PROJECT_DIALOG])
1949    change_color_table = False
1950
1951    if is_default_map == False and reset_map_format == True:
1952        # a notification message is popup, close it
1953        logging.info('Close warning dialog about reset pixelmap format')
1954        close_message_dialog(studio_dialogs[CONFIGURE_PROJECT_DIALOG])
1955    reset_map_format = False
1956
1957    if wait_close == CLOSE_WAIT:
1958        wait_dialog_close(CONFIGURE_PROJECT_DIALOG)
1959
1960def cancel_project_configure():
1961    logging.info("cance project configure")
1962    post_to_project_configure_dialog('CMD_CANCEL_PROJECT_CONFIGURE', 0)
1963    wait_dialog_close(CONFIGURE_PROJECT_DIALOG)
1964
1965#================================================================#
1966#           Send Commands to Color Edit Dialog                   #
1967#================================================================#
1968color_edit_commands = [
1969'',
1970'CMD_SET_COLOR_NAME',
1971'CMD_SET_COLOR_RED',
1972'CMD_SET_COLOR_GREEN',
1973'CMD_SET_COLOR_BLUE',
1974'CMD_SET_COLOR_HUE',
1975'CMD_SET_COLOR_SAT',
1976'CMD_SET_COLOR_LUM',
1977'CMD_PALETTE_COLOR_INDEX',
1978'CMD_SAVE_COLOR_EDIT',
1979'CMD_CANCEL_COLOR_EDIT'
1980]
1981
1982def send_to_color_edit_dialog(cmd, param):
1983    handle = studio_dialogs[EDIT_COLOR_DIALOG]
1984    command = color_edit_commands.index(cmd)
1985    return(send_to_studio(handle, command, param))
1986
1987def post_to_color_edit_dialog(cmd, param):
1988    handle = studio_dialogs[EDIT_COLOR_DIALOG]
1989    command = color_edit_commands.index(cmd)
1990    return(post_to_studio(handle, command, param))
1991
1992# command the color edit dialog to set color name
1993def set_color_name(name):
1994    logging.info('set color name: %s', name)
1995    send_to_color_edit_dialog('CMD_SET_COLOR_NAME', name)
1996
1997# command the color edit dialog to set value of red channel
1998def set_color_red(red):
1999    logging.info('set red value: %d', red)
2000    send_to_color_edit_dialog('CMD_SET_COLOR_RED', str(red))
2001
2002# command the color edit dialog to set value of green channel
2003def set_color_green(green):
2004    logging.info('set green value: %d', green)
2005    send_to_color_edit_dialog('CMD_SET_COLOR_GREEN', str(green))
2006
2007# command the color edit dialog to set value of blue channel
2008def set_color_blue(blue):
2009    logging.info('set blue value: %d', blue)
2010    send_to_color_edit_dialog('CMD_SET_COLOR_BLUE', str(blue))
2011
2012# command the color edit dialog to set value of hue channel
2013def set_color_hue(hue):
2014    logging.info('set hue value: %d', hue)
2015    send_to_color_edit_dialog('CMD_SET_COLOR_HUE', str(hue))
2016
2017# command the color edit dialog to set value of saturation channel
2018def set_color_sat(sat):
2019    logging.info('set sat value: %d', sat)
2020    send_to_color_edit_dialog('CMD_SET_COLOR_SAT', str(sat))
2021
2022# command the color edit dialog to set value of luminance channel
2023def set_color_lum(lum):
2024    logging.info('set lum value: %d', lum)
2025    send_to_color_edit_dialog('CMD_SET_COLOR_LUM', str(lum))
2026
2027def set_palette_color_index(index):
2028    logging.info('set palette color index: %d', index)
2029    send_to_color_edit_dialog('CMD_PALETTE_COLOR_INDEX', index)
2030
2031# command the color edit dialog to save color edit
2032def save_color_edit(wait_close = CLOSE_WAIT):
2033    logging.info('save color edit')
2034    post_to_color_edit_dialog('CMD_SAVE_COLOR_EDIT', 0)
2035    if wait_close == CLOSE_WAIT:
2036        wait_dialog_close(EDIT_COLOR_DIALOG)
2037
2038# command the color edit dialog to cancel color edit
2039def cancel_color_edit():
2040    logging.info('cancel color edit')
2041    post_to_color_edit_dialog('CMD_CANCEL_COLOR_EDIT', 0)
2042    wait_dialog_close(EDIT_COLOR_DIALOG)
2043
2044#================================================================#
2045#           Send Commands to Font Edit Dialog                    #
2046#================================================================#
2047font_edit_commands = [
2048'',
2049'CMD_SET_FONT_PATH',
2050'CMD_SET_FONT_NAME',
2051'CMD_SET_FONT_HEIGHT',
2052'CMD_SET_FONT_HEIGHT_POST',
2053'CMD_SET_FONT_FORMAT',
2054'CMD_SET_FONT_COMPRESSION',
2055'CMD_SET_FONT_GENERATE_KERNING',
2056'CMD_SET_PAGE_RANGE',
2057'CMD_CHECK_EXTENDED_UNICODE',
2058'CMD_CHECK_CUSTOM_OUTPUT',
2059'CMD_SET_CUSTOM_OUTPUT_FILE',
2060'CMD_SAVE_FONT_EDIT',
2061'CMD_CANCEL_FONT_EDIT'
2062]
2063
2064def send_to_font_edit_dialog(cmd, param):
2065    handle = studio_dialogs[EDIT_FONT_DIALOG]
2066    command = font_edit_commands.index(cmd)
2067    return(send_to_studio(handle, command, param))
2068
2069def post_to_font_edit_dialog(cmd, param):
2070    handle = studio_dialogs[EDIT_FONT_DIALOG]
2071    command = font_edit_commands.index(cmd)
2072    return(post_to_studio(handle, command, param))
2073
2074# command the font edit dialog to set font path
2075def set_font_path(font_path):
2076    logging.info('set truetype path: %s', font_path)
2077    send_to_font_edit_dialog('CMD_SET_FONT_PATH', font_path)
2078
2079# command the font edit dialog to set font name
2080def set_font_name(font_name):
2081    logging.info('set font name: %s', font_name)
2082    send_to_font_edit_dialog('CMD_SET_FONT_NAME', font_name)
2083
2084# command the font edit dialog to set font format
2085def set_font_format(format):
2086    logging.info('set font format: %d', font_formats[format])
2087    send_to_font_edit_dialog('CMD_SET_FONT_FORMAT', font_formats[format])
2088
2089# command the font edit dialog to set font height
2090def set_font_height(height):
2091    logging.info('set font height: %d', height)
2092    send_to_font_edit_dialog('CMD_SET_FONT_HEIGHT', str(height))
2093
2094def set_font_height_post(height, close_notification = False):
2095    logging.info('set font height: %d', height)
2096    post_to_font_edit_dialog('CMD_SET_FONT_HEIGHT_POST', str(height))
2097
2098    if close_notification == True:
2099        close_message_dialog(studio_dialogs[EDIT_FONT_DIALOG])
2100
2101# command the font edit dialog to set font compression
2102def set_font_compression(compress):
2103    logging.info('set font compression: %d', compress)
2104    send_to_font_edit_dialog('CMD_SET_FONT_COMPRESSION', compress)
2105
2106def set_font_generate_kerning(kerning):
2107    logging.info('set font generate kerning info: %d', kerning)
2108    send_to_font_edit_dialog('CMD_SET_FONT_GENERATE_KERNING', kerning)
2109
2110# command the font edit dialog to set page range information
2111def set_page_range(range_index, range_enabled, range_start, range_end):
2112    logging.info('set page range, range_index %d, range_enabled, %d range_start %s, range_end %s',
2113                 range_index, range_enabled, range_start, range_end)
2114    param = str(range_index) + ','
2115    param += str(range_enabled) + ','
2116    param += str(range_start) + ','
2117    param += str(range_end)
2118
2119    send_to_font_edit_dialog('CMD_SET_PAGE_RANGE', param)
2120
2121# command the font edit dialog to check on/off extended unicode support
2122def check_extended_unicode(check):
2123    logging.info('check extended unicode support: %d', check)
2124    send_to_font_edit_dialog('CMD_CHECK_EXTENDED_UNICODE', check)
2125
2126def check_font_custom_output(check):
2127    logging.info('check font custom output: %d', check)
2128    send_to_font_edit_dialog('CMD_CHECK_CUSTOM_OUTPUT', check)
2129
2130def set_font_custom_output_file(filename):
2131    logging.info('set font custom output file: %s', filename)
2132    send_to_font_edit_dialog('CMD_SET_CUSTOM_OUTPUT_FILE', filename)
2133
2134# command the font edit dialog to save modifications
2135def save_font_edit(wait_close = CLOSE_WAIT):
2136    logging.info('save font edit')
2137    post_to_font_edit_dialog('CMD_SAVE_FONT_EDIT', 0)
2138    if wait_close == CLOSE_WAIT:
2139        wait_dialog_close(EDIT_FONT_DIALOG)
2140
2141# command the font edit dialog to cancel modifications
2142def cancel_font_edit():
2143    logging.info('cancel font edit')
2144    post_to_font_edit_dialog('CMD_CANCEL_FONT_EDIT', 0)
2145    wait_dialog_close(EDIT_FONT_DIALOG)
2146
2147
2148#================================================================#
2149#           Send Commands to Pixelmap Edit Dialog                #
2150#================================================================#
2151pixelmap_edit_commands = [
2152"",
2153'CMD_SET_IMAGE_PATH',
2154'CMD_SET_IMAGE_NAME',
2155'CMD_CHECK_CUSTOM_OUTPUT',
2156'CMD_SET_CUSTOM_OUTPUT_FILE',
2157'CMD_CHECK_RAW_FORMAT',
2158'CMD_CHECK_COMPRESS',
2159'CMD_CHECK_ALPHA',
2160'CMD_CHECK_DITHER',
2161'CMD_SET_OUTPUT_FORMAT',
2162'CMD_SET_PALETTE_TYPE',
2163'CMD_SAVE_PIXELMAP_EDIT',
2164'CMD_CANCEL_PIXELMAP_EDIT'
2165]
2166
2167def send_to_pixelmap_edit_dialog(cmd, param):
2168    handle = studio_dialogs[EDIT_PIXELMAP_DIALOG]
2169    command = pixelmap_edit_commands.index(cmd)
2170    return(send_to_studio(handle, command, param))
2171
2172def post_to_pixelmap_edit_dialog(cmd, param):
2173    handle = studio_dialogs[EDIT_PIXELMAP_DIALOG]
2174    command = pixelmap_edit_commands.index(cmd)
2175    return(post_to_studio(handle, command, param))
2176
2177def set_image_path(path):
2178    logging.info('set image path: %s', path)
2179    send_to_pixelmap_edit_dialog('CMD_SET_IMAGE_PATH', path)
2180
2181def set_image_id_name(id_name):
2182    logging.info('set image id name: %s', id_name)
2183    send_to_pixelmap_edit_dialog('CMD_SET_IMAGE_NAME', id_name)
2184
2185def check_custom_output(check):
2186    logging.info('check custom output: %d', check)
2187    send_to_pixelmap_edit_dialog('CMD_CHECK_CUSTOM_OUTPUT', check)
2188
2189def set_custom_output_file(filename):
2190    logging.info('set custom output file: %s', filename)
2191    send_to_pixelmap_edit_dialog('CMD_SET_CUSTOM_OUTPUT_FILE', filename)
2192
2193def check_raw_format(check, close_edit_dialog = False):
2194    logging.info('check raw format: %d', check)
2195
2196    if(close_edit_dialog == True):
2197        post_to_pixelmap_edit_dialog('CMD_CHECK_RAW_FORMAT', check)
2198        close_error_dialog(studio_dialogs[EDIT_PIXELMAP_DIALOG])
2199    else:
2200        send_to_pixelmap_edit_dialog('CMD_CHECK_RAW_FORMAT', check)
2201
2202def check_compress(check):
2203    logging.info('check compress: %d', check)
2204    send_to_pixelmap_edit_dialog('CMD_CHECK_COMPRESS', check)
2205
2206def check_alpha(check):
2207    logging.info('check compress: %d', check)
2208    send_to_pixelmap_edit_dialog('CMD_CHECK_ALPHA', check)
2209
2210def check_dither(check):
2211    logging.info('check dither: %d', check)
2212    send_to_pixelmap_edit_dialog('CMD_CHECK_DITHER', check)
2213
2214def set_output_format(format):
2215    logging.info('set output format: %s', format)
2216    send_to_pixelmap_edit_dialog('CMD_SET_OUTPUT_FORMAT', color_formats[format])
2217
2218def set_palette_type(type):
2219    logging.info('set palette type: %s', format)
2220    send_to_pixelmap_edit_dialog('CMD_SET_PALETTE_TYPE', palette_types[type])
2221
2222def save_pixelmap_edit(wait_close = CLOSE_WAIT):
2223    logging.info('save pixelmap edit')
2224    post_to_pixelmap_edit_dialog('CMD_SAVE_PIXELMAP_EDIT', 0)
2225    if wait_close == CLOSE_WAIT:
2226        wait_dialog_close(EDIT_PIXELMAP_DIALOG)
2227
2228def cancel_pixelmap_edit():
2229    logging.info('cancel pixelmap edit')
2230    post_to_pixelmap_edit_dialog('CMD_CANCEL_PIXELMAP_EDIT', 0)
2231    wait_dialog_close(EDIT_PIXELMAP_DIALOG)
2232
2233
2234#================================================================#
2235#           Send Commands to Folder Name Dialog                  #
2236#================================================================#
2237folder_name_commands=[
2238'',
2239'CMD_SET_FOLDER_NAME',
2240'CMD_SAVE_FOLDER_NAME_EDIT',
2241'CMD_CHECK_SPECIFY_OUTPUT_FILE',
2242'CMD_SET_FOLDER_OUTPUT_FILE_NAME',
2243]
2244
2245def send_to_folder_name_dialog(cmd, param):
2246    handle = studio_dialogs[EDIT_FOLDER_NAME_DIALOG]
2247    command = folder_name_commands.index(cmd)
2248    return(send_to_studio(handle, command, param))
2249
2250def post_to_folder_name_dialog(cmd, param):
2251    handle = studio_dialogs[EDIT_FOLDER_NAME_DIALOG]
2252    command = folder_name_commands.index(cmd)
2253    return(post_to_studio(handle, command, param))
2254
2255def set_folder_name(name):
2256    logging.info('set folder name to "%s"', name)
2257    send_to_folder_name_dialog('CMD_SET_FOLDER_NAME', name)
2258
2259def save_folder_name_edit():
2260    logging.info('save folder name edit')
2261    post_to_folder_name_dialog('CMD_SAVE_FOLDER_NAME_EDIT', 0)
2262    wait_dialog_close(EDIT_FOLDER_NAME_DIALOG)
2263
2264def check_specify_output_file(check):
2265    logging.info('set folder name to "%d"', check)
2266    send_to_folder_name_dialog('CMD_CHECK_SPECIFY_OUTPUT_FILE', check)
2267
2268def set_folder_output_file_name(name):
2269    logging.info('set folder output file name to "%s"', name)
2270    send_to_folder_name_dialog('CMD_SET_FOLDER_OUTPUT_FILE_NAME', name)
2271
2272#================================================================#
2273#           Send Commands to New Project Dialog                  #
2274#================================================================#
2275new_project_commands = [
2276'',
2277'CMD_SET_NEW_PROJECT_PATH',
2278'CMD_SET_NEW_PROJECT_NAME',
2279'CMD_SAVE_NEW_PROJECT_CREATE',
2280'CMD_CANCEL_NEW_PROJECT_CREATE'
2281]
2282
2283def send_to_new_project_dialog(cmd, param):
2284    handle = studio_dialogs[CREATE_NEW_PROJECT_DIALOG]
2285    command = new_project_commands.index(cmd)
2286    return(send_to_studio(handle, command, param))
2287
2288def post_to_new_project_dialog(cmd, param):
2289    handle = studio_dialogs[CREATE_NEW_PROJECT_DIALOG]
2290    command = new_project_commands.index(cmd)
2291    return(post_to_studio(handle, command, param))
2292
2293def set_new_project_path(path):
2294    path = os.path.realpath(path)
2295
2296    if os.path.exists(path) == False:
2297        os.makedirs(path)
2298
2299    logging.info('set project path to "%s"', path)
2300    send_to_new_project_dialog('CMD_SET_NEW_PROJECT_PATH', path)
2301
2302def set_new_project_name(name):
2303    logging.info('set project name to "%s"', name)
2304    send_to_new_project_dialog('CMD_SET_NEW_PROJECT_NAME', name)
2305
2306def save_new_project_create():
2307    logging.info('save new project create')
2308    post_to_new_project_dialog('CMD_SAVE_NEW_PROJECT_CREATE', 0)
2309    wait_dialog_close(CREATE_NEW_PROJECT_DIALOG)
2310
2311    # wait for project configure dialog show up
2312    wait_dialog_open(test_utils.CONFIGURE_PROJECT_DIALOG)
2313
2314    # save configure
2315    save_project_configure()
2316
2317def cancel_new_project_create():
2318    logging.info('cancel new project create')
2319    post_to_new_project_dialog('CMD_CANCEL_NEW_PROJECT_CREATE', 0)
2320    wait_dialog_close(CREATE_NEW_PROJECT_DIALOG)
2321
2322#================================================================#
2323#           Send Commands to String Table Dialog                 #
2324#================================================================#
2325string_edit_commands = [
2326'',
2327'CMD_GET_STRING_COUNT',
2328'CMD_ADD_STRING',
2329'CMD_DELETE_STRING',
2330'CMD_IMPORT_STRING',
2331'CMD_EXPORT_STRING',
2332'CMD_TOGGLE_THREE_COLUMN_MODE',
2333'CMD_INCREMENT_TRANS_LANGUAGE',
2334'CMD_DECREMENT_TRANS_LANGUAGE',
2335'CMD_EDIT_TOP_STRING',
2336'CMD_EDIT_BOTTOM_STRING',
2337'CMD_EDIT_STRING_ID',
2338'CMD_SELECT_STRING',
2339'CMD_SAVE_STRING_EDIT',
2340'CMD_CANCEL_STRING_EDIT',
2341'CMD_SORT_STRING'
2342]
2343
2344def send_to_string_edit_dialog(cmd, param):
2345    handle = studio_dialogs[STRING_TABLE_EDITOR_DIALOG]
2346    command = string_edit_commands.index(cmd)
2347    return(send_to_studio(handle, command, param))
2348
2349def post_to_string_edit_dialog(cmd, param):
2350    handle = studio_dialogs[STRING_TABLE_EDITOR_DIALOG]
2351    command = string_edit_commands.index(cmd)
2352    return(post_to_studio(handle, command, param))
2353
2354# command the string table edit dialog to get string count
2355def get_string_count():
2356    return send_to_string_edit_dialog('CMD_GET_STRING_COUNT', 0)
2357
2358# command the string table edit dialog to add a string
2359def add_string():
2360    logging.info('add a string')
2361    send_to_string_edit_dialog('CMD_ADD_STRING', 0)
2362
2363# command the string table edit dialog to delete a string
2364def delete_string():
2365    logging.info('delete a string')
2366    send_to_string_edit_dialog('CMD_DELETE_STRING', 0)
2367
2368# command the string table edit dialog to import a xliff file
2369def import_string(filename):
2370    filename = os.path.realpath(filename)
2371    logging.info('import string file: %s', filename)
2372    post_to_string_edit_dialog('CMD_IMPORT_STRING', filename)
2373    close_message_dialog(studio_dialogs[STRING_TABLE_EDITOR_DIALOG])
2374
2375# command the string table edit dialog to export a xliff file
2376def export_string():
2377    logging.info('export to string file')
2378    post_to_string_edit_dialog('CMD_EXPORT_STRING', 0)
2379    wait_dialog_open(STRING_EXPORT_CONTROL_DIALOG, studio_dialogs[STRING_TABLE_EDITOR_DIALOG])
2380
2381# command the string table edit dialog to toggole three column mode
2382def toggle_three_column_mode():
2383    logging.info('toggle three column mode')
2384    send_to_string_edit_dialog('CMD_TOGGLE_THREE_COLUMN_MODE', 0)
2385
2386# command the string table edit dialog to increment transfer language
2387def increment_trans_language():
2388    logging.info('increment transfer language')
2389    send_to_string_edit_dialog('CMD_INCREMENT_TRANS_LANGUAGE', 0)
2390
2391# command the string table edit dialog to decrement transfer language
2392def decrement_trans_language():
2393    logging.info('decrement transfer language')
2394    send_to_string_edit_dialog('CMD_DECREMENT_TRANS_LANGUAGE', 0)
2395
2396# command the string table edit dialog to edit top string
2397def edit_top_string(string):
2398    logging.info('edit top string: %s', string.encode(sys.stdout.encoding, 'replace'))
2399    send_to_string_edit_dialog('CMD_EDIT_TOP_STRING', string)
2400
2401# command the string table edit dialog to edit bottom string
2402def edit_bottom_string(string):
2403    logging.info('edit bottom string: %s', string.encode(sys.stdout.encoding, 'replace'))
2404    send_to_string_edit_dialog('CMD_EDIT_BOTTOM_STRING', string)
2405
2406# command the string table edit dialog to edit string id
2407def edit_string_id(id_name):
2408    logging.info('edit string id: %s', id_name)
2409    send_to_string_edit_dialog('CMD_EDIT_STRING_ID', id_name)
2410
2411# command the string table edit dialog to select a string
2412def select_string(row_index):
2413    logging.info('select string row: %d', row_index)
2414    send_to_string_edit_dialog('CMD_SELECT_STRING', row_index)
2415
2416# command the string table edit dialog to save the string table changes
2417def save_string_edit(wait_close = CLOSE_WAIT):
2418    logging.info('save string edit')
2419    post_to_string_edit_dialog('CMD_SAVE_STRING_EDIT', 0)
2420    if wait_close == CLOSE_WAIT:
2421        wait_dialog_close(STRING_TABLE_EDITOR_DIALOG)
2422
2423# command the string table edit dialog to close dialog
2424def cancel_string_edit():
2425    logging.info('cancel string edit')
2426    post_to_string_edit_dialog('CMD_CANCEL_STRING_EDIT', 0)
2427    wait_dialog_close(STRING_TABLE_EDITOR_DIALOG)
2428
2429def sort_string(type):
2430    logging.info('sort string by: %s', type)
2431    send_to_string_edit_dialog('CMD_SORT_STRING', type)
2432
2433#================================================================#
2434#           Send Commands to String Export Dialog                #
2435#================================================================#
2436string_export_commands = [
2437'',
2438'CMD_SET_STRING_EXPORT_SRC_LANGUAGE',
2439'CMD_SET_STRING_EXPORT_TARGET_LANGUAGE',
2440'CMD_SET_XLIFF_VERSION',
2441'CMD_SET_STRING_EXPORT_FILENAME',
2442'CMD_SET_STRING_EXPORT_PATH',
2443'CMD_SELECT_STRING_EXPORT_FORMAT',
2444'CMD_SAVE_STRING_EXPORT',
2445'CMD_CANCEL_STRING_EXPORT'
2446]
2447
2448def send_to_string_export_dialog(cmd, param):
2449    handle = studio_dialogs[STRING_EXPORT_CONTROL_DIALOG]
2450    command = string_export_commands.index(cmd)
2451    return(send_to_studio(handle, command, param))
2452
2453def post_to_string_export_dialog(cmd, param):
2454    handle = studio_dialogs[STRING_EXPORT_CONTROL_DIALOG]
2455    command = string_export_commands.index(cmd)
2456    return(post_to_studio(handle, command, param))
2457
2458# command the string export control dialog to set source language
2459def set_string_export_src_language(language):
2460    logging.info('set source language: %s', language)
2461    send_to_string_export_dialog('CMD_SET_STRING_EXPORT_SRC_LANGUAGE', language)
2462
2463# command the string export control dialog to set target language
2464def set_string_export_target_language(language):
2465    logging.info('set target language: %s', language)
2466    send_to_string_export_dialog('CMD_SET_STRING_EXPORT_TARGET_LANGUAGE', language)
2467
2468# command the string export control dialog to set xliff version
2469def set_xliff_version(version):
2470    logging.info('set XLIFF version: %s', test_constants.xliff_versions[version])
2471    send_to_string_export_dialog('CMD_SET_XLIFF_VERSION', test_constants.xliff_versions[version])
2472
2473# command the string export control dialog to set string export filename
2474def set_string_export_filename(filename):
2475    logging.info('set string export filename: %s', filename)
2476    send_to_string_export_dialog('CMD_SET_STRING_EXPORT_FILENAME', filename)
2477
2478# command the string export control dialog to set string export filepath
2479def set_string_export_path(path):
2480    path = os.path.realpath(path)
2481
2482    if os.path.exists(path) == False:
2483        os.makedirs(path)
2484
2485    logging.info('set string export file path: %s', path)
2486    send_to_string_export_dialog('CMD_SET_STRING_EXPORT_PATH', path)
2487
2488def select_string_export_format(format_type):
2489    logging.info('set string export format to: %s', test_constants.string_export_types[format_type])
2490    send_to_string_export_dialog('CMD_SELECT_STRING_EXPORT_FORMAT', test_constants.string_export_types[format_type])
2491
2492# command the string export control dialog to save string export
2493def save_string_export():
2494    logging.info('save string export')
2495    post_to_string_export_dialog('CMD_SAVE_STRING_EXPORT', 0)
2496    wait_dialog_close(STRING_EXPORT_CONTROL_DIALOG, studio_dialogs[STRING_TABLE_EDITOR_DIALOG])
2497    close_message_dialog(studio_dialogs[STRING_TABLE_EDITOR_DIALOG])
2498
2499# command the string export control dialog to cancel string export
2500def cancel_string_export():
2501    logging.info('cancel string export')
2502    post_to_string_export_dialog('CMD_CANCEL_STRING_EXPORT', 0)
2503    wait_dialog_close(STRING_EXPORT_CONTROL_DIALOG, studio_dialogs[STRING_TABLE_EDITOR_DIALOG])
2504
2505
2506#================================================================#
2507#          Send Commands to Grid Snap Setting Dialog             #
2508#================================================================#
2509grid_snap_setting_commands = [
2510    '',
2511    'CMD_CHECK_SHOW_GRID',
2512    'CMD_CHECK_SNAP',
2513    'CMD_SET_GRID_SPACING',
2514    'CMD_SET_SNAP_SPACING',
2515    'CMD_SAVE',
2516    'CMD_CANCEL'
2517]
2518
2519def send_to_grid_snap_setting_dialog(cmd, param):
2520    handle = studio_dialogs[GRID_SNAP_SETTING_DIALOG]
2521    command = grid_snap_setting_commands.index(cmd)
2522    return(send_to_studio(handle, command, param))
2523
2524def post_to_grid_snap_setting_dialog(cmd, param):
2525    handle = studio_dialogs[GRID_SNAP_SETTING_DIALOG]
2526    command = grid_snap_setting_commands.index(cmd)
2527    return(post_to_studio(handle, command, param))
2528
2529def check_show_grid(check):
2530    if check:
2531        logging.info('check on show grid')
2532    else:
2533        logging.info('check off show grid')
2534
2535    send_to_grid_snap_setting_dialog('CMD_CHECK_SHOW_GRID', check)
2536
2537def check_snap(check):
2538    if check:
2539        logging.info('check on snap to grid')
2540    else:
2541        logging.info('check off snap to grid')
2542
2543    send_to_grid_snap_setting_dialog('CMD_CHECK_SNAP', check)
2544
2545def set_grid_spacing(spacing):
2546    logging.info('set grid spacing to: %d', spacing)
2547    send_to_grid_snap_setting_dialog('CMD_SET_GRID_SPACING', spacing)
2548
2549def set_snap_spacing(spacing):
2550    logging.info('set snap spacing to: %d', spacing)
2551    send_to_grid_snap_setting_dialog('CMD_SET_SNAP_SPACING', spacing)
2552
2553def save_grid_snap_setting():
2554    logging.info('save grid snap setting')
2555    post_to_grid_snap_setting_dialog('CMD_SAVE', 0)
2556    wait_dialog_close(GRID_SNAP_SETTING_DIALOG)
2557
2558def cancel_grid_snap_setting():
2559    logging.info('save grid snap setting')
2560    post_to_grid_snap_setting_dialog('CMD_CANCEL', 0)
2561    wait_dialog_close(GRID_SNAP_SETTING_DIALOG)
2562
2563#================================================================#
2564#          Send Commands to Resource Export Dialog               #
2565#================================================================#
2566resource_export_dialog_commands = [
2567    '',
2568    'CMD_CHECK_BINARY_MODE',
2569    'CMD_CHECK_RES_HEADER_GEN',
2570    'CMD_CHECK_RESOURCE',
2571    'CMD_SET_CUSTOM_RESOURCE_NAME',
2572    'CMD_GENERATE',
2573    'CMD_CANCEL'
2574]
2575
2576def send_to_resource_export_dialog(cmd, param):
2577    handle = studio_dialogs[RESOURCE_EXPORT_DIALOG]
2578    command = resource_export_dialog_commands.index(cmd)
2579    return(send_to_studio(handle, command, param))
2580
2581def post_to_resource_export_dialog(cmd, param):
2582    handle = studio_dialogs[RESOURCE_EXPORT_DIALOG]
2583    command = resource_export_dialog_commands.index(cmd)
2584    return(post_to_studio(handle, command, param))
2585
2586def check_binary_mode(check):
2587    if check:
2588        logging.info('check on binary mode')
2589    else:
2590        logging.info('check off binary mode')
2591
2592    send_to_resource_export_dialog('CMD_CHECK_BINARY_MODE', check)
2593
2594def check_res_header_gen(check):
2595    if check:
2596        logging.info('check on resource header generation')
2597    else:
2598        logging.info('check off resource header genearation')
2599
2600    send_to_resource_export_dialog('CMD_CHECK_RES_HEADER_GEN', check)
2601
2602def check_resource(parent_name, resource_name, check):
2603    if check:
2604        logging.info('check on %s/%s', parent_name, resource_name)
2605    else:
2606        logging.info('check off %s/%s', parent_name, resource_name)
2607
2608    param = parent_name + ','
2609    param += resource_name + ','
2610    param += str(check)
2611
2612    send_to_resource_export_dialog('CMD_CHECK_RESOURCE', param)
2613
2614def set_custom_resource_name(custom_name):
2615    logging.info('set ')
2616    send_to_resource_export_dialog('CMD_SET_CUSTOM_RESOURCE_NAME', custom_name)
2617
2618def click_generate_button(close_notification = 1):
2619    logging.info('click generate button')
2620    post_to_resource_export_dialog('CMD_GENERATE', 0)
2621    wait_dialog_close(RESOURCE_EXPORT_DIALOG)
2622
2623    if close_notification:
2624        close_message_dialog()
2625
2626def cancel_resource_generation():
2627    logging.info('cance resource generation')
2628    post_to_resource_export_dialog('CMD_CANCEL', 0)
2629    wait_dialog_close(RESOURCE_EXPORT_DIALOG)
2630
2631#================================================================#
2632#          Send Commands to Configure Theme Dialog               #
2633#================================================================#
2634configure_theme_dialog_commands = [
2635    '',
2636    'CMD_SELECT_DISPLAY_NAME',
2637    'CMD_ADD_THEME',
2638    'CMD_DELETE_THEME',
2639    'CMD_SET_ACTIVE_THEME',
2640    'CMD_SELECT_THEME_INDEX',
2641    'CMD_SET_THEME_NAME',
2642    'CMD_EDIT_PALETTE',
2643    'CMD_CANCEL_THEME_CONFIGURE',
2644    'CMD_SAVE_THEME_CONFIGURE'
2645]
2646
2647def send_to_configure_theme_dialog(cmd, param):
2648    handle = studio_dialogs[CONFIGURE_THEME_DIALOG]
2649    command = configure_theme_dialog_commands.index(cmd)
2650    return(send_to_studio(handle, command, param))
2651
2652def post_to_configure_theme_dialog(cmd, param):
2653    handle = studio_dialogs[CONFIGURE_THEME_DIALOG]
2654    command = configure_theme_dialog_commands.index(cmd)
2655    return(post_to_studio(handle, command, param))
2656
2657def select_display_name(display_name):
2658    logging.info("select display name: %s", display_name)
2659    send_to_configure_theme_dialog('CMD_SELECT_DISPLAY_NAME', display_name)
2660
2661def add_theme():
2662    logging.info("increate theme number")
2663    send_to_configure_theme_dialog('CMD_ADD_THEME', 0)
2664
2665def delete_theme():
2666    logging.info("decrease theme number")
2667    send_to_configure_theme_dialog('CMD_DELETE_THEME', 0)
2668
2669def set_active_theme(theme_name):
2670    logging.info("set active theme: %s", theme_name)
2671    send_to_configure_theme_dialog('CMD_SET_ACTIVE_THEME', theme_name)
2672
2673def select_theme_index(index):
2674    logging.info("select theme index: %d", index)
2675    send_to_configure_theme_dialog('CMD_SELECT_THEME_INDEX', index)
2676
2677def post_select_theme_index(index):
2678    logging.info("post select theme index: %d", index)
2679    post_to_configure_theme_dialog('CMD_SELECT_THEME_INDEX', index)
2680
2681def set_theme_name(theme_name):
2682    logging.info("set theme name: %s", theme_name)
2683    send_to_configure_theme_dialog('CMD_SET_THEME_NAME', theme_name)
2684
2685def edit_palette():
2686    logging.info("edit palette")
2687    post_to_configure_theme_dialog('CMD_EDIT_PALETTE', 0)
2688    wait_dialog_open(EDIT_PALETTE_DIALOG, studio_dialogs[CONFIGURE_THEME_DIALOG])
2689
2690def cancel_theme_configure():
2691    logging.info("cancel theme configure")
2692    post_to_configure_theme_dialog('CMD_CANCEL_THEME_CONFIGURE', 0)
2693    wait_dialog_close(CONFIGURE_THEME_DIALOG)
2694
2695def save_theme_configure(wait_close = CLOSE_WAIT):
2696    logging.info("save theme configure")
2697    post_to_configure_theme_dialog('CMD_SAVE_THEME_CONFIGURE', 0)
2698
2699    if wait_close == CLOSE_WAIT:
2700        wait_dialog_close(CONFIGURE_THEME_DIALOG)
2701
2702#================================================================#
2703#          Send Commands to Edit palette                         #
2704#================================================================#
2705palette_layout_dialog_commands = [
2706    '',
2707    'CMD_SET_PREDEFINED_PALETTE_ENTRY',
2708    'CMD_SET_PALETTE_COLOR',
2709    'CMD_SAVE_PALETTE_EDIT',
2710    'CMD_CANCEL_PALETTE_EDIT'
2711]
2712
2713def send_to_palette_layout_dialog(cmd, param):
2714    handle = studio_dialogs[EDIT_PALETTE_DIALOG]
2715    command = palette_layout_dialog_commands.index(cmd)
2716    return(send_to_studio(handle, command, param))
2717
2718def post_to_palette_layout_dialog(cmd, param):
2719    handle = studio_dialogs[EDIT_PALETTE_DIALOG]
2720    command = palette_layout_dialog_commands.index(cmd)
2721    return(post_to_studio(handle, command, param))
2722
2723def set_predefined_palette_entry(count):
2724    logging.info("set predefined palette entry to %d", count)
2725    send_to_palette_layout_dialog('CMD_SET_PREDEFINED_PALETTE_ENTRY', count)
2726
2727def set_palette_color(index, red, green, blue):
2728    color = (red << 16) | (green << 8) | blue
2729    logging.info("set color[%d] to %x", index, color)
2730    param = str(index) + ',' + str(color)
2731    send_to_palette_layout_dialog('CMD_SET_PALETTE_COLOR', param)
2732
2733def save_palette_edit():
2734    logging.info("save palette edit")
2735    post_to_palette_layout_dialog('CMD_SAVE_PALETTE_EDIT', 0)
2736    wait_dialog_close(EDIT_PALETTE_DIALOG, studio_dialogs[CONFIGURE_THEME_DIALOG])
2737
2738def cancel_palette_edit():
2739    logging.info("cancel palette edit")
2740    post_to_palette_layout_dialog('CMD_CANCEL_PALETTE_EDIT', 0)
2741    wait_dialog_close(EDIT_PALETTE_DIALOG, studio_dialogs[CONFIGURE_THEME_DIALOG])
2742
2743#================================================================#
2744#          Send Commands to String Scroll Wheel Edit Dialog      #
2745#================================================================#
2746string_scroll_wheel_edit_dialog_commands = [
2747    '',
2748    'CMD_SET_STRING',
2749    'CMD_SAVE',
2750    'CMD_CANCEL'
2751]
2752
2753def send_to_string_scroll_wheel_edit_dialog(cmd, param):
2754    handle = studio_dialogs[STRING_SCROLL_WHEEL_EDIT_DIALOG]
2755    command = string_scroll_wheel_edit_dialog_commands.index(cmd)
2756    return(send_to_studio(handle, command, param))
2757
2758def post_to_string_scroll_wheel_edit_dialog(cmd, param):
2759    handle = studio_dialogs[STRING_SCROLL_WHEEL_EDIT_DIALOG]
2760    command = string_scroll_wheel_edit_dialog_commands.index(cmd)
2761    return(post_to_studio(handle, command, param))
2762
2763def edit_string_scroll_wheel_string(id, string):
2764    logging.info("edit string list: row = %d, string = %s", id, string)
2765    param = str(id) + ',' + string
2766    send_to_string_scroll_wheel_edit_dialog('CMD_SET_STRING', param)
2767
2768def cancel_string_scroll_wheel_edit():
2769    logging.info("cancel string scroll wheel edit")
2770    post_to_string_scroll_wheel_edit_dialog('CMD_CANCEL', 0)
2771    wait_dialog_close(STRING_SCROLL_WHEEL_EDIT_DIALOG)
2772
2773def save_string_scroll_wheel_edit():
2774    logging.info("save string scroll wheel edit")
2775    post_to_string_scroll_wheel_edit_dialog('CMD_SAVE', 0)
2776    wait_dialog_close(STRING_SCROLL_WHEEL_EDIT_DIALOG)
2777
2778#================================================================#
2779#          Send Commands to String Scroll Wheel Edit Dialog      #
2780#================================================================#
2781string_scroll_wheel_edit_dialog_commands = [
2782    '',
2783    'CMD_SET_STRING',
2784    'CMD_SAVE',
2785    'CMD_CANCEL'
2786]
2787
2788def send_to_string_scroll_wheel_edit_dialog(cmd, param):
2789    handle = studio_dialogs[STRING_SCROLL_WHEEL_EDIT_DIALOG]
2790    command = string_scroll_wheel_edit_dialog_commands.index(cmd)
2791    return(send_to_studio(handle, command, param))
2792
2793def post_to_string_scroll_wheel_edit_dialog(cmd, param):
2794    handle = studio_dialogs[STRING_SCROLL_WHEEL_EDIT_DIALOG]
2795    command = string_scroll_wheel_edit_dialog_commands.index(cmd)
2796    return(post_to_studio(handle, command, param))
2797
2798def edit_string_scroll_wheel_string(id, string):
2799    logging.info("edit string list: row = %d, string = %s", id, string)
2800    param = str(id) + ',' + string
2801    send_to_string_scroll_wheel_edit_dialog('CMD_SET_STRING', param)
2802
2803def cancel_string_scroll_wheel_edit():
2804    logging.info("cancel string scroll wheel edit")
2805    post_to_string_scroll_wheel_edit_dialog('CMD_CANCEL', 0)
2806    wait_dialog_close(STRING_SCROLL_WHEEL_EDIT_DIALOG)
2807
2808def save_string_scroll_wheel_edit():
2809    logging.info("save string scroll wheel edit")
2810    post_to_string_scroll_wheel_edit_dialog('CMD_SAVE', 0)
2811    wait_dialog_close(STRING_SCROLL_WHEEL_EDIT_DIALOG)
2812
2813#================================================================#
2814#          Send Commands to String Scroll Wheel Edit Dialog      #
2815#================================================================#
2816string_scroll_wheel_edit_dialog_commands = [
2817    '',
2818    'CMD_SET_STRING',
2819    'CMD_SAVE',
2820    'CMD_CANCEL'
2821]
2822
2823def send_to_string_scroll_wheel_edit_dialog(cmd, param):
2824    handle = studio_dialogs[STRING_SCROLL_WHEEL_EDIT_DIALOG]
2825    command = string_scroll_wheel_edit_dialog_commands.index(cmd)
2826    return(send_to_studio(handle, command, param))
2827
2828def post_to_string_scroll_wheel_edit_dialog(cmd, param):
2829    handle = studio_dialogs[STRING_SCROLL_WHEEL_EDIT_DIALOG]
2830    command = string_scroll_wheel_edit_dialog_commands.index(cmd)
2831    return(post_to_studio(handle, command, param))
2832
2833def edit_string_scroll_wheel_string(id, string):
2834    logging.info("edit string list: row = %d, string = %s", id, string)
2835    param = str(id) + ',' + string
2836    send_to_string_scroll_wheel_edit_dialog('CMD_SET_STRING', param)
2837
2838def cancel_string_scroll_wheel_edit():
2839    logging.info("cancel string scroll wheel edit")
2840    post_to_string_scroll_wheel_edit_dialog('CMD_CANCEL', 0)
2841    wait_dialog_close(STRING_SCROLL_WHEEL_EDIT_DIALOG)
2842
2843def save_string_scroll_wheel_edit():
2844    logging.info("save string scroll wheel edit")
2845    post_to_string_scroll_wheel_edit_dialog('CMD_SAVE', 0)
2846    wait_dialog_close(STRING_SCROLL_WHEEL_EDIT_DIALOG)
2847
2848#================================================================#
2849#          Send Commands to Project Import Dialog                #
2850#================================================================#
2851project_import_dialog_commands = [
2852    '',
2853    'CMD_IMPORT',
2854    'CMD_CANCEL',
2855    'CMD_CHECK_SCREEN'
2856]
2857
2858def send_to_project_import_dialog(cmd, param):
2859    handle = studio_dialogs[IMPORT_PROJECT_DIALOG]
2860    command = project_import_dialog_commands.index(cmd)
2861    return(send_to_studio(handle, command, param))
2862
2863def post_to_project_import_dialog(cmd, param):
2864    handle = studio_dialogs[IMPORT_PROJECT_DIALOG]
2865    command = project_import_dialog_commands.index(cmd)
2866    return(post_to_studio(handle, command, param))
2867
2868def check_import_screen(parent_name, screen_name, check):
2869    if check:
2870        logging.info('check on %s/%s', parent_name, screen_name)
2871    else:
2872        logging.info('check off %s/%s', parent_name, screen_name)
2873
2874    param = parent_name + ','
2875    param += screen_name + ','
2876    param += str(check)
2877
2878    send_to_project_import_dialog('CMD_CHECK_SCREEN', param)
2879
2880def cancel_project_import_dialog(wait_close = CLOSE_WAIT):
2881    logging.info("cancel project import")
2882    post_to_project_import_dialog('CMD_CANCEL', 0)
2883    if wait_close == CLOSE_WAIT:
2884        wait_dialog_close(IMPORT_PROJECT_DIALOG)
2885
2886def save_project_import_dialog(wait_close = CLOSE_WAIT):
2887    logging.info("save project import")
2888    post_to_project_import_dialog('CMD_IMPORT', 0)
2889    if wait_close == CLOSE_WAIT:
2890        wait_dialog_close(IMPORT_PROJECT_DIALOG)
2891
2892#================================================================#
2893#                Send Commands to Option Dialog                  #
2894#================================================================#
2895option_dialog_commands = [
2896    '',
2897    'CMD_SELECT_OPTION'
2898]
2899
2900def post_to_option_dialog(cmd, param):
2901    handle = studio_dialogs[OPTION_DIALOG]
2902    command = option_dialog_commands.index(cmd)
2903    return(post_to_studio(handle, command, param))
2904
2905def select_option(option_index):
2906    wait_dialog_open(OPTION_DIALOG, studio_windows['main_frame'])
2907    logging.info("select option %d", option_index)
2908    post_to_option_dialog('CMD_SELECT_OPTION', option_index)
2909    wait_dialog_close(OPTION_DIALOG, studio_windows['main_frame'])
2910
2911
2912#================================================================#
2913#          Send Commands to Screen Flow Edit Dialog              #
2914#================================================================#
2915screen_flow_edit_dialog_commands = [
2916    '',
2917    'CMD_EDIT_TRIGGER_LIST',
2918    'CMD_SAVE_SCREEN_FLOW_EDIT',
2919    'CMD_CANCEL_SCREEN_FLOW_EDIT'
2920]
2921
2922def send_to_screen_flow_edit_dialog(cmd, param):
2923    handle = studio_dialogs[SCREEN_FLOW_EDIT_DIALOG]
2924    command = screen_flow_edit_dialog_commands.index(cmd)
2925    return(send_to_studio(handle, command, param))
2926
2927def post_to_screen_flow_edit_dialog(cmd, param):
2928    handle = studio_dialogs[SCREEN_FLOW_EDIT_DIALOG]
2929    command = screen_flow_edit_dialog_commands.index(cmd)
2930    return(post_to_studio(handle, command, param))
2931
2932def edit_trigger_list(screen_name):
2933    global selected_screen_name;
2934    selected_screen_name = screen_name;
2935    logging.info('edit trigger list: %s', screen_name)
2936    post_to_screen_flow_edit_dialog('CMD_EDIT_TRIGGER_LIST', screen_name)
2937    wait_dialog_open(TRIGGER_LIST_EDIT_DIALOG, studio_dialogs[SCREEN_FLOW_EDIT_DIALOG])
2938
2939def cancel_screen_flow_edit_dialog():
2940    logging.info("cancel screen flow edit")
2941    post_to_screen_flow_edit_dialog('CMD_CANCEL_SCREEN_FLOW_EDIT', 0)
2942    wait_dialog_close(SCREEN_FLOW_EDIT_DIALOG)
2943
2944def save_screen_flow_edit_dialog():
2945    logging.info("save screen flow edit")
2946    post_to_screen_flow_edit_dialog('CMD_SAVE_SCREEN_FLOW_EDIT', 0)
2947    wait_dialog_close(SCREEN_FLOW_EDIT_DIALOG)
2948
2949#================================================================#
2950#          Send Commands to Trigger List Edit Dialog             #
2951#================================================================#
2952trigger_list_edit_dialog_commands = [
2953    '',
2954    'CMD_ADD_TRIGGER',
2955    'CMD_DELETE_TRIGGER',
2956    'CMD_EDIT_TRIGGER',
2957    'CMD_EDIT_ACTION',
2958    'CMD_SELETE_ROW',
2959    'CMD_SAVE_TRIGGER_LIST_EDIT',
2960    'CMD_CANCEL_TRIGGER_LIST_EDIT'
2961]
2962
2963def send_to_trigger_list_edit_dialog(cmd, param):
2964    handle = studio_dialogs[TRIGGER_LIST_EDIT_DIALOG]
2965    command = trigger_list_edit_dialog_commands.index(cmd)
2966    return(send_to_studio(handle, command, param))
2967
2968def post_to_trigger_list_edit_dialog(cmd, param):
2969    handle = studio_dialogs[TRIGGER_LIST_EDIT_DIALOG]
2970    command = trigger_list_edit_dialog_commands.index(cmd)
2971    return(post_to_studio(handle, command, param))
2972
2973def add_trigger():
2974    logging.info('add trigger')
2975    post_to_trigger_list_edit_dialog('CMD_ADD_TRIGGER', 0)
2976    global TRIGGER_EDIT_DIALOG
2977    TRIGGER_EDIT_DIALOG = 'Add Trigger for [' + selected_screen_name +']'
2978    wait_dialog_open(TRIGGER_EDIT_DIALOG, studio_dialogs[TRIGGER_LIST_EDIT_DIALOG])
2979
2980def delete_trigger():
2981    logging.info('delete trigger')
2982    send_to_trigger_list_edit_dialog('CMD_DELETE_TRIGGER', 0)
2983
2984def edit_trigger():
2985    logging.info('edit trigger')
2986    post_to_trigger_list_edit_dialog('CMD_EDIT_TRIGGER', 0)
2987    global TRIGGER_EDIT_DIALOG
2988    TRIGGER_EDIT_DIALOG = 'Edit Trigger for [' + selected_screen_name + ']'
2989    wait_dialog_open(TRIGGER_EDIT_DIALOG, studio_dialogs[TRIGGER_LIST_EDIT_DIALOG])
2990
2991def edit_action(trigger_name):
2992    logging.info('edit action')
2993    post_to_trigger_list_edit_dialog('CMD_EDIT_ACTION', 0)
2994    global TRIGGER_ACTION_EDIT_DIALOG
2995    TRIGGER_ACTION_EDIT_DIALOG = 'Edit Actions for Trigger [on_' + trigger_name + ']'
2996    wait_dialog_open(TRIGGER_ACTION_EDIT_DIALOG, studio_dialogs[TRIGGER_LIST_EDIT_DIALOG])
2997
2998def select_trigger_list_row(row):
2999    logging.info('selete trigger list row: %d', row)
3000    send_to_trigger_list_edit_dialog('CMD_SELETE_ROW', row)
3001
3002def cancel_trigger_list_edit_dialog():
3003    logging.info("cancel trigger list edit")
3004    post_to_trigger_list_edit_dialog('CMD_CANCEL_TRIGGER_LIST_EDIT', 0)
3005    wait_dialog_close(TRIGGER_LIST_EDIT_DIALOG)
3006
3007def save_trigger_list_edit_dialog():
3008    logging.info("save trigger list edit")
3009    post_to_trigger_list_edit_dialog('CMD_SAVE_TRIGGER_LIST_EDIT', 0)
3010    wait_dialog_close(TRIGGER_LIST_EDIT_DIALOG)
3011
3012#================================================================#
3013#          Send Commands to Trigger Edit Dialog                  #
3014#================================================================#
3015trigger_edit_dialog_commands = [
3016    '',
3017    'CMD_SET_TRIGGER_TYPE',
3018    'CMD_SET_EVENT_TYPE',
3019    'CMD_SAVE_TRIGGER_EDIT',
3020    'CMD_CANCEL_TRIGGER_EDIT'
3021]
3022
3023def send_to_trigger_edit_dialog(cmd, param):
3024    handle = studio_dialogs[TRIGGER_EDIT_DIALOG]
3025    command = trigger_edit_dialog_commands.index(cmd)
3026    return(send_to_studio(handle, command, param))
3027
3028def post_to_trigger_edit_dialog(cmd, param):
3029    handle = studio_dialogs[TRIGGER_EDIT_DIALOG]
3030    command = trigger_edit_dialog_commands.index(cmd)
3031    return(post_to_studio(handle, command, param))
3032
3033def set_trigger_type(type_string):
3034    logging.info('set trigger type to %s', type_string)
3035    send_to_trigger_edit_dialog('CMD_SET_TRIGGER_TYPE', trigger_types[type_string])
3036
3037def set_event_type(type_string):
3038    logging.info('set event type to \"%s\"', type_string)
3039    send_to_trigger_edit_dialog('CMD_SET_EVENT_TYPE', type_string)
3040
3041def cancel_trigger_edit_dialog():
3042    logging.info("cancel trigger edit dialog")
3043    post_to_trigger_edit_dialog('CMD_CANCEL_TRIGGER_EDIT', 0)
3044    wait_dialog_close(TRIGGER_EDIT_DIALOG)
3045
3046def save_trigger_edit_dialog(wait = CLOSE_WAIT):
3047    logging.info("save trigger edit dialog")
3048    post_to_trigger_edit_dialog('CMD_SAVE_TRIGGER_EDIT', 0)
3049
3050    if wait == CLOSE_WAIT:
3051        wait_dialog_close(TRIGGER_EDIT_DIALOG)
3052
3053#================================================================#
3054#      Send Commands to Trigger Action Edit Dialog               #
3055#================================================================#
3056trigger_action_edit_dialog_commands = [
3057    '',
3058    'CMD_ADD_ACTION',
3059    'CMD_SELECT_ACTION',
3060    'CMD_DELETE_ACTION',
3061    'CMD_SELECT_TARGET',
3062    'CMD_SELECT_PARENT',
3063    'CMD_TARGET_SHOW_CHILD_WIDGETS',
3064    'CMD_PARENT_SHOW_CHILD_WIDGETS',
3065    'CMD_EDIT_ACTION_NAME',
3066    'CMD_EDIT_ANIMATION_INFO',
3067    'CMD_CHECK_DETACH_TARGET',
3068    'CMD_CONFIGURE_EASING_FUNCTION',
3069    'CMD_SAVE_TRIGGER_ACTION_EDIT',
3070    'CMD_CANCEL_TRIGGER_ACTION_EDIT'
3071]
3072
3073def send_to_trigger_action_edit_dialog(cmd, param):
3074    handle = studio_dialogs[TRIGGER_ACTION_EDIT_DIALOG]
3075    command = trigger_action_edit_dialog_commands.index(cmd)
3076    return(send_to_studio(handle, command, param))
3077
3078def post_to_trigger_action_edit_dialog(cmd, param):
3079    handle = studio_dialogs[TRIGGER_ACTION_EDIT_DIALOG]
3080    command = trigger_action_edit_dialog_commands.index(cmd)
3081    return(post_to_studio(handle, command, param))
3082
3083def add_action(action_type):
3084    logging.info('set action type to %s', action_type)
3085    post_to_trigger_action_edit_dialog('CMD_ADD_ACTION', 0)
3086    wait_dialog_open(TRIGGER_ACTION_SELECT_DIALOG, studio_dialogs[TRIGGER_ACTION_EDIT_DIALOG])
3087    action_select_dlg_select_action(action_type)
3088    save_action_select_dialog()
3089
3090def select_action(action_name):
3091    logging.info('select action: %s', action_name)
3092    send_to_trigger_action_edit_dialog('CMD_SELECT_ACTION', action_name)
3093
3094#def select_action()
3095def delete_action():
3096    logging.info('delete current selected action')
3097    send_to_trigger_action_edit_dialog('CMD_DELETE_ACTION', 0)
3098
3099def select_target(target_name):
3100    logging.info('select target \"%s\"', target_name)
3101    send_to_trigger_action_edit_dialog('CMD_SELECT_TARGET', target_name)
3102
3103def select_parent(parent_name):
3104    logging.info('select parent \"%s\"', parent_name)
3105    send_to_trigger_action_edit_dialog('CMD_SELECT_PARENT', parent_name)
3106
3107def check_target_show_child_widgets(check):
3108    if check:
3109        logging.info('check on target show child widgets')
3110    else:
3111        logging.info('check off target show child widgets')
3112
3113    send_to_trigger_action_edit_dialog('CMD_TARGET_SHOW_CHILD_WIDGETS', check)
3114
3115def check_parent_show_child_widgets(check):
3116    if check:
3117        logging.info('check on parent show child widgets')
3118    else:
3119        logging.info('check off parent show child widgets')
3120
3121    send_to_trigger_action_edit_dialog('CMD_PARENT_SHOW_CHILD_WIDGETS', check)
3122
3123def edit_action_name(name):
3124    logging.info('set action name to \"%s\"', name)
3125    send_to_trigger_action_edit_dialog('CMD_EDIT_ACTION_NAME', name)
3126
3127def edit_animation_info(control_id, string):
3128    control_id = 'ID_' + control_id
3129    logging.info('set %s = %s', control_id, string)
3130    param = str(animation_param_ids[control_id]) + ',' + string
3131    send_to_trigger_action_edit_dialog('CMD_EDIT_ANIMATION_INFO', param)
3132
3133def check_detach_target(check):
3134    if check:
3135        logging.info('check on detach target')
3136    else:
3137        logging.info('check off detach target')
3138
3139    send_to_trigger_action_edit_dialog('CMD_CHECK_DETACH_TARGET', check)
3140
3141def configure_easing_function():
3142    logging.info('click on easing function button')
3143    post_to_trigger_action_edit_dialog('CMD_CONFIGURE_EASING_FUNCTION', 0)
3144    wait_dialog_open(EASING_FUNCTION_SELECT_DIALOG, studio_dialogs[TRIGGER_ACTION_EDIT_DIALOG])
3145
3146def cancel_trigger_action_edit_dialog():
3147    logging.info("cancel trigger action edit dialog")
3148    post_to_trigger_action_edit_dialog('CMD_CANCEL_TRIGGER_ACTION_EDIT', 0)
3149    wait_dialog_close(TRIGGER_ACTION_EDIT_DIALOG)
3150
3151def save_trigger_action_edit_dialog(wait = CLOSE_WAIT):
3152    logging.info("save trigger action edit dialog")
3153    post_to_trigger_action_edit_dialog('CMD_SAVE_TRIGGER_ACTION_EDIT', 0)
3154
3155    if wait == CLOSE_WAIT:
3156        wait_dialog_close(TRIGGER_ACTION_EDIT_DIALOG)
3157
3158#================================================================#
3159#      Send Commands to Trigger Action Select Dialog             #
3160#================================================================#
3161action_select_dialog_commands = [
3162    '',
3163    'CMD_SELECT_ACTION',
3164    'CMD_SAVE_ACTION_SELECT',
3165    'CMD_CANCEL_ACTION_SELECT'
3166]
3167
3168def send_to_action_select_dialog(cmd, param):
3169    handle = studio_dialogs[TRIGGER_ACTION_SELECT_DIALOG]
3170    command = action_select_dialog_commands.index(cmd)
3171    return(send_to_studio(handle, command, param))
3172
3173def post_to_action_select_dialog(cmd, param):
3174    handle = studio_dialogs[TRIGGER_ACTION_SELECT_DIALOG]
3175    command = action_select_dialog_commands.index(cmd)
3176    return(post_to_studio(handle, command, param))
3177
3178def action_select_dlg_select_action(type):
3179    logging.info('select action type: %s', type)
3180    send_to_action_select_dialog('CMD_SELECT_ACTION', type)
3181
3182def cancel_action_select_dialog():
3183    logging.info("cancel action select dialog")
3184    post_to_action_select_dialog('CMD_CANCEL_ACTION_SELECT', 0)
3185    wait_dialog_close(TRIGGER_ACTION_SELECT_DIALOG)
3186
3187def save_action_select_dialog():
3188    logging.info("save action select dialog")
3189    post_to_action_select_dialog('CMD_SAVE_ACTION_SELECT', 0)
3190    wait_dialog_close(TRIGGER_ACTION_SELECT_DIALOG)
3191
3192#================================================================#
3193#      Send Commands to Easing Function Select Dialog            #
3194#================================================================#
3195easing_function_select_dialog_commands = [
3196    '',
3197    'CMD_SELECT_EASING_FUNCTION',
3198    'CMD_SAVE_EASING_FUNCTION_SELECT',
3199    'CMD_CANCEL_EASING_FUNCTION_SELECT'
3200]
3201
3202def send_to_easing_function_select_dialog(cmd, param):
3203    handle = studio_dialogs[EASING_FUNCTION_SELECT_DIALOG]
3204    command = easing_function_select_dialog_commands.index(cmd)
3205    return(send_to_studio(handle, command, param))
3206
3207def post_to_easing_function_select_dialog(cmd, param):
3208    handle = studio_dialogs[EASING_FUNCTION_SELECT_DIALOG]
3209    command = easing_function_select_dialog_commands.index(cmd)
3210    return(post_to_studio(handle, command, param))
3211
3212def select_easing_function(name):
3213    logging.info('select easing function: %s', name)
3214    send_to_easing_function_select_dialog('CMD_SELECT_EASING_FUNCTION', name)
3215
3216def cancel_easing_function_select_dialog():
3217    logging.info("cancel easing function select dialog")
3218    post_to_easing_function_select_dialog('CMD_CANCEL_EASING_FUNCTION_SELECT', 0)
3219    wait_dialog_close(EASING_FUNCTION_SELECT_DIALOG)
3220
3221def save_easing_function_select_dialog():
3222    logging.info("save easing function select dialog")
3223    post_to_easing_function_select_dialog('CMD_SAVE_EASING_FUNCTION_SELECT', 0)
3224    wait_dialog_close(EASING_FUNCTION_SELECT_DIALOG)
3225
3226#================================================================#
3227#      Send Commands to Synergy Settings Dialog                  #
3228#================================================================#
3229synergy_settings_dialog_commands = [
3230    '',
3231    'CMD_CHECK_2D_DRAWING_ENGINE',
3232    'CMD_SAVE_SYNERGY_SETTING',
3233    'CMD_CANCEL_SYNERGY_SETTING'
3234]
3235
3236def send_to_synergy_settings_dialog(cmd, param):
3237    handle = studio_dialogs[SYNERGY_SETTINGS_DIALOG]
3238    command = synergy_settings_dialog_commands.index(cmd)
3239    return(send_to_studio(handle, command, param))
3240
3241def post_to_synergy_settings_dialog(cmd, param):
3242    handle = studio_dialogs[SYNERGY_SETTINGS_DIALOG]
3243    command = synergy_settings_dialog_commands.index(cmd)
3244    return(post_to_studio(handle, command, param))
3245
3246def check_2d_drawing_engine(enabled):
3247    logging.info('check 2d drawing engine: %d', enabled)
3248    send_to_synergy_settings_dialog('CMD_CHECK_2D_DRAWING_ENGINE', enabled)
3249
3250def cancel_synergy_settings_dialog():
3251    logging.info("cancel synergy settings dialog")
3252    post_to_synergy_settings_dialog('CMD_CANCEL_SYNERGY_SETTING', 0)
3253    wait_dialog_close(EASING_FUNCTION_SELECT_DIALOG, studio_dialogs[CONFIGURE_PROJECT_DIALOG])
3254
3255def save_synergy_settings_dialog():
3256    logging.info("save synergy settings dialog")
3257    post_to_synergy_settings_dialog('CMD_SAVE_SYNERGY_SETTING', 0)
3258    wait_dialog_close(EASING_FUNCTION_SELECT_DIALOG, studio_dialogs[CONFIGURE_PROJECT_DIALOG])
3259
3260#================================================================#
3261#              Send Commands to Rich Text Edit Dialog            #
3262#================================================================#
3263rich_text_edit_dialog_commands = [
3264    '',
3265    'CMD_SET_STRING',
3266    'CMD_SAVE',
3267    'CMD_CANCEL'
3268]
3269
3270def send_to_rich_text_edit_dialog(cmd, param):
3271    handle = studio_dialogs[RICH_TEXT_EDIT_DIALOG]
3272    command = rich_text_edit_dialog_commands.index(cmd)
3273    return(send_to_studio(handle, command, param))
3274
3275def post_to_rich_text_edit_dialog(cmd, param):
3276    handle = studio_dialogs[RICH_TEXT_EDIT_DIALOG]
3277    command = rich_text_edit_dialog_commands.index(cmd)
3278    return(post_to_studio(handle, command, param))
3279
3280def edit_rich_text_view_string(string):
3281    logging.info("edit rich text view string: %s", string)
3282    send_to_rich_text_edit_dialog('CMD_SET_STRING', string)
3283
3284def cancel_rich_text_edit():
3285    logging.info("cancel rich text edit")
3286    post_to_rich_text_edit_dialog('CMD_CANCEL', 0)
3287    wait_dialog_close(RICH_TEXT_EDIT_DIALOG)
3288
3289def save_rich_text_edit():
3290    logging.info("save rich text edit")
3291    post_to_rich_text_edit_dialog('CMD_SAVE', 0)
3292    wait_dialog_close(RICH_TEXT_EDIT_DIALOG)
3293
3294#================================================================#
3295#          Send Commands to Edit Sprite Frames Dialog            #
3296#================================================================#
3297sprite_frame_edit_dialog_commands = [
3298    '',
3299    'CMD_EDIT_FRAME',
3300    'CMD_EDIT_NUM_FRAMES',
3301    'CMD_SET_ALPHA',
3302    'CMD_SET_XOFFSET',
3303    'CMD_SET_YOFFSET',
3304    'CMD_SET_DELAY',
3305    'CMD_CHECK_APPLY_TO_ALL_FRAMES',
3306    'CMD_IMPORT_FRAMES',
3307    'CMD_SAVE',
3308    'CMD_CANCEL'
3309]
3310
3311def send_to_sprite_frame_edit_dialog(cmd, param):
3312    handle = studio_dialogs[SPRITE_FRAME_EDIT_DIALOG]
3313    command = sprite_frame_edit_dialog_commands.index(cmd)
3314    return(send_to_studio(handle, command, param))
3315
3316def post_to_sprite_frame_edit_dialog(cmd, param):
3317    handle = studio_dialogs[SPRITE_FRAME_EDIT_DIALOG]
3318    command = sprite_frame_edit_dialog_commands.index(cmd)
3319    return(post_to_studio(handle, command, param))
3320
3321def edit_sprite_frame(frame_id, pixelmap_string):
3322    logging.info("edit sprite frame: (%d, %s)", frame_id, pixelmap_string)
3323    string = str(frame_id) + ',' + pixelmap_string
3324    send_to_sprite_frame_edit_dialog('CMD_EDIT_FRAME', string)
3325
3326def edit_sprite_total_frames(frame_count):
3327    logging.info("edit sprite total frames: %d", frame_count)
3328    send_to_sprite_frame_edit_dialog('CMD_EDIT_NUM_FRAMES', frame_count)
3329
3330def edit_sprite_frame_alpha(value):
3331    logging.info("edit sprite frame alpha: %d", value)
3332    send_to_sprite_frame_edit_dialog('CMD_SET_ALPHA', value)
3333
3334def edit_sprite_frame_xoffset(xoffset):
3335    logging.info("edit sprite frame x offset: %d", xoffset)
3336    send_to_sprite_frame_edit_dialog('CMD_SET_XOFFSET', xoffset)
3337
3338def edit_sprite_frame_yoffset(yoffset):
3339    logging.info("edit sprite frame y offset: %d", yoffset)
3340    send_to_sprite_frame_edit_dialog('CMD_SET_YOFFSET', yoffset)
3341
3342def edit_sprite_frame_delay(delay):
3343    logging.info("edit sprite frame delay: %d", delay)
3344    send_to_sprite_frame_edit_dialog('CMD_SET_DELAY', delay)
3345
3346def check_apply_to_all_frames(check):
3347    logging.info("check apply to all frames: %d", check)
3348    send_to_sprite_frame_edit_dialog('CMD_CHECK_APPLY_TO_ALL_FRAMES', check)
3349
3350def import_sprite_frames():
3351    logging.info("import sprite frames")
3352    post_to_sprite_frame_edit_dialog('CMD_IMPORT_FRAMES', 0)
3353    wait_dialog_open(SPRITE_FRAME_IMPORT_DIALOG)
3354
3355def cancel_sprite_frame_edit():
3356    logging.info("cancel sprite frame edit")
3357    post_to_sprite_frame_edit_dialog('CMD_CANCEL', 0)
3358    wait_dialog_close(SPRITE_FRAME_EDIT_DIALOG)
3359
3360def save_sprite_frame_edit():
3361    logging.info("save sprite frame edit")
3362    post_to_sprite_frame_edit_dialog('CMD_SAVE', 0)
3363    wait_dialog_close(SPRITE_FRAME_EDIT_DIALOG)
3364
3365#================================================================#
3366#          Send Commands to Import Sprite Frames Dialog          #
3367#================================================================#
3368sprite_frame_import_dialog_commands = [
3369    '',
3370    'CMD_SAVE',
3371    'CMD_CANCEL'
3372]
3373
3374def send_to_sprite_frame_import_dialog(cmd, param):
3375    handle = studio_dialogs[SPRITE_FRAME_IMPORT_DIALOG]
3376    command = sprite_frame_import_dialog_commands.index(cmd)
3377    return(send_to_studio(handle, command, param))
3378
3379def post_to_sprite_frame_import_dialog(cmd, param):
3380    handle = studio_dialogs[SPRITE_FRAME_IMPORT_DIALOG]
3381    command = sprite_frame_import_dialog_commands.index(cmd)
3382    return(post_to_studio(handle, command, param))
3383
3384def cancel_sprite_frame_import_edit():
3385    logging.info("cancel sprite frame import")
3386    post_to_sprite_frame_import_dialog('CMD_CANCEL', 0)
3387    wait_dialog_close(SPRITE_FRAME_IMPORT_DIALOG)
3388
3389def save_sprite_frame_import_edit():
3390    logging.info("save sprite frame import")
3391    post_to_sprite_frame_import_dialog('CMD_SAVE', 0)
3392    wait_dialog_close(SPRITE_FRAME_IMPORT_DIALOG)