예제 #1
0
    def __init__(self):
        ##################################
        # init GUI
        self.builder = Gtk.Builder()
        self.builder.set_translation_domain(GETTEXT_PACKAGE)
        self.builder.add_from_file(os.path.join(WORK_DIR, 'GameConqueror.xml'))

        self.main_window = self.builder.get_object('MainWindow')
        self.main_window.set_title('GameConqueror %s' % (VERSION, ))
        self.about_dialog = self.builder.get_object('AboutDialog')
        # set version
        self.about_dialog.set_version(VERSION)

        self.process_list_dialog = self.builder.get_object('ProcessListDialog')
        self.addcheat_dialog = self.builder.get_object('AddCheatDialog')

        # init memory editor
        self.memoryeditor_window = self.builder.get_object(
            'MemoryEditor_Window')
        self.memoryeditor_hexview = HexView()
        self.memoryeditor_window.get_child().pack_start(
            self.memoryeditor_hexview, True, True, 0)
        self.memoryeditor_hexview.show_all()
        self.memoryeditor_address_entry = self.builder.get_object(
            'MemoryEditor_Address_Entry')
        self.memoryeditor_hexview.connect(
            'char-changed', self.memoryeditor_hexview_char_changed_cb)

        self.found_count_label = self.builder.get_object('FoundCount_Label')
        self.process_label = self.builder.get_object('Process_Label')
        self.value_input = self.builder.get_object('Value_Input')

        self.scanoption_frame = self.builder.get_object('ScanOption_Frame')
        self.scanprogress_progressbar = self.builder.get_object(
            'ScanProgress_ProgressBar')
        self.input_box = self.builder.get_object('Value_Input')

        self.scan_button = self.builder.get_object('Scan_Button')
        self.reset_button = self.builder.get_object('Reset_Button')

        ###
        # Set scan data type
        self.scan_data_type_combobox = self.builder.get_object(
            'ScanDataType_ComboBoxText')
        for entry in SCAN_VALUE_TYPES:
            self.scan_data_type_combobox.append_text(entry)
        # apply setting
        misc.combobox_set_active_item(self.scan_data_type_combobox,
                                      SETTINGS['scan_data_type'])

        ###
        # set search scope
        self.search_scope_scale = self.builder.get_object('SearchScope_Scale')
        # apply setting
        self.search_scope_scale.set_value(SETTINGS['search_scope'])

        # init scanresult treeview
        # we may need a cell data func here
        # create model
        self.scanresult_tv = self.builder.get_object('ScanResult_TreeView')
        # liststore contents:                     addr,                value, type, valid, offset,              region type, match_id
        self.scanresult_liststore = Gtk.ListStore(GObject.TYPE_UINT64, str,
                                                  str, bool,
                                                  GObject.TYPE_UINT64, str,
                                                  int)
        self.scanresult_tv.set_model(self.scanresult_liststore)
        # init columns
        misc.treeview_append_column(self.scanresult_tv,
                                    _('Address'),
                                    0,
                                    hex_col=0,
                                    attributes=(('text', 0), ),
                                    properties=(('family', 'monospace'), ))
        misc.treeview_append_column(self.scanresult_tv,
                                    _('Value'),
                                    1,
                                    attributes=(('text', 1), ),
                                    properties=(('family', 'monospace'), ))
        misc.treeview_append_column(self.scanresult_tv,
                                    _('Offset'),
                                    4,
                                    hex_col=4,
                                    attributes=(('text', 4), ),
                                    properties=(('family', 'monospace'), ))
        misc.treeview_append_column(self.scanresult_tv,
                                    _('Region Type'),
                                    5,
                                    attributes=(('text', 5), ),
                                    properties=(('family', 'monospace'), ))

        # init CheatList TreeView
        self.cheatlist_tv = self.builder.get_object('CheatList_TreeView')
        # cheatlist contents:                    lockflag, locked, description, addr,                type, value, valid
        self.cheatlist_liststore = Gtk.ListStore(str, bool, str,
                                                 GObject.TYPE_UINT64, str, str,
                                                 bool)
        self.cheatlist_tv.set_model(self.cheatlist_liststore)
        self.cheatlist_editing = False
        # Lock Flag
        misc.treeview_append_column(
            self.cheatlist_tv,
            '',
            0,
            renderer_class=Gtk.CellRendererCombo,
            attributes=(('text', 0), ),
            properties=(('editable', True), ('has-entry', False),
                        ('model', LOCK_FLAG_TYPES), ('text-column', 0)),
            signals=(
                ('edited', self.cheatlist_toggle_lock_flag_cb),
                ('editing-started', self.cheatlist_edit_start),
                ('editing-canceled', self.cheatlist_edit_cancel),
            ))
        # Lock
        misc.treeview_append_column(
            self.cheatlist_tv,
            _('Lock'),
            1,
            renderer_class=Gtk.CellRendererToggle,
            attributes=(('active', 1), ),
            properties=(('activatable', True), ('radio', False),
                        ('inconsistent', False)),
            signals=(('toggled', self.cheatlist_toggle_lock_cb), ))
        # Description
        misc.treeview_append_column(
            self.cheatlist_tv,
            _('Description'),
            2,
            attributes=(('text', 2), ),
            properties=(('editable', True), ),
            signals=(
                ('edited', self.cheatlist_edit_description_cb),
                ('editing-started', self.cheatlist_edit_start),
                ('editing-canceled', self.cheatlist_edit_cancel),
            ))
        # Address
        misc.treeview_append_column(self.cheatlist_tv,
                                    _('Address'),
                                    3,
                                    hex_col=3,
                                    attributes=(('text', 3), ),
                                    properties=(('family', 'monospace'), ))
        # Type
        misc.treeview_append_column(
            self.cheatlist_tv,
            _('Type'),
            4,
            renderer_class=Gtk.CellRendererCombo,
            attributes=(('text', 4), ),
            properties=(('editable', True), ('has-entry', False),
                        ('model',
                         misc.build_simple_str_liststore(MEMORY_TYPES)),
                        ('text-column', 0)),
            signals=(
                ('edited', self.cheatlist_edit_type_cb),
                ('editing-started', self.cheatlist_edit_start),
                ('editing-canceled', self.cheatlist_edit_cancel),
            ))
        # Value
        misc.treeview_append_column(
            self.cheatlist_tv,
            _('Value'),
            5,
            attributes=(('text', 5), ),
            properties=(('editable', True), ('family', 'monospace')),
            signals=(
                ('edited', self.cheatlist_edit_value_cb),
                ('editing-started', self.cheatlist_edit_start),
                ('editing-canceled', self.cheatlist_edit_cancel),
            ))

        # init ProcessList
        self.processfilter_input = self.builder.get_object(
            'ProcessFilter_Input')
        self.userfilter_input = self.builder.get_object('UserFilter_Input')
        # init ProcessList_TreeView
        self.processlist_tv = self.builder.get_object('ProcessList_TreeView')
        self.processlist_liststore = Gtk.ListStore(int, str, str)
        self.processlist_filter = self.processlist_liststore.filter_new(
            root=None)
        self.processlist_filter.set_visible_func(self.processlist_filter_func,
                                                 data=None)
        self.processlist_tv.set_model(
            Gtk.TreeModelSort(model=self.processlist_filter))
        self.processlist_tv.set_search_column(1)
        # first col
        misc.treeview_append_column(self.processlist_tv,
                                    'PID',
                                    0,
                                    attributes=(('text', 0), ))
        # second col
        misc.treeview_append_column(self.processlist_tv,
                                    _('User'),
                                    1,
                                    attributes=(('text', 1), ))

        # third col
        misc.treeview_append_column(self.processlist_tv,
                                    _('Process'),
                                    2,
                                    attributes=(('text', 2), ))

        # get list of things to be disabled during scan
        self.disablelist = []
        self.disablelist.append(self.cheatlist_tv)
        self.disablelist.append(self.scanresult_tv)
        self.disablelist.append(self.builder.get_object('processGrid'))
        self.disablelist.append(self.builder.get_object('searchGrid'))
        self.disablelist.append(self.builder.get_object('buttonGrid'))
        self.disablelist.append(self.memoryeditor_window)

        # init AddCheatDialog
        self.addcheat_address_input = self.builder.get_object('Address_Input')
        self.addcheat_address_input.override_font(
            gi.repository.Pango.FontDescription("Monospace"))

        self.addcheat_description_input = self.builder.get_object(
            'Description_Input')
        self.addcheat_length_spinbutton = self.builder.get_object(
            'Length_SpinButton')

        self.addcheat_type_combobox = self.builder.get_object(
            'Type_ComboBoxText')
        for entry in MEMORY_TYPES:
            self.addcheat_type_combobox.append_text(entry)
        misc.combobox_set_active_item(self.addcheat_type_combobox,
                                      SETTINGS['lock_data_type'])
        self.Type_ComboBoxText_changed_cb(self.addcheat_type_combobox)

        # init popup menu for scanresult
        self.scanresult_popup = Gtk.Menu()
        misc.menu_append_item(self.scanresult_popup, _('Add to cheat list'),
                              self.scanresult_popup_cb, 'add_to_cheat_list')
        misc.menu_append_item(self.scanresult_popup, _('Browse this address'),
                              self.scanresult_popup_cb, 'browse_this_address')
        misc.menu_append_item(self.scanresult_popup,
                              _('Scan for this address'),
                              self.scanresult_popup_cb,
                              'scan_for_this_address')
        misc.menu_append_item(self.scanresult_popup, _('Remove this match'),
                              self.scanresult_delete_selected_matches)
        self.scanresult_popup.show_all()

        # init popup menu for cheatlist
        self.cheatlist_popup = Gtk.Menu()
        misc.menu_append_item(self.cheatlist_popup, _('Browse this address'),
                              self.cheatlist_popup_cb, 'browse_this_address')
        misc.menu_append_item(self.cheatlist_popup, _('Copy address'),
                              self.cheatlist_popup_cb, 'copy_address')
        misc.menu_append_item(self.cheatlist_popup, _('Remove this entry'),
                              self.cheatlist_popup_cb, 'remove_entry')
        self.cheatlist_popup.show_all()

        self.builder.connect_signals(self)
        self.main_window.connect('destroy', self.exit)

        ###########################
        # init others (backend, flag...)
        self.pid = 0  # target pid
        self.maps = []
        self.last_hexedit_address = (0, 0)  # used for hexview
        self.is_scanning = False
        self.exit_flag = False  # currently for data_worker only, other 'threads' may also use this flag

        self.backend = GameConquerorBackend(
            os.path.join(LIBDIR, 'libscanmem.so.1'))
        self.check_backend_version()
        self.is_first_scan = True
        GLib.timeout_add(DATA_WORKER_INTERVAL, self.data_worker)
        self.command_lock = threading.RLock()
예제 #2
0
    def __init__(self):
        Gtk.Settings.get_default().set_long_property('gtk-tooltip-timeout', 0, '')
        ##################################
        # init GUI
        self.builder = Gtk.Builder()
        self.builder.add_from_file(os.path.join(WORK_DIR, 'GameConqueror.xml'))

        self.main_window = self.builder.get_object('MainWindow')
        self.main_window.set_title('GameConqueror %s' % (VERSION,))
        self.about_dialog = self.builder.get_object('AboutDialog')
        # set version
        self.about_dialog.set_version(VERSION)

        self.process_list_dialog = self.builder.get_object('ProcessListDialog')
        self.addcheat_dialog = self.builder.get_object('AddCheatDialog')

        # init memory editor
        self.memoryeditor_window = self.builder.get_object('MemoryEditor_Window')
        self.memoryeditor_hexview = HexView()
        self.memoryeditor_window.get_child().pack_start(self.memoryeditor_hexview, True, True, 0)
        self.memoryeditor_hexview.show_all()
        self.memoryeditor_address_entry = self.builder.get_object('MemoryEditor_Address_Entry')
        self.memoryeditor_hexview.connect('char-changed', self.memoryeditor_hexview_char_changed_cb)

        self.found_count_label = self.builder.get_object('FoundCount_Label')
        self.process_label = self.builder.get_object('Process_Label')
        self.value_input = self.builder.get_object('Value_Input')
        
        self.scanoption_frame = self.builder.get_object('ScanOption_Frame')
        self.scanprogress_progressbar = self.builder.get_object('ScanProgress_ProgressBar')

        self.scan_button = self.builder.get_object('Scan_Button')
        self.reset_button = self.builder.get_object('Reset_Button')
        self.is_first_scan = True

        ###
        # Set scan data type
        self.scan_data_type_combobox = self.builder.get_object('ScanDataType_ComboBox')
        misc.build_combobox(self.scan_data_type_combobox, SCAN_VALUE_TYPES)
        # apply setting
        misc.combobox_set_active_item(self.scan_data_type_combobox, SETTINGS['scan_data_type'])

        ###
        # set search scope
        self.search_scope_scale = self.builder.get_object('SearchScope_Scale')
        self.search_scope_scale_adjustment = Gtk.Adjustment(lower=0, upper=2, step_incr=1, page_incr=1, page_size=0)
        self.search_scope_scale.set_adjustment(self.search_scope_scale_adjustment)
        # apply setting
        self.search_scope_scale.set_value(SETTINGS['search_scope'])



        # init scanresult treeview
        # we may need a cell data func here
        # create model
        self.scanresult_tv = self.builder.get_object('ScanResult_TreeView')
        self.scanresult_liststore = Gtk.ListStore(str, str, str, bool) #addr, value, type, valid
        self.scanresult_tv.set_model(self.scanresult_liststore)
        # init columns
        misc.treeview_append_column(self.scanresult_tv, 'Address', attributes=(('text',0),), properties = (('family', 'monospace'),))
        misc.treeview_append_column(self.scanresult_tv, 'Value', attributes=(('text',1),), properties = (('family', 'monospace'),))

        # init CheatList TreeView
        self.cheatlist_tv = self.builder.get_object('CheatList_TreeView')
        self.cheatlist_liststore = Gtk.ListStore(str, bool, str, str, str, str, bool) #lockflag, locked, description, addr, type, value, valid
        self.cheatlist_tv.set_model(self.cheatlist_liststore)
        self.cheatlist_tv.set_reorderable(True)
        self.cheatlist_updates = []
        self.cheatlist_editing = False
        self.cheatlist_tv.connect('key-press-event', self.cheatlist_keypressed)
        # Lock Flag
        misc.treeview_append_column(self.cheatlist_tv, '' 
                                        ,renderer_class = Gtk.CellRendererCombo
                                        ,attributes = (('text',0),)
                                        ,properties = (('editable', True)
                                                      ,('has-entry', False)
                                                      ,('model', LOCK_FLAG_TYPES)
                                                      ,('text-column', 0)
                                        )
                                        ,signals = (('edited', self.cheatlist_toggle_lock_flag_cb),
                                                    ('editing-started', self.cheatlist_edit_start),
                                                    ('editing-canceled', self.cheatlist_edit_cancel),)
                                   )
        # Lock
        misc.treeview_append_column(self.cheatlist_tv, 'Lock'
                                        ,renderer_class = Gtk.CellRendererToggle
                                        ,attributes = (('active',1),)
                                        ,properties = (('activatable', True)
                                                      ,('radio', False)
                                                      ,('inconsistent', False)) 
                                        ,signals = (('toggled', self.cheatlist_toggle_lock_cb),)
                                   )
        # Description
        misc.treeview_append_column(self.cheatlist_tv, 'Description'
                                        ,attributes = (('text',2),)
                                        ,properties = (('editable', True),)
                                        ,signals = (('edited', self.cheatlist_edit_description_cb),
                                                    ('editing-started', self.cheatlist_edit_start),
                                                    ('editing-canceled', self.cheatlist_edit_cancel),)
                                   )
        # Address
        misc.treeview_append_column(self.cheatlist_tv, 'Address'
                                        ,attributes = (('text',3),)
                                        ,properties = (('family', 'monospace'),)
                                   )
        # Type
        misc.treeview_append_column(self.cheatlist_tv, 'Type'
                                        ,renderer_class = Gtk.CellRendererCombo
                                        ,attributes = (('text',4),)
                                        ,properties = (('editable', True)
                                                      ,('has-entry', False)
                                                      ,('model', LOCK_VALUE_TYPES)
                                                      ,('text-column', 0))
                                        ,signals = (('edited', self.cheatlist_edit_type_cb),
                                                    ('editing-started', self.cheatlist_edit_start),
                                                    ('editing-canceled', self.cheatlist_edit_cancel),)
                                   )
        # Value 
        misc.treeview_append_column(self.cheatlist_tv, 'Value'
                                        ,attributes = (('text',5),)
                                        ,properties = (('editable', True)
                                                      ,('family', 'monospace'))
                                        ,signals = (('edited', self.cheatlist_edit_value_cb),
                                                    ('editing-started', self.cheatlist_edit_start),
                                                    ('editing-canceled', self.cheatlist_edit_cancel),)
                                   )

        # init ProcessList
        self.processfilter_input = self.builder.get_object('ProcessFilter_Input')
        self.userfilter_input = self.builder.get_object('UserFilter_Input')
        # init ProcessList_TreeView
        self.processlist_tv = self.builder.get_object('ProcessList_TreeView')
        self.processlist_tv.get_selection().set_mode(Gtk.SelectionMode.SINGLE)
        self.processlist_liststore = Gtk.ListStore(str, str, str)
        self.processlist_filter = self.processlist_liststore.filter_new(root=None)
        self.processlist_filter.set_visible_func(self.processlist_filter_func, data=None)
        self.processlist_tv.set_model(self.processlist_filter)
        self.processlist_tv.set_enable_search(True)
        self.processlist_tv.set_search_column(1)
        # first col
        misc.treeview_append_column(self.processlist_tv, 'PID'
                                        ,attributes = (('text',0),)
                                   )
        # second col
        misc.treeview_append_column(self.processlist_tv, 'User'
                                        ,attributes = (('text',1),)
                                   )

        # third col
        misc.treeview_append_column(self.processlist_tv, 'Process'
                                        ,attributes = (('text',2),)
                                   )
        # init AddCheatDialog
        self.addcheat_address_input = self.builder.get_object('Address_Input')
        self.addcheat_description_input = self.builder.get_object('Description_Input')
        self.addcheat_type_combobox = self.builder.get_object('Type_ComboBox')
        misc.build_combobox(self.addcheat_type_combobox, LOCK_VALUE_TYPES)
        misc.combobox_set_active_item(self.addcheat_type_combobox, SETTINGS['lock_data_type'])
        
        
        
        # init popup menu for scanresult
        self.scanresult_popup = Gtk.Menu()
        misc.menu_append_item(self.scanresult_popup, 'Add to cheat list', self.scanresult_popup_cb, 'add_to_cheat_list')
        misc.menu_append_item(self.scanresult_popup, 'Browse this address', self.scanresult_popup_cb, 'browse_this_address')
        misc.menu_append_item(self.scanresult_popup, 'Scan for this address', self.scanresult_popup_cb, 'scan_for_this_address')
        self.scanresult_popup.show_all()

        # init popup menu for cheatlist
        self.cheatlist_popup = Gtk.Menu()
        misc.menu_append_item(self.cheatlist_popup, 'Browse this address', self.cheatlist_popup_cb, 'browse_this_address')
        misc.menu_append_item(self.cheatlist_popup, 'Copy address', self.cheatlist_popup_cb, 'copy_address')
        misc.menu_append_item(self.cheatlist_popup, 'Remove this entry', self.cheatlist_popup_cb, 'remove_entry')
        self.cheatlist_popup.show_all()

        self.builder.connect_signals(self)
        self.main_window.connect('destroy', self.exit)

        ###########################
        # init others (backend, flag...)
        self.pid = 0 # target pid
        self.maps = []
        self.last_hexedit_address = (0,0) # used for hexview
        self.is_scanning = False
        self.exit_flag = False # currently for data_worker only, other 'threads' may also use this flag
        self.is_data_worker_working = False

        self.backend = GameConquerorBackend()
        self.check_backend_version()
        self.search_count = 0
        GObject.timeout_add(DATA_WORKER_INTERVAL, self.data_worker)
        self.command_lock = threading.RLock()
예제 #3
0
    def __init__(self):
        ##################################
        # init GUI
        self.builder = Gtk.Builder()
        self.builder.set_translation_domain(GETTEXT_PACKAGE)
        self.builder.add_from_file(os.path.join(WORK_DIR, 'GameConqueror.xml'))

        self.main_window = self.builder.get_object('MainWindow')
        self.main_window.set_title('GameConqueror %s' % (VERSION, ))
        self.about_dialog = self.builder.get_object('AboutDialog')
        # set version
        self.about_dialog.set_version(VERSION)

        self.process_list_dialog = self.builder.get_object('ProcessListDialog')
        self.addcheat_dialog = self.builder.get_object('AddCheatDialog')

        # init memory editor
        self.memoryeditor_window = self.builder.get_object(
            'MemoryEditor_Window')
        self.memoryeditor_hexview = HexView()
        self.memoryeditor_window.get_child().pack_start(
            self.memoryeditor_hexview, True, True, 0)
        self.memoryeditor_hexview.show_all()
        self.memoryeditor_address_entry = self.builder.get_object(
            'MemoryEditor_Address_Entry')
        self.memoryeditor_hexview.connect(
            'char-changed', self.memoryeditor_hexview_char_changed_cb)

        self.found_count_label = self.builder.get_object('FoundCount_Label')
        self.process_label = self.builder.get_object('Process_Label')
        self.value_input = self.builder.get_object('Value_Input')

        self.scanoption_frame = self.builder.get_object('ScanOption_Frame')
        self.scanprogress_progressbar = self.builder.get_object(
            'ScanProgress_ProgressBar')

        self.scan_button = self.builder.get_object('Scan_Button')
        self.reset_button = self.builder.get_object('Reset_Button')
        self.is_first_scan = True

        ###
        # Set scan data type
        self.scan_data_type_combobox = self.builder.get_object(
            'ScanDataType_ComboBox')
        misc.build_combobox(self.scan_data_type_combobox, SCAN_VALUE_TYPES)
        # apply setting
        misc.combobox_set_active_item(self.scan_data_type_combobox,
                                      SETTINGS['scan_data_type'])

        ###
        # set search scope
        self.search_scope_scale = self.builder.get_object('SearchScope_Scale')
        self.search_scope_scale_adjustment = Gtk.Adjustment(lower=0,
                                                            upper=2,
                                                            step_incr=1,
                                                            page_incr=1,
                                                            page_size=0)
        self.search_scope_scale.set_adjustment(
            self.search_scope_scale_adjustment)
        # apply setting
        self.search_scope_scale.set_value(SETTINGS['search_scope'])

        # init scanresult treeview
        # we may need a cell data func here
        # create model
        self.scanresult_tv = self.builder.get_object('ScanResult_TreeView')
        # liststore contents: addr, value, type, valid, offset, region type
        self.scanresult_liststore = Gtk.ListStore(str, str, str, bool, str,
                                                  str)
        self.scanresult_tv.set_model(self.scanresult_liststore)
        self.scanresult_tv.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        self.scanresult_last_clicked = 0
        # init columns
        misc.treeview_append_column(self.scanresult_tv,
                                    _('Address'),
                                    attributes=(('text', 0), ),
                                    properties=(('family', 'monospace'), ))
        misc.treeview_append_column(self.scanresult_tv,
                                    _('Value'),
                                    attributes=(('text', 1), ),
                                    properties=(('family', 'monospace'), ))
        misc.treeview_append_column(self.scanresult_tv,
                                    _('Offset'),
                                    attributes=(('text', 4), ),
                                    properties=(('family', 'monospace'), ))
        misc.treeview_append_column(self.scanresult_tv,
                                    _('Region Type'),
                                    attributes=(('text', 5), ),
                                    properties=(('family', 'monospace'), ))

        # init CheatList TreeView
        self.cheatlist_tv = self.builder.get_object('CheatList_TreeView')
        self.cheatlist_liststore = Gtk.ListStore(
            str, bool, str, str, str, str,
            bool)  #lockflag, locked, description, addr, type, value, valid
        self.cheatlist_tv.set_model(self.cheatlist_liststore)
        self.cheatlist_tv.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        self.cheatlist_last_clicked = 0
        self.cheatlist_tv.set_reorderable(True)
        self.cheatlist_editing = False
        self.cheatlist_tv.connect('key-press-event', self.cheatlist_keypressed)
        # Lock Flag
        misc.treeview_append_column(
            self.cheatlist_tv,
            '',
            renderer_class=Gtk.CellRendererCombo,
            attributes=(('text', 0), ),
            properties=(('editable', True), ('has-entry', False),
                        ('model', LOCK_FLAG_TYPES), ('text-column', 0)),
            signals=(
                ('edited', self.cheatlist_toggle_lock_flag_cb),
                ('editing-started', self.cheatlist_edit_start),
                ('editing-canceled', self.cheatlist_edit_cancel),
            ))
        # Lock
        misc.treeview_append_column(
            self.cheatlist_tv,
            _('Lock'),
            renderer_class=Gtk.CellRendererToggle,
            attributes=(('active', 1), ),
            properties=(('activatable', True), ('radio', False),
                        ('inconsistent', False)),
            signals=(('toggled', self.cheatlist_toggle_lock_cb), ))
        # Description
        misc.treeview_append_column(
            self.cheatlist_tv,
            _('Description'),
            attributes=(('text', 2), ),
            properties=(('editable', True), ),
            signals=(
                ('edited', self.cheatlist_edit_description_cb),
                ('editing-started', self.cheatlist_edit_start),
                ('editing-canceled', self.cheatlist_edit_cancel),
            ))
        # Address
        misc.treeview_append_column(self.cheatlist_tv,
                                    _('Address'),
                                    attributes=(('text', 3), ),
                                    properties=(('family', 'monospace'), ))
        # Type
        misc.treeview_append_column(
            self.cheatlist_tv,
            _('Type'),
            renderer_class=Gtk.CellRendererCombo,
            attributes=(('text', 4), ),
            properties=(('editable', True), ('has-entry', False),
                        ('model', LOCK_VALUE_TYPES), ('text-column', 0)),
            signals=(
                ('edited', self.cheatlist_edit_type_cb),
                ('editing-started', self.cheatlist_edit_start),
                ('editing-canceled', self.cheatlist_edit_cancel),
            ))
        # Value
        misc.treeview_append_column(
            self.cheatlist_tv,
            _('Value'),
            attributes=(('text', 5), ),
            properties=(('editable', True), ('family', 'monospace')),
            signals=(
                ('edited', self.cheatlist_edit_value_cb),
                ('editing-started', self.cheatlist_edit_start),
                ('editing-canceled', self.cheatlist_edit_cancel),
            ))

        # init ProcessList
        self.processfilter_input = self.builder.get_object(
            'ProcessFilter_Input')
        self.userfilter_input = self.builder.get_object('UserFilter_Input')
        # init ProcessList_TreeView
        self.processlist_tv = self.builder.get_object('ProcessList_TreeView')
        self.processlist_tv.get_selection().set_mode(Gtk.SelectionMode.SINGLE)
        self.processlist_liststore = Gtk.ListStore(str, str, str)
        self.processlist_filter = self.processlist_liststore.filter_new(
            root=None)
        self.processlist_filter.set_visible_func(self.processlist_filter_func,
                                                 data=None)
        self.processlist_tv.set_model(self.processlist_filter)
        self.processlist_tv.set_enable_search(True)
        self.processlist_tv.set_search_column(1)
        # first col
        misc.treeview_append_column(self.processlist_tv,
                                    'PID',
                                    attributes=(('text', 0), ))
        # second col
        misc.treeview_append_column(self.processlist_tv,
                                    _('User'),
                                    attributes=(('text', 1), ))

        # third col
        misc.treeview_append_column(self.processlist_tv,
                                    _('Process'),
                                    attributes=(('text', 2), ))
        # init AddCheatDialog
        self.addcheat_address_input = self.builder.get_object('Address_Input')
        self.addcheat_description_input = self.builder.get_object(
            'Description_Input')
        self.addcheat_type_combobox = self.builder.get_object('Type_ComboBox')
        misc.build_combobox(self.addcheat_type_combobox, LOCK_VALUE_TYPES)
        misc.combobox_set_active_item(self.addcheat_type_combobox,
                                      SETTINGS['lock_data_type'])

        # init popup menu for scanresult
        self.scanresult_popup = Gtk.Menu()
        misc.menu_append_item(self.scanresult_popup, _('Add to cheat list'),
                              self.scanresult_popup_cb, 'add_to_cheat_list')
        misc.menu_append_item(self.scanresult_popup, _('Browse this address'),
                              self.scanresult_popup_cb, 'browse_this_address')
        misc.menu_append_item(self.scanresult_popup,
                              _('Scan for this address'),
                              self.scanresult_popup_cb,
                              'scan_for_this_address')
        self.scanresult_popup.connect('button-press-event',
                                      self.check_for_leftclick)
        self.scanresult_popup.show_all()

        # init popup menu for cheatlist
        self.cheatlist_popup = Gtk.Menu()
        misc.menu_append_item(self.cheatlist_popup, _('Browse this address'),
                              self.cheatlist_popup_cb, 'browse_this_address')
        misc.menu_append_item(self.cheatlist_popup, _('Copy address'),
                              self.cheatlist_popup_cb, 'copy_address')
        misc.menu_append_item(self.cheatlist_popup, _('Remove this entry'),
                              self.cheatlist_popup_cb, 'remove_entry')
        self.cheatlist_popup.connect('button-press-event',
                                     self.check_for_leftclick)
        self.cheatlist_popup.show_all()

        self.builder.connect_signals(self)
        self.main_window.connect('destroy', self.exit)

        ###########################
        # init others (backend, flag...)
        self.pid = 0  # target pid
        self.maps = []
        self.last_hexedit_address = (0, 0)  # used for hexview
        self.is_scanning = False
        self.exit_flag = False  # currently for data_worker only, other 'threads' may also use this flag
        self.is_data_worker_working = False

        self.backend = GameConquerorBackend()
        self.check_backend_version()
        self.search_count = 0
        GObject.timeout_add(DATA_WORKER_INTERVAL, self.data_worker)
        self.command_lock = threading.RLock()