def __init__(self, editor, schema):
        mforms.Box.__init__(self, False)
        self.set_managed()
        self.set_release_on_add()

        self.schema = schema
        self.editor = editor

        self.set_padding(8)
        self.set_spacing(8)

        self.tree = mforms.newTreeNodeView(mforms.TreeFlatList|mforms.TreeAltRowColors)
        self.tree.set_selection_mode(mforms.TreeSelectMultiple)
        for field, type, caption, width in self.columns:
            self.tree.add_column(type, caption, width, False)
        self.tree.end_columns()
        self.tree.set_allow_sorting(True)
        self.add(self.tree, True, True)

        self.menu = mforms.newContextMenu()
        self.menu.add_will_show_callback(self.menu_will_show)
        self.tree.set_context_menu(self.menu)

        self.icon_path = mforms.App.get().get_resource_path(self.klass+".16x16.png")

        self.bbox = mforms.newBox(True)
        self.bbox.set_spacing(8)
        self.add(self.bbox, False, True)

        self.refresh_btn = mforms.newButton()
        self.refresh_btn.set_text("Refresh")
        self.refresh_btn.add_clicked_callback(self.refresh)
        self.bbox.add_end(self.refresh_btn, False, True)

        for caption, callback_name in self.actions:
            if not caption:
                self.bbox.add(mforms.newLabel(" "), False, True)
                continue
            btn = mforms.newButton()
            btn.set_text(caption)
            btn.add_clicked_callback(getattr(self, callback_name))
            self.bbox.add(btn, False, True)
    def create_ui(self):
        self.content.set_spacing(4)
        self.content.add(
            mforms.newLabel(
                "Review and edit migrated objects. You can manually edit the generated SQL before applying them to the target database."
            ), False, True)

        hbox = mforms.newBox(True)
        self.tree_head_label = mforms.newLabel("Migrated Objects")
        hbox.add(self.tree_head_label, False, False)
        self._filter = mforms.newSelector()
        self._filter.add_items(
            ["Migration Problems", "All Objects", "Column Mappings"])
        self._filter.add_changed_callback(self._filter_changed)
        hbox.add_end(self._filter, False, True)
        hbox.add_end(mforms.newLabel("View:"), False, False)
        self.content.add(hbox, False, True)

        self._no_errors_text = "No migration problems found. %d warning(s).\nUse the View pulldown menu to review all objects."
        self._no_errors = mforms.newLabel(
            ''
        )  # Label text will be set later when the warning count is calculated
        self._no_errors.set_style(mforms.BigStyle)
        self._no_errors.set_text_align(mforms.MiddleLeft)
        self.content.add(self._no_errors, True, True)

        self._tree = mforms.newTreeNodeView(mforms.TreeDefault)
        self._tree.add_column(mforms.IconStringColumnType, "Source Object",
                              200, False)
        self._tree.add_column(mforms.IconStringColumnType, "Target Object",
                              200, True)
        self._tree.add_column(mforms.IconStringColumnType, "Migration Message",
                              300, False)
        self._tree.end_columns()
        self._tree.add_changed_callback(self._selection_changed)
        self.content.add(self._tree, True, True)
        self._tree.set_cell_edited_callback(self._cell_edited)

        self._all_menu = mforms.newContextMenu()
        self._all_menu.add_will_show_callback(self.all_menu_will_show)
        self._all_menu.add_check_item_with_title("Skip Object",
                                                 self.skip_object,
                                                 "skip_object")

        self._tree.set_context_menu(self._all_menu)

        self._columns = mforms.newTreeNodeView(mforms.TreeShowColumnLines
                                               | mforms.TreeShowRowLines
                                               | mforms.TreeFlatList)
        self.COL_SOURCE_SCHEMA = self._columns.add_column(
            mforms.StringColumnType, "Source Schema", 100, False)
        self.COL_SOURCE_TABLE = self._columns.add_column(
            mforms.IconStringColumnType, "Source Table", 100, False)
        self.COL_SOURCE_COLUMN = self._columns.add_column(
            mforms.IconStringColumnType, "Source Column", 100, False)
        self.COL_SOURCE_TYPE = self._columns.add_column(
            mforms.StringColumnType, "Source Type", 100, False)
        self.COL_SOURCE_FLAGS = self._columns.add_column(
            mforms.StringColumnType, "Source Flags", 100, False)
        self.COL_SOURCE_NOTNULL = self._columns.add_column(
            mforms.CheckColumnType, "NN", 25, False)
        self.COL_SOURCE_DEFAULT = self._columns.add_column(
            mforms.StringColumnType, "Source Default Value", 100, False)
        self.COL_SOURCE_COLLATION = self._columns.add_column(
            mforms.StringColumnType, "Source Collation", 100, False)
        self.COL_TARGET_SCHEMA = self._columns.add_column(
            mforms.StringColumnType, "Target Schema", 100, False)
        self.COL_TARGET_TABLE = self._columns.add_column(
            mforms.IconStringColumnType, "Target Table", 100, False)
        self.COL_TARGET_COLUMN = self._columns.add_column(
            mforms.IconStringColumnType, "Target Column", 100, True)
        self.COL_TARGET_TYPE = self._columns.add_column(
            mforms.StringColumnType, "Target Type", 100, True)
        self.COL_TARGET_FLAGS = self._columns.add_column(
            mforms.StringColumnType, "Target Flags", 100, True)
        self.COL_TARGET_AI = self._columns.add_column(mforms.CheckColumnType,
                                                      "AI", 25, True)
        self.COL_TARGET_NOTNULL = self._columns.add_column(
            mforms.CheckColumnType, "NN", 25, True)
        self.COL_TARGET_DEFAULT = self._columns.add_column(
            mforms.StringColumnType, "Target Default Value", 100, True)
        self.COL_TARGET_COLLATION = self._columns.add_column(
            mforms.StringColumnType, "Target Collation", 100, True)
        self.COL_MESSAGE = self._columns.add_column(
            mforms.IconStringColumnType, "Migration Message", 300, False)
        self._columns.end_columns()
        self._columns.set_allow_sorting(True)
        self._columns.set_selection_mode(mforms.TreeSelectMultiple)
        self._columns.add_changed_callback(self._selection_changed)
        self.content.add(self._columns, True, True)
        self._columns.set_cell_edited_callback(self._columns_cell_edited)
        self._columns.show(False)

        self._menu = mforms.newContextMenu()
        self._menu.add_will_show_callback(self.menu_will_show)
        self._menu.add_item_with_title(
            "Set Target Type of Selected Columns...", self.set_target_type,
            "set_target_type")
        self._menu.add_item_with_title("Find and Replace Target Type...",
                                       self.replace_target_type,
                                       "replace_target_type")
        self._menu.add_item_with_title("Find and Replace Target Flags...",
                                       self.replace_target_flags,
                                       "replace_target_flags")
        self._menu.add_item_with_title(
            "Find and Replace Target Default Value...",
            self.replace_target_default_value, "replace_target_default_value")
        self._menu.add_item_with_title("Find and Replace Target Collation...",
                                       self.replace_target_collation,
                                       "replace_target_collation")
        self._columns.set_context_menu(self._menu)

        self.help_label = mforms.newLabel(
            "You can rename target schemas and tables, and change column definitions by clicking them once selected."
        )
        self.help_label.set_style(mforms.SmallStyle)
        self.content.add(self.help_label, False, True)

        self._advbox = mforms.newPanel(mforms.TitledBoxPanel)
        self._advbox.set_title("SQL CREATE Script for Selected Object")
        box = mforms.newBox(True)
        self._code = mforms.newCodeEditor()
        self._code.set_language(mforms.LanguageMySQL)
        self._code.add_changed_callback(self._code_changed)
        box.add(self._code, True, True)
        vbox = mforms.newBox(False)
        vbox.set_padding(12)
        vbox.set_spacing(8)

        self._lock_check = mforms.newCheckBox()
        self._lock_check.set_text("Lock edited SQL")
        self._lock_check.set_tooltip(
            "Lock the SQL code to the edited one, preventing automatic regenerations from discarding changes made directly to the SQL script."
        )
        self._lock_check.add_clicked_callback(self._lock_clicked)
        vbox.add(self._lock_check, False, True)

        self._comment_check = mforms.newCheckBox()
        self._comment_check.set_text("Comment out")
        self._comment_check.set_tooltip(
            "Mark the object to be commented out on the generated script, making it not get created in the target server."
        )
        self._comment_check.add_clicked_callback(self._comment_clicked)
        vbox.add(self._comment_check, False, True)

        self._sql_outdated_label = mforms.newLabel("Code is outdated")
        self._sql_outdated_label.show(False)
        self._sql_outdated_label.set_tooltip(
            "The locked SQL code seems to be outdated compared to a newer, automatically generated one. Unlocking the object will update it, but your changes will be lost."
        )
        vbox.add(self._sql_outdated_label, False, True)

        self._revert_btn = mforms.newButton()
        self._revert_btn.set_text("Discard Changes")
        vbox.add_end(self._revert_btn, False, True)
        self._revert_btn.add_clicked_callback(self._discard_clicked)

        self._apply_btn = mforms.newButton()
        self._apply_btn.set_text("Apply Changes")
        vbox.add_end(self._apply_btn, False, True)
        self._apply_btn.add_clicked_callback(self._apply_clicked)
        box.add(vbox, False, True)

        self._advbox.add(box)
        self._advbox.set_size(-1, 200)
        self._advbox_shown = True
        self.go_advanced()  # toggle to hide

        self.content.add(self._advbox, False, True)

        self._filter_errors = False
        self._filter_changed()
    def create_ui(self):
        self.content.set_spacing(4)
        self.content.add(mforms.newLabel("Review and edit migrated objects. You can manually edit the generated SQL before applying them to the target database."), False, True)
        
        hbox = mforms.newBox(True)
        self.tree_head_label = mforms.newLabel("Migrated Objects")
        hbox.add(self.tree_head_label, False, False)
        self._filter = mforms.newSelector()
        self._filter.add_items(["Migration Problems", "All Objects", "Column Mappings"])
        self._filter.add_changed_callback(self._filter_changed)
        hbox.add_end(self._filter, False, True)
        hbox.add_end(mforms.newLabel("View:"), False, False)
        self.content.add(hbox, False, True)
        
        self._no_errors_text = "No migration problems found. %d warning(s).\nUse the View pulldown menu to review all objects."
        self._no_errors = mforms.newLabel('')  # Label text will be set later when the warning count is calculated
        self._no_errors.set_style(mforms.BigStyle)
        self._no_errors.set_text_align(mforms.MiddleLeft)
        self.content.add(self._no_errors, True, True)
        
        self._tree = mforms.newTreeView(mforms.TreeDefault)
        self._tree.add_column(mforms.IconStringColumnType, "Source Object", 200, False)
        self._tree.add_column(mforms.IconStringColumnType, "Target Object", 200, True)
        self._tree.add_column(mforms.IconStringColumnType, "Migration Message", 300, False)
        self._tree.end_columns()
        self._tree.add_changed_callback(self._selection_changed)
        self.content.add(self._tree, True, True)
        self._tree.set_cell_edited_callback(self._cell_edited)

        self._all_menu = mforms.newContextMenu()
        self._all_menu.add_will_show_callback(self.all_menu_will_show)
        self._all_menu.add_check_item_with_title("Skip Object", self.skip_object, "skip_object")

        self._tree.set_context_menu(self._all_menu)

        
        self._columns = mforms.newTreeView(mforms.TreeShowColumnLines|mforms.TreeShowRowLines|mforms.TreeFlatList)
        self.COL_SOURCE_SCHEMA = self._columns.add_column(mforms.StringColumnType, "Source Schema", 100, False)
        self.COL_SOURCE_TABLE = self._columns.add_column(mforms.IconStringColumnType, "Source Table", 100, False)
        self.COL_SOURCE_COLUMN = self._columns.add_column(mforms.IconStringColumnType, "Source Column", 100, False)
        self.COL_SOURCE_TYPE = self._columns.add_column(mforms.StringColumnType, "Source Type", 100, False)
        self.COL_SOURCE_FLAGS = self._columns.add_column(mforms.StringColumnType, "Source Flags", 100, False)
        self.COL_SOURCE_NOTNULL = self._columns.add_column(mforms.CheckColumnType, "NN", 25, False)
        self.COL_SOURCE_DEFAULT = self._columns.add_column(mforms.StringColumnType, "Source Default Value", 100, False)
        self.COL_SOURCE_COLLATION = self._columns.add_column(mforms.StringColumnType, "Source Collation", 100, False)
        self.COL_TARGET_SCHEMA = self._columns.add_column(mforms.StringColumnType, "Target Schema", 100, False)
        self.COL_TARGET_TABLE = self._columns.add_column(mforms.IconStringColumnType, "Target Table", 100, False)
        self.COL_TARGET_COLUMN = self._columns.add_column(mforms.IconStringColumnType, "Target Column", 100, True)
        self.COL_TARGET_TYPE = self._columns.add_column(mforms.StringColumnType, "Target Type", 100, True)
        self.COL_TARGET_FLAGS = self._columns.add_column(mforms.StringColumnType, "Target Flags", 100, True)
        self.COL_TARGET_AI = self._columns.add_column(mforms.CheckColumnType, "AI", 25, True)
        self.COL_TARGET_NOTNULL = self._columns.add_column(mforms.CheckColumnType, "NN", 25, True)
        self.COL_TARGET_DEFAULT = self._columns.add_column(mforms.StringColumnType, "Target Default Value", 100, True)
        self.COL_TARGET_COLLATION = self._columns.add_column(mforms.StringColumnType, "Target Collation", 100, True)
        self.COL_MESSAGE = self._columns.add_column(mforms.IconStringColumnType, "Migration Message", 300, False)
        self._columns.end_columns()
        self._columns.set_allow_sorting(True)
        self._columns.set_selection_mode(mforms.TreeSelectMultiple)
        self._columns.add_changed_callback(self._selection_changed)
        self.content.add(self._columns, True, True)
        self._columns.set_cell_edited_callback(self._columns_cell_edited)
        self._columns.show(False)
        
        self._menu = mforms.newContextMenu()
        self._menu.add_will_show_callback(self.menu_will_show)
        self._menu.add_item_with_title("Set Target Type of Selected Columns...", self.set_target_type, "set_target_type")
        self._menu.add_item_with_title("Find and Replace Target Type...", self.replace_target_type, "replace_target_type")
        self._menu.add_item_with_title("Find and Replace Target Flags...", self.replace_target_flags, "replace_target_flags")
        self._menu.add_item_with_title("Find and Replace Target Default Value...", self.replace_target_default_value, "replace_target_default_value")
        self._menu.add_item_with_title("Find and Replace Target Collation...", self.replace_target_collation, "replace_target_collation")
        self._columns.set_context_menu(self._menu)
        
        self.help_label = mforms.newLabel("You can rename target schemas and tables, and change column definitions by clicking them once selected.")
        self.help_label.set_style(mforms.SmallStyle)
        self.content.add(self.help_label, False, True)
        
        self._advbox = mforms.newPanel(mforms.TitledBoxPanel)
        self._advbox.set_title("SQL CREATE Script for Selected Object")
        box = mforms.newBox(True)
        self._code = mforms.newCodeEditor()
        self._code.set_language(mforms.LanguageMySQL)
        self._code.add_changed_callback(self._code_changed)
        box.add(self._code, True, True)
        vbox = mforms.newBox(False)
        vbox.set_padding(12)
        vbox.set_spacing(8)

        self._lock_check = mforms.newCheckBox()
        self._lock_check.set_text("Lock edited SQL")
        self._lock_check.set_tooltip("Lock the SQL code to the edited one, preventing automatic regenerations from discarding changes made directly to the SQL script.")
        self._lock_check.add_clicked_callback(self._lock_clicked)
        vbox.add(self._lock_check, False, True)

        self._comment_check = mforms.newCheckBox()
        self._comment_check.set_text("Comment out")
        self._comment_check.set_tooltip("Mark the object to be commented out on the generated script, making it not get created in the target server.")
        self._comment_check.add_clicked_callback(self._comment_clicked)
        vbox.add(self._comment_check, False, True)
        
        self._sql_outdated_label = mforms.newLabel("Code is outdated")
        self._sql_outdated_label.show(False)
        self._sql_outdated_label.set_tooltip("The locked SQL code seems to be outdated compared to a newer, automatically generated one. Unlocking the object will update it, but your changes will be lost.")
        vbox.add(self._sql_outdated_label, False, True)

        self._revert_btn = mforms.newButton()
        self._revert_btn.set_text("Discard Changes")
        vbox.add_end(self._revert_btn, False, True)
        self._revert_btn.add_clicked_callback(self._discard_clicked)

        self._apply_btn = mforms.newButton()
        self._apply_btn.set_text("Apply Changes")
        vbox.add_end(self._apply_btn, False, True)
        self._apply_btn.add_clicked_callback(self._apply_clicked)
        box.add(vbox, False, True)

        self._advbox.add(box)
        self._advbox.set_size(-1, 200)
        self._advbox_shown = True
        self.go_advanced() # toggle to hide
                
        self.content.add(self._advbox, False, True)
        
        self._filter_errors = False
        self._filter_changed()
예제 #4
0
    def __init__(self, editor, schema):
        mforms.Box.__init__(self, False)
        self.set_managed()
        self.set_release_on_add()

        self.schema = schema
        self.editor = editor

        self.target_version = Version.fromgrt(editor.serverVersion)

        self.main = mforms.newBox(False)
        self.add(self.main, True, True)

        self.error_heading = mforms.newLabel("")
        self.error_heading.set_style(mforms.BoldStyle)
        self.error_body = mforms.newLabel("")
        self.error_box = mforms.newBox(False)
        self.error_box.set_spacing(8)
        self.error_box.set_padding(8)
        self.error_box.add(self.error_heading, True, False)
        self.error_box.add(self.error_body, True, False)
        self.add(self.error_box, True, False)
        self.error_box.show(False)

        self.main.set_padding(8)
        self.main.set_spacing(8)

        self.tree = mforms.newTreeNodeView(mforms.TreeFlatList
                                           | mforms.TreeAltRowColors
                                           | mforms.TreeShowColumnLines)
        self.tree.set_selection_mode(mforms.TreeSelectMultiple)

        #Check if there is method to load the columns, if not, skip.
        if hasattr(self, "preload_columns") and callable(
                getattr(self, "preload_columns")):
            self.preload_columns()

        for field, type, caption, width, min_version in self.columns:
            if min_version and not self.target_version.is_supported_mysql_version_at_least(
                    Version.fromstr(min_version)):
                continue
            self.tree.add_column(type, caption, width, False)
        self.tree.end_columns()
        self.tree.set_allow_sorting(True)
        self.main.add(self.tree, True, True)

        self.menu = mforms.newContextMenu()
        self.menu.add_will_show_callback(self.menu_will_show)
        self.tree.add_activated_callback(self.on_activate)
        self.tree.set_context_menu(self.menu)

        self.icon_path = mforms.App.get().get_resource_path(self.klass +
                                                            ".16x16.png")
        self.bad_icon_path = mforms.App.get().get_resource_path(
            self.bad_icon_path)

        self.row_count = mforms.newLabel("")
        self.row_count.set_text("")

        self.refresh_btn = mforms.newButton()
        self.refresh_btn.set_text("Refresh")
        self.refresh_btn.add_clicked_callback(self.refresh)

        self.bbox = mforms.newBox(True)
        self.bbox.set_spacing(8)
        self.main.add(self.bbox, False, True)

        self.bbox.add(self.row_count, False, True)
        self.bbox.add_end(self.refresh_btn, False, True)

        for caption, callback_name in self.actions:
            if not caption:
                self.bbox.add(mforms.newLabel(" "), False, True)
                continue
            btn = mforms.newButton()
            btn.set_text(caption)
            btn.add_clicked_callback(getattr(self, callback_name))
            self.bbox.add(btn, False, True)
예제 #5
0
    def __init__(self, group_container, vars):
        mforms.Form.__init__(self, None)
        self.pending_changes = False
        self.sel_vars = vars
        self.group_container = group_container
        self.suspend_layout()
        
        self.set_title("Custom Variable Categories")

        content = mforms.newBox(False)
        self.set_content(content)
        content.set_padding(20)
        content.set_spacing(12)
        
        l = mforms.newLabel("Select or create new category for custom variable categories.")
        content.add(l, False, False)
        
        self.groups = newTreeNodeView(mforms.TreeFlatList)
        self.groups.set_selection_mode(mforms.TreeSelectMultiple)
        self.groups.add_column(mforms.StringColumnType, "Category name", 100, False)
        self.groups.end_columns()
        self.groups.set_size(200, 200)
        self.menu = mforms.newContextMenu()
        self.menu.add_item_with_title("Delete Category", self.group_delete, "group_delete")
        self.groups.set_context_menu(self.menu)

        content.add(self.groups, True, True)

        entry_box = mforms.newBox(True)
        entry_box.set_spacing(5)

        l = mforms.newLabel("Category name:")
        entry_box.add(l, False, False)
        self.name = mforms.newTextEntry()
        self.name.add_action_callback(self.group_name_action)
        entry_box.add(self.name, True, True)
        self.add_btn = newButton()
        self.add_btn.set_text("Add")
        self.add_btn.add_clicked_callback(self.group_add)
        entry_box.add_end(self.add_btn, False, False)

        content.add(entry_box, False, True)

        self.cancel = newButton()
        self.cancel.set_text("Cancel")
        self.cancel.add_clicked_callback(self.cancel_click)
        self.ok = newButton()
        self.ok.set_text("OK")
        self.ok.add_clicked_callback(self.ok_click)

        self.delete = newButton()
        self.delete.set_text("Delete")
        self.delete.add_clicked_callback(self.group_delete)
        
        bbox = mforms.newBox(True)
        bbox.set_spacing(12)
        
        okcancel_box = mforms.newBox(True)
        okcancel_box.set_spacing(12)

        bbox.add_end(okcancel_box, False, True)
        bbox.add(self.delete, False, True)

        mforms.Utilities.add_end_ok_cancel_buttons(okcancel_box, self.ok, self.cancel)
        content.add_end(bbox, False, True)

        self.set_size(550, -1)
        self.center()
        self.load_groups()

        self.resume_layout()
예제 #6
0
    def __init__(self, ctrl_be, variables, command, type):
        mforms.Box.__init__(self, False)
        self.set_managed()
        self.set_release_on_add()

        self.user_groups = VariablesGroupContainer(type)
        self.user_groups.load()
        
        self.variables = variables

        self.suspend_layout()

        self.command = command
        self.ctrl_be = ctrl_be

        box = newBox(True)
        box.set_spacing(12)
        self.add(box, True, True)
        self.tree = newTreeNodeView(mforms.TreeFlatList)
        self.tree.set_selection_mode(mforms.TreeSelectMultiple)

        sidebox = newBox(False)
        box.add(sidebox, False, True)

        self.searchEntry = newTextEntry(mforms.SearchEntry)

        sidebox.set_spacing(12)
        sidebox.add(self.searchEntry, False, True)
        sidebox.add(self.tree, True, True)
        self.tree.set_size(210, -1)

        self.searchEntry.add_changed_callback(self.filterOutput)

        self.tree.add_column(mforms.StringColumnType, "Category", 200, False)
        self.tree.end_columns()
        self.tree.add_changed_callback(weakcb(self, "refresh"))
        self.cat_menu = mforms.newContextMenu()
        self.cat_menu.add_will_show_callback(self.cat_menu_will_show)
        self.cat_menu.add_item_with_title("Delete Category", self.delete_category, "delete")
        self.tree.set_context_menu(self.cat_menu)

        self.values = newTreeNodeView(mforms.TreeFlatList)
        self.values.set_selection_mode(mforms.TreeSelectMultiple)
        box.add(self.values, True, True)

        self.values.add_column(mforms.StringColumnType, "Name", 200, False)
        self.values.add_column(mforms.StringColumnType, "Value", 120, True)
        self.values.add_column(mforms.StringColumnType, "Description", 1000, False)
        self.values.end_columns()
        self.values.set_allow_sorting(True)
        self.values.set_cell_edited_callback(self.edit_variable)
        self.values.add_changed_callback(weakcb(self, "value_selection_changed"))
        self.menu = mforms.newContextMenu()
        self.menu.add_will_show_callback(self.menu_will_show)
        self.values.set_context_menu(self.menu)

        box = newBox(True)
        box.set_spacing(8)
        copy_all_button = newButton()
        copy_all_button.set_text('Copy Global Status and Variables to Clipboard')
        copy_all_button.add_clicked_callback(self.copy_status_to_clipboard)
        box.add(copy_all_button, False, False)
        copy_shown_button = newButton()
        copy_shown_button.set_text('Copy Selected to Clipboard')
        copy_shown_button.add_clicked_callback(self.copy_selected_to_clipboard)
        box.add(copy_shown_button, False, False)
        self.copy_selected_to_clipboard_button = copy_shown_button
        button = newButton()
        box.add_end(button, False, True)
        button.set_text("Refresh")
        box.set_padding(12)

        button.add_clicked_callback(weakcb(self, "refresh"))

        self.add(box, False, True)

        row = self.tree.add_node()
        row.set_string(0, "All")
        row = self.tree.add_node()
        row.set_string(0, "Filtered")

        self.resume_layout()

        self.variable_info = {}
        self.variables_in_group = {"Other":[]}

        self._delayed_init_tm = mforms.Utilities.add_timeout(0.1, lambda: self.delayed_init(self.variables))
예제 #7
0
    def update_ui(self):
        if self.error_box:
            self.remove(self.error_box)
            self.error_box = None

        if self.tree:
            self.remove(self.tree)
            self.tree = None

        if self.bbox:
            self.remove(self.bbox)
            self.bbox = None

        if self.warning_box:
            self.remove(self.warning_box)
            self.warning_box = None

        self.set_padding(8)
        self.set_spacing(8)
        
        filter_box = self.create_filter_box()
        if filter_box:
            if filter_box.get_parent():
                self.remove(filter_box)
            self.add(filter_box, False, True)
        
        try:
            self.log_reader = self.BackendLogReaderClass(*self.args)
        except Exception as error:
            import traceback
            log_error("Exception creating log reader: %s\n%s\n" % (error, traceback.format_exc()))
            self._show_error("Error creating log reader: %s\n" % error)
            return

        if self.log_reader.partial_support:
            self.warning_box = newBox(True)
            self.warning_box.set_spacing(8)
            warning_label = newLabel(self.log_reader.partial_support)
            self.warning_box.add(warning_label, False, True)
            self.add(self.warning_box, False, True)

        self.tree = newTreeView(mforms.TreeFlatList)
        self.tree.set_selection_mode(mforms.TreeSelectMultiple)

        for colspec in self.log_reader.column_specs:
            self.tree.add_column(mforms.StringColumnType,
                                 colspec[0],  # column header
                                 colspec[1],  # column width
                                 False)
        self.tree.end_columns()

        self.add(self.tree, True, True)

        table = mforms.newTable()
        table.set_row_spacing(4)
        table.set_column_spacing(4)
        table.set_column_count(4)
        table.set_row_count(2)

        table.add(newLabel("Log File Location:"), 0, 1, 0, 1, mforms.HFillFlag)
        if self.log_reader.log_file:
            if self.log_reader.log_file.path == "stderr":
                self.query = """<QueryList><Query Id = "0" Path = "Application">
                                <Select Path = "Application">*[System[Provider[@Name = 'MySQL'] and TimeCreated[timediff(@SystemTime) &lt;= 604800000]]]</Select>
                                </Query></QueryList>"""
                grt.setEventlogCallback(self.printResults)
                label = newLabel("Windows Event viewer")
            else:
                label = newLabel(self.log_reader.log_file.path)
        else:
            label = newLabel("TABLE")
        label.set_style(mforms.BoldStyle)
        table.add(label, 1, 2, 0, 1, mforms.VFillFlag|mforms.HFillFlag|mforms.HExpandFlag)

        table.add(newLabel("Log File Size:"), 2, 3, 0, 1, mforms.VFillFlag|mforms.HFillFlag)
        self.size_label = newLabel("retrieving..." if self.log_reader.log_file else "-")
        self.size_label.set_style(mforms.BoldStyle)
        table.add(self.size_label, 3, 4, 0, 1, mforms.VFillFlag|mforms.HFillFlag|mforms.HExpandFlag)

        table.add(newLabel("Showing:"), 0, 1, 1, 2, mforms.VFillFlag|mforms.HFillFlag)
        self.range_label = newLabel("retrieving data...")
        self.range_label.set_style(mforms.BoldStyle)
        table.add(self.range_label, 1, 2, 1, 2, mforms.VFillFlag|mforms.HFillFlag)
        self.add(table, False, True)

        self.bbox = newBox(True)
        self.bbox.set_spacing(8)
        self.add_end(self.bbox, False, True)

        self._menu = mforms.newContextMenu()
        self._menu.add_item_with_title("Copy Row", self.copy_record, "Copy Record", "Copy Record")
        self._menu.add_item_with_title("Copy Details", self.copy_details, "Copy Details", "Copy Details")
        self.tree.set_context_menu(self._menu)

        self.bbox.add(newLabel(""), True, True)

        self.bof_button = newButton()
        self.bof_button.set_text("Oldest")
        self.bbox.add(self.bof_button, False, True)
        self.bof_button.add_clicked_callback(self.go_bof)

        self.back_button = newButton()
        self.back_button.set_text("< Previous Page")
        self.bbox.add(self.back_button, False, True)
        self.back_button.add_clicked_callback(self.go_back)

        self.next_button = newButton()
        self.next_button.set_text("Next Page >")
        self.bbox.add(self.next_button, False, True)
        self.next_button.add_clicked_callback(self.go_next)

        self.eof_button = newButton()
        self.eof_button.set_text("Most Recent")
        self.bbox.add(self.eof_button, False, True)
        self.eof_button.add_clicked_callback(self.go_eof)

        self.refresh_button = newButton()
        self.refresh_button.set_text("Refresh")
        self.bbox.add(self.refresh_button, False, True)
        self.refresh_button.add_clicked_callback(self.refresh)

        if self.log_reader.log_file and self.log_reader.log_file.path == "stderr":
            self.actual_position = 0
            grt.getEventLogEntry(0, self.query)
    def create_ui(self):
        dprint_ex(4, "Enter")
        self.suspend_layout()

        self.heading = make_panel_header("title_connections.png", self.instance_info.name, "Client Connections")
        self.add(self.heading, False, False)

        self.warning = not_running_warning_label()
        self.add(self.warning, False, True)

        self.connection_list = newTreeNodeView(mforms.TreeDefault|mforms.TreeFlatList|mforms.TreeAltRowColors)
        self.connection_list.add_column(mforms.LongIntegerColumnType, "Id", 50, False)
        self.connection_list.add_column(mforms.StringColumnType, "User", 80, False)
        self.connection_list.add_column(mforms.StringColumnType, "Host", 120, False)
        self.connection_list.add_column(mforms.StringColumnType, "DB", 100, False)
        self.connection_list.add_column(mforms.StringColumnType, "Command", 80, False)
        self.connection_list.add_column(mforms.LongIntegerColumnType, "Time", 60, False)
        self.connection_list.add_column(mforms.StringColumnType, "State", 80, False)
        self.info_column = self.connection_list.add_column(mforms.StringColumnType, "Info", 300, False)
        self.connection_list.end_columns()
        self.connection_list.set_allow_sorting(True)
        
        self.connection_list.add_changed_callback(weakcb(self, "connection_selected"))
        
        #self.set_padding(8)
        self.add(self.connection_list, True, True)
        
        self.button_box = box = newBox(True)
        
        box.set_spacing(12)
        
        refresh_button = newButton()
        refresh_button.set_text("Refresh")
        box.add_end(refresh_button, False, True)
        refresh_button.add_clicked_callback(weakcb(self, "refresh"))

        self.kill_button = newButton()
        self.kill_button.set_text("Kill Connection")
        box.add_end(self.kill_button, False, True)
        self.kill_button.add_clicked_callback(weakcb(self, "kill_connection"))
        
        self.killq_button = newButton()
        self.killq_button.set_text("Kill Query")
        box.add_end(self.killq_button, False, True)
        self.killq_button.add_clicked_callback(weakcb(self, "kill_query"))
        
        refresh_label = newLabel("Refresh Rate:")
        box.add(refresh_label, False, True)

        self._menu = mforms.newContextMenu()
        self._menu.add_item_with_title("Copy Info", self.copy_selected, "copy_selected")
        self._menu.add_item_with_title("Show in Editor", self.edit_selected, "edit_selected")
        self.connection_list.set_context_menu(self._menu)

        
        self.refresh_values = [0.5, 1, 2, 3, 4, 5, 10, 15, 30]
        self.refresh_values_size = len(self.refresh_values)
        
        self.refresh_selector = newSelector()
        self.refresh_selector.set_size(100,-1)
        
        for s in self.refresh_values:
            self.refresh_selector.add_item(str(s) + " seconds")
        
        self.refresh_selector.add_item("Don't Refresh")
        
        refresh_rate_index = grt.root.wb.options.options.get('Administrator:refresh_connections_rate_index', 9)
        self.refresh_selector.set_selected(refresh_rate_index)
        self.update_refresh_rate()
        self.refresh_selector.add_changed_callback(weakcb(self, "update_refresh_rate"))
        box.add(self.refresh_selector, False, True)

        self.hide_sleep_connections = newCheckBox()
        self.hide_sleep_connections.set_text('Hide sleeping connections')
        self.hide_sleep_connections.add_clicked_callback(self.refresh)
        box.add(self.hide_sleep_connections, False, True)
        
        self.add(box, False, True)
        
        self.resume_layout()
        
        self.connection_selected()
        dprint_ex(4, "Leave")
    def __init__(self, owner):
        mforms.Form.__init__(self, None, mforms.FormDialogFrame|mforms.FormResizable|mforms.FormMinimizable)
        self.owner = owner
        self.tables_by_id = {}

        self.set_title("Table Templates")

        box = mforms.newBox(False)
        box.set_padding(12)
        box.set_spacing(12)

        label = mforms.newLabel("Manage templates of tables with pre-defined columns, for frequently used table structures.")
        box.add(label, False, True)

        top = mforms.newBox(True)
        box.add(top, False, True)

        #top.set_padding(12)
        top.set_spacing(12)
        self.template_list = mforms.newTreeView(mforms.TreeFlatList)
        self.template_list.add_column(mforms.IconStringColumnType, "Table Template", 200, True)
        self.template_list.end_columns()
        self.template_list.add_changed_callback(self.table_selected)
        self.template_list.set_cell_edited_callback(self.table_edited)
        top.add(self.template_list, True, True)
        if sys.platform.lower() != "darwin":
            self.template_list.set_size(-1, 150)

        bbox = mforms.newBox(False)
        bbox.set_spacing(8)
        top.add(bbox, False, True)

        self.add = mforms.newButton()
        self.add.set_text("New Template")
        self.add.add_clicked_callback(self.add_templ)
        bbox.add(self.add, False, True)

        self.duplicate = mforms.newButton()
        self.duplicate.set_text("Duplicate")
        self.duplicate.add_clicked_callback(self.dup_templ)
        bbox.add(self.duplicate, False, True)

        self.delete = mforms.newButton()
        self.delete.set_text("Delete")
        self.delete.add_clicked_callback(self.del_templ)
        bbox.add(self.delete, False, True)

        hbox = mforms.newBox(True)
        hbox.set_spacing(12)
      
        self.column_list = mforms.newTreeView(mforms.TreeFlatList)
        self.column_list.add_column(mforms.IconStringColumnType, "Column", 100, True)
        self.column_list.add_column(mforms.StringColumnType, "Datatype", 100, True)
        self.column_list.add_column(mforms.StringColumnType, "Default", 150, True)
        self.column_list.add_column(mforms.CheckColumnType, "PK", 25, True)
        self.column_list.add_column(mforms.CheckColumnType, "NN", 25, True)
        self.column_list.add_column(mforms.CheckColumnType, "UQ", 25, True)
        self.column_list.add_column(mforms.CheckColumnType, "AI", 25, True)
        self.column_list.end_columns()
        self.column_list.set_cell_edited_callback(self.column_edited)
        self.column_list.add_changed_callback(self.column_selected)
        hbox.add(self.column_list, True, True)
      
        vbox = mforms.newBox(False)
        vbox.set_spacing(8)
      
        vbox.add(mforms.newLabel("Column Collation:"), False, True)
        self.charset = mforms.newSelector(mforms.SelectorPopup)
        self.charset.add_changed_callback(self.collation_changed)
        collations = ["Table Default"]
        for ch in grt.root.wb.rdbmsMgmt.rdbms[0].characterSets:
            collations += ch.collations
        self.charset.add_items(collations)
        vbox.add(self.charset, False, True)

        vbox.add(mforms.newLabel("Additional Flags:"), False, True)
        self.flag_checkboxes = []
        hbox.add(vbox, False, True)
        self.column_details = vbox
      
        box.add(hbox, True, True)

        self.column_menu = mforms.newContextMenu()
        self.column_menu.add_item_with_title("Delete", self.delete_column)
        self.column_list.set_context_menu(self.column_menu)

        bbox = mforms.newBox(True)
        self.ok = mforms.newButton()
        self.ok.set_text("Close")
        bbox.add_end(self.ok, False, True)

        box.add(bbox, False, True)

        self.set_content(box)
        self.set_size(800, 500)
        self.center()

        self.refresh_tables()
예제 #10
0
    def __init__(self, owner):
        mforms.Form.__init__(
            self, None, mforms.FormDialogFrame | mforms.FormResizable
            | mforms.FormMinimizable)
        self.owner = owner

        # We need to have some default catalog and schema so parser is happy
        self.tmpCatalog = grt.classes.db_mysql_Catalog()
        self.tmpCatalog.name = 'tmpCatalog'
        self.tmpCatalog.oldName = self.tmpCatalog.name
        self.tmpCatalog.simpleDatatypes.extend(
            grt.root.wb.rdbmsMgmt.rdbms[0].simpleDatatypes)

        self.tmpSchema = grt.classes.db_mysql_Schema()
        self.tmpSchema.name = "tmpSchema"
        self.tmpSchema.oldName = self.tmpSchema.name
        self.tmpSchema.owner = self.tmpCatalog
        self.tmpCatalog.schemata.append(self.tmpSchema)

        self.tables_by_id = {}

        self.set_title("Table Templates")

        box = mforms.newBox(False)
        box.set_padding(12)
        box.set_spacing(12)

        label = mforms.newLabel(
            "Manage templates of tables with pre-defined columns, for frequently used table structures."
        )
        box.add(label, False, True)

        top = mforms.newBox(True)
        box.add(top, False, True)

        #top.set_padding(12)
        top.set_spacing(12)
        self.template_list = mforms.newTreeView(mforms.TreeFlatList)
        self.template_list.add_column(mforms.IconStringColumnType,
                                      "Table Template", 200, True)
        self.template_list.end_columns()
        self.template_list.add_changed_callback(self.table_selected)
        self.template_list.set_cell_edited_callback(self.table_edited)
        top.add(self.template_list, True, True)
        if sys.platform.lower() != "darwin":
            self.template_list.set_size(-1, 150)

        bbox = mforms.newBox(False)
        bbox.set_spacing(8)
        top.add(bbox, False, True)

        self.add = mforms.newButton()
        self.add.set_text("New Template")
        self.add.add_clicked_callback(self.add_templ)
        bbox.add(self.add, False, True)

        self.duplicate = mforms.newButton()
        self.duplicate.set_text("Duplicate")
        self.duplicate.add_clicked_callback(self.dup_templ)
        self.duplicate.set_enabled(False)
        bbox.add(self.duplicate, False, True)

        self.delete = mforms.newButton()
        self.delete.set_text("Delete")
        self.delete.add_clicked_callback(self.del_templ)
        self.delete.set_enabled(False)
        bbox.add(self.delete, False, True)

        hbox = mforms.newBox(True)
        hbox.set_spacing(12)

        self.column_list = mforms.newTreeView(mforms.TreeFlatList)
        self.column_list.add_column(mforms.IconStringColumnType, "Column", 100,
                                    True)
        self.column_list.add_column(mforms.StringColumnType, "Datatype", 100,
                                    True)
        self.column_list.add_column(mforms.StringColumnType, "Default", 150,
                                    True)
        self.column_list.add_column(mforms.CheckColumnType, "PK", 25, True)
        self.column_list.add_column(mforms.CheckColumnType, "NN", 25, True)
        self.column_list.add_column(mforms.CheckColumnType, "UQ", 25, True)
        self.column_list.add_column(mforms.CheckColumnType, "AI", 25, True)
        self.column_list.end_columns()
        self.column_list.set_cell_edited_callback(self.column_edited)
        self.column_list.add_changed_callback(self.column_selected)
        hbox.add(self.column_list, True, True)

        vbox = mforms.newBox(False)
        vbox.set_spacing(8)

        vbox.add(mforms.newLabel("Column Collation:"), False, True)
        self.charset = mforms.newSelector(mforms.SelectorPopup)
        self.charset.add_changed_callback(self.collation_changed)
        collations = ["Table Default"]
        for ch in grt.root.wb.rdbmsMgmt.rdbms[0].characterSets:
            collations += ch.collations
        self.charset.add_items(collations)
        vbox.add(self.charset, False, True)

        vbox.add(mforms.newLabel("Additional Flags:"), False, True)
        self.flag_checkboxes = []
        hbox.add(vbox, False, True)
        self.column_details = vbox

        box.add(hbox, True, True)

        self.column_menu = mforms.newContextMenu()
        self.column_menu.add_item_with_title("Delete", self.delete_column)
        self.column_list.set_context_menu(self.column_menu)

        bbox = mforms.newBox(True)
        self.ok = mforms.newButton()
        self.ok.set_text("Close")
        bbox.add_end(self.ok, False, True)

        box.add(bbox, False, True)

        self.set_content(box)
        self.set_size(800, 500)
        self.center()

        self.refresh_tables()
    def __init__(self, editor, schema):
        mforms.Box.__init__(self, False)
        self.set_managed()
        self.set_release_on_add()

        self.schema = schema
        self.editor = editor
        
        self.target_version = Version.fromgrt(editor.serverVersion)

        self.main = mforms.newBox(False)
        self.add(self.main, True, True)

        self.error_heading = mforms.newLabel("")
        self.error_heading.set_style(mforms.BoldStyle)
        self.error_body = mforms.newLabel("")
        self.error_box = mforms.newBox(False)
        self.error_box.set_spacing(8)
        self.error_box.set_padding(8)
        self.error_box.add(self.error_heading, True, False)
        self.error_box.add(self.error_body, True, False)
        self.add(self.error_box, True, False)
        self.error_box.show(False)

        self.main.set_padding(8)
        self.main.set_spacing(8)

        self.tree = mforms.newTreeView(mforms.TreeFlatList|mforms.TreeAltRowColors|mforms.TreeShowColumnLines)
        self.tree.set_selection_mode(mforms.TreeSelectMultiple)
        
        #Check if there is method to load the columns, if not, skip.
        if hasattr(self, "preload_columns") and callable(getattr(self, "preload_columns")):
            self.preload_columns()
        
        for field, type, caption, width, min_version in self.columns:
            if min_version and not self.target_version.is_supported_mysql_version_at_least(Version.fromstr(min_version)):
                continue
            self.tree.add_column(type, caption, width, False)
        self.tree.end_columns()
        self.tree.set_allow_sorting(True)
        self.main.add(self.tree, True, True)

        self.menu = mforms.newContextMenu()
        self.menu.add_will_show_callback(self.menu_will_show)
        self.tree.add_activated_callback(self.on_activate)
        self.tree.set_context_menu(self.menu)

        self.icon_path = mforms.App.get().get_resource_path(self.klass+".16x16.png")
        self.bad_icon_path = mforms.App.get().get_resource_path(self.bad_icon_path)

        self.row_count = mforms.newLabel("")
        self.row_count.set_text("");
        
        self.refresh_btn = mforms.newButton()
        self.refresh_btn.set_text("Refresh")
        self.refresh_btn.add_clicked_callback(self.refresh)

        self.bbox = mforms.newBox(True)
        self.bbox.set_spacing(8)
        self.main.add(self.bbox, False, True)

        self.bbox.add(self.row_count, False, True)
        self.bbox.add_end(self.refresh_btn, False, True)

        for caption, callback_name in self.actions:
            if not caption:
                self.bbox.add(mforms.newLabel(" "), False, True)
                continue
            btn = mforms.newButton()
            btn.set_text(caption)
            btn.add_clicked_callback(getattr(self, callback_name))
            self.bbox.add(btn, False, True)
    def create_ui(self):
        dprint_ex(4, "Enter")
        self.suspend_layout()

        self.heading = make_panel_header("title_connections.png",
                                         self.instance_info.name,
                                         "Client Connections")
        self.add(self.heading, False, False)

        self.warning = not_running_warning_label()
        self.add(self.warning, False, True)

        self.connection_list = newTreeNodeView(mforms.TreeDefault
                                               | mforms.TreeFlatList
                                               | mforms.TreeAltRowColors)
        self.connection_list.add_column(mforms.LongIntegerColumnType, "Id", 50,
                                        False)
        self.connection_list.add_column(mforms.StringColumnType, "User", 80,
                                        False)
        self.connection_list.add_column(mforms.StringColumnType, "Host", 120,
                                        False)
        self.connection_list.add_column(mforms.StringColumnType, "DB", 100,
                                        False)
        self.connection_list.add_column(mforms.StringColumnType, "Command", 80,
                                        False)
        self.connection_list.add_column(mforms.LongIntegerColumnType, "Time",
                                        60, False)
        self.connection_list.add_column(mforms.StringColumnType, "State", 80,
                                        False)
        self.info_column = self.connection_list.add_column(
            mforms.StringColumnType, "Info", 300, False)
        self.connection_list.end_columns()
        self.connection_list.set_allow_sorting(True)

        self.connection_list.add_changed_callback(
            weakcb(self, "connection_selected"))

        #self.set_padding(8)
        self.add(self.connection_list, True, True)

        self.button_box = box = newBox(True)

        box.set_spacing(12)

        refresh_button = newButton()
        refresh_button.set_text("Refresh")
        box.add_end(refresh_button, False, True)
        refresh_button.add_clicked_callback(weakcb(self, "refresh"))

        self.kill_button = newButton()
        self.kill_button.set_text("Kill Connection")
        box.add_end(self.kill_button, False, True)
        self.kill_button.add_clicked_callback(weakcb(self, "kill_connection"))

        self.killq_button = newButton()
        self.killq_button.set_text("Kill Query")
        box.add_end(self.killq_button, False, True)
        self.killq_button.add_clicked_callback(weakcb(self, "kill_query"))

        refresh_label = newLabel("Refresh Rate:")
        box.add(refresh_label, False, True)

        self._menu = mforms.newContextMenu()
        self._menu.add_item_with_title("Copy Info", self.copy_selected,
                                       "copy_selected")
        self._menu.add_item_with_title("Show in Editor", self.edit_selected,
                                       "edit_selected")
        self.connection_list.set_context_menu(self._menu)

        self.refresh_values = [0.5, 1, 2, 3, 4, 5, 10, 15, 30]
        self.refresh_values_size = len(self.refresh_values)

        self.refresh_selector = newSelector()
        self.refresh_selector.set_size(100, -1)

        for s in self.refresh_values:
            self.refresh_selector.add_item(str(s) + " seconds")

        self.refresh_selector.add_item("Don't Refresh")

        refresh_rate_index = grt.root.wb.options.options.get(
            'Administrator:refresh_connections_rate_index', 9)
        self.refresh_selector.set_selected(refresh_rate_index)
        self.update_refresh_rate()
        self.refresh_selector.add_changed_callback(
            weakcb(self, "update_refresh_rate"))
        box.add(self.refresh_selector, False, True)

        self.hide_sleep_connections = newCheckBox()
        self.hide_sleep_connections.set_text('Hide sleeping connections')
        self.hide_sleep_connections.add_clicked_callback(self.refresh)
        box.add(self.hide_sleep_connections, False, True)

        self.add(box, False, True)

        self.resume_layout()

        self.connection_selected()
        dprint_ex(4, "Leave")
예제 #13
0
    def create_ui(self):
        dprint_ex(4, "Enter")
        self.suspend_layout()

        self.create_basic_ui("title_connections.png", "Client Connections")

        if self.new_processlist():
            widths = grt.root.wb.state.get("wb.admin:ConnectionListColumnWidthsPS", None)
        else:
            widths = grt.root.wb.state.get("wb.admin:ConnectionListColumnWidths", None)
        if widths:
            column_widths = [int(i) for i in widths.split(",")]
        else:
            column_widths = None

        self.connection_box = mforms.newBox(True)
        self.connection_box.set_spacing(8)
        self.connection_list = newTreeNodeView(mforms.TreeDefault|mforms.TreeFlatList|mforms.TreeAltRowColors)
        self.connection_list.set_selection_mode(mforms.TreeSelectMultiple)
        self.connection_list.add_column_resized_callback(self.column_resized)
        for i, (field, type, caption, width) in enumerate(self.columns):
            if column_widths and i < len(column_widths):
                width = column_widths[i]
            self.connection_list.add_column(type, caption, width, False)

        self.connection_list.end_columns()
        self.connection_list.set_allow_sorting(True)
        
        self.connection_list.add_changed_callback(weakcb(self, "connection_selected"))

        self.connection_box.add(self.connection_list, True, True)

        info_table = mforms.newTable()
        info_table.set_row_count(2)
        info_table.set_column_count(5)
        info_table.set_row_spacing(4)
        info_table.set_column_spacing(20)

        info_table.add(self.create_labeled_info("Threads Connected:", "lbl_Threads_connected"),                     0, 1, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Threads Running:", "lbl_Threads_running"),                          1, 2, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Threads Created:", "lbl_Threads_created"),                         2, 3, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Threads Cached:", "lbl_Threads_cached"),                           3, 4, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Rejected (over limit):", "lbl_Connection_errors_max_connections"), 4, 5, 0, 1, mforms.HFillFlag)

        info_table.add(self.create_labeled_info("Total Connections:", "lbl_Connections"),                           0, 1, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Connection Limit:", "lbl_max_connections"),                        1, 2, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Aborted Clients:", "lbl_Aborted_clients"),                         2, 3, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Aborted Connections:", "lbl_Aborted_connects"),                    3, 4, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Errors:", "lbl_errors", "tooltip_errors"),                         4, 5, 1, 2, mforms.HFillFlag)

        self.info_table = info_table
        self.add(info_table, False, True)

        #self.set_padding(8)
        self.add(self.connection_box, True, True)


        box = newBox(True)
        self.button_box = box
        self.add_end(box, False, True)

        box.set_spacing(12)
        
        refresh_button = newButton()
        refresh_button.set_text("Refresh")
        box.add_end(refresh_button, False, True)
        refresh_button.add_clicked_callback(weakcb(self, "refresh"))

        self.kill_button = newButton()
        self.kill_button.set_text("Kill Connection(s)")
        box.add_end(self.kill_button, False, True)
        self.kill_button.add_clicked_callback(weakcb(self, "kill_connection"))
        
        self.killq_button = newButton()
        self.killq_button.set_text("Kill Query(s)")
        box.add_end(self.killq_button, False, True)
        self.killq_button.add_clicked_callback(weakcb(self, "kill_query"))
        
        refresh_label = newLabel("Refresh Rate:")
        box.add(refresh_label, False, True)

        self._menu = mforms.newContextMenu()
        self._menu.add_will_show_callback(self.menu_will_show)
        self.connection_list.set_context_menu(self._menu)

        
        self.refresh_values = [0.5, 1, 2, 3, 4, 5, 10, 15, 30]
        self.refresh_values_size = len(self.refresh_values)
        
        self.refresh_selector = newSelector()
        self.refresh_selector.set_size(100,-1)
        
        for s in self.refresh_values:
            self.refresh_selector.add_item(str(s) + " seconds")
        
        self.refresh_selector.add_item("Don't Refresh")
        
        refresh_rate_index = grt.root.wb.options.options.get('Administrator:refresh_connections_rate_index', 9)
        self.refresh_selector.set_selected(refresh_rate_index)
        self.update_refresh_rate()
        self.refresh_selector.add_changed_callback(weakcb(self, "update_refresh_rate"))
        box.add(self.refresh_selector, False, True)

        self.check_box = newBox(True)
        self.check_box.set_spacing(12)

        self.hide_sleep_connections = newCheckBox()
        self.hide_sleep_connections.set_text('Hide sleeping connections')
        self.hide_sleep_connections.add_clicked_callback(self.refresh)
        self.hide_sleep_connections.set_tooltip('Remove connections in the Sleeping state from the connection list.')
        self.check_box.add(self.hide_sleep_connections, False, True)

        self.mdl_locks_page = None
        self._showing_extras = False
        if self.new_processlist():
            self.hide_background_threads = newCheckBox()
            self.hide_background_threads.set_active(True)
            self.hide_background_threads.set_text('Hide background threads')
            self.hide_background_threads.set_tooltip('Remove background threads (internal server threads) from the connection list.')
            self.hide_background_threads.add_clicked_callback(self.refresh)
            self.check_box.add(self.hide_background_threads, False, True)
            
            self.truncate_info = newCheckBox()
            self.truncate_info.set_active(True)
            self.truncate_info.set_text('Don\'t load full thread info')
            self.truncate_info.set_tooltip('Toggle whether to load the entire query information for all connections or just the first 255 characters.\nEnabling this can have a large impact in busy servers or server executing large INSERTs.')
            self.truncate_info.add_clicked_callback(self.refresh)
            self.check_box.add(self.truncate_info, False, True)

            # tab with some extra info, only available if PS exists
            self.extra_info_tab = mforms.newTabView(mforms.TabViewSystemStandard)
            self.extra_info_tab.set_size(350, -1)
            self.extra_info_tab.add_tab_changed_callback(self.extra_tab_changed)

            self.connection_details_scrollarea = mforms.newScrollPanel()
            self.connection_details = ConnectionDetailsPanel(self)
            self.connection_details_scrollarea.add(self.connection_details)
            self.details_page = self.extra_info_tab.add_page(self.connection_details_scrollarea, "Details")

            self.mdl_list_box = None
            if self.ctrl_be.target_version.is_supported_mysql_version_at_least(5, 7, 3):
                self.mdl_list_box_scrollarea = mforms.newScrollPanel()
                self.mdl_list_box = mforms.newBox(False)
                self.mdl_list_box_scrollarea.add(self.mdl_list_box)

                self.mdl_label = mforms.newLabel('Metadata locks (MDL) protect concurrent access to\nobject metadata (not table row/data locks)')
                self.mdl_list_box.add(self.mdl_label, False, True)

                label = mforms.newLabel("\nGranted Locks (and threads waiting on them)")
                label.set_style(mforms.BoldStyle)
                self.mdl_list_box.add(label, False, True)
                label = mforms.newLabel("Locks this connection currently owns and\nconnections that are waiting for them.")
                label.set_style(mforms.SmallHelpTextStyle)
                self.mdl_list_box.add(label, False, True)

                self.mdl_list_held = mforms.newTreeNodeView(mforms.TreeAltRowColors)
                self.mdl_list_held.add_column(mforms.IconStringColumnType, "Object", 130, False)
                self.mdl_list_held.add_column(mforms.StringColumnType, "Type", 100, False)
                self.mdl_list_held.add_column(mforms.StringColumnType, "Duration", 100, False)
                self.mdl_list_held.end_columns()
                self.mdl_list_held.set_size(0, 100)
                self.mdl_list_box.add(self.mdl_list_held, True, True)

                label = mforms.newLabel("\nPending Locks")
                label.set_style(mforms.BoldStyle)
                self.mdl_list_box.add(label, False, True)
                hbox = mforms.newBox(True)
                hbox.set_spacing(4)
                self.mdl_blocked_icon = mforms.newImageBox()
                self.mdl_blocked_icon.set_image(mforms.App.get().get_resource_path("message_warning.png"))
                hbox.add(self.mdl_blocked_icon, False, True)
                self.mdl_waiting_label = mforms.newLabel("Locks this connection is currently waiting for.")
                hbox.add(self.mdl_waiting_label, True, True)
                self.mdl_list_box.add(hbox, False, True)
                self.mdl_locks_page = self.extra_info_tab.add_page(self.mdl_list_box_scrollarea, "Locks")

            if self.ctrl_be.target_version.is_supported_mysql_version_at_least(5, 6, 0):
                self.attributes_list = mforms.newTreeNodeView(mforms.TreeFlatList|mforms.TreeAltRowColors)
                self.attributes_list.add_column(mforms.StringColumnType, "Attribute", 150, False)
                self.attributes_list.add_column(mforms.StringColumnType, "Value", 200, False)
                self.attributes_list.end_columns()
                self.attributes_page = self.extra_info_tab.add_page(self.attributes_list, "Attributes")

            self.connection_box.add(self.extra_info_tab, False, True)
            self.extra_info_tab.show(False)

            self.show_extras = newButton()
            self.show_extras.set_text('Show Details')
            self.show_extras.add_clicked_callback(self.toggle_extras)
            self.check_box.add_end(self.show_extras, False, True)

        self.add(self.check_box, False, True)
        
        self.resume_layout()
        
        self.connection_selected()
        
        dprint_ex(4, "Leave")
    def init_ui(self):
        if self._title:
            return

        if self._wait_table:
            self._pbar.stop()
            self._pbar = None
            self.remove(self._wait_table)
            self._wait_table = None

        self._title = mforms.newLabel(to_unicode(self.caption))
        self._title.set_style(mforms.BigBoldStyle)
        self.add(self._title, False, True)

        self._column_file = None

        if self.description:
            self._description = mforms.newLabel(to_unicode(self.description))
            self.add(self._description, False, True)

        self._tree = mforms.newTreeView(mforms.TreeFlatList
                                        | mforms.TreeAltRowColors
                                        | mforms.TreeShowColumnLines)
        self._tree.set_selection_mode(mforms.TreeSelectMultiple)
        self._tree.add_column_resized_callback(self._tree_column_resized)
        c = 0

        self._hmenu = mforms.newContextMenu()
        self._hmenu.add_will_show_callback(self._header_menu_will_show)
        self._tree.set_header_menu(self._hmenu)

        self._column_types = []
        self._column_units = []
        self._column_names = []
        self._column_titles = []
        for i, (column, cname, ctype,
                length) in enumerate(self.get_view_columns()):
            unit = None
            if type(ctype) is tuple:
                ctype, unit = ctype
            unit = grt.root.wb.state.get(
                "wb.admin.psreport:unit:%s:%i" % (self.view, i), unit)

            width = min(max(length, 40), 300)
            width = grt.root.wb.state.get(
                "wb.admin.psreport:width:%s:%i" % (self.view, i), width)

            label = to_unicode(self.column_label(column))
            self._column_units.append(unit)
            self._column_names.append(cname)
            self._column_titles.append(label)
            self._column_types.append(ctype)

            if unit:
                self._tree.add_column(ctype, label + " (%s)" % unit, width,
                                      False)
            else:
                self._tree.add_column(ctype, label, width, False)
            c += 1
        self._tree.end_columns()
        self._tree.set_allow_sorting(True)
        self.add(self._tree, True, True)

        bbox = mforms.newBox(True)
        bbox.set_spacing(12)

        btn = mforms.newButton()
        btn.set_text("Export...")
        btn.add_clicked_callback(self.do_export)
        bbox.add(btn, False, True)

        btn = mforms.newButton()
        btn.set_text("Copy Selected")
        btn.add_clicked_callback(self.do_copy)
        bbox.add(btn, False, True)

        btn = mforms.newButton()
        btn.set_text("Copy Query")
        btn.add_clicked_callback(self.do_copy_query)
        bbox.add(btn, False, True)

        self._refresh = mforms.newButton()
        self._refresh.set_text("Refresh")
        self._refresh.add_clicked_callback(self.do_refresh)
        bbox.add_end(self._refresh, False, True)
        self.add(bbox, False, True)
    def create_ui(self):
        dprint_ex(4, "Enter")
        self.suspend_layout()

        self.create_basic_ui("title_connections.png", "Client Connections")

        if self.new_processlist():
            widths = grt.root.wb.state.get("wb.admin:ConnectionListColumnWidthsPS", None)
        else:
            widths = grt.root.wb.state.get("wb.admin:ConnectionListColumnWidths", None)
        if widths:
            column_widths = [int(i) for i in widths.split(",")]
        else:
            column_widths = None

        self.connection_box = mforms.newBox(True)
        self.connection_box.set_spacing(8)
        self.connection_list = newTreeNodeView(mforms.TreeDefault|mforms.TreeFlatList|mforms.TreeAltRowColors)
        self.connection_list.set_selection_mode(mforms.TreeSelectMultiple)
        self.connection_list.add_column_resized_callback(self.column_resized)
        for i, (field, type, caption, width) in enumerate(self.columns):
            if column_widths and i < len(column_widths):
                width = column_widths[i]
            self.connection_list.add_column(type, caption, width, False)

        self.connection_list.end_columns()
        self.connection_list.set_allow_sorting(True)
        
        self.connection_list.add_changed_callback(weakcb(self, "connection_selected"))

        self.connection_box.add(self.connection_list, True, True)

        info_table = mforms.newTable()
        info_table.set_row_count(2)
        info_table.set_column_count(5)
        info_table.set_row_spacing(4)
        info_table.set_column_spacing(20)

        info_table.add(self.create_labeled_info("Threads Connected:", "lbl_Threads_connected"),                     0, 1, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Threads Running:", "lbl_Threads_running"),                          1, 2, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Threads Created:", "lbl_Threads_created"),                         2, 3, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Threads Cached:", "lbl_Threads_cached"),                           3, 4, 0, 1, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Rejected (over limit):", "lbl_Connection_errors_max_connections"), 4, 5, 0, 1, mforms.HFillFlag)

        info_table.add(self.create_labeled_info("Total Connections:", "lbl_Connections"),                           0, 1, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Connection Limit:", "lbl_max_connections"),                        1, 2, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Aborted Clients:", "lbl_Aborted_clients"),                         2, 3, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Aborted Connections:", "lbl_Aborted_connects"),                    3, 4, 1, 2, mforms.HFillFlag)
        info_table.add(self.create_labeled_info("Errors:", "lbl_errors", "tooltip_errors"),                         4, 5, 1, 2, mforms.HFillFlag)

        self.info_table = info_table
        self.add(info_table, False, True)

        #self.set_padding(8)
        self.add(self.connection_box, True, True)


        box = newBox(True)
        self.button_box = box
        self.add_end(box, False, True)

        box.set_spacing(12)
        
        refresh_button = newButton()
        refresh_button.set_text("Refresh")
        box.add_end(refresh_button, False, True)
        refresh_button.add_clicked_callback(weakcb(self, "refresh"))

        self.kill_button = newButton()
        self.kill_button.set_text("Kill Connection(s)")
        box.add_end(self.kill_button, False, True)
        self.kill_button.add_clicked_callback(weakcb(self, "kill_connection"))
        
        self.killq_button = newButton()
        self.killq_button.set_text("Kill Query(s)")
        box.add_end(self.killq_button, False, True)
        self.killq_button.add_clicked_callback(weakcb(self, "kill_query"))
        
        refresh_label = newLabel("Refresh Rate:")
        box.add(refresh_label, False, True)

        self._menu = mforms.newContextMenu()
        self._menu.add_will_show_callback(self.menu_will_show)
        self.connection_list.set_context_menu(self._menu)

        
        self.refresh_values = [0.5, 1, 2, 3, 4, 5, 10, 15, 30]
        self.refresh_values_size = len(self.refresh_values)
        
        self.refresh_selector = newSelector()
        self.refresh_selector.set_size(100,-1)
        
        for s in self.refresh_values:
            self.refresh_selector.add_item(str(s) + " seconds")
        
        self.refresh_selector.add_item("Don't Refresh")
        
        refresh_rate_index = grt.root.wb.options.options.get('Administrator:refresh_connections_rate_index', 9)
        self.refresh_selector.set_selected(refresh_rate_index)
        self.update_refresh_rate()
        self.refresh_selector.add_changed_callback(weakcb(self, "update_refresh_rate"))
        box.add(self.refresh_selector, False, True)

        self.check_box = newBox(True)
        self.check_box.set_spacing(12)

        self.hide_sleep_connections = newCheckBox()
        self.hide_sleep_connections.set_text('Hide sleeping connections')
        self.hide_sleep_connections.add_clicked_callback(self.refresh)
        self.hide_sleep_connections.set_tooltip('Remove connections in the Sleeping state from the connection list.')
        self.check_box.add(self.hide_sleep_connections, False, True)

        self.mdl_locks_page = None
        self._showing_extras = False
        if self.new_processlist():
            self.hide_background_threads = newCheckBox()
            self.hide_background_threads.set_active(True)
            self.hide_background_threads.set_text('Hide background threads')
            self.hide_background_threads.set_tooltip('Remove background threads (internal server threads) from the connection list.')
            self.hide_background_threads.add_clicked_callback(self.refresh)
            self.check_box.add(self.hide_background_threads, False, True)
            
            self.truncate_info = newCheckBox()
            self.truncate_info.set_active(True)
            self.truncate_info.set_text('Don\'t load full thread info')
            self.truncate_info.set_tooltip('Toggle whether to load the entire query information for all connections or just the first 255 characters.\nEnabling this can have a large impact in busy servers or server executing large INSERTs.')
            self.truncate_info.add_clicked_callback(self.refresh)
            self.check_box.add(self.truncate_info, False, True)

            # tab with some extra info, only available if PS exists
            self.extra_info_tab = mforms.newTabView(mforms.TabViewSystemStandard)
            self.extra_info_tab.set_size(350, -1)
            self.extra_info_tab.add_tab_changed_callback(self.extra_tab_changed)

            self.connection_details_scrollarea = mforms.newScrollPanel()
            self.connection_details = ConnectionDetailsPanel(self)
            self.connection_details_scrollarea.add(self.connection_details)
            self.details_page = self.extra_info_tab.add_page(self.connection_details_scrollarea, "Details")

            self.mdl_list_box = None
            if self.ctrl_be.target_version.is_supported_mysql_version_at_least(5, 7, 3):
                self.mdl_list_box_scrollarea = mforms.newScrollPanel()
                self.mdl_list_box = mforms.newBox(False)
                self.mdl_list_box_scrollarea.add(self.mdl_list_box)

                self.mdl_label = mforms.newLabel('Metadata locks (MDL) protect concurrent access to\nobject metadata (not table row/data locks)')
                self.mdl_list_box.add(self.mdl_label, False, True)

                label = mforms.newLabel("\nGranted Locks (and threads waiting on them)")
                label.set_style(mforms.BoldStyle)
                self.mdl_list_box.add(label, False, True)
                label = mforms.newLabel("Locks this connection currently owns and\nconnections that are waiting for them.")
                label.set_style(mforms.SmallHelpTextStyle)
                self.mdl_list_box.add(label, False, True)

                self.mdl_list_held = mforms.newTreeNodeView(mforms.TreeAltRowColors)
                self.mdl_list_held.add_column(mforms.IconStringColumnType, "Object", 130, False)
                self.mdl_list_held.add_column(mforms.StringColumnType, "Type", 100, False)
                self.mdl_list_held.add_column(mforms.StringColumnType, "Duration", 100, False)
                self.mdl_list_held.end_columns()
                self.mdl_list_held.set_size(0, 100)
                self.mdl_list_box.add(self.mdl_list_held, True, True)

                label = mforms.newLabel("\nPending Locks")
                label.set_style(mforms.BoldStyle)
                self.mdl_list_box.add(label, False, True)
                hbox = mforms.newBox(True)
                hbox.set_spacing(4)
                self.mdl_blocked_icon = mforms.newImageBox()
                self.mdl_blocked_icon.set_image(mforms.App.get().get_resource_path("message_warning.png"))
                hbox.add(self.mdl_blocked_icon, False, True)
                self.mdl_waiting_label = mforms.newLabel("Locks this connection is currently waiting for.")
                hbox.add(self.mdl_waiting_label, True, True)
                self.mdl_list_box.add(hbox, False, True)
                self.mdl_locks_page = self.extra_info_tab.add_page(self.mdl_list_box_scrollarea, "Locks")

            if self.ctrl_be.target_version.is_supported_mysql_version_at_least(5, 6, 0):
                self.attributes_list = mforms.newTreeNodeView(mforms.TreeFlatList|mforms.TreeAltRowColors)
                self.attributes_list.add_column(mforms.StringColumnType, "Attribute", 150, False)
                self.attributes_list.add_column(mforms.StringColumnType, "Value", 200, False)
                self.attributes_list.end_columns()
                self.attributes_page = self.extra_info_tab.add_page(self.attributes_list, "Attributes")

            self.connection_box.add(self.extra_info_tab, False, True)
            self.extra_info_tab.show(False)

            self.show_extras = newButton()
            self.show_extras.set_text('Show Details')
            self.show_extras.add_clicked_callback(self.toggle_extras)
            self.check_box.add_end(self.show_extras, False, True)

        self.add(self.check_box, False, True)
        
        self.resume_layout()
        
        self.connection_selected()
        
        dprint_ex(4, "Leave")