Пример #1
0
class MultipleTextEntry(Dialog):
    def __init__(self, parent, title, values):
        Dialog.__init__(self,
                        parent,
                        title=title,
                        style=DEFAULT_DIALOG_STYLE | RESIZE_BORDER)
        self.values = None

        sizer = GridBagSizer(5, 5)
        row = 0
        self.labels = []
        self.txt_ctrls = []
        for value in values:
            label = StaticText(self, label=value)
            self.labels.append(label)
            sizer.Add(label, pos=(row, 0), flag=ALIGN_RIGHT)

            txtctrl = TextCtrl(self)
            self.txt_ctrls.append(txtctrl)
            sizer.Add(txtctrl, pos=(row, 1), flag=FLAG_ALL_AND_EXPAND)
            row += 1

        self.btn_cancel = Button(self, label=u'Cancel')
        self.btn_cancel.Bind(EVT_BUTTON, self.__on_btn)
        sizer.Add(self.btn_cancel, pos=(row, 0), flag=FLAG_ALL_AND_EXPAND)

        self.btn_ok = Button(self, label=u'OK')
        self.btn_ok.Bind(EVT_BUTTON, self.__on_btn)
        sizer.Add(self.btn_ok, pos=(row, 1), flag=FLAG_ALL_AND_EXPAND)

        sizer.AddGrowableCol(1)
        self.SetSizerAndFit(sizer)
        self.SetSize(400, self.GetSizeTuple()[1])

    def __on_btn(self, evt):
        errors = []
        obj = evt.GetEventObject()
        if obj == self.btn_ok:
            self.values = {}
            for txt_ctrl in self.txt_ctrls:
                label_ctrl = self.labels[self.txt_ctrls.index(txt_ctrl)]
                label = label_ctrl.GetLabel()
                value = txt_ctrl.GetValue()
                self.values[label] = value
                if len(value) == 0:
                    errors.append(u"Variable '%s' has empty value '%s'" %
                                  (label, value))

            return_code = ID_OK
        else:
            self.values = None
            return_code = ID_CANCEL

        if len(errors) > 0:
            show_dialog(self, LINESEP.join(errors), 'Bad entered data')
        else:
            self.EndModal(return_code)
Пример #2
0
    def __init__(self, ch: int, channel_label: wx.StaticText,
                 waveform_choice: wx.Choice, trigger_choice: wx.Choice,
                 continuous_toggle: wx.ToggleButton, trigger_button: wx.Button,
                 stop_button: wx.Button, trigger_out_check: wx.CheckBox,
                 status_text: wx.TextCtrl, mf):
        self.ch = ch
        self.mf = mf
        self.channel_label = channel_label
        self.channel_name = channel_label.GetLabel()
        self.waveform_choice = waveform_choice
        self.waveform_choice.Bind(wx.EVT_CHOICE, self.on_waveform_choice)
        self.trigger_choice = trigger_choice
        self.trigger_choice.Bind(wx.EVT_CHOICE, self.on_trigger_source)
        self.continuous_toggle = continuous_toggle
        self.continuous_toggle.Bind(wx.EVT_TOGGLEBUTTON, self.on_toggle)
        self.trigger_button = trigger_button
        trigger_button.Bind(wx.EVT_BUTTON,
                            lambda _: mf.device.trigger_channel(ch))
        self.stop_button = stop_button
        self.stop_button.Bind(
            wx.EVT_BUTTON, lambda evt: mf.device.set_enable(
                ch,
                stop_button.GetLabel() == 'Enable'))
        self.trigger_out_check = trigger_out_check
        self.status_text = status_text

        self.waveform = 'Waveform 1'
        self.trigger = 0
        self.continuous = 0
        self._enabled = False
        self.output = False
        self.warnings = []
        self.modified = False
Пример #3
0
def button(element, instance: wx.Button):
    props = element['props']
    set_basic_props(instance, props)
    instance.Unbind(wx.EVT_BUTTON)
    if props.get('on_click'):
        instance.Bind(wx.EVT_BUTTON, props['on_click'])
    return instance
Пример #4
0
    def __init__(self,
                 message: str,
                 label: str = None,
                 url: str = None,
                 **kwargs) -> None:
        super(HyperlinkDialog, self).__init__(parent=None, **kwargs)
        pane = self.GetContentsPane()

        text_ctrl = StaticText(pane, label=message)
        text_ctrl.SetFocus()
        text_ctrl.SetSizerProps(align="center")

        if url is not None:
            if label is None:
                label = url
            hyperlink = HyperlinkCtrl(pane, label=label, url=url)
            hyperlink.Bind(EVT_HYPERLINK, self.on_hyperlink)

        button_ok = Button(pane, label="OK")
        button_ok.Bind(EVT_BUTTON, self.on_ok)
        button_ok.SetSizerProps(align="center", border=(["top"], 10))

        self.SetIcon(
            Icon(ArtProvider.GetBitmap(ART_INFORMATION, ART_MESSAGE_BOX)))
        self.Fit()
        self.Centre()
Пример #5
0
class DialogWithText(Dialog):
    def __init__(self, parent, title, text=None):
        Dialog.__init__(self,
                        parent,
                        title=title,
                        style=DEFAULT_DIALOG_STYLE | RESIZE_BORDER)
        self.SetTitle(title)
        self.SetSize(600, 400)

        sizer = BoxSizer(VERTICAL)

        self.txt_ctrl = TextCtrl(self,
                                 style=TE_MULTILINE | TE_READONLY | HSCROLL)
        if text:
            self.txt_ctrl.SetValue(text)
        sizer.Add(self.txt_ctrl, 1, flag=FLAG_ALL_AND_EXPAND)

        self.btn_ok = Button(self, label=u'OK')
        self.btn_ok.Bind(EVT_BUTTON, self.__close)
        sizer.Add(self.btn_ok, flag=CENTER)

        self.SetSizer(sizer)

    def __close(self, evt):
        self.EndModal(ID_OK)
        self.Hide()
Пример #6
0
    def __init__(self, parent, id, title):
        # zavolání konstruktoru předka (kompatibilní s Pythonem 2.x)
        super(MainFrame, self).__init__(parent, id, title, size=(320, 240))

        # vytvoření panelu
        panel = Panel(self, ID_ANY)

        # vytvoření tlačítka s jeho vložením do panelu
        x = y = 20
        button = Button(panel, ID_ANY, "Press me", (x, y))
        button.Bind(EVT_BUTTON, onButtonPress)

        # zobrazení hlavního okna aplikace
        self.Show(True)
Пример #7
0
class FieldsTableAndTestFilesTabs(Panel):
    TAB_INDEX_FOR_TABLE = 0
    TAB_INDEX_FOR_PO_CLASS_FILE = 1

    def __init__(self, parent, editor_tab):
        Panel.__init__(self, parent)

        self.__editor_tab = editor_tab
        self.__cur_po_class = None

        sizer = GridBagSizer(5, 5)
        full_span = (1, 4)

        row = 0
        inner_sizer = BoxSizer(HORIZONTAL)
        self.btn_open_test_file = Button(self, label=u'Open test file')
        self.btn_open_test_file.Bind(EVT_BUTTON, self.__on_open_test_file)
        inner_sizer.Add(self.btn_open_test_file)

        self.btn_create_test_file = Button(self, label=u'Create test file')
        self.btn_create_test_file.Bind(EVT_BUTTON, self.__on_create_test_file)
        inner_sizer.Add(self.btn_create_test_file)

        self.btn_save_test_file = Button(self, label=u'Save current file')
        self.btn_save_test_file.Bind(EVT_BUTTON, self.__on_save_test_file)
        inner_sizer.Add(self.btn_save_test_file)

        inner_sizer.AddStretchSpacer(1)

        self.btn_create_test = Button(self,
                                      label=u'Create new method/test case')
        self.btn_create_test.Bind(EVT_BUTTON, self.__create_method_or_test)
        inner_sizer.Add(self.btn_create_test)
        sizer.Add(inner_sizer,
                  pos=(row, 0),
                  span=full_span,
                  flag=FLAG_ALL_AND_EXPAND)

        row += 1
        self.tabs = Tabs(self, [(Table, "Fields' table")])
        self.table = self.tabs.GetPage(0)
        self.table.Bind(EVT_GRID_SELECT_CELL, self.__on_cell_click)
        self.table.Bind(EVT_GRID_CELL_RIGHT_CLICK, self.__on_cell_click)

        sizer.Add(self.tabs,
                  pos=(row, 0),
                  span=full_span,
                  flag=FLAG_ALL_AND_EXPAND)

        sizer.AddGrowableCol(1, 1)
        sizer.AddGrowableRow(1, 1)
        self.SetSizer(sizer)

    def load_po_class(self, po_class):
        self.__cur_po_class = po_class
        self.__set_pageobject_class(self.__cur_po_class)

        file_name = os.path.basename(self.__cur_po_class.file_path)

        more_than_1_tab = self.tabs.GetPageCount() > 1
        if more_than_1_tab:
            py_file_ui = self.tabs.GetPage(self.TAB_INDEX_FOR_PO_CLASS_FILE)
            py_file_ui.load_file(self.__cur_po_class.file_path)
        else:
            py_file_ui = PyFileUI(self.tabs, self.__cur_po_class.file_path,
                                  True)
            self.tabs.AddPage(py_file_ui,
                              os.path.basename(self.__cur_po_class.file_path))

        if not more_than_1_tab and self.tabs.GetSelection(
        ) != self.TAB_INDEX_FOR_PO_CLASS_FILE:
            self.tabs.SetSelection(self.TAB_INDEX_FOR_PO_CLASS_FILE)

        self.tabs.set_tabs_text(file_name, self.TAB_INDEX_FOR_PO_CLASS_FILE)

    def get_current_po_class(self):
        return self.__cur_po_class

    def clear_table(self):
        self.table.ClearGrid()

    def get_current_pageobject_class(self):
        return self.__cur_po_class

    def __set_pageobject_class(self, po_class):
        self.__cur_po_class = po_class
        self.table.load_data(po_class.fields)

    def __create_method_or_test(self, evt):
        count = self.tabs.GetPageCount()
        if count > 1:
            page = self.tabs.GetPage(self.tabs.GetSelection())
            if type(page) == PyFileUI:
                self.__create_method(page)
            elif type(page) == TestFileUI:
                self.__create_test(page)
            else:
                show_dialog(
                    self, u'Selected tab is not supported' + LINESEP +
                    u'Please selected test file or page object class',
                    'Bad selected tab')
        else:
            show_dialog(
                self, u'Test file was not created.' + LINESEP +
                'Please create a test file.', u'Test file was not created')

    def __create_method(self, page):
        modal = TextEntryDialog(self, u'Enter method name', u'Create method')
        if modal.ShowModal() == ID_OK:
            method_name = modal.GetValue()
            if StringUtils.is_method_name_correct(method_name):
                page.create_method(method_name)
            else:
                show_dialog_bad_name(self, method_name, 'search', 'login',
                                     'fill_data')

    def __create_test(self, page):
        modal = TextEntryDialog(self, u'Enter test case name',
                                u'Create new test case')
        if modal.ShowModal() == ID_OK:
            test_case_name = modal.GetValue()
            if StringUtils.is_test_case_name_correct(test_case_name):
                page.create_new_test_case(test_case_name)
            else:
                show_dialog_bad_name(self, test_case_name, 'test_search')

    def __on_save_test_file(self, evt):
        count = self.tabs.GetPageCount()
        if count > 1:
            page = self.tabs.GetPage(self.tabs.GetSelection())
            page.save_file()
        else:
            show_dialog(self, u'Please create/open test file.',
                        u'Nothing to save')

    def __open_or_create_test_file(self, style):
        if self.__cur_po_class:
            folder = self.GetTopLevelParent().get_root_folder()
            if not folder:
                folder = os.path.dirname(self.__cur_po_class.file_path)
            elif RootFolder.TESTS_FOLDER in os.listdir(folder):
                folder = os.path.join(folder, RootFolder.TESTS_FOLDER)

            dialog = FileDialog(self,
                                defaultDir=folder,
                                style=style,
                                wildcard='*.py')
            if dialog.ShowModal() == ID_OK:
                test_file = dialog.GetPath()
                load_file = style == FD_OPEN

                filename = os.path.basename(test_file)
                if StringUtils.is_test_file_name_correct(test_file):
                    test_file_ui = TestFileUI(self.tabs, test_file,
                                              self.__cur_po_class, load_file)
                    self.tabs.AddPage(test_file_ui, filename)
                    self.tabs.SetSelection(self.tabs.GetPageCount() - 1)

                    if style == FD_SAVE:
                        test_file_ui.set_file_was_changed()
                else:
                    show_dialog_bad_name(self, filename, 'my_first_test.py')
        else:
            show_dialog(self, u'Please select class file.',
                        u'Class file was not opened')

    def __on_open_test_file(self, evt):
        self.__open_or_create_test_file(FD_OPEN)

    def __on_create_test_file(self, evt):
        self.__open_or_create_test_file(FD_SAVE)

    def __on_cell_click(self, evt):
        self.table.selected_row = evt.GetRow()
        field = self.table.get_selected_data()
        if field:
            self.__editor_tab.image_panel.draw_selected_field(field, True)
            if evt.GetEventType(
            ) == EVT_GRID_CELL_RIGHT_CLICK.typeId and field:
                self.__editor_tab.show_content_menu()
        evt.Skip()
Пример #8
0
class EditDialog(Dialog):
    __hosts = None
    __window = None

    def __init__(self, parent, dpi=(1, 1)):
        Dialog.__init__(self,
                        parent,
                        id=ID_ANY,
                        title=u"编辑/添加Hosts",
                        pos=Point(600, 600),
                        size=Size(394 * dpi[0], 210 * dpi[1]),
                        style=DEFAULT_DIALOG_STYLE | FRAME_FLOAT_ON_PARENT)
        self.__window = parent
        self.SetSizeHints(DefaultSize, DefaultSize)

        font = Font(10, FONTFAMILY_DEFAULT, FONTSTYLE_NORMAL,
                    FONTWEIGHT_NORMAL, False, EmptyString)
        inputSize = Size(260 * dpi[0], -1)
        self.SetFont(font)
        fgSizer3 = FlexGridSizer(0, 2, 0, 0)
        fgSizer3.SetFlexibleDirection(BOTH)
        fgSizer3.SetNonFlexibleGrowMode(FLEX_GROWMODE_SPECIFIED)

        self.localRadio = RadioButton(self, ID_ANY, u"本地Hosts",
                                      DefaultPosition, DefaultSize, 0)
        self.localRadio.SetFont(font)
        fgSizer3.Add(self.localRadio, 0, ALL, 5)
        self.localRadio.Bind(EVT_RADIOBUTTON, self.OnRadioChange)

        self.onlineRadio = RadioButton(self, ID_ANY, u"在线Hosts",
                                       DefaultPosition, DefaultSize, 0)
        fgSizer3.Add(self.onlineRadio, 0, ALL, 5)
        self.onlineRadio.Bind(EVT_RADIOBUTTON, self.OnRadioChange)

        self.m_staticText4 = StaticText(self, ID_ANY, u"名称", DefaultPosition,
                                        DefaultSize, 0)
        self.m_staticText4.Wrap(-1)

        fgSizer3.Add(self.m_staticText4, 0, ALL, 5)

        self.nameInput = TextCtrl(self, ID_ANY, EmptyString, DefaultPosition,
                                  inputSize, 0)
        fgSizer3.Add(self.nameInput, 0, ALL, 5)

        self.m_staticText5 = StaticText(self, ID_ANY, u"地址", DefaultPosition,
                                        DefaultSize, 0)
        self.m_staticText5.Wrap(-1)

        fgSizer3.Add(self.m_staticText5, 0, ALL, 5)

        self.urlInput = TextCtrl(self, ID_ANY, u"http://", DefaultPosition,
                                 inputSize, 0)
        fgSizer3.Add(self.urlInput, 0, ALL, 5)

        self.m_staticText3 = StaticText(self, ID_ANY, u"图标", DefaultPosition,
                                        DefaultSize, 0)
        self.m_staticText3.Wrap(-1)

        fgSizer3.Add(self.m_staticText3, 0, ALL, 5)

        self.iconComboBox = ComboBox(self, ID_ANY, u"请选择图标", DefaultPosition,
                                     inputSize, list(GetIcons().keys()), 0)
        self.iconComboBox.SetFont(font)
        fgSizer3.Add(self.iconComboBox, 0, ALL, 5)

        self.cancelButton = Button(self, ID_ANY, u"取消", DefaultPosition,
                                   DefaultSize, 0)
        fgSizer3.Add(self.cancelButton, 0, ALL, 5)

        self.saveButton = Button(self, ID_ANY, u"保存", DefaultPosition,
                                 DefaultSize, 0)
        fgSizer3.Add(self.saveButton, 0, ALL, 5)

        self.SetSizer(fgSizer3)
        self.Layout()

        self.Centre(BOTH)

        self.cancelButton.Bind(EVT_BUTTON, self.OnButtonClicked)
        self.saveButton.Bind(EVT_BUTTON, self.OnButtonClicked)
        self.Bind(EVT_CLOSE, self.OnClose)

    def __del__(self):
        pass

    def OnClose(self, event):
        self.SetHosts(None)
        event.Skip()

    def SetHosts(self, hosts):
        self.__hosts = hosts
        if hosts:
            if hosts["url"] and len(hosts["url"] > 0):
                self.onlineRadio.SetValue(hosts["url"])
            self.localRadio.SetValue(not hosts["url"])
            self.nameInput.SetValue(hosts["name"])
            self.urlInput.SetValue(hosts["url"] or "")
            self.iconComboBox.SetValue(hosts["icon"])
            self.onlineRadio.Enable(False)
            self.localRadio.Enable(False)
        else:
            self.onlineRadio.Enable(False)
            self.localRadio.Enable(True)
            self.localRadio.SetValue(True)
            self.urlInput.SetValue("")
            self.iconComboBox.SetValue("logo")
            self.nameInput.SetValue("")

    def OnButtonClicked(self, event):
        if event.GetId() == self.cancelButton.GetId():
            self.Close()
            return
        name = self.nameInput.GetValue()
        url = self.urlInput.GetValue()
        isOnline = self.onlineRadio.GetValue()
        if not isOnline:
            url = None
        if not name or len(name) < 1:
            MessageBox("请输入Hosts名称", "提示", ICON_WARNING)
        elif isOnline and (not url or len(url) < 1):
            MessageBox("请输入在线Hosts地址", "提示", ICON_WARNING)
        else:
            if not self.iconComboBox.GetValue():
                self.iconComboBox.SetValue("logo")
            if self.__hosts:
                self.__hosts["name"] = name
                self.__hosts["url"] = url
                self.__hosts["lastUpdateTime"] = Now()
                self.__hosts["icon"] = self.iconComboBox.GetValue()
                hostsId = self.__hosts['id']
            else:
                hostsId = 0x1994 + len(Settings.settings["hosts"])
                Settings.settings["hosts"].append(
                    hostsDict(hostsId,
                              name,
                              url=url,
                              lastUpdateTime=Now(),
                              content="# Created by mHosts v%s, %s\n" %
                              (Settings.version(), Now()),
                              icon=self.iconComboBox.GetValue()))
            Settings.Save()
            self.__window.InitHostsTree(select=hostsId)
            self.Close()

    def OnRadioChange(self, event):
        self.urlInput.Enable(event.GetId() == self.onlineRadio.GetId())
Пример #9
0
class TestRunnerTab(Panel):
    def __init__(self, *args, **kwargs):
        Panel.__init__(self, *args, **kwargs)
        sizer = GridBagSizer(5, 5)

        row = 0
        col = 0
        self.cb_html_output = CheckBox(self, label=u'Report in HTML')
        self.cb_html_output.Bind(EVT_CHECKBOX, self.__on_check)
        sizer.Add(self.cb_html_output,
                  pos=(row, col),
                  flag=FLAG_ALL_AND_EXPAND)

        col += 1
        self.txt_html_report = TextCtrl(self, style=TE_READONLY)
        self.txt_html_report.Disable()
        sizer.Add(self.txt_html_report,
                  pos=(row, col),
                  span=(1, 3),
                  flag=FLAG_ALL_AND_EXPAND)

        col += 3
        self.btn_select_html = Button(self, label=u'Select HTML file')
        self.btn_select_html.Disable()
        self.btn_select_html.Bind(EVT_BUTTON, self.__on_select_file)
        sizer.Add(self.btn_select_html,
                  pos=(row, col),
                  flag=FLAG_ALL_AND_EXPAND)

        row += 1
        col = 0
        self.cb_xml_output = CheckBox(self, label=u'Report in XML')
        self.cb_xml_output.Bind(EVT_CHECKBOX, self.__on_check)
        sizer.Add(self.cb_xml_output, pos=(row, col), flag=FLAG_ALL_AND_EXPAND)

        col += 1
        self.txt_xml_report = TextCtrl(self, style=TE_READONLY)
        self.txt_xml_report.Disable()
        sizer.Add(self.txt_xml_report,
                  pos=(row, col),
                  span=(1, 3),
                  flag=FLAG_ALL_AND_EXPAND)

        col += 3
        self.btn_select_xml = Button(self, label=u'Select XML file')
        self.btn_select_xml.Disable()
        self.btn_select_xml.Bind(EVT_BUTTON, self.__on_select_file)
        sizer.Add(self.btn_select_xml,
                  pos=(row, col),
                  flag=FLAG_ALL_AND_EXPAND)

        row += 1
        col = 0
        self.cb_options = CheckBox(self, label=u'Additional options')
        self.cb_options.Bind(EVT_CHECKBOX, self.__on_check)
        sizer.Add(self.cb_options, pos=(row, col), flag=FLAG_ALL_AND_EXPAND)

        col += 1
        self.txt_options = TextCtrl(self)
        self.txt_options.Disable()
        sizer.Add(self.txt_options,
                  pos=(row, col),
                  span=(1, 3),
                  flag=FLAG_ALL_AND_EXPAND)

        col += 3
        self.btn_nose_help = Button(self, label=u'Show help')
        self.btn_nose_help.Bind(EVT_BUTTON, self.__on_show_help)
        sizer.Add(self.btn_nose_help, pos=(row, col), flag=FLAG_ALL_AND_EXPAND)

        row += 1
        col = 0
        self.btn_load_tests_from_files = Button(self,
                                                label=u'Load tests from files')
        self.btn_load_tests_from_files.Bind(EVT_BUTTON,
                                            self.__load_tests_from_files)
        sizer.Add(self.btn_load_tests_from_files,
                  pos=(row, col),
                  flag=FLAG_ALL_AND_EXPAND)

        col += 1
        self.btn_load_tests_from_dir = Button(
            self, label=u'Load tests from directory')
        self.btn_load_tests_from_dir.Bind(EVT_BUTTON,
                                          self.__load_tests_from_directory)
        sizer.Add(self.btn_load_tests_from_dir,
                  pos=(row, col),
                  flag=FLAG_ALL_AND_EXPAND)

        col += 1
        dummy_label = StaticText(self)
        sizer.Add(dummy_label, pos=(row, col), flag=FLAG_ALL_AND_EXPAND)

        col += 1
        self.cb_browser = Choice(self,
                                 choices=Browser.get_supported_browsers())
        self.cb_browser.Select(0)
        sizer.Add(self.cb_browser, pos=(row, col), flag=FLAG_ALL_AND_EXPAND)

        col += 1
        self.btn_run = Button(self, label=u'Run test cases')
        self.btn_run.Bind(EVT_BUTTON, self.__run_tests)
        sizer.Add(self.btn_run, pos=(row, col), flag=FLAG_ALL_AND_EXPAND)

        row += 1
        col = 0
        window = SplitterWindow(self, style=SP_3D | SP_LIVE_UPDATE)
        self.tree_ctrl = CustomTreeCtrl(
            window,
            style=TR_SINGLE | TR_HAS_BUTTONS | TR_AUTO_CHECK_CHILD
            | TR_AUTO_CHECK_PARENT | TR_AUTO_TOGGLE_CHILD)
        self.tree_ctrl.SetBackgroundColour(self.GetBackgroundColour())
        self.tree_ctrl.SetForegroundColour(self.GetForegroundColour())
        self.tree_ctrl.Bind(EVT_TREE_ITEM_CHECKED, self.__on_tree_check)

        self.txt_ctrl = TextCtrl(window,
                                 style=TE_MULTILINE | TE_READONLY | HSCROLL
                                 | VSCROLL)
        font_size = self.txt_ctrl.GetFont().GetPointSize()
        self.txt_ctrl.SetFont(
            Font(font_size, FONTFAMILY_TELETYPE, NORMAL, NORMAL))

        window.SplitVertically(self.tree_ctrl, self.txt_ctrl)
        sizer.Add(window,
                  pos=(row, col),
                  span=(1, 5),
                  flag=FLAG_ALL_AND_EXPAND)

        sizer.AddGrowableCol(2, 1)
        sizer.AddGrowableRow(row, 1)
        self.SetSizerAndFit(sizer)

    def __on_show_help(self, evt):
        text = check_output(['nosetests', '--help'])
        DialogWithText(self, u'Help for nosetests', text).ShowModal()

    def __on_select_file(self, evt):
        folder = self.__get_safe_path_from_root_folder(RootFolder.REPORTS)
        obj = evt.GetEventObject()
        txt_ctrl = None
        if obj == self.btn_select_html:
            wildcard = u'*.html'
            txt_ctrl = self.txt_html_report
        elif obj == self.btn_select_xml:
            wildcard = u'*.xml'
            txt_ctrl = self.txt_xml_report
        else:
            wildcard = u'*.*'
        dialog = FileDialog(self,
                            defaultDir=folder,
                            style=FD_SAVE | FD_OVERWRITE_PROMPT,
                            wildcard=wildcard)
        if dialog.ShowModal() == ID_OK and txt_ctrl:
            txt_ctrl.SetValue(dialog.GetPath())

    def __on_check(self, evt):
        cb_obj = evt.GetEventObject()
        checkboxes_and_txt_ctrls = {
            self.cb_html_output: self.txt_html_report,
            self.cb_options: self.txt_options,
            self.cb_xml_output: self.txt_xml_report
        }
        checkboxes_and_btns = {
            self.cb_html_output: self.btn_select_html,
            self.cb_xml_output: self.btn_select_xml
        }
        txt_ctrl = checkboxes_and_txt_ctrls[cb_obj]
        btn = checkboxes_and_btns.get(cb_obj)
        if txt_ctrl.IsEnabled():
            txt_ctrl.Disable()
            if btn:
                btn.Disable()
        else:
            txt_ctrl.Enable()
            if btn:
                btn.Enable()

    def __on_tree_check(self, evt):
        # styles doesn't work: TR_AUTO_CHECK_CHILD | TR_AUTO_CHECK_PARENT | TR_AUTO_TOGGLE_CHILD
        # TODO: fix if all children are check then one child is uncheck - parent is checked
        item = evt.GetItem()
        checked = item.IsChecked()
        parent = item.GetParent()

        def all_children_are_checked(_parent):
            states = [child.IsChecked() for child in _parent.GetChildren()]
            uniq_states = list(set(states))
            return len(uniq_states) == 1 and uniq_states[0] is True

        self.tree_ctrl.AutoCheckChild(item, checked)
        if parent:
            self.tree_ctrl.AutoCheckParent(item,
                                           all_children_are_checked(parent))

    def __get_safe_path_from_root_folder(self, subfolder=None):
        folder = self.GetTopLevelParent().get_root_folder()
        if subfolder and folder:
            path_for_subfolder = os.path.join(folder, subfolder)
            if os.path.exists(path_for_subfolder):
                return path_for_subfolder

        return folder if folder else '.'

    def __load_tests_to_tree(self, file_paths=None, dir_path=None):
        if file_paths:
            python_files = file_paths
        elif dir_path:
            python_files = [f for f in get_list_of_files(dir_path, True)]
        else:
            python_files = []

        python_files = [
            f for f in python_files if 'test' in os.path.basename(f)
            and os.path.splitext(f)[-1] == '.py'
        ]
        if len(python_files) > 0:
            syspath = list(os.sys.path)
            try:
                root_folder = self.__get_safe_path_from_root_folder()

                if root_folder not in os.sys.path:
                    os.sys.path.append(root_folder)

                checkbox_type = 1
                self.tree_ctrl.DeleteAllItems()
                root = self.tree_ctrl.AddRoot('All test cases', checkbox_type)

                for python_file in python_files:
                    top_item = self.tree_ctrl.AppendItem(
                        root, os.path.abspath(python_file), checkbox_type)

                    parsed_classes = ParsedClass.get_parsed_classes(
                        python_file)
                    for parsed_class in parsed_classes:
                        item = self.tree_ctrl.AppendItem(
                            top_item, parsed_class.name, checkbox_type)

                        test_methods = [
                            k for k in parsed_class.methods.keys()
                            if k.startswith('test_')
                        ]
                        for tc_name in test_methods:
                            self.tree_ctrl.AppendItem(item, tc_name,
                                                      checkbox_type)

                self.tree_ctrl.ExpandAll()
            except Exception:
                show_error_dialog(self, traceback.format_exc(),
                                  'Cannot add test cases')
            finally:
                os.sys.path = syspath

    def __load_tests_from_directory(self, evt):
        folder = self.__get_safe_path_from_root_folder(RootFolder.TESTS_FOLDER)
        if folder:
            dialog = DirDialog(self,
                               defaultPath=folder,
                               style=DD_DIR_MUST_EXIST)
            if dialog.ShowModal() == ID_OK:
                self.__load_tests_to_tree(dir_path=dialog.GetPath())
        else:
            show_dialog_path_doesnt_exist(self, folder)

    def __load_tests_from_files(self, evt):
        folder = self.__get_safe_path_from_root_folder(RootFolder.TESTS_FOLDER)
        if folder:
            dialog = FileDialog(self,
                                defaultDir=folder,
                                style=FD_OPEN | FD_FILE_MUST_EXIST
                                | FD_MULTIPLE,
                                wildcard=u'*.py')
            if dialog.ShowModal() == ID_OK:
                self.__load_tests_to_tree(file_paths=dialog.GetPaths())
        else:
            show_dialog_path_doesnt_exist(self, folder)

    def __get_nose_command(self):
        root = self.tree_ctrl.GetRootItem()
        tests = []
        for _file in root.GetChildren():
            for _class in _file.GetChildren():
                for test_case in _class.GetChildren():
                    if test_case.IsChecked():
                        # TODO: fix for files that contain spaces
                        tests.append(u'%s:%s.%s' %
                                     (_file.GetText(), _class.GetText(),
                                      test_case.GetText()))
        args = [
            '--with-path="%s"' % self.__get_safe_path_from_root_folder(),
            '--logging-level=INFO'
        ]

        use_html_report = (self.cb_html_output.IsChecked()
                           and len(self.txt_html_report.GetValue()) > 0)
        if use_html_report:
            report_path = self.txt_html_report.GetValue()
            args.append('--with-html --html-file="%s"' % report_path)

        use_xml_report = (self.cb_xml_output.IsChecked()
                          and len(self.txt_xml_report.GetValue()) > 0)
        if use_xml_report:
            report_path = self.txt_xml_report.GetValue()
            args.append('--with-xunit --xunit-file="%s"' % report_path)

        use_options = (self.cb_options.IsChecked()
                       and len(self.txt_options.GetValue()) > 0)
        if use_options:
            report_path = self.txt_options.GetValue()
            args.append(report_path)

        nose_cmd = [u'nosetests'] + args + tests
        return nose_cmd

    def __run_tests(self, evt):
        # TODO: do not run if root folder is not selected
        self.txt_ctrl.Clear()

        dialog = InfiniteProgressBarDialog(
            self, u'Running test cases',
            u'Running selected test cases... Please wait...')

        def wrap_func():
            stdout = os.sys.stdout
            stderr = os.sys.stderr
            redirected = RedirectText(self.txt_ctrl)
            os.sys.stdout = redirected
            os.sys.stderr = redirected
            try:
                nose_cmd = self.__get_nose_command()
                browser_name = self.cb_browser.GetStringSelection()
                Browser.DEFAULT_BROWSER = browser_name
                report_folder = self.__get_safe_path_from_root_folder(
                    RootFolder.REPORTS)
                BaseTest.FAILED_SCREENSHOT_FOLDER = report_folder

                easy_selenium_cmd = u" ".join(nose_cmd).replace(
                    "nosetests", "easy_selenium_cli.py -b " + browser_name)
                print(u"Executing command:\n%s" % easy_selenium_cmd)
                print(u"Nose output:")

                run(argv=nose_cmd[1:])
            finally:
                dialog.close_event.set()
                os.sys.stdout = stdout
                os.sys.stderr = stderr

        run_in_separate_thread(wrap_func)
        dialog.ShowModal()
Пример #10
0
class EditorTab(Panel):
    def __init__(self, parent):
        Panel.__init__(self, parent)
        sizer = GridBagSizer(5, 5)
        self.SetSizer(sizer)

        self.__cur_po_class = None
        self.__create_widgets()

    def __create_widgets(self):
        sizer = self.GetSizer()

        # Next row
        inner_sizer = BoxSizer(HORIZONTAL)
        label = StaticText(self, label=u'Class path:')
        inner_sizer.Add(label, flag=ALL)

        self.cb_class_path = ComboBox(self, style=CB_READONLY)
        self.cb_class_path.Bind(EVT_COMBOBOX, self.__on_load_po_class)
        inner_sizer.Add(self.cb_class_path, 1, flag=FLAG_ALL_AND_EXPAND)

        self.btn_reload = Button(self, label=u'Reload')
        self.btn_reload.Bind(EVT_BUTTON, self.__on_load_po_class)
        inner_sizer.Add(self.btn_reload, flag=ALL)

        self.btn_open_class = Button(self, label=u'Open class')
        self.btn_open_class.Bind(EVT_BUTTON, self.__open_class)
        inner_sizer.Add(self.btn_open_class, flag=ALL)

        row = 0
        sizer.Add(inner_sizer, pos=(row, 0), flag=FLAG_ALL_AND_EXPAND)

        # Next row
        row += 1
        splitter = SplitterWindow(self, style=SP_3D | SP_LIVE_UPDATE)

        self.image_panel = ImageWithElements(splitter)
        self.image_panel.static_bitmap.Bind(EVT_MOTION, self.__on_mouse_move)
        self.image_panel.static_bitmap.Bind(EVT_RIGHT_DOWN, self.__on_right_click)

        self.table_and_test_file_tabs = FieldsTableAndTestFilesTabs(splitter, self)

        splitter.SplitHorizontally(self.image_panel, self.table_and_test_file_tabs)
        sizer.Add(splitter, pos=(row, 0), flag=FLAG_ALL_AND_EXPAND)

        sizer.AddGrowableRow(row, 1)
        sizer.AddGrowableCol(0, 1)

    def __get_parsed_classes(self, field):
        classes = ParsedPageObjectClass.get_parsed_classes(self.__cur_po_class.file_path)
        if len(classes) > 0 and len(classes[0].methods) == 0:
            classes = []
        classes += [ParsedModule.get_parsed_module(tools)]
        if field:
            classes += ParsedMouseClass.get_parsed_classes()
            classes += ParsedBrowserClass.get_parsed_classes()
        return classes

    def show_content_menu(self, field):
        tabs = self.table_and_test_file_tabs.tabs
        count = tabs.GetPageCount()
        if count > 1:
            selected_tab = tabs.GetPage(tabs.GetSelection())
            if type(selected_tab) in (TestFileUI, PyFileUI):
                file_path = selected_tab.get_file_path()
                txt_ctrl_ui = tabs.GetPage(tabs.GetSelection())
                parsed_classes = self.__get_parsed_classes(field)
                context_menu = FieldContextMenu(field,
                                                parsed_classes,
                                                file_path,
                                                txt_ctrl_ui)
                self.PopupMenu(context_menu)
                context_menu.Destroy()
            else:
                show_dialog(self, u'Please select tab with test file.',
                            u'Tab with test file was not selected')
        else:
            show_dialog(self, u'Please create/open test file.',
                        u'Test file was not created/opened')

    def __on_load_po_class(self, evt):
        path = self.cb_class_path.GetValue()
        if len(path) > 0:
            self.__load_po_class(path)

    def __on_right_click(self, evt):
        field = self.__get_current_field(evt)
        self.show_content_menu(field)

    def __on_mouse_move(self, evt):
        if self.__cur_po_class:
            ImageAndTableHelper.select_field_on_mouse_move(
                evt,
                self.__cur_po_class.fields,
                self.image_panel,
                self.table_and_test_file_tabs.table
            )

    def __get_current_field(self, evt):
        return self.image_panel.get_field(evt.GetPosition())

    def __open_class(self, evt):
        folder = self.GetTopLevelParent().get_root_folder()
        if folder:
            if RootFolder.PO_FOLDER in os.listdir(folder):
                folder = os.path.join(folder, RootFolder.PO_FOLDER)
            dialog = FileDialog(self, defaultDir=folder, wildcard=u'*.py')
            if dialog.ShowModal() == ID_OK:
                self.__load_po_class(dialog.GetPath())
        else:
            show_dialog_path_doesnt_exist(self, folder)

    def __load_po_class(self, path):
        self.table_and_test_file_tabs.table.clear_table()

        if not os.path.exists(path):
            show_dialog_path_doesnt_exist(self, path)
        if not is_correct_python_file(path):
            show_dialog(self, u'File name is incorrect: %s' % path,
                        u'Bad file name')
        else:
            folder = os.path.dirname(path)
            files = [os.path.join(folder, p) for p in os.listdir(folder)
                     if is_correct_python_file(p)]
            self.cb_class_path.Clear()
            self.cb_class_path.AppendItems(files)
            self.cb_class_path.Select(files.index(path))
            try:
                self.__cur_po_class = PageObjectClass.parse_string_to_po_class(read_file(path))
                area = self.__cur_po_class.area
                self.image_panel.set_po_fields(self.__cur_po_class.fields)
                self.image_panel.load_image(self.__cur_po_class.img_path, area)

                self.cb_class_path.SetValue(self.__cur_po_class.file_path)

                self.table_and_test_file_tabs.load_po_class(self.__cur_po_class)
            except Exception:
                self.__cur_po_class = None
                show_error_dialog(self, traceback.format_exc(),
                                  u'Failed to open file %s' % path)
Пример #11
0
class GeneratorTab(Panel):
    def __init__(self, parent):
        Panel.__init__(self, parent)
        self.main_frame = self.GetTopLevelParent()

        self.__create_widgets()

    def __create_widgets(self):
        sizer = GridBagSizer(5, 5)

        row = 0
        col = 0

        # first row
        label = StaticText(self, label=u'Selected area:')
        sizer.Add(label, pos=(row, col))

        col += 1
        self.txt_selected_area = TextCtrl(self, value=u'(0, 0, 0, 0)')
        sizer.Add(self.txt_selected_area,
                  pos=(row, col),
                  flag=FLAG_ALL_AND_EXPAND)

        col += 1
        label = StaticText(self, label=u'Class name:')
        sizer.Add(label, pos=(row, col))

        col += 1
        self.txt_class_name = TextCtrl(self)
        sizer.Add(self.txt_class_name,
                  pos=(row, col),
                  flag=FLAG_ALL_AND_EXPAND)

        col += 1
        self.bth_reload_img = Button(self, label=u'Reload image')
        self.bth_reload_img.Bind(EVT_BUTTON, self.__load_img)
        sizer.Add(self.bth_reload_img,
                  pos=(row, col),
                  flag=FLAG_ALL_AND_EXPAND)

        col += 1
        self.btn_generate = Button(self, label=u'Generate')
        self.btn_generate.Bind(EVT_BUTTON, self.generate)
        sizer.Add(self.btn_generate, pos=(row, col), flag=FLAG_ALL_AND_EXPAND)

        # second row
        row += 1
        col = 0
        self.select_image_panel = SelectableImagePanel(self)
        self.select_image_panel.static_bitmap.Bind(EVT_MOTION,
                                                   self._on_mouse_move)
        sizer.Add(self.select_image_panel,
                  pos=(row, col),
                  span=(1, 6),
                  flag=FLAG_ALL_AND_EXPAND)

        sizer.AddGrowableCol(1, 1)
        sizer.AddGrowableRow(row, 1)

        self.SetSizer(sizer)

    def __get_root_folder(self):
        return self.main_frame.get_root_folder()

    def __load_img(self, evt=None):
        browser = self.main_frame.get_browser()
        if browser:
            img_path = browser.save_screenshot(self.main_frame.get_tmp_dir())
            self.select_image_panel.load_image(img_path)

            w, h = self.select_image_panel.get_image_dimensions()

            self.txt_selected_area.SetValue(u'(%d, %d, %d, %d)' % (0, 0, w, h))
            self.main_frame.set_url(browser.get_current_url())

    def _on_mouse_move(self, evt):
        if self.select_image_panel.was_image_loaded():
            SelectableImagePanel.on_mouse_move(self.select_image_panel, evt)
            selected_area = self.select_image_panel.get_selected_area()
            self.txt_selected_area.SetValue(repr(selected_area))

    def __is_gen_data_correct(self):
        root_folder = self.__get_root_folder()
        class_name = self.txt_class_name.GetValue()
        area = self.txt_selected_area.GetValue()
        if not self.main_frame.get_browser():
            msg = u"Browser is not opened." + LINESEP + "Please open url."
            caption = u'Browser is not opened'
            show_dialog(self, msg, caption)
            return False
        elif not re.match(
                '\(\s*[0-9]+\s*,\s*[0-9]+\s*,\s*[0-9]+\s*,\s*[0-9]+\s*\)',
                area):
            msg = u"Selected area is not correct: '%s'" % area
            caption = u'Bad selected area'
            show_dialog(self, msg, caption)
            return False
        elif root_folder is None or not os.path.exists(root_folder):
            show_dialog_path_doesnt_exist(self, root_folder)
            return False
        elif len(class_name) == 0:  # if bad class_name
            msg = u"Unsupported name for class: '%s'" % class_name
            caption = u'Bad name for class'
            show_dialog(self, msg, caption)
            return False
        return True

    def __get_frames(self):
        browser = self.main_frame.get_browser()
        if browser:
            frames = []
            for e in browser.find_elements((By.CSS_SELECTOR, 'frame, iframe')):
                name = browser.get_attribute(e, 'name')
                src = browser.get_attribute(e, 'src')
                frames.append((name, src))
            return frames
        else:
            return None

    def generate(self, evt):
        if self.__is_gen_data_correct():
            folder = self.__get_root_folder()
            if RootFolder.PO_FOLDER in os.listdir(folder):
                folder = os.path.join(folder, RootFolder.PO_FOLDER)

            class_name = self.txt_class_name.GetValue()
            file_path = os.path.join(
                folder, get_py_file_name_from_class_name(class_name))
            area_as_text = self.txt_selected_area.GetValue()
            url = self.main_frame.get_url()
            if os.path.exists(file_path):
                show_dialog_path_does_exist(self, file_path)
            elif not StringUtils.is_class_name_correct(class_name):
                show_dialog_bad_name(self, class_name, 'Header', 'ContextMenu')
            elif not StringUtils.is_area_correct(area_as_text):
                show_dialog(self, u'Bad selected area: %s' % area_as_text,
                            u'Bad selected area')
            elif not StringUtils.is_url_correct(url):
                show_dialog(self, u'Bad url: %s' % url, u'Bad url')
            else:
                dialog = DialogWithText(self,
                                        'Generating page object class...')
                handler = WxTextCtrlHandler(dialog.txt_ctrl)
                logger = Logger(log_to_console=False, handler=handler)

                dialog.Show()

                area = eval(area_as_text)
                generator = PageObjectGenerator(self.main_frame.get_browser(),
                                                logger)
                folder_path = self.main_frame.get_tmp_dir()

                def generate():
                    dialog.btn_ok.Disable()
                    po_class = generator.get_po_class_for_url(
                        url, class_name, folder_path, area)
                    po_class.save(folder)
                    logger.info(u"Saving class '%s'..." % po_class.name)
                    logger.info(u'Saved file: %s' % po_class.file_path)
                    logger.info(u'Saved file: %s' % po_class.img_path)
                    logger.info(u'DONE')
                    dialog.btn_ok.Enable()

                thread = Thread(target=generate)
                thread.setDaemon(True)
                thread.start()
Пример #12
0
class MainFrame(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.__browser = None
        self.__tmp_dir = mkdtemp()

        self.SetTitle("Easy Selenium UI")
        self.SetSize((800, 600))

        self.__create_widgets()
        self.Bind(EVT_CLOSE, self.__on_close)

    def __create_widgets(self):
        panel = Panel(self)

        sizer = GridBagSizer(5, 5)
        row = 0
        col = 0
        label = StaticText(panel, label=u'Root folder:')
        sizer.Add(label, pos=(row, col))

        col += 1
        col_width = 4
        self.__txt_root_path = TextCtrl(panel)
        sizer.Add(self.__txt_root_path,
                  pos=(row, col),
                  span=(1, col_width),
                  flag=FLAG_ALL_AND_EXPAND)

        col += col_width
        self.__btn_set_root = Button(panel, label=u'Set root folder')
        self.__btn_set_root.Bind(EVT_BUTTON, self.__set_root_folder)
        sizer.Add(self.__btn_set_root,
                  pos=(row, col),
                  flag=FLAG_ALL_AND_EXPAND)

        row += 1
        col = 0
        label = StaticText(panel, label=u'Url:')
        sizer.Add(label, pos=(row, col))

        col += 1
        self.__txt_url = TextCtrl(
            panel, value=u'https://www.google.com/')  # TODO: remove url
        sizer.Add(self.__txt_url, pos=(row, col), flag=FLAG_ALL_AND_EXPAND)

        col += 1
        label = StaticText(panel, label=u'Browser:')
        sizer.Add(label, pos=(row, col), flag=FLAG_ALL_AND_EXPAND)

        col += 1
        self.__cb_browser = Choice(panel,
                                   choices=Browser.get_supported_browsers())
        self.__cb_browser.Select(0)
        sizer.Add(self.__cb_browser, pos=(row, col), flag=FLAG_ALL_AND_EXPAND)

        col += 1
        self.bth_open_url = Button(panel, label=u'Open url')
        self.bth_open_url.Bind(EVT_BUTTON, self.__open_url)
        sizer.Add(self.bth_open_url, pos=(row, col), flag=FLAG_ALL_AND_EXPAND)

        col += 1
        self.bth_close_url = Button(panel, label=u'Close browser')
        self.bth_close_url.Bind(EVT_BUTTON, self.__close_browser)
        sizer.Add(self.bth_close_url, pos=(row, col), flag=FLAG_ALL_AND_EXPAND)

        row += 1
        col = 0
        tabs = Tabs(panel, [(GeneratorTab, "Generator"), (EditorTab, "Editor"),
                            (TestRunnerTab, "Test runner"),
                            (SelectorFinderTab, "Selector finder")])
        sizer.Add(tabs, pos=(row, col), span=(1, 6), flag=FLAG_ALL_AND_EXPAND)

        sizer.AddGrowableCol(1, 1)
        sizer.AddGrowableRow(2, 1)
        panel.SetSizer(sizer)
        self.Layout()

    def get_root_folder(self):
        text = self.__txt_root_path.GetValue()
        if text and len(text) > 0:
            return text
        else:
            return None

    def __set_root_folder(self, evt):
        dialog = DirDialog(self)
        if dialog.ShowModal() == ID_OK:
            path = dialog.GetPath()
            RootFolder.prepare_folder(path)
            self.__txt_root_path.SetValue(path)

    def __open_url(self, evt):
        url = self.__txt_url.GetValue()
        if StringUtils.is_url_correct(url):
            self.bth_open_url.Disable()

            name = self.get_browser_initials()

            try:
                if self.__browser and self.__browser.get_browser_initials(
                ) != name:
                    self.__browser.quit()
                    self.__browser = Browser(name)
                elif not self.__browser:
                    self.__browser = Browser(name)
            except Exception:
                show_error_dialog(self, traceback.format_exc(),
                                  u'Failed to open browser')
                self.__browser = None

            if self.__browser:
                self.__browser.open(url)
            # TODO: if generator or selector -> load image
            self.bth_open_url.Enable()
        else:
            show_dialog(self, u'Bad url: %s' % url, u'Bad url')

    def __close_browser(self, evt):
        if self.__browser:
            self.__browser.quit()
            self.__browser = None

    def __on_close(self, evt):
        self.__close_browser(evt)

        shutil.rmtree(self.__tmp_dir)
        self.Destroy()

    def get_url(self):
        return self.__txt_url.GetValue()

    def set_url(self, url):
        self.__txt_url.SetValue(url)

    def get_browser(self):
        return self.__browser

    def get_browser_initials(self):
        return self.__cb_browser.GetStringSelection()

    def get_tmp_dir(self):
        return self.__tmp_dir
Пример #13
0
class MainDialog(Dialog):
    """
    Main window. Hit a button to profile the system, then another to scan what was plugged in
    """
    def __init__(self):
        """Constructor"""
        Dialog.__init__(self, None, title="Bad Cop", size=Size(500, 100))
        ico = Icon('logo.ico', BITMAP_TYPE_ICO)
        self.SetIcon(ico)
        self.message = StaticText(
            self, label="Click Profile, then insert device and click Test")
        self.profile = Button(self, label="Profile")
        self.test = Button(self, label="Test")
        self.test.Disable()
        self.profile.Bind(EVT_BUTTON, self.profileusb)
        self.test.Bind(EVT_BUTTON, self.testusb)
        self.Bind(EVT_CLOSE, self.onclose)
        main_sizer = BoxSizer(VERTICAL)
        t_sizer = BoxSizer(HORIZONTAL)
        p_sizer = BoxSizer(HORIZONTAL)
        t_sizer.Add(self.message, 0, ALL | CENTER, 5)
        p_sizer.Add(self.profile, 0, ALL | CENTER, 5)
        p_sizer.Add(self.test, 0, ALL | CENTER, 5)
        main_sizer.Add(p_sizer, 0, ALL | CENTER, 5)
        main_sizer.Add(t_sizer, 0, ALL | EXPAND | CENTER, 5)
        self.SetSizer(main_sizer)

    def profileusb(self, other):
        del other
        dev = find(find_all=True)
        devices = []
        for cfg in dev:
            devclass = str(cfg.bDeviceClass)
            product = str(cfg.iProduct)
            vid = hex(cfg.idVendor)
            pid = hex(cfg.idProduct)
            for line in Configuration(find(idVendor=cfg.idVendor)):
                line = str(line)
                linestrip = line.strip()
                linesplit = linestrip.split('\n')
                linesplit = [x.split(':') for x in linesplit]
                lines = []
                for w in linesplit:
                    lines.append([y.strip(' ') for y in w])
                for e in lines:
                    if 'bInterfaceClass' in e[0]:
                        intclass = e[1]
                        devices.append([devclass, product, vid, pid, intclass])
        with open('devices.pkl', 'wb') as f:
            dump(devices, f)
        self.profile.SetLabel("Done!")
        self.profile.Disable()
        self.test.Enable()

    def testusb(self, other):
        del other
        with open('devices.pkl', 'rb') as f:
            benchmark = load(f)
        dev = find(find_all=True)
        devices = []
        for cfg in dev:
            devclass = str(cfg.bDeviceClass)
            product = str(cfg.iProduct)
            vid = hex(cfg.idVendor)
            pid = hex(cfg.idProduct)
            for line in Configuration(find(idVendor=cfg.idVendor)):
                line = str(line)
                linestrip = line.strip()
                linesplit = linestrip.split('\n')
                linesplit = [x.split(':') for x in linesplit]
                lines = []
                for w in linesplit:
                    lines.append([y.strip(' ') for y in w])
                for e in lines:
                    if 'bInterfaceClass' in e[0]:
                        intclass = e[1]
                        devices.append([devclass, product, vid, pid, intclass])
        first_tuple_list = [tuple(lst) for lst in benchmark]
        secnd_tuple_list = [tuple(lst) for lst in devices]
        first_set = set(first_tuple_list)
        secnd_set = set(secnd_tuple_list)
        output = ""
        height = 100
        first = 0
        for devclass, product, vid, pid, usbtype in first_set.symmetric_difference(
                secnd_set):
            if usbtype == "0xa CDC Data":
                devicedesc = "Virtual Data Port (Network)"
            elif usbtype == "0xe0 Wireless Controller":
                devicedesc = "Wireless Internet Or Bluetooth"
            elif usbtype == "0x8 Mass Storage":
                devicedesc = "Data Storage Device"
            elif usbtype == "0x9 Hub":
                devicedesc = "USB Hub"
            elif usbtype == "0x3 Human Interface Device":
                devicedesc = "Keyboard, Mouse, or Other Input Device"
            elif usbtype == "0x2 CDC Communication":
                devicedesc = "Vitual Communications Port (Network)"
            else:
                devicedesc = usbtype + " device "
            if first == 0:
                output += "This appears to be a: \n                     " + devicedesc + " \n"
            else:
                output += "                     " + devicedesc + " \n"
            height = height + 30
            first = 1
        self.SetSize((500, height))
        self.message.SetLabel(output)

    def onclose(self, event):
        del event
        try:
            remove('devices.pkl')
        except:
            print('file missing')
        self.Destroy()
        exit("Application Exited")
Пример #14
0
class SelectorFinderTab(Panel):
    def __init__(self, parent):
        Panel.__init__(self, parent)

        self.main_frame = self.GetTopLevelParent()
        self.po_fields = None

        self.__create_widgets()

    def __create_widgets(self):
        sizer = GridBagSizer(5, 5)

        row = 0
        col = 1
        self.bth_reload_img = Button(self, label=u'Reload image')
        self.bth_reload_img.Bind(EVT_BUTTON, self.__load_img)
        sizer.Add(self.bth_reload_img,
                  pos=(row, col),
                  flag=FLAG_ALL_AND_EXPAND)

        col += 1
        self.bth_reload_selectors = Button(self, label=u'Find selectors')
        self.bth_reload_selectors.Bind(EVT_BUTTON, self.__find_selectors)
        sizer.Add(self.bth_reload_selectors,
                  pos=(row, col),
                  flag=FLAG_ALL_AND_EXPAND)
        # third row
        row += 1
        col = 0

        splitter = SplitterWindow(self, style=SP_3D | SP_LIVE_UPDATE)

        self.image_panel = ImageWithElements(splitter)
        self.image_panel.static_bitmap.Bind(EVT_MOTION, self.__on_mouse_move)

        self.table = Table(splitter)
        self.table.Bind(EVT_GRID_SELECT_CELL, self.__on_cell_select)

        splitter.SplitHorizontally(self.image_panel, self.table)
        sizer.Add(splitter,
                  pos=(row, col),
                  span=(1, 3),
                  flag=FLAG_ALL_AND_EXPAND)

        sizer.AddGrowableCol(0, 1)
        sizer.AddGrowableRow(row, 1)

        self.SetSizer(sizer)

    def __update_table(self):
        if self.po_fields:
            self.table.load_data(self.po_fields)

    def __on_mouse_move(self, evt):
        ImageAndTableHelper.select_field_on_mouse_move(evt, self.po_fields,
                                                       self.image_panel,
                                                       self.table)

    def __on_cell_select(self, evt):
        self.table.selected_row = evt.GetRow()
        self.image_panel.draw_selected_field(self.table.get_selected_data(),
                                             True)
        evt.Skip()

    def __load_img(self, evt=None):
        browser = self.main_frame.get_browser()
        if browser:
            img_path = browser.save_screenshot(self.main_frame.get_tmp_dir())
            self.image_panel.load_image(img_path)
            self.main_frame.set_url(browser.get_current_url())

    def __find_selectors(self, evt):
        browser = self.main_frame.get_browser()
        if browser:
            url = self.main_frame.get_url()
            if not StringUtils.is_url_correct(url):
                show_dialog(self, u'Bad url: %s' % url, u'Bad url')
            else:
                dialog = DialogWithText(self, 'Finding selectors...')
                handler = WxTextCtrlHandler(dialog.txt_ctrl)
                logger = Logger(log_to_console=False, handler=handler)

                dialog.Show()

                generator = PageObjectGenerator(browser, logger)

                def find_selectors():
                    dialog.btn_ok.Disable()
                    self.po_fields = generator.get_all_po_fields(url, None)
                    logger.info(u'DONE')
                    self.__update_table()
                    dialog.btn_ok.Enable()

                thread = Thread(target=find_selectors)
                thread.setDaemon(True)
                thread.start()
Пример #15
0
class AssetFrame(wx.Frame):
    def __init__(self, parent, title="PyAsset", cfgFile="", assetFile=""):
        self.parent = parent
        self.frame = self
        self.assets = AssetList(self)
        self.bills = BillList()
        self.cur_asset = Asset(name=assetFile)
        self.edited = False
        self.payType = ""
        self.ref_date = None
        self.netpay = ""
        self.payDepositAcct = ""
        self.cfgFile = copy.deepcopy(cfgFile)

        super(AssetFrame, self).__init__(parent, title=title)

        if self.readConfigFile(cfgFile):
            valid_date_seps = ['/', '-']
            for j in range(len(valid_date_seps)):
                date_sep = valid_date_seps[j]
                date_fields = self.dateFormat.split(valid_date_seps[j])
                if len(date_fields) == 3:
                    break
            if len(date_fields) == 3:
                Date.set_global_date_format(self, self.dateFormat)
                Date.set_global_date_sep(self, date_sep)

                self.curr_date = Date.set_curr_date(self)
                self.proj_date = Date.set_proj_date(self, "")
                Date.set_global_curr_date(self, self.curr_date)
                Date.set_global_proj_date(self, self.proj_date)
                Date.set_curr_paydate(self)
                Date.set_next_paydate(self)

                self.make_widgets()
                self.filename = assetFile
                if self.filename == "":
                    d = wx.FileDialog(self, "Open", "", "", "*.qif",
                                      wx.FD_OPEN)
                    if d.ShowModal() == wx.ID_OK:
                        fname = d.GetFilename()
                        dir = d.GetDirectory()
                        self.filename = os.path.join(dir, fname)
                if self.filename:
                    latest_assets = qif.load_file(self, self.filename)
                    self.process_asset_list(latest_assets)
            else:
                error = 'Badly formatted date format sting: %s - Aborting!\n'
                self.DisplayMsg(error)
        else:
            error = cfgFile + ' does not exist / cannot be opened!! - Aborting\n'
            self.DisplayMsg(error)

    def clear_all_assets(self):
        self.assets = AssetList(self)
        self.redraw_all(-1)

    def readConfigFile(self, cfgFile):
        if cfgFile == "":
            d = wx.FileDialog(self, "", "", "", "*.cfg", wx.FD_OPEN)
            if d.ShowModal() == wx.ID_OK:
                fname = d.GetFilename()
                dir = d.GetDirectory()
                total_name_in = os.path.join(dir, fname)
                self.cfgFile = total_name_in
        else:
            self.cfgFile = cfgFile
        try:
            file = open(self.cfgFile, 'r')
            lines = file.readlines()
            self.dateFormat = lines.pop(0).replace('\n', '')
            Date.set_global_date_format(self, self.dateFormat)
            self.payType = lines.pop(0).replace('\n', '')
            in_ref_date = lines.pop(0).replace('\n', '')
            ref_date = Date.parse_date(self, in_ref_date, self.dateFormat)
            self.ref_date = ref_date["dt"]
            self.netpay = lines.pop(0).replace('\n', '')
            self.payDepositAcct = lines.pop(0).replace('\n', '')
            file.close()
            return True
        except:
            return False

    def writeConfigFile(self):
        if self.cfgFile == "":
            d = wx.FileDialog(self, "", "", "", "*.cfg", wx.FD_OPEN)
            if d.ShowModal() == wx.ID_OK:
                fname = d.GetFilename()
                dir = d.GetDirectory()
                total_name_in = os.path.join(dir, fname)
                self.cfgFile = total_name_in
        file = open(self.cfgFile, 'w')
        file.write("%s\n" % self.dateFormat)
        file.write("%s\n" % self.payType)
        file.write("%s\n" % self.ref_date)
        file.write("%s\n" % self.netpay)
        file.write("%s\n" % self.payDepositAcct)
        file.close()

    def DisplayMsg(self, str):
        d = wx.MessageDialog(self, str, "Error", wx.OK | wx.ICON_INFORMATION)
        d.ShowModal()
        d.Destroy()

    def make_widgets(self):
        self.menubar = wx.MenuBar()
        self.SetMenuBar(self.menubar)
        self.make_filemenu()
        self.make_editmenu()
        self.make_helpmenu()
        self.setup_layout()

    def make_filemenu(self):
        self.filemenu = wx.Menu()
        ID_EXPORT_TEXT = wx.NewId()
        ID_ARCHIVE = wx.NewId()
        ID_IMPORT_CSV = wx.NewId()
        ID_IMPORT_XLSM = wx.NewId()
        ID_UPDATE_FROM_NET = wx.NewId()
        ID_PROPERTIES = wx.NewId()
        self.filemenu.Append(wx.ID_OPEN, "Open\tCtrl-o",
                             "Open a new transction file", wx.ITEM_NORMAL)
        self.filemenu.Append(wx.ID_SAVE, "Save\tCtrl-s",
                             "Save the current transactions in the same file",
                             wx.ITEM_NORMAL)
        self.filemenu.Append(
            wx.ID_SAVEAS, "Save As",
            "Save the current transactions under a different name",
            wx.ITEM_NORMAL)
        self.filemenu.Append(wx.ID_CLOSE, "Close\tCtrl-w",
                             "Close the current file", wx.ITEM_NORMAL)
        self.filemenu.Append(
            ID_EXPORT_TEXT, "Export Text",
            "Export the current transaction register as a text file",
            wx.ITEM_NORMAL)
        self.filemenu.Append(
            ID_ARCHIVE, "Archive",
            "Archive transactions older than a specified date", wx.ITEM_NORMAL)
        self.filemenu.AppendSeparator()
        self.filemenu.Append(ID_IMPORT_CSV, "Import CSV\tCtrl-c",
                             "Import transactions from a CSV file",
                             wx.ITEM_NORMAL)
        self.filemenu.Append(
            ID_IMPORT_XLSM, "Import XLSM file\tCtrl-i",
            "Import transactions from an EXCEL file with Macros",
            wx.ITEM_NORMAL)
        self.filemenu.Append(ID_UPDATE_FROM_NET,
                             "Update Accounts from Net\tCtrl-u",
                             "Update accounts using pre-defined iMacros",
                             wx.ITEM_NORMAL)
        self.filemenu.AppendSeparator()
        self.filemenu.Append(
            ID_PROPERTIES, "Properties\tCtrl-p",
            "Display and/or edit Number and Data/Time display properties, pay frequencies",
            wx.ITEM_NORMAL)
        self.filemenu.AppendSeparator()
        self.filemenu.Append(wx.ID_EXIT, "Quit\tCtrl-q", "Exit PyAsset",
                             wx.ITEM_NORMAL)
        self.menubar.Append(self.filemenu, "&File")
        self.Bind(wx.EVT_MENU, self.load_file, None, wx.ID_OPEN)
        self.Bind(wx.EVT_MENU, self.save_file, None, wx.ID_SAVE)
        self.Bind(wx.EVT_MENU, self.save_as_file, None, wx.ID_SAVEAS)
        self.Bind(wx.EVT_MENU, self.close, None, wx.ID_CLOSE)
        self.Bind(wx.EVT_MENU, self.export_text, None, ID_EXPORT_TEXT)
        self.Bind(wx.EVT_MENU, self.archive, None, ID_ARCHIVE)
        self.Bind(wx.EVT_MENU, self.import_CSV_file, None, ID_IMPORT_CSV)
        self.Bind(wx.EVT_MENU, self.import_XLSM_file, None, ID_IMPORT_XLSM)
        self.Bind(wx.EVT_MENU, self.update_from_net, None, ID_UPDATE_FROM_NET)
        self.Bind(wx.EVT_MENU, self.properties, None, ID_PROPERTIES)
        self.Bind(wx.EVT_MENU, self.quit, None, wx.ID_EXIT)

    def make_editmenu(self):
        ID_SORT = wx.NewId()
        ID_DELETE_ENTRY = wx.NewId()
        self.editmenu = wx.Menu()
        self.editmenu.Append(wx.ID_NEW, "New Entry\tCtrl-n",
                             "Create a new asset in the list", wx.ITEM_NORMAL)
        self.editmenu.Append(ID_DELETE_ENTRY, "Delete Entry",
                             "Delete the current asset", wx.ITEM_NORMAL)
        self.editmenu.Append(ID_SORT, "Sort Entries", "Sort entries",
                             wx.ITEM_NORMAL)
        self.menubar.Append(self.editmenu, "&Edit")
        self.Bind(wx.EVT_MENU, self.newentry, None, wx.ID_NEW)
        self.Bind(wx.EVT_MENU, self.deleteentry, None, ID_DELETE_ENTRY)
        self.Bind(wx.EVT_MENU, self.sort, None, ID_SORT)

    def make_helpmenu(self):
        ID_HELP = wx.NewId()
        self.helpmenu = wx.Menu()
        self.helpmenu.Append(wx.ID_ABOUT, "About", "About PyAsset",
                             wx.ITEM_NORMAL)
        self.helpmenu.Append(ID_HELP, "Help\tCtrl-h", "PyAsset Help",
                             wx.ITEM_NORMAL)

        self.menubar.Append(self.helpmenu, "&Help")
        self.Bind(wx.EVT_MENU, self.about, None, wx.ID_ABOUT)
        self.Bind(wx.EVT_MENU, self.gethelp, None, ID_HELP)

    def make_bill_button(self, panel):
        self.billButton = Button(panel, label="Bills")
        self.billButton.Bind(wx.EVT_LEFT_DOWN, self.onBillButtonClick)

    def onBillButtonClick(self, evt):
        self.DisplayMsg("Bill button clicked!")

    def make_date_grid(self, panel):
        self.currDateLabel = wx.StaticText(panel, label="Curr Date")
        dates = Date(self, self.dateFormat, self.payType, self.ref_date)
        self.curr_date = dates.get_curr_date()
        self.currDate = wx.StaticText(panel, label=self.curr_date["str"])
        self.projDateLabel = wx.StaticText(panel, label="Proj Date")
        displayDateFormat = self.dateFormat.replace("%m", "mm").replace(
            "%d", "dd").replace("%y", "yy").replace("%Y", "yyyy")
        self.projDateInput = wx.TextCtrl(panel,
                                         style=wx.TE_PROCESS_ENTER,
                                         value=displayDateFormat)
        self.currPayDateLabel = wx.StaticText(panel, label="Current Pay Date")
        self.currPayDate = dates.get_curr_paydate()
        self.currPayDateOutput = wx.StaticText(panel,
                                               label=str(self.currPayDate))
        self.nextPayDateLabel = wx.StaticText(panel, label="Next Pay Date")
        self.nextPayDate = dates.get_next_paydate()
        self.nextPayDateOutput = wx.StaticText(panel,
                                               label=str(self.nextPayDate))

        self.projDateInput.Bind(wx.EVT_TEXT_ENTER, self.onProjDateEntered)

    def update_date_grid_dates(self, oldDateFormat, newDateFormat):
        if oldDateFormat != newDateFormat:
            self.curr_date = Date.convertDateFormat(self, self.curr_date,
                                                    oldDateFormat,
                                                    newDateFormat)
        self.currDate.LabelText = self.curr_date["str"]
        self.currDate.Refresh()
        try:
            if oldDateFormat != newDateFormat:
                self.proj_date = Date.convertDateFormat(
                    self, self.proj_date, oldDateFormat, newDateFormat)
            if self.proj_date == None:
                self.projDateInput.LabelText = newDateFormat.replace(
                    "%m",
                    "mm").replace("%d",
                                  "dd").replace("%y",
                                                "yy").replace("%Y", "yyyy")
            else:
                self.projDateInput.LabelText = self.proj_date
        except:
            self.projDateInput.LabelText = newDateFormat.replace(
                "%m", "mm").replace("%d",
                                    "dd").replace("%y",
                                                  "yy").replace("%Y", "yyyy")
        self.projDateInput.Refresh()
        if oldDateFormat != newDateFormat:
            self.currPayDate = Date.convertDateFormat(self, self.currPayDate,
                                                      oldDateFormat,
                                                      newDateFormat)
        self.currPayDateOutput.LabelText = Date.get_curr_paydate(self)
        self.currPayDateOutput.Refresh()
        if oldDateFormat != newDateFormat:
            self.nextPayDate = Date.convertDateFormat(self, self.nextPayDate,
                                                      oldDateFormat,
                                                      newDateFormat)
        self.nextPayDateOutput.LabelText = Date.get_next_paydate(self)
        self.nextPayDateOutput.Refresh()

    def onProjDateEntered(self, evt):
        in_date = evt.String
        date_format = Date.get_global_date_format(self)
        returned_date = Date.parse_date(self, in_date, date_format)
        if returned_date != None:
            self.proj_date = wx.DateTime.FromDMY(returned_date["day"],
                                                 returned_date["month"] - 1,
                                                 returned_date["year"])
            self.proj_year = returned_date["year"]
            self.proj_month = returned_date["month"]
            self.proj_day = returned_date["day"]
            print(
                "Projected date %s, parse: Month: %02d, Day: %02d, Year: %04d"
                % (self.proj_date.Format(self.dateFormat), self.proj_month,
                   self.proj_day, self.proj_year))
            Date.set_proj_date(self, in_date)
        else:
            self.proj_date = None
            self.DisplayMsg("Bad projected date ignored: %s" % (in_date))

    def make_asset_grid(self, panel):
        self.assetGrid = AssetGrid(panel)
        self.needed_width = self.assetGrid.set_properties(self)

    def add_transaction_frame(self, row, col):
        name = self.assets[row].name
        transactions = self.assets[row].transactions
        self.trans_frame = TransactionFrame(None, self, -1, row, transactions,
                                            name)

    def get_transaction_frame(self):
        return self.trans_frame

    def setup_layout(self):
        self.panel = wx.Panel(self)

        self.make_bill_button(self.panel)
        self.make_date_grid(self.panel)
        self.make_asset_grid(self.panel)

        self.date_fgs = wx.FlexGridSizer(1, 9, 5, 5)
        self.date_fgs.AddMany([(self.billButton),
                               (self.currDateLabel, 1, wx.ALIGN_CENTER),
                               (self.currDate, 1, wx.ALIGN_CENTER),
                               (self.projDateLabel, 1, wx.ALIGN_CENTER),
                               (self.projDateInput, 1, wx.EXPAND),
                               (self.currPayDateLabel, 1, wx.ALIGN_CENTER),
                               (self.currPayDateOutput, 1, wx.ALIGN_CENTER),
                               (self.nextPayDateLabel, 1, wx.ALIGN_CENTER),
                               (self.nextPayDateOutput, 1, wx.ALIGN_CENTER)])

        self.asset_fgs = wx.FlexGridSizer(2, 1, 0, 0)
        self.asset_fgs.Add(self.assetGrid,
                           proportion=1,
                           flag=wx.RESERVE_SPACE_EVEN_IF_HIDDEN | wx.EXPAND)

        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
        self.mainSizer.Add(self.date_fgs)
        self.mainSizer.Add(self.asset_fgs)

        self.panel.Fit()
        self.panel.SetSizer(self.mainSizer)
        self.date_fgs.SetSizeHints(self.panel)
        self.asset_fgs.SetSizeHints(self.panel)

        self.Fit()
        self.Layout()
        self.Show()

    def redraw_all(self, index=-1):
        self.edited = True
        nassets = len(self.assets)
        if index == -1:
            nrows = nassets + 1
            if nrows > 0 and (index == None or index == -1):
                self.assetGrid.DeleteRows(0, nrows)
                nrows = 0
            start_range = 0
            end_range = nassets
            if nrows < nassets:
                rows_needed = nassets - nrows
                self.assetGrid.AppendRows(rows_needed)
        else:
            start_range = index
            end_range = start_range + 1
        for row in range(start_range, end_range):
            for col in range(self.assetGrid.getNumLayoutCols()):
                ret_val = wx.OK
                if row < 0 or row >= len(self.assets):
                    str = "Warning: skipping redraw on bad cell %d %d!" % (row,
                                                                           col)
                    ret_val = self.DisplayMsg(str)
                if ret_val != wx.OK:
                    continue

                # Logic to always display Value (Curr), Value (Proj), Avail(Proj), Amt Over, Cash Limit, Cash Used and Cash Avail for credit cards,store cards, and overdraft
                asset_type = self.assets[row].get_type()
                col_name = self.assetGrid.getColName(col)
                self.assetGrid.setColZeroSuppress(row, col, True)
                if (asset_type == "store card" or asset_type == "credit card"
                        or asset_type == "overdraft") and (
                            "Curr" in col_name or "Proj" in col_name
                            or "Amt" in col_name or "Cash" in col_name):
                    self.assetGrid.setColZeroSuppress(row, col, False)
                cellValue = self.assetGrid.GridCellDefaultRenderer(row, col)
                cellType = self.assetGrid.getColType(col)
                if cellType == self.assetGrid.DOLLAR_TYPE:
                    self.assetGrid.GridCellDollarRenderer(row, col)
                elif cellType == self.assetGrid.RATE_TYPE:
                    self.assetGrid.GridCellPercentRenderer(row, col)
                elif cellType == self.assetGrid.DATE_TYPE:
                    self.assetGrid.GridCellDateRenderer(row, col)
                elif cellType == self.assetGrid.DATE_TIME_TYPE:
                    self.assetGrid.GridCellDateTimeRenderer(row, col)
                elif cellType == self.assetGrid.STRING_TYPE:
                    self.assetGrid.GridCellStringRenderer(row, col)
                else:
                    self.assetGrid.GridCellErrorRenderer(row, col)
        if index == -1:
            self.assetGrid.SetGridCursor(0, 0)  # was (nassets-1, 0)
            self.assetGrid.MakeCellVisible(0, True)  # was (nassets-1, 0)
        elif index > 0:
            self.assetGrid.SetGridCursor(index, 0)
            self.assetGrid.MakeCellVisible(index, True)

    def assetchange(self, evt):
        row = evt.GetRow()
        col = evt.GetCol()
        val = evt.String
        modified = True
        colName = self.assetGrid.getColName(col)
        if colName == "Acct name":
            self.assets[row].set_name(val)
        elif colName == "Curr val":
            self.assets[row].set_value(val)
        elif colName == "Last pulled":
            self.assets[row].set_last_pull_date(val)
        elif colName == "Limit":
            self.assets[row].set_limit(val)
        elif colName == "Avail online":
            self.assets[row].set_avail(val)
        elif colName == "Rate":
            self.assets[row].set_rate(val)
        elif colName == "Payment amt":
            self.assets[row].set_payment(val)
        elif colName == "Due date":
            self.assets[row].set_due_date(val)
        elif colName == "Sched date":
            self.assets[row].set_sched_date(val)
        elif colName == "Min Pmt":
            self.assets[row].set_min_pay(val)
        elif colName == "Stmt Bal":
            self.assets[row].set_stme_bal(val)
        elif colName == "Amt Over":
            self.assets[row].set_amt_over(val)
        elif colName == "Cash Limit":
            self.assets[row].set_cash_limit(val)
        elif colName == "Cash Used":
            self.assets[row].set_cash_used(val)
        elif colName == "Cash Avail":
            self.assets[row].set_cash_avail(val)
        else:
            print("assetchange: Warning: modifying incorrect cell! row, ", row,
                  " col ", col)
            modified = False

        if modified == True:
            self.edited = True

    def update_all_Date_Formats(self, oldDateFormat, newDateFormat):
        self.edited = True
        self.update_date_grid_dates(oldDateFormat, newDateFormat)
        #TODO:  Add code to update asset_grids and transaction grids   JJG 06/10/2020

    def load_file(self, assetFile):
        latest_assets = qif.load_file(self, "")
        if latest_assets != None:
            self.process_asset_list(latest_assets)

    def save_file(self, *args):
        for cur_asset in self.assets:
            if cur_asset.filename == "":
                self.save_as_file()
            else:
                self.edited = False
            self.cur_asset.write_qif()

    def save_as_file(self, *args):
        d = wx.FileDialog(self, "Save", "", "", "*.qif", wx.FD_SAVE)
        if d.ShowModal() == wx.ID_OK:
            fname = d.GetFilename()
            dir = d.GetDirectory()
            self.cur_asset.write_qif(os.path.join(dir, fname))
        if self.cur_asset.name:
            self.SetTitle("PyAsset: %s" % self.cur_asset.name)

    def close(self, *args):
        pass  # Not sure what to do here yet!  JJG 1/17/2022
        #self.cur_asset = None
        #del self.assets
        #del self.bills
        #self.assets = AssetList(self)
        #self.bills = BillList()
        #self.redraw_all()
        #self.edited = False
        #self.SetTitle("PyAsset: Asset")

    def quit(self, *args):
        self.close()
        self.Close()

    #
    #     @brief Receives data to be written to and its location
    #
    #     @params[in] date_
    #     Data of transaction
    #     @params[in] amount_
    #     Amount of money for transaction
    #     @params[in] memo_
    #     Description of transaction
    #     @params[in] payee_
    #     Who transaction was paid to
    #     @params[in] filelocation_
    #     Location of the Output file
    #
    #
    # https://en.wikipedia.org/wiki/Quicken_Interchange_Format
    #

    def write_file(self, date_, amount_, memo_, payee_, filelocation_):
        outFile = open(filelocation_, "a")  # Open file to be appended
        outFile.write(
            "!Type:Cash\n")  # Header of transaction, Currently all set to cash
        outFile.write("D")  # Date line starts with the capital D
        outFile.write(date_)
        outFile.write("\n")

        outFile.write("T")  # Transaction amount starts here
        outFile.write(amount_)
        outFile.write("\n")

        outFile.write("M")  # Memo Line
        outFile.write(memo_)
        outFile.write("\n")

        if (payee_ != -1):
            outFile.write("P")  # Payee line
            outFile.write(payee_)
            outFile.write("\n")

        outFile.write(
            "^\n"
        )  # The last line of each transaction starts with a Caret to mark the end
        outFile.close()

    #
    #     @brief  Takes given CSV and parses it to be exported to a QIF
    #
    #     @params[in] inf_
    #     File to be read and converted to QIF
    #     @params[in] outf_
    #     File that the converted data will go
    #     @params[in] deff_
    #     File with the settings for converting CSV
    #
    #

    def read_csv(self, inf_, outf_,
                 deff_):  # will need to receive input csv and def file
        csvdeff = csv.reader(deff_, delimiter=',')
        next(csvdeff, None)

        for settings in csvdeff:
            date_ = (settings[0])  # convert to
            amount_ = (settings[2])  # How much was the transaction
            memo_ = (settings[3])  # discription of the transaction
            payee_ = (settings[4])  # Where the money is going
            deli_ = settings[5]  # How the csv is separated
            header_ = (settings[6])  # Set if there is a header to skip

        csvIn = csv.reader(
            inf_,
            delimiter=deli_)  # create csv object using the given separator

        if header_ >= 1:  # If there is a header skip the fist line
            next(csvIn, None)  # skip header

        for row in csvIn:
            self.write_file(row[date_], row[amount_], row[memo_], row[payee_],
                            outf_)  # export each row as a qif entry

        inf_.close()
        deff_.close()

    def import_CSV_file(self, *args):
        # Appends the records from a .csv file to the current Asset
        d = wx.FileDialog(self, "Import", "", "", "*.csv", wx.FD_OPEN)
        if d.ShowModal() == wx.ID_OK:
            self.edited = True
            fname = d.GetFilename()
            dir = d.GetDirectory()
            total_name_in = os.path.join(dir, fname)
            total_name_extension_place = total_name_in.find(".csv")
            total_name_def = ""
            total_name_qif = ""
            if total_name_extension_place != -1:
                total_name_def = total_name_in[:total_name_extension_place] + ".def"
                total_name_qif = total_name_in[:total_name_extension_place] + ".qif"
            # pr total_name_in, total_name_def, total_name_qif
            error = ""
            try:
                fromfile = open(total_name_in, 'r')
            except:
                error = total_name_in + ' does not exist / cannot be opened !!\n'

            if total_name_qif != "":
                try:
                    tofile = open(totoal_name_qif, 'a')
                except:
                    error = total_name_qif + ' cannot be created !!\n'

            if total_name_def != "":
                if os.path.isfile(total_name_def):
                    deffile = open(total_name_def, 'r')
                else:
                    error = total_name_def + ' does not exist / cannot be opened !!\n'

            if error == "":
                tofile = total_name_qif
                self.read_csv(fromfile, tofile, deffile)
                self.cur_asset.read_qif(total_name_qif)
                fromfile.close()
                deffile.close()
                self.redraw_all(-1)
                if self.cur_asset.name:
                    self.SetTitle("PyAsset: %s" % self.cur_asset.name)
            else:
                self.Display(error)
                return

    def process_asset_list(self, assetList):
        for i in range(len(assetList.assets)):
            cur_asset = assetList.assets[i]
            cur_name = cur_asset.get_name()
            j = self.assets.index(cur_name)
            if j != -1:
                self.assets.assets[
                    j] = cur_asset  # For now, just replace, when dates are working, save later date JJG 1/22/2022
            else:
                self.assets.append_by_object(cur_asset)
        self.redraw_all()

    def import_XLSM_file(self, *args):
        # Appends or Merges as appropriate the records from a .xlsm file to the current Asset
        d = wx.FileDialog(self, "Import", "", "", "*.xlsm", wx.FD_OPEN)
        if d.ShowModal() == wx.ID_OK:
            self.edited = True
            fname = d.GetFilename()
            dir = d.GetDirectory()
            total_name_in = os.path.join(dir, fname)
            error = ""
            try:
                fromfile = open(total_name_in, 'r')
                fromfile.close()
            except:
                error = total_name_in + ' does not exist / cannot be opened !!\n'

            if error == "":
                self.cur_assets = None
                xlsm = ExcelToAsset(ignore_sheets=[
                    'Assets', 'Bills', 'Shop Your Way transactions',
                    'Slate transactions', 'Slate old transactions'
                ])
                xlsm.OpenXLSMFile(total_name_in)
                latest_assets = xlsm.ProcessAssetsSheet(self)
                self.process_asset_list(latest_assets)
                transaction_sheet_names = xlsm.GetTransactionSheetNames()
                for sheet in transaction_sheet_names:
                    sheet_index = self.assets.index(sheet)
                    if sheet_index != -1:
                        self.assets[
                            sheet_index].transactions = xlsm.ProcessTransactionSheet(
                                self.assets[sheet_index], sheet)
                        if self.assets[sheet_index].transactions:
                            proj_value = self.assets[
                                sheet_index].transactions.update_current_and_projected_values(
                                )
                            self.assets[sheet_index].set_value_proj(proj_value)
                    else:
                        print(sheet + " not found in asset list")

                #TODO: Process latest_bills here (False since not written yet!)
                if False:
                    self.latest_bills = xlsm.ProcessBillsSheet(self.bills)
                    print(self.latest_bills)
            else:
                self.DisplayMsg(error)

    def update_from_net(self, *args):
        w = iMacrosToAsset()
        w.Init()
        net_asset_codes = [
            ("HFCU", 1, [False, False, False, True]),
            #("BOA",-1,[False,True]),
            #("AMEX",-1,[True,True]),
            #("CITI",-1,[True]),
            #("MACYS",-1,[True]),
            #("SYW",-1,[True]),
            #("TSP",-1,[False,False,False,True]),
            #("MET",1,[False])
        ]
        for net_asset_code in net_asset_codes:
            latest_assets = w.GetNetInfo(net_asset_code)
            #print latest_assets
            for i in range(len(latest_assets)):
                net_asset = latest_assets.__getitem__(i)
                if net_asset != None:
                    latest_name = net_asset.get_name()
                    found = False
                    for j in range(len(self.assets)):
                        cur_name = self.assets[j].get_name()
                        if "(" in cur_name:
                            cur_name = cur_name.split("(")[1].split(")")[0]
                        if cur_name in latest_name:
                            net_index = j
                            found = True
                            break
                    if not found:
                        self.assets.append(latest_name)
                        net_index = -1
                    # Always update Value (Curr) column and type ... others check if non-zero value before update is done!
                    self.assets[net_index].set_value(net_asset.get_value())
                    self.assets[net_index].set_type(net_asset.get_type())
                    if net_asset.get_value_proj() != 0.0:
                        self.assets[net_index].set_value_proj(
                            net_asset.get_value_proj())
                    if net_asset.get_last_pull_date() != 0.0:
                        self.assets[net_index].set_last_pull_date(
                            net_asset.get_last_pull_date())
                    if net_asset.get_limit() != 0.0:
                        self.assets[net_index].set_limit(net_asset.get_limit())
                    if net_asset.get_avail() != 0.0:
                        self.assets[net_index].set_avail(net_asset.get_avail())
                    if net_asset.get_avail_proj() != 0.0:
                        self.assets[net_index].set_avail_proj(
                            net_asset.get_avail_proj())
                    if net_asset.get_rate() != 0.0:
                        self.assets[net_index].set_rate(net_asset.get_rate())
                    if net_asset.get_payment() != 0.0:
                        self.assets[net_index].set_payment(
                            net_asset.get_payment())
                    if net_asset.get_due_date() != None:
                        self.assets[net_index].set_due_date(
                            net_asset.get_due_date())
                    if net_asset.get_sched_date() != None:
                        self.assets[net_index].set_sched_date(
                            net_asset.get_sched_date())
                    if net_asset.get_min_pay() != 0.0:
                        self.assets[net_index].set_min_pay(
                            net_asset.get_min_pay())
                    if net_asset.get_stmt_bal() != 0.0:
                        self.assets[net_index].set_stmt_bal(
                            net_asset.get_stmt_bal())
                    if net_asset.get_amt_over() != 0.0:
                        self.assets[net_index].set_amt_over(
                            net_asset.get_amt_over())
                    if net_asset.get_cash_limit() != 0.0:
                        self.assets[net_index].set_cash_limit(
                            net_asset.get_cash_limit())
                    if net_asset.get_cash_used() != 0.0:
                        self.assets[net_index].set_cash_used(
                            net_asset.get_cash_used())
                    if net_asset.get_cash_avail() != 0.0:
                        self.assets[net_index].set_cash_avail(
                            net_asset.get_cash_avail())
        w.Finish()
        self.redraw_all()

    def properties(self, *args):
        dateFormat = Date.get_global_date_format(self)
        ref_date_parsed = Date.parse_date(self, self.ref_date, dateFormat)
        if ref_date_parsed != None:
            ref_date_dt = ref_date_parsed["dt"]
            ref_date = wx.DateTime.FromDMY(ref_date_dt.day, ref_date_dt.month,
                                           ref_date_dt.year).Format(dateFormat)
        else:
            ref_date = ""  # For now to test!  JJG 08/06/2021
        frame = PropertyFrameWithForm(self, self.dateFormat, self.payType,
                                      ref_date, self.netpay,
                                      self.payDepositAcct)
        frame.Show()

    def setDateFormat(self, new_DateFormat):
        self.dateFormat = new_DateFormat

    def setPayType(self, new_type):
        self.payType = new_type

    def setRefDate(self, new_ref_date):
        self.ref_date = new_ref_date

    def setNetPay(self, new_netpay):
        self.netpay = new_netpay

    def setPayDepositAcct(self, new_PayDepositAcct):
        self.payDepositAcct = new_PayDepositAcct

    def getDateFormat(self):
        return self.dateFormat

    def getPayType(self):
        return self.payType

    def getRefDate(self):
        return self.ref_date

    def getNetPay(self):
        return self.netpay

    def getPayDepositAcct(self):
        return self.payDepositAcct

    def export_text(self, *args):
        d = wx.FileDialog(self, "Save", "", "", "*.txt", wx.SAVE)
        if d.ShowModal() == wx.ID_OK:
            fname = d.GetFilename()
            dir = d.GetDirectory()
            self.cur_asset.write_txt(os.path.join(dir, fname))

    def archive(self, *args):
        d = wx.TextEntryDialog(
            self, "Archive transactions before what date (mm/dd/yy)?",
            "Archive Date")
        if d.ShowModal() == wx.ID_OK:
            date = Date(d.GetValue())
        else:
            date = None
        d.Destroy()
        if not date:
            return
        archive = Asset()
        newcb_starttransaction = Transaction()
        newcb_starttransaction.amount = 0
        newcb_starttransaction.payee = "Starting Balance"
        newcb_starttransaction.memo = "Archived by PyAsset"
        newcb_starttransaction.state = "cleared"
        newcb_starttransaction.date = date

        newcb = Asset()
        newcb.filename = self.cur_asset.filename
        newcb.name = self.cur_asset.name
        newcb.append(newcb_starttransaction)
        archtot = 0

        for transaction in self.cur_asset:
            if transaction.date < date and transaction.state == "cleared":
                archive.append(transaction)
                archtot += transaction.amount
            else:
                newcb.append(transaction)
        newcb_starttransaction.amount = archtot
        self.cur_asset = newcb
        while 1:
            d = wx.FileDialog(self, "Save Archive As", "", "", "*.qif",
                              wx.SAVE)
            if d.ShowModal() == wx.ID_OK:
                fname = d.GetFilename()
                dir = d.GetDirectory()
            d.Destroy()
            if fname: break
        archive.write_qif(os.path.join(dir, fname))
        self.redraw_all(-1)
        self.edited = True

    def newentry(self, *args):
        self.edited = True
        self.assets.append("New Asset")
        self.assetGrid.AppendRows()
        nassets = self.assetGrid.GetNumberRows()
        self.assetGrid.SetGridCursor(nassets - 1, 0)
        self.assetGrid.MakeCellVisible(nassets - 1, 1)
        self.redraw_all()

    def sort(self, *args):
        self.edited = True
        self.assets.sort()
        self.redraw_all()

    def deleteentry(self, *args):
        index = self.assetGrid.GetGridCursorRow()
        indices = self.assetGrid.SelectedCells
        if index >= 0:
            d = wx.MessageDialog(self, "Really delete this asset?",
                                 "Really delete?", wx.YES_NO)
            if d.ShowModal() == wx.ID_YES:
                del self.assets[index]
            self.redraw_all(
            )  # TODO: Can we make a self.redraw(index-1)  so that only the assets[index-1:] get updated?  JJG 07/09/2021

    def about(self, *args):
        d = wx.MessageDialog(
            self, "Python Asset Manager\n"
            "Copyright (c) 2016-2022 Joseph J. Gorak\n"
            "Released under the Gnu GPL\n", "About PyAsset",
            wx.OK | wx.ICON_INFORMATION)
        d.ShowModal()
        d.Destroy()

    def gethelp(self, *args):
        d = HelpDialog(self, -1, "Help", __doc__)
        val = d.ShowModal()
        d.Destroy()

    def MsgBox(self, message):
        d = wx.MessageDialog(self, message, "error",
                             wx.OK | wx.ICON_INFORMATION)
        d.ShowModal()
        d.Destroy()
Пример #16
0
class MyTaskBarIcon(TaskBarIcon):
    ICON = "logo.ico"  # 图标地址
    ID_ABOUT = NewIdRef()  # 菜单选项“关于”的ID
    ID_EXIT = NewIdRef()  # 菜单选项“退出”的ID
    ID_UPLOAD = NewIdRef()  # 菜单选项“显示页面”的ID
    ID_LOGIN = NewIdRef()  # 菜单选项“显示页面”的ID
    TITLE = "SMPIC"  # 鼠标移动到图标上显示的文字

    def __init__(self):
        TaskBarIcon.__init__(self)
        self.SetIcon(Icon(self.ICON), self.TITLE)  # 设置图标和标题
        self.Bind(EVT_MENU, self.onAbout, id=self.ID_ABOUT)  # 绑定“关于”选项的点击事件
        self.Bind(EVT_MENU, self.onExit, id=self.ID_EXIT)  # 绑定“退出”选项的点击事件
        self.Bind(EVT_MENU, self.onUpload, id=self.ID_UPLOAD)
        self.Bind(EVT_MENU, self.OnLogin, id=self.ID_LOGIN)

        self.frame = Frame(parent=None, title='登录', size=(285, 160))
        self.frame.Bind(EVT_CLOSE, lambda event: self.frame.Show(False))

        panel = Panel(self.frame, -1)
        label_user = StaticText(panel, -1, "账号:", pos=(10, 10))
        label_pass = StaticText(panel, -1, "密码:", pos=(10, 50))

        self.entry_user = TextCtrl(panel, -1, size=(210, 20), pos=(50, 10))
        self.entry_pass = TextCtrl(panel, -1, size=(210, 20), pos=(50, 50), style=TE_PASSWORD)

        self.but_login = Button(panel, -1, "登陆", size=(50, 30), pos=(10, 80))
        self.but_register = Button(panel, -1, "注册SM.MS账号", size=(110, 30), pos=(150, 80))
        self.but_not_login = Button(panel, -1, "免登陆使用", size=(80, 30), pos=(65, 80))

        self.but_login.Bind(EVT_BUTTON, self.on_but_login)
        self.but_register.Bind(EVT_BUTTON, self.on_but_register)
        self.but_not_login.Bind(EVT_BUTTON, self.on_but_not_login)

        self.frame.Center()
        token = init_config()
        if token == '0':
            self.frame.Show(True)
        else:
            self.frame.Show(False)

        self.frame.SetMaxSize((285, 160))
        self.frame.SetMinSize((285, 160))
        ThreadKey(self)

        self.frame2 = Trans(parent=None, title='上传中', size=(50, 20))
        self.frame2.Center()
        self.frame2.Show(False)

        self.frame3 = Trans(parent=None, title='上传成功', size=(50, 20))
        self.frame3.Center()
        self.frame3.Show(False)

        self.frame4 = Trans(parent=None, title='上传失败', size=(50, 20))
        self.frame4.Center()
        self.frame4.Show(False)

        self.frame5 = Trans(parent=None, title='每分钟限制上传20张,请等待冷却', size=(200, 20))
        self.frame5.Center()
        self.frame5.Show(False)

    # “关于”选项的事件处理器
    def onAbout(self, event):
        MessageBox('Author:Jack Wang\nEmail Address:[email protected]\nLatest Update:2019-12-13', "info")

    # “退出”选项的事件处理器
    def onExit(self, event):
        global listener
        listener.stop()
        Exit()

    # “显示页面”选项的事件处理器
    def onUpload(self, event):
        get_pic_from_clipboard(self)

    def OnLogin(self, event):
        self.frame.Show(True)

    # 创建菜单选项
    def CreatePopupMenu(self):
        menu = Menu()
        for mentAttr in self.getMenuAttrs():
            menu.Append(mentAttr[1], mentAttr[0])
        return menu

    # 获取菜单的属性元组
    def getMenuAttrs(self):
        return [('上传剪贴板至SM.MS', self.ID_UPLOAD),
                ('登录', self.ID_LOGIN),
                ('关于', self.ID_ABOUT),
                ('退出', self.ID_EXIT)]

    def on_but_login(self, event):
        username = self.entry_user.GetValue()
        password = self.entry_pass.GetValue()
        try:
            token = Smms.get_token(username, password)
            with open('config.yml', 'r', encoding='utf-8') as f:
                cont = f.read()
                config = yaml.load(cont, Loader=yaml.BaseLoader)
                with open('config.yml', 'w', encoding='utf-8') as f:
                    config['token'] = token
                    yaml.dump(config, f, default_flow_style=False, encoding='utf-8', allow_unicode=True)
            self.frame.Show(False)
            MessageBox('登陆成功!\n'
                       '使用方法:\n1.首先复制一张图片,本地的或者网\n'
                       '页上的,或者使用截图工具截图;\n'
                       '2.随后按' + hotkeys + '上传;\n'
                                           '3.成功后会返回url至你的剪贴板。\n\n提示:\n可编辑config.yml修改快捷键',
                       "温馨提示")
        except KeyError:
            MessageBox('密码或账号错误', "警告")

    def on_but_not_login(self, event):
        try:
            with open('config.yml', 'r', encoding='utf-8') as f:
                cont = f.read()
                config = yaml.load(cont, Loader=yaml.BaseLoader)
                with open('config.yml', 'w', encoding='utf-8') as f:
                    config['token'] = 'not login'
                    yaml.dump(config, f, default_flow_style=False, encoding='utf-8', allow_unicode=True)
            self.frame.Show(False)

            MessageBox(
                '使用方法:\n1.首先复制一张图片,本地的或者网\n'
                '页上的,或者使用截图工具截图;\n'
                '2.随后按' + hotkeys + '上传;\n'
                                    '3.成功后会返回url至你的剪贴板。\n\n提示:\n1.免登录使用将无法在线查看你的全部上\n传记录,仅可查看本IP的上传记录\n2.可编辑config.yml修改快捷键',
                "温馨提示")
        except KeyError:
            MessageBox('出现了未知问题,请提交issue', "警告")

    def on_but_register(self, event):
        openweb('https://sm.ms/register')

    def LoginAgain(self):  # 删除线程
        MessageBox('登录已失效,需重新登录', "警告")
        self.frame.Show(True)

    def Uploading(self):
        pos = GetMousePosition()
        pos = (pos[0] + 15, pos[1])
        self.frame2.SetPosition(pos)
        def timestop():
            self.frame2.Show(False)
            timer.cancel()

        self.frame2.Show(True)
        timer = Timer(2.0, timestop)
        timer.start()

    def UploadSuccess(self):
        pos = GetMousePosition()
        pos = (pos[0] + 15, pos[1])
        self.frame3.SetPosition(pos)
        def timestop():
            self.frame3.Show(False)
            timer.cancel()

        self.frame3.Show(True)
        timer = Timer(2.0, timestop)
        timer.start()

    def UploadFailed(self):
        pos = GetMousePosition()
        pos = (pos[0] + 15, pos[1])
        self.frame4.SetPosition(pos)
        def timestop():
            self.frame4.Show(False)
            timer.cancel()

        self.frame4.Show(True)
        timer = Timer(2.0, timestop)
        timer.start()

    def UploadMax(self):
        pos = GetMousePosition()
        pos = (pos[0]+15,pos[1])
        self.frame5.SetPosition(pos)
        def timestop():
            self.frame5.Show(False)
            timer.cancel()

        self.frame5.Show(True)
        timer = Timer(5.0, timestop)
        timer.start()