class OpenInfoDialog(wx.Dialog): def __init__(self, info_list): wx.Dialog.__init__(self, None, size=(750, 600)) self.SetTitle('Choose Run') #~ info_list = [{'description': 'Test', #~ 'creation' : '2017-07-11 08:30:00'}] panel = wx.Panel(self) self.lb = ObjectListView(self, -1, style=wx.LC_REPORT) self.lb.SetColumns([ ColumnDefn('Description', 'left', 300, 'description'), ColumnDefn('# Triangles', 'center', 150, 'num_polys'), ColumnDefn('Date/Time', 'left', 300, 'creation'), ]) self.lb.SetObjects(info_list) btn_sizer = wx.Dialog.CreateButtonSizer(self, wx.OK|wx.CANCEL) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.lb, 1, flag=wx.EXPAND) sizer.Add(btn_sizer, 0, flag=wx.EXPAND) self.SetSizer(sizer) self.lb.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.onDoubleClick) def onDoubleClick(self, event): self.EndModal(wx.ID_OK)
class VenueWindow(wx.Panel): def __init__(self, parent, db=None): wx.Panel.__init__(self, parent, -1) self.listview = ObjectListView(self, wx.ID_ANY, style=wx.LC_REPORT | wx.SUNKEN_BORDER) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.listview, 1, flag=wx.EXPAND) self.SetSizer(sizer) if db: self.load(db) # pub.subscribe(self.onMapSelect, "map_selection") self.listview.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnSelect) def OnSelect(self, event): pub.sendMessage('selected_venues', venues=self.listview.GetSelectedObjects()) def load(self, db): cursor = db.cursor() cursor.execute("SELECT id, name, lat, lon FROM venue ORDER BY name") self.venues = dict([(x[0], Venue(x)) for x in cursor.fetchall()]) self.listview.SetColumns([ ColumnDefn("ID", "left", -1, "db_id"), ColumnDefn("Venue", "left", -1, "name"), ]) # self.listview.CreateCheckStateColumn() self.listview.SetObjects(list(self.venues.values())) pub.sendMessage('venues', venues=list(self.venues.values()))
class FtpPanel(wx.Panel): def __init__(self, parent): super().__init__(parent) self.frame = parent self.ftp = None self.paths = [] self.main_sizer = wx.BoxSizer(wx.VERTICAL) self.create_ui() self.SetSizer(self.main_sizer) pub.subscribe(self.update, 'update') pub.subscribe(self.update_status, 'update_status') def create_ui(self): size = (150, -1) connect_sizer = wx.BoxSizer() # host, username, password, port, connect button host_lbl = wx.StaticText(self, label='Host:') connect_sizer.Add(host_lbl, 0, wx.ALL | wx.CENTER, 5) self.host = wx.TextCtrl(self, size=size) connect_sizer.Add(self.host, 0, wx.ALL, 5) user_lbl = wx.StaticText(self, label='Username:'******'Password:'******'Port:') connect_sizer.Add(port_lbl, 0, wx.ALL | wx.CENTER, 5) self.port = wx.TextCtrl(self, value='21', size=(50, -1)) connect_sizer.Add(self.port, 0, wx.ALL, 5) connect_btn = wx.Button(self, label='Connect') connect_btn.Bind(wx.EVT_BUTTON, self.on_connect) connect_sizer.Add(connect_btn, 0, wx.ALL, 5) self.main_sizer.Add(connect_sizer) self.status = wx.TextCtrl(self, style=wx.TE_MULTILINE) self.main_sizer.Add(self.status, 1, wx.ALL | wx.EXPAND, 5) folder_ico = wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_TOOLBAR, (16, 16)) file_ico = wx.ArtProvider.GetBitmap(wx.ART_HELP_PAGE, wx.ART_TOOLBAR, (16, 16)) self.remote_server = ObjectListView(self, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.remote_server.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_change_directory) self.remote_server.AddNamedImages('folder', smallImage=folder_ico) self.remote_server.AddNamedImages('file', smallImage=file_ico) self.remote_server.SetEmptyListMsg("Not Connected") self.main_sizer.Add(self.remote_server, 2, wx.ALL | wx.EXPAND, 5) self.update_ui() def on_connect(self, event): host = self.host.GetValue() username = self.user.GetValue() password = self.password.GetValue() port = int(self.port.GetValue()) self.frame.SetStatusText('Connecting...', 1) if host and username and password and port: self.ftp = FTP() try: self.ftp.disconnect() except: pass args = [self.ftp, host, port, username, password] self.thread = threading.Thread(target=self.connect_thread, args=args) self.thread.daemon = True self.thread.start() def change_dir_thread(self, ftp, folder): """ This method should only be run using a thread """ ftp.change_directory(folder) def connect_thread(self, ftp, host, port, username, password): """ This method should only be run using a thread """ ftp.connect(host, port, username, password) def image_getter(self, path): """ Helper method to determine which image to use in the ObjectListView widget """ if path.folder: return "folder" else: return "file" def on_change_directory(self, event): current_selection = self.remote_server.GetSelectedObject() if current_selection.folder: self.thread = threading.Thread( target=self.change_dir_thread, args=[self.ftp, current_selection.filename]) self.thread.daemon = True self.thread.start() def update(self, paths): """ Called by pubsub / thread """ self.paths = paths self.update_ui() def update_status(self, message): """ Called by pubsub / thread """ ts = time.strftime(time.strftime('%H:%M:%S', time.gmtime(time.time()))) if '\n' in message: for line in message.split('\n'): line = f'{ts} {line}' self.status.WriteText(f'{line}\n') else: message = f'{ts} {message}' self.status.WriteText(f'{message}\n') def update_ui(self): self.remote_server.SetColumns([ ColumnDefn("File/Folder", "left", 800, "filename", imageGetter=self.image_getter), ColumnDefn("Filesize", "right", 80, "size"), ColumnDefn("Last Modified", "left", 150, "last_modified") ]) self.remote_server.SetObjects(self.paths)
class RssPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent, style=wx.NO_FULL_REPAINT_ON_RESIZE) self.data = [] lbl = wx.StaticText(self, label="URL канала:") lbl2 = wx.StaticText(self, label="Поиск:") self.rssSearch = wx.TextCtrl(self, value="") # self.rssSearch2 = wx.TextCtrl(self, value="") self.rssUrlTxt = wx.TextCtrl(self, value="https://lenta.ru/rss") searchBtn = wx.Button(self, label="Поиск по названию") searchBtn.Bind(wx.EVT_BUTTON, self.searchTitle) searchBtn2 = wx.Button(self, label="Поиск по содержанию") searchBtn2.Bind(wx.EVT_BUTTON, self.searchSummary) resetSearchBtn = wx.Button(self, label="Сбросить поиск") resetSearchBtn.Bind(wx.EVT_BUTTON, self.searchReset) urlBtn = wx.Button(self, label="Загрузить") urlBtn.Bind(wx.EVT_BUTTON, self.get_data) self.rssOlv = ObjectListView(self, style=wx.LC_REPORT|wx.SUNKEN_BORDER) self.rssOlv.SetEmptyListMsg("Пусто") self.rssOlv.Bind(wx.EVT_LIST_ITEM_SELECTED, self.on_select) self.rssOlv.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_double_click) self.summaryTxt = wx.html2.WebView.New(self) self.wv = wx.html2.WebView.New(self) self.listoffeeds = [] toolbar2 = wx.ToolBar(self) qtool = toolbar2.AddTool(wx.ID_ANY, '', wx.Bitmap('book-add.png'), "Добавить категорию") qtool2 = toolbar2.AddTool(wx.ID_ANY, '', wx.Bitmap('book_open-add.png'), "Добавить новость в список") qtool3 = toolbar2.AddTool(wx.ID_ANY, '', wx.Bitmap('book_open.png'), "Открыть список") toolbar2.Realize() toolbar2.Bind(wx.EVT_TOOL, self.enterCategory, qtool) toolbar2.Bind(wx.EVT_TOOL, self.save_page, qtool2) toolbar2.Bind(wx.EVT_TOOL, self.new_window, qtool3) rowSizer = wx.BoxSizer(wx.HORIZONTAL) rowSizer.Add(lbl, 0, wx.ALL, 5) rowSizer.Add(self.rssUrlTxt, 1, wx.EXPAND|wx.ALL, 5) rowSizer.Add(urlBtn, 0, wx.ALL, 5) vSizer = wx.BoxSizer(wx.VERTICAL) vSizer.Add(self.rssOlv, 1, wx.EXPAND|wx.ALL, 5) vSizer.Add(self.summaryTxt, 1, wx.EXPAND|wx.ALL, 5) rowSizer1 = wx.BoxSizer(wx.HORIZONTAL) rowSizer1.Add(lbl2, 0, wx.ALL, 5) rowSizer1.Add(self.rssSearch, 1, wx.EXPAND|wx.ALL, 5) rowSizer1.Add(searchBtn, 0, wx.ALL, 5) rowSizer1.Add(searchBtn2, 0, wx.ALL, 5) rowSizer1.Add(resetSearchBtn, 0, wx.ALL, 5) dispSizer = wx.BoxSizer(wx.HORIZONTAL) dispSizer.Add(vSizer, 1, wx.EXPAND|wx.ALL, 5) rowSizer2 = wx.BoxSizer(wx.HORIZONTAL) rowSizer2.Add(dispSizer, 0, wx.EXPAND|wx.ALL, 5) rowSizer2.Add(self.wv, 2, wx.EXPAND|wx.ALL, 5) mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(toolbar2, 0 , wx.RIGHT) mainSizer.Add(rowSizer, 0, wx.EXPAND) mainSizer.Add(rowSizer1, 0, wx.EXPAND) mainSizer.Add(rowSizer2, 1, wx.EXPAND|wx.ALL) self.SetSizer(mainSizer) self.update_display(self.data) def enterCategory(self, event): global category dlog=wx.TextEntryDialog(None,"Введите категорию") dlog.ShowModal() category=dlog.GetValue() def new_window(self, event): window = wx.Frame(None, -1, "Все записи") list_view = wx.ListCtrl(window, -1, style = wx.LC_REPORT) list_view.InsertColumn(0, 'Название', width = 100) list_view.InsertColumn(1, 'Ссылка', wx.LIST_FORMAT_RIGHT, 100) list_view.InsertColumn(2, 'Категория', wx.LIST_FORMAT_RIGHT, 100) for i in select_sth(): index = list_view.InsertStringItem(sys.maxsize, i[0]) list_view.SetStringItem(index, 1, i[1]) list_view.SetStringItem(index, 2, i[2]) window.Show() def save_page(self, event): obj = self.rssOlv.GetSelectedObject() name = obj.title link = obj.link insert_sth_smw(name, link, category) def get_data(self, event): msg = "Загрузка данных..." busyDlg = wx.BusyInfo(msg) rss = self.rssUrlTxt.GetValue() feed = feedparser.parse(rss) website = feed["feed"]["title"] for key in feed["entries"]: title = key["title"] link = key["link"] summary = key["summary"] self.data.append(RSS(title, link, website, summary, key)) busyDlg = None self.update_display(self.data) def searchTitle(self, event): search_list = [] for key in self.data: title = key.title result = re.search('\s*%s' % self.rssSearch.GetValue(), title) if result != None: search_list.append(key) self.update_display(search_list) def searchSummary(self, event): search_list1 = [] for key in self.data: summary = key.summary result1 = re.search('\s*%s' % self.rssSearch.GetValue(), summary) if result1 != None: search_list1.append(key) self.update_display(search_list1) def searchReset(self, event): self.update_display(self.data) def on_double_click(self, event): obj = self.rssOlv.GetSelectedObject() self.wv.LoadURL(obj.link) def on_select(self, event): obj = self.rssOlv.GetSelectedObject() html = "<html><body>%s</body></html>" % obj.summary self.summaryTxt.SetPage(html, "") def update_display(self, data): self.rssOlv.SetColumns([ ColumnDefn("Название", "left", 200, "title"), ColumnDefn("Сайт", "left", 200, "website"), ]) self.rssOlv.SetObjects(data)
class MainPanel(wx.Panel): def __init__(self, parent): super().__init__(parent) self.search_results = [] self.main_sizer = wx.BoxSizer(wx.VERTICAL) self.create_ui() self.SetSizer(self.main_sizer) pub.subscribe(self.update_search_results, 'update') module_path = os.path.dirname(os.path.abspath( __file__ )) self.config = os.path.join(module_path, 'config.ini') if not os.path.exists(self.config): message = 'Unable to find grin3 for text searches. ' \ 'Install grin3 and open preferences to ' \ 'configure it: pip install grin3' self.show_error(message) def create_ui(self): # Create the widgets for the search path row_sizer = wx.BoxSizer() lbl = wx.StaticText(self, label='Location:') row_sizer.Add(lbl, 0, wx.ALL | wx.CENTER, 5) self.directory = wx.TextCtrl(self, style=wx.TE_READONLY) row_sizer.Add(self.directory, 1, wx.ALL | wx.EXPAND, 5) open_dir_btn = wx.Button(self, label='Choose Folder') open_dir_btn.Bind(wx.EVT_BUTTON, self.on_choose_folder) row_sizer.Add(open_dir_btn, 0, wx.ALL, 5) self.main_sizer.Add(row_sizer, 0, wx.EXPAND) # Add search bar self.search_ctrl = wx.SearchCtrl( self, style=wx.TE_PROCESS_ENTER, size=(-1, 25)) self.search_ctrl.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN, self.on_search) self.search_ctrl.Bind(wx.EVT_TEXT_ENTER, self.on_search) self.main_sizer.Add(self.search_ctrl, 0, wx.ALL | wx.EXPAND, 5) # Search results widget self.search_results_olv = ObjectListView( self, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.search_results_olv.SetEmptyListMsg("No Results Found") self.search_results_olv.Bind(wx.EVT_LIST_ITEM_SELECTED, self.on_selection) self.main_sizer.Add(self.search_results_olv, 1, wx.ALL | wx.EXPAND, 5) self.update_ui() self.results_txt = wx.TextCtrl( self, style=wx.TE_MULTILINE | wx.TE_READONLY) self.main_sizer.Add(self.results_txt, 1, wx.ALL | wx.EXPAND, 5) show_result_btn = wx.Button(self, label='Open Containing Folder') show_result_btn.Bind(wx.EVT_BUTTON, self.on_show_result) self.main_sizer.Add(show_result_btn, 0, wx.ALL | wx.CENTER, 5) def on_choose_folder(self, event): with wx.DirDialog(self, "Choose a directory:", style=wx.DD_DEFAULT_STYLE, ) as dlg: if dlg.ShowModal() == wx.ID_OK: self.directory.SetValue(dlg.GetPath()) def on_selection(self, event): current_selection = self.search_results_olv.GetSelectedObject() self.results_txt.SetValue('\n'.join(current_selection.data)) def on_show_result(self, event): """ Attempt to open the folder that the result was found in """ result = self.search_results_olv.GetSelectedObject() if result: path = os.path.dirname(result.path) try: if sys.platform == 'darwin': subprocess.check_call(['open', '--', path]) elif 'linux' in sys.platform: subprocess.check_call(['xdg-open', path]) elif sys.platform == 'win32': subprocess.check_call(['explorer', path]) except: if sys.platform == 'win32': # Ignore error on Windows as there seems to be # a weird return code on Windows return message = f'Unable to open file manager to {path}' self.show_error(message) def on_search(self, event): search_term = self.search_ctrl.GetValue() self.search(search_term) def search(self, search_term): """ Search for the specified term in the directory and its sub-directories """ folder = self.directory.GetValue() config = ConfigParser() config.read(self.config) try: grin = config.get("Settings", "grin") except NoSectionError: self.show_error('Settings or grin section not found') return if not os.path.exists(grin): self.show_error(f'Grin location does not exist {grin}') return if folder: self.search_results = [] SearchThread(folder, search_term) def show_error(self, message): with wx.MessageDialog(None, message=message, caption='Error', style= wx.ICON_ERROR) as dlg: dlg.ShowModal() def update_search_results(self, results): """ Called by pubsub from thread """ for key in results: if os.path.exists(key): stat = os.stat(key) modified_time = stat.st_mtime result = SearchResult(key, modified_time, results[key]) self.search_results.append(result) if results: self.update_ui() def update_ui(self): self.search_results_olv.SetColumns([ ColumnDefn("File Path", "left", 800, "path"), ColumnDefn("Modified Time", "left", 150, "modified") ]) self.search_results_olv.SetObjects(self.search_results)
class RssPanel(wx.Panel): """""" # ---------------------------------------------------------------------- def __init__(self, parent): """Constructor""" wx.Panel.__init__(self, parent, style=wx.NO_FULL_REPAINT_ON_RESIZE) self.data = [] lbl = wx.StaticText(self, label="Feed URL:") self.rssUrlTxt = wx.TextCtrl(self, value="http://www.blog.pythonlibrary.org/feed/") urlBtn = wx.Button(self, label="Get Feed") urlBtn.Bind(wx.EVT_BUTTON, self.get_data) self.rssOlv = ObjectListView(self, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.rssOlv.SetEmptyListMsg("No data") self.rssOlv.Bind(wx.EVT_LIST_ITEM_SELECTED, self.on_select) self.rssOlv.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_double_click) self.summaryTxt = webview.WebView.New(self) self.wv = webview.WebView.New(self) # add sizers rowSizer = wx.BoxSizer(wx.HORIZONTAL) rowSizer.Add(lbl, 0, wx.ALL, 5) rowSizer.Add(self.rssUrlTxt, 1, wx.EXPAND | wx.ALL, 5) rowSizer.Add(urlBtn, 0, wx.ALL, 5) vSizer = wx.BoxSizer(wx.VERTICAL) vSizer.Add(self.rssOlv, 1, wx.EXPAND | wx.ALL, 5) vSizer.Add(self.summaryTxt, 1, wx.EXPAND | wx.ALL, 5) dispSizer = wx.BoxSizer(wx.HORIZONTAL) dispSizer.Add(vSizer, 1, wx.EXPAND | wx.ALL, 5) dispSizer.Add(self.wv, 2, wx.EXPAND | wx.ALL, 5) mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(rowSizer, 0, wx.EXPAND) mainSizer.Add(dispSizer, 1, wx.EXPAND) self.SetSizer(mainSizer) self.update_display() # ---------------------------------------------------------------------- def get_data(self, event): """ Get RSS feed and add it to display """ msg = "Processing feed..." busyDlg = wx.BusyInfo(msg) rss = self.rssUrlTxt.GetValue() feed = feedparser.parse(rss) website = feed["feed"]["title"] for key in feed["entries"]: title = unidecode.unidecode(key["title"]) link = key["link"] summary = key["summary"] self.data.append(RSS(title, link, website, summary, key)) busyDlg = None self.update_display() # ---------------------------------------------------------------------- def on_double_click(self, event): """ Load the selected link in the browser widget """ obj = self.rssOlv.GetSelectedObject() self.wv.LoadURL(obj.link) # ---------------------------------------------------------------------- def on_select(self, event): """ Load the summary in the text control """ base_path = os.path.dirname(os.path.abspath(__file__)) obj = self.rssOlv.GetSelectedObject() html = "<html><body>%s</body></html>" % obj.summary fname = "summary.html" full_path = os.path.join(base_path, fname) try: with open(full_path, "w") as fh: fh.write(html) print "file:///" + full_path self.summaryTxt.LoadURL("file:///" + full_path) except (OSError, IOError): print "Error writing html summary" # ---------------------------------------------------------------------- def update_display(self): """ Update the RSS feed display """ self.rssOlv.SetColumns([ ColumnDefn("Title", "left", 200, "title"), ColumnDefn("Website", "left", 200, "website"), ]) self.rssOlv.SetObjects(self.data)
class MainPanel(wx.Panel): """""" #---------------------------------------------------------------------- def __init__(self, parent): """Constructor""" wx.Panel.__init__(self, parent=parent) self.currentSelection = None self.gui_shown = False self.procs = [] self.sort_col = 0 self.col_w = { "name": 175, "pid": 50, "exe": 300, "user": 175, "cpu": 60, "mem": 75 } self.procmonOlv = ObjectListView(self, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.procmonOlv.Bind(wx.EVT_LIST_COL_CLICK, self.onColClick) self.procmonOlv.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onSelect) #self.procmonOlv.Select self.setProcs() endProcBtn = wx.Button(self, label="End Process") endProcBtn.Bind(wx.EVT_BUTTON, self.onKillProc) mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(self.procmonOlv, 1, wx.EXPAND | wx.ALL, 5) mainSizer.Add(endProcBtn, 0, wx.ALIGN_RIGHT | wx.ALL, 5) self.SetSizer(mainSizer) # check for updates every 15 seconds self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.update, self.timer) self.update("") self.setProcs() # create a pubsub receiver Publisher.subscribe(self.updateDisplay, "update") #---------------------------------------------------------------------- def onColClick(self, event): """ Remember which column to sort by, currently only does ascending """ self.sort_col = event.GetColumn() #---------------------------------------------------------------------- def onKillProc(self, event): """ Kill the selected process by pid """ obj = self.procmonOlv.GetSelectedObject() print pid = int(obj.pid) try: p = psutil.Process(pid) p.terminate() self.update("") except Exception as e: print "Error: ", e #---------------------------------------------------------------------- def onSelect(self, event): """ Gets called when an item is selected and helps keep track of what item is selected """ item = event.GetItem() itemId = item.GetId() self.currentSelection = itemId #---------------------------------------------------------------------- def setProcs(self): """ Updates the ObjectListView widget display """ cw = self.col_w # change column widths as necessary if self.gui_shown: cw["name"] = self.procmonOlv.GetColumnWidth(0) cw["pid"] = self.procmonOlv.GetColumnWidth(1) cw["exe"] = self.procmonOlv.GetColumnWidth(2) cw["user"] = self.procmonOlv.GetColumnWidth(3) cw["cpu"] = self.procmonOlv.GetColumnWidth(4) cw["mem"] = self.procmonOlv.GetColumnWidth(5) cols = [ ColumnDefn("name", "left", cw["name"], "name"), ColumnDefn("pid", "left", cw["pid"], "pid"), ColumnDefn("exe location", "left", cw["exe"], "exe"), ColumnDefn("username", "left", cw["user"], "user"), ColumnDefn("cpu", "left", cw["cpu"], "cpu"), ColumnDefn("mem", "left", cw["mem"], "mem"), #ColumnDefn("description", "left", 200, "desc") ] self.procmonOlv.SetColumns(cols) self.procmonOlv.SetObjects(self.procs) self.procmonOlv.SortBy(self.sort_col) if self.currentSelection: self.procmonOlv.Select(self.currentSelection) self.procmonOlv.SetFocus() self.gui_shown = True #---------------------------------------------------------------------- def update(self, event): """ Start a thread to get the pid information """ print "update thread started!" self.timer.Stop() controller.ProcThread() #---------------------------------------------------------------------- def updateDisplay(self, msg): """ Catches the pubsub message from the thread and updates the display """ print "thread done, updating display!" self.procs = msg.data self.setProcs() if not self.timer.IsRunning(): self.timer.Start(15000)
class MainFrame(wx.Frame): def __init__(self, parent): wx.Frame.__init__(self, parent, id=wx.ID_ANY, title='ActOf', size=wx.Size(1037, 605), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) #Создание меню menubar = wx.MenuBar() fileMenu = wx.Menu() refMenu = wx.Menu() ftMenu = wx.Menu() fileMenu.Append(ID_MB_SETTINGS, "Настройки", "Открытие окна настроек") fileMenu.AppendSeparator() fileMenu.Append(ID_MB_EXIT, "Выход", "Выход из приложения") ftMenu.Append(ID_MB_OPENFOLDERLOCAL, "Открыть папку локальных актов") ftMenu.Append(ID_MB_OPENFOLDERREPO, "Открыть папку актов") ftMenu.Append(ID_MB_OPENDOCX, "Открыть шаблон docx") refMenu.Append(ID_MB_ABOUT, "О программе", "Описание программы") menubar.Append(fileMenu, "Файл") menubar.Append(ftMenu, "Навигация") menubar.Append(refMenu, "Справка") self.SetMenuBar(menubar) #Назначение функций кнопкам меню: self.Bind(wx.EVT_MENU, self.onSettings, id=ID_MB_SETTINGS) self.Bind(wx.EVT_MENU, self.onQuit, id=ID_MB_EXIT) self.Bind(wx.EVT_MENU, self.openFolderLocalActs, id=ID_MB_OPENFOLDERLOCAL) self.Bind(wx.EVT_MENU, self.openFolderActs, id=ID_MB_OPENFOLDERREPO) self.Bind(wx.EVT_MENU, self.openDocxTemplate, id=ID_MB_OPENDOCX) self.Bind(wx.EVT_MENU, self.about, id=ID_MB_ABOUT) #Определение шрифтов: self.fontSTactNum = wx.Font(15, wx.MODERN, wx.NORMAL, wx.BOLD, False, u'Times New Roman') self.fontBodyAct = wx.Font(12, wx.MODERN, wx.NORMAL, wx.NORMAL, False, u'Times New Roman') self.fontOLV = wx.Font(10, wx.MODERN, wx.NORMAL, wx.NORMAL, False, u'Roboto') self.font = wx.Font(12, wx.MODERN, wx.NORMAL, wx.NORMAL, False, u'Montserrat') #Создание панели: self.panel = wx.Panel(self) self.panel.SetFont(self.font) #Объявление сайзеров------------------------------------------------------------------------ #Главный сайзер программы: self.mainSizer = wx.BoxSizer(wx.HORIZONTAL) #Левая часть для шаблонов актов: self.leftSTemplActs = wx.BoxSizer(wx.VERTICAL) #Центральная часть сайзеры для создания актов: self.centrSCreateActs = wx.BoxSizer(wx.VERTICAL) self.centrSCreateActsGeneral = wx.BoxSizer(wx.HORIZONTAL) self.centrSActNumDef = wx.BoxSizer(wx.HORIZONTAL) self.centrSAZSSSONumDef = wx.BoxSizer(wx.HORIZONTAL) #Правая часть: Сайзеры для отправки актов(горизонтальный для добавления кнопок): self.rightSSendActs = wx.BoxSizer(wx.VERTICAL) self.rightSSendActsTopBTN = wx.BoxSizer(wx.HORIZONTAL) self.rSizerfileworkBTN = wx.BoxSizer(wx.HORIZONTAL) #Левая часть программы, список шаблонов и кнопки управления ими: #Создание кнопки Сохранить шаблон акта self.BTNSaveTemplateAct = wx.Button(self.panel, id=ID_BTN_SAVETEMPLACT, label="Сохранить шаблон <-") self.BTNChangeTemplAct = wx.Button(self.panel, id=ID_BTN_CHANGETEMPLACT, label="Изменить шаблон") self.BTNRefreshTemplAct = wx.Button(self.panel, id=ID_BTN_REFTEMPLACT, label="Обновить список шаблонов") self.BTNDeleteTemplAct = wx.Button(self.panel, id=ID_BTN_DELTEMPLACT, label="Удалить шаблон") self.BTNAddTemplAct = wx.Button(self.panel, id=ID_BTN_ADDTEMPLACT, label="Применить шаблон ->") #Добавление виджетов управления шаблонами актов в левый сайзер: self.leftSTemplActs.Add(self.BTNSaveTemplateAct, flag=wx.LEFT | wx.TOP | wx.EXPAND, border=5) self.leftSTemplActs.Add(self.BTNChangeTemplAct, flag=wx.LEFT | wx.TOP | wx.EXPAND, border=5) self.leftSTemplActs.Add(self.BTNRefreshTemplAct, flag=wx.LEFT | wx.TOP | wx.EXPAND, border=5) self.leftSTemplActs.Add(self.BTNDeleteTemplAct, flag=wx.LEFT | wx.TOP | wx.EXPAND, border=5) self.leftSTemplActs.Add(self.BTNAddTemplAct, flag=wx.LEFT | wx.TOP | wx.EXPAND, border=5) #Создание списка шаблонов: self.OLVtempl_acts = ObjectListView(self.panel, wx.ID_ANY, style=wx.LC_REPORT | wx.SUNKEN_BORDER) templnum = ColumnDefn("№", "left", 50, "templnum", isSpaceFilling=False) desctempl = ColumnDefn("Описание шаблона", "left", 300, "desctempl", isSpaceFilling=False) self.OLVtempl_acts.oddRowsBackColor = wx.WHITE self.OLVtempl_acts.SetFont(self.fontOLV) self.OLVtempl_acts.SetColumns([templnum, desctempl]) self.OLVtempl_acts.SetObjects(db.gettemplateslistfromdb()) # Добавление списка актов в левый сайзер self.leftSTemplActs.Add(self.OLVtempl_acts, proportion=1, flag=wx.EXPAND | wx.TOP | wx.LEFT, border=5) #Добавление левого сайзера в главный сайзер: self.mainSizer.Add(self.leftSTemplActs, flag=wx.EXPAND | wx.BOTTOM, border=5) #Центральная часть программы, поле для ввода текста и кнопка создать акт: #Создание кнопок "Обновить всё", "Создать Акт", "Очистить": self.BTNrefreshAll = wx.Button(self.panel, id=ID_BTN_REFALL, label="Обновить всё") self.BTNCreateActCS = wx.Button(self.panel, id=ID_BTN_CRARCT, label=u"Создать Акт") self.BTNclearAll = wx.Button(self.panel, id=ID_BTN_CLEAR, label="Очистить всё") #Создание заголовка "Акт №" + поле ввода акта + кнопка обновить: self.BTNactNum = wx.Button(self.panel, ID_BTN_ACTNUM, label="Акт №") self.BTNactNum.SetFont(self.fontSTactNum) self.TCActNumDef = wx.TextCtrl(self.panel, ID_TC_ACTNUM, wx.EmptyString, wx.DefaultPosition, size=(85, -1)) self.TCActNumDef.SetFont(self.fontSTactNum) #Создание шапки документа номер АЗС номер ССО по аналогии с номером акта, текущая дата: self.BTNAZSnum = wx.Button(self.panel, ID_BTN_AZSNUM, label="АЗС №") self.BTNAZSnum.SetFont(self.fontBodyAct) self.TCAZSNumDef = wx.TextCtrl(self.panel, ID_TC_AZSNUM, wx.EmptyString, wx.DefaultPosition, size=(65, -1)) self.TCAZSNumDef.SetFont(self.fontBodyAct) self.BTNSSOnum = wx.Button(self.panel, ID_BTN_SSONUM, label="ССО №") self.BTNSSOnum.SetFont(self.fontBodyAct) self.TCSSONumDef = wx.TextCtrl(self.panel, ID_TC_SSONUM, wx.EmptyString, wx.DefaultPosition, size=(65, -1)) self.TCSSONumDef.SetFont(self.fontBodyAct) self.BTNdatenum = wx.Button(self.panel, ID_BTN_DATEINP, label="Дата") self.BTNdatenum.SetFont(self.fontBodyAct) self.TCdateNumDef = wx.TextCtrl(self.panel, ID_TC_DATEINP, wx.EmptyString, wx.DefaultPosition, size=(150, -1)) self.TCdateNumDef.SetFont(self.fontBodyAct) #Создание текстового поля ввода текста акта: self.TCTextInputCS = wx.TextCtrl(self.panel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE) self.TCTextInputCS.SetFont(self.fontBodyAct) # Добавление кнопки обновить, создать, очистить в сайзер: self.centrSCreateActsGeneral.Add(self.BTNrefreshAll) self.centrSCreateActsGeneral.Add(self.BTNCreateActCS, wx.EXPAND) self.centrSCreateActsGeneral.Add(self.BTNclearAll) # Добавление виджетов номера акта в сайзер определения акта: self.centrSActNumDef.Add(self.BTNactNum) self.centrSActNumDef.Add(self.TCActNumDef) # Добавление виджетов номера АЗС, ССО, и текущей даты в сайзер: self.centrSAZSSSONumDef.Add(self.BTNAZSnum) self.centrSAZSSSONumDef.Add(self.TCAZSNumDef) self.centrSAZSSSONumDef.Add(self.BTNSSOnum, flag=wx.LEFT, border=5) self.centrSAZSSSONumDef.Add(self.TCSSONumDef) self.centrSAZSSSONumDef.Add(self.BTNdatenum, flag=wx.LEFT, border=5) self.centrSAZSSSONumDef.Add(self.TCdateNumDef) # Добавление всех элементов в центральный сайзер: self.centrSCreateActs.Add(self.centrSCreateActsGeneral, 0, wx.TOP | wx.LEFT | wx.RIGHT | wx.EXPAND, 5) self.centrSCreateActs.Add(self.centrSActNumDef, proportion=0, flag=wx.TOP | wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER, border=5) self.centrSCreateActs.Add(self.centrSAZSSSONumDef, proportion=0, flag=wx.TOP | wx.LEFT | wx.RIGHT, border=5) self.centrSCreateActs.Add(self.TCTextInputCS, 1, wx.ALL | wx.EXPAND, 5) #Добавление центрального сайзера в главный сайзер: self.mainSizer.Add(self.centrSCreateActs, proportion=1, flag=wx.EXPAND, border=5) #Правая часть программы, список созданных актов и кнопки для работы с ними: #Создание и добавление кнопок в сайзер: self.send_actBTN = wx.Button(self.panel, id=ID_BTN_SENDACT, label="Отправить Акт") self.del_actBTN = wx.Button(self.panel, id=ID_BTN_DELACT, label="Удалить файлы") self.refresh_lactsBTN = wx.Button(self.panel, id=ID_BTN_REFLACT, label="Обновить список") self.rightSSendActsTopBTN.Add(self.send_actBTN, 1, flag=wx.EXPAND | wx.TOP | wx.RIGHT, border=5) self.rightSSendActsTopBTN.Add(self.del_actBTN, 1, flag=wx.EXPAND | wx.TOP | wx.RIGHT, border=5) self.rightSSendActsTopBTN.Add(self.refresh_lactsBTN, 1, flag=wx.EXPAND | wx.TOP | wx.RIGHT, border=5) self.open_docx_BTN = wx.Button(self.panel, id=ID_BTN_OPENDOCX, label="Открыть docx") self.recopy_act_BTN = wx.Button(self.panel, id=ID_BTN_RECOPYACT, label="Коп. в папку Актов") self.copy_pdf_inbufferBTN = wx.Button(self.panel, id=ID_BTN_COPYPDFBUFF, label="Коп. pdf в буфер") self.rSizerfileworkBTN.Add(self.open_docx_BTN, 1, flag=wx.EXPAND | wx.TOP | wx.RIGHT, border=5) self.rSizerfileworkBTN.Add(self.recopy_act_BTN, 1, flag=wx.EXPAND | wx.TOP | wx.RIGHT, border=5) self.rSizerfileworkBTN.Add(self.copy_pdf_inbufferBTN, 1, flag=wx.EXPAND | wx.TOP | wx.RIGHT, border=5) self.rightSSendActs.Add(self.rightSSendActsTopBTN, proportion=0, flag=wx.EXPAND) self.rightSSendActs.Add(self.rSizerfileworkBTN, proportion=0, flag=wx.EXPAND) #Создание списка актов self.OLVlocal_acts = ObjectListView(self.panel, wx.ID_ANY, style=wx.LC_REPORT | wx.SUNKEN_BORDER) #Создание столбцов title = ColumnDefn("Имя", "left", 280, "title", isSpaceFilling=False) creating = ColumnDefn("Дата создания", "left", 130, "creating", stringConverter="%d-%m-%Y %H:%M:%S", isSpaceFilling=False) modifine = ColumnDefn("Дата изменения", "left", 130, "modifine", stringConverter="%d-%m-%Y %H:%M:%S", isSpaceFilling=False) self.OLVlocal_acts.oddRowsBackColor = wx.WHITE self.OLVlocal_acts.SetFont(self.fontOLV) self.OLVlocal_acts.SetColumns([title, creating, modifine]) #Добавление в список актов из папки locals_act self.OLVlocal_acts.SetObjects( filetools.get_listdir_docx_files_in_dict( settings.get_local_acts_path_folder())) #Добавление списка актов в сайзер self.rightSSendActs.Add(self.OLVlocal_acts, proportion=1, flag=wx.EXPAND | wx.TOP | wx.RIGHT | wx.BOTTOM, border=5) #Добавление правого сайзера в главный сайзер. self.mainSizer.Add(self.rightSSendActs, proportion=0, flag=wx.EXPAND) #Назначение главного сайзера self.panel.SetSizer(self.mainSizer) #Назначение событий self.Bind(wx.EVT_BUTTON, self.createActOn, id=ID_BTN_CRARCT) self.Bind(wx.EVT_BUTTON, self.sendActOn, id=ID_BTN_SENDACT) self.Bind(wx.EVT_BUTTON, self.del_acts_action, id=ID_BTN_DELACT) self.Bind(wx.EVT_BUTTON, self.refresh_list_acts, id=ID_BTN_REFLACT) self.Bind(wx.EVT_BUTTON, self.open_docx, id=ID_BTN_OPENDOCX) self.Bind(wx.EVT_BUTTON, self.recopy_file_in_general, id=ID_BTN_RECOPYACT) self.Bind(wx.EVT_BUTTON, self.copy_pdf_in_clipboard, id=ID_BTN_COPYPDFBUFF) self.Bind(wx.EVT_BUTTON, self.act_num_refresh, id=ID_BTN_ACTNUM) self.Bind(wx.EVT_BUTTON, self.azs_num_refresh, id=ID_BTN_AZSNUM) self.Bind(wx.EVT_BUTTON, self.sso_num_refresh, id=ID_BTN_SSONUM) self.Bind(wx.EVT_BUTTON, self.current_data_refresh, id=ID_BTN_DATEINP) self.Bind(wx.EVT_BUTTON, self.refresh_all, id=ID_BTN_REFALL) self.Bind(wx.EVT_BUTTON, self.clear_all, id=ID_BTN_CLEAR) self.OLVlocal_acts.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.open_docx) self.OLVlocal_acts.Bind(wx.EVT_KEY_DOWN, self.ctrl_c_in_list) self.OLVlocal_acts.Bind(wx.EVT_KEY_DOWN, self.enter_and_del_action_in_list) self.Bind(wx.EVT_BUTTON, self.btn_save_templ_act, id=ID_BTN_SAVETEMPLACT) self.Bind(wx.EVT_BUTTON, self.btn_change_templ_act, id=ID_BTN_CHANGETEMPLACT) self.Bind(wx.EVT_BUTTON, self.btn_refresh_templ_act, id=ID_BTN_REFTEMPLACT) self.Bind(wx.EVT_BUTTON, self.btn_delete_templ_act, id=ID_BTN_DELTEMPLACT) self.Bind(wx.EVT_BUTTON, self.btn_add_templ_act, id=ID_BTN_ADDTEMPLACT) self.OLVtempl_acts.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.btn_add_templ_act) self.OLVtempl_acts.Bind(wx.EVT_KEY_DOWN, self.enter_del_btn_action_in_templ_ovl) def enter_del_btn_action_in_templ_ovl(self, event): if event.GetKeyCode() == 127: self.btn_delete_templ_act(event) elif event.GetKeyCode() == 370 or event.GetKeyCode() == 13: self.btn_add_templ_act(event) def btn_add_templ_act(self, event): selection = self.OLVtempl_acts.GetSelectedObjects() if selection: complitetextlist = filetools.settextactfromtemplate( filetools.splittextonlist( db.gettemplatetextfromdb(selection[0]['templnum'])), filetools.splittextonlist(self.TCTextInputCS.GetValue())) self.TCTextInputCS.SetLabel('') for i in range(len(complitetextlist)): if len(complitetextlist) - 1 == i: self.TCTextInputCS.AppendText(complitetextlist[i]) else: self.TCTextInputCS.AppendText(complitetextlist[i] + '\n') def btn_delete_templ_act(self, event): selection = self.OLVtempl_acts.GetSelectedObjects() if selection: dlg = wx.MessageBox('Удалить выбранный шаблон?', 'Подтверждение', wx.YES_NO | wx.NO_DEFAULT, self) if dlg == wx.YES: db.deletetemplatefromdb(selection[0]['templnum']) self.btn_refresh_templ_act(event) def btn_refresh_templ_act(self, event): self.OLVtempl_acts.SetObjects(db.gettemplateslistfromdb()) def btn_change_templ_act(self, event): selection = self.OLVtempl_acts.GetSelectedObjects() if selection: with changetemplatedlg.ChangeTemplDlg(self, title="Изменение шаблона", size=wx.Size(500, 600)) as dlg: dlg.ShowModal() self.btn_refresh_templ_act(event) def btn_save_templ_act(self, event): dlg = wx.TextEntryDialog(self, message="Укажите краткое описание:", caption="Добавление шаблона", style=wx.TextEntryDialogStyle) res = dlg.ShowModal() if res == wx.ID_OK: db.inserttemplateindb( (dlg.GetValue(), self.TCTextInputCS.GetValue())) self.btn_refresh_templ_act(event) def enter_and_del_action_in_list(self, event): if event.GetKeyCode() == 127: self.del_acts_action(event) elif event.GetKeyCode() == 370 or event.GetKeyCode() == 13: selection = self.OLVlocal_acts.GetSelectedObjects() if selection: os.startfile( os.path.realpath( filetools.get_path_to_file_to_string( selection[0]['title']))) def ctrl_c_in_list(self, event): if event.ControlDown() and event.GetKeyCode() == 67: self.copy_pdf_in_clipboard(event) def clear_all(self, event): if event.GetId() == ID_BTN_CLEAR: self.TCActNumDef.SetLabel("") self.TCAZSNumDef.SetLabel("") self.TCSSONumDef.SetLabel("") self.TCdateNumDef.SetLabel("") self.TCTextInputCS.SetLabel("") def refresh_all(self, event): if event.GetId() == ID_BTN_REFALL: self.act_num_refresh(event) self.azs_num_refresh(event) self.sso_num_refresh(event) self.current_data_refresh(event) def current_data_refresh(self, event): if event.GetId() == ID_BTN_DATEINP or event.GetId() == ID_BTN_REFALL: self.TCdateNumDef.SetLabel(filetools.get_current_date()) def sso_num_refresh(self, event): if event.GetId() == ID_BTN_SSONUM or event.GetId() == ID_BTN_REFALL: txtlst = list( map(lambda x: x.strip(), self.TCTextInputCS.GetValue().split('\n'))) if self.TCTextInputCS.GetValue(): if filetools.get_from_bodylist_ssonum(txtlst): self.TCSSONumDef.SetLabel( filetools.get_from_bodylist_ssonum(txtlst)) def azs_num_refresh(self, event): if event.GetId() == ID_BTN_AZSNUM or event.GetId() == ID_BTN_REFALL: txtlst = filetools.splittextonlist(self.TCTextInputCS.GetValue()) if self.TCTextInputCS.GetValue(): if filetools.get_from_bodylist_azsnum(txtlst): self.TCAZSNumDef.SetLabel( filetools.get_from_bodylist_azsnum(txtlst)) def act_num_refresh(self, event): if event.GetId() == ID_BTN_ACTNUM or event.GetId() == ID_BTN_REFALL: self.TCActNumDef.SetLabel(filetools.get_number_act()) def copy_pdf_in_clipboard(self, event): selection = self.OLVlocal_acts.GetSelectedObjects() if selection: progress = wx.ProgressDialog( "Копирование файлов в буфер обмена", f"Количество файлов в очереди {len(selection)}", maximum=len(selection), parent=self, style=wx.PD_AUTO_HIDE | wx.PD_APP_MODAL) for i in range(len(selection)): path = filetools.get_path_to_file_to_string( filetools.get_name_pdf_from_docx(selection[i]['title'])) if i == 0: proc = subprocess.Popen( ['powershell', f'Set-Clipboard -Path {path}']) proc.wait() progress.Update( 1, f"Количество файлов в очереди {len(selection) - (i + 1)}" ) else: proc = subprocess.Popen( ['powershell', f'Set-Clipboard -Append -Path {path}']) proc.wait() progress.Update( i + 1, f"Количество файлов в очереди {len(selection) - (i + 1)}" ) def recopy_file_in_general(self, event): selection = self.OLVlocal_acts.GetSelectedObjects() if selection: progress = wx.ProgressDialog("Копирование...", "Копирование файлов в общую папку", maximum=len(selection), parent=self, style=wx.PD_AUTO_HIDE | wx.PD_APP_MODAL) for i in range(len(selection)): filetools.create_pdf_file_from_docx( filetools.get_path_to_file_to_string( selection[i]['title'])) filetools.copy_files_to_general_folder(selection[i]['title']) progress.Update(i + 1) progress.Destroy() def open_docx(self, event): selection = self.OLVlocal_acts.GetSelectedObjects() if selection: os.startfile( os.path.realpath( filetools.get_path_to_file_to_string( selection[0]['title']))) def onSettings(self, event): with settingsdlg.SettingsDlg(self, title="Настройки") as dlg: dlg.ShowModal() def onQuit(self, event): self.Close() def openFolderLocalActs(self, event): os.startfile(os.path.realpath(settings.get_local_acts_path_folder())) def openFolderActs(self, event): os.startfile(os.path.realpath(settings.get_general_acts_path_folder())) def openDocxTemplate(self, event): os.startfile(os.path.realpath(settings.get_docx_templ_path())) def about(self, event): with aboutdlg.AboutDlg(self, title="Настройки") as dlg: dlg.ShowModal() def del_acts_action(self, event): selection = self.OLVlocal_acts.GetSelectedObjects() if selection: dlg = wx.MessageBox('Удалить выбранные файлы?', 'Подтверждение', wx.YES_NO | wx.NO_DEFAULT, self) if dlg == wx.YES: for i in range(len(selection)): os.remove( filetools.get_path_to_file_to_string( selection[i]['title'])) os.remove( filetools.get_path_to_file_to_string( filetools.get_name_pdf_from_docx( selection[i]['title']))) self.refresh_list_acts(event) def refresh_list_acts(self, event): self.OLVlocal_acts.SetObjects( filetools.get_listdir_docx_files_in_dict( settings.get_local_acts_path_folder())) def createActOn(self, event): if "template.docx" not in settings.get_docx_templ_path(): msgdlg = wx.MessageDialog(self, "Не найден файл шаблона template.docx", "Ошибка", wx.OK | wx.STAY_ON_TOP | wx.CENTRE) msgdlg.ShowModal() return -1 if not event.GetId( ) == ID_BTN_CRARCT and self.TCTextInputCS.GetNumberOfLines() > 0: txtlst = list( map(lambda x: x.strip(), self.TCTextInputCS.GetValue().split('\n'))) progress = wx.ProgressDialog( "Создание Акта...", "Этап 0 из 6: Инициализация метода создания акта", maximum=100, parent=self, style=wx.PD_AUTO_HIDE | wx.PD_APP_MODAL) progress.Update(10, "Этап 1 из 6: Формирование имя акта") filenamedocx = \ f"Акт{self.TCActNumDef.GetValue()}_АЗС{self.TCAZSNumDef.GetValue()}_ССО{self.TCSSONumDef.GetValue()}." \ f"docx" progress.Update( 20, "Этап 2 из 6: Формирование пути расположения акта") docxpath = settings.get_local_acts_path_folder() + filenamedocx progress.Update(30, "Этап 3 из 6: Создание docx документа") filetools.create_docx_file_from_bodylist( txtlst, self.TCAZSNumDef.GetValue(), self.TCSSONumDef.GetValue(), self.TCActNumDef.GetValue(), self.TCdateNumDef.GetValue(), docxpath) progress.Update(60, "Этап 4 из 6: Создание pdf документа") filetools.create_pdf_file_from_docx(docxpath) progress.Update(80, "Этап 5 из 6: Копирование файлов в общую папку") filetools.copy_files_to_general_folder(filenamedocx) self.refresh_list_acts(event) progress.Update(100, "Этап 6 из 6: Обновление списка актов") progress.Destroy() def sendActOn(self, event): if event.GetId() == ID_BTN_SENDACT: selection = self.OLVlocal_acts.GetSelectedObjects() if selection: app = win32com.client.Dispatch("Outlook.Application") mess = app.CreateItem(0) mess.Subject = filetools.get_theme_from_act_list(selection) mess.GetInspector() index = mess.HTMLbody.find('>', mess.HTMLbody.find('<body')) mess.HTMLbody = mess.HTMLbody[:index + 1] + filetools.get_text_for_mail_from_act_list(selection) +\ mess.HTMLbody[index + 1:] for i in range(len(selection)): if os.path.exists( filetools.get_path_to_file_to_string( filetools.get_name_pdf_from_docx( selection[i]['title']))): mess.Attachments.Add( filetools.get_path_to_file_to_string( filetools.get_name_pdf_from_docx( selection[i]['title']))) mess.Display(True)
class Meds(wx.Panel): def __init__(self, parent, id, ptID): wx.Panel.__init__(self, parent, id) self.ptID = ptID self.toggler = 'Current Meds' self.reviewed = 0 meds = med_find(ptID) self.list = ObjectListView(self, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.list.SetColumns([ ColumnDefn("Name", "left", 250, valueGetter="med_name"), ColumnDefn("Dose", "center", 180, valueGetter="dose"), ColumnDefn("Tablets", "center", 60, valueGetter="number_tablets"), ColumnDefn("Route", "left", 60, valueGetter="route"), ColumnDefn("Frequency", "left", 80, valueGetter="frequency"), ColumnDefn("#", "center", 40, valueGetter="number_pills"), ColumnDefn("Refills", "center", 50, valueGetter="refills"), ColumnDefn("Date", "left", 100, valueGetter="script_date") ]) self.list.SetObjects(meds) self.list.cellEditMode = ObjectListView.CELLEDIT_DOUBLECLICK self.list.Bind(EVT_CELL_EDIT_STARTING, self.HandleCellEditStarting) self.list.Bind(EVT_CELL_EDIT_FINISHED, self.listHandleCellEditFinished) leftmed = wx.BoxSizer(wx.VERTICAL) rightmed = wx.BoxSizer(wx.VERTICAL) mainmed = wx.BoxSizer(wx.HORIZONTAL) medbuttons = (('Archive', self.OnArchMed), ('Print', self.OnpRintMed), ('Delete', self.OnDeleteMed), ('Toggle', self.OnToggleMed), ('Interactions', self.OnInteractions), ('Reviewed', self.OnReviewed)) for label, handler in medbuttons: EMR_utilities.buildOneButton(self, self, label, handler, leftmed) allergies = allergy_find(ptID) self.allergylist = ObjectListView(self, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.allergylist.SetColumns([ ColumnDefn("Allergy", "left", 200, valueGetter="allergy"), ColumnDefn("Reaction", "left", 250, valueGetter="reaction") ]) self.allergylist.SetObjects(allergies) self.allergylist.cellEditMode = ObjectListView.CELLEDIT_DOUBLECLICK self.allergylist.Bind(EVT_CELL_EDIT_STARTING, self.HandleCellEditStarting) self.allergylist.Bind(EVT_CELL_EDIT_FINISHED, self.allergyHandleCellEditFinished) leftall = wx.BoxSizer(wx.VERTICAL) rightall = wx.BoxSizer(wx.VERTICAL) mainall = wx.BoxSizer(wx.HORIZONTAL) allbuttons = (('Add', self.OnNewAll, leftall), ('Remove', self.OnRemAll, leftall)) for label, handler, sizer in allbuttons: EMR_utilities.buildOneButton(self, self, label, handler, sizer) addmed = AddMed(self, -1, self.ptID) #Set the sizers that have not already been set mainsizer = wx.BoxSizer(wx.VERTICAL) rightmed.Add(self.list, 1, wx.EXPAND | wx.TOP, 3) self.medtitle = wx.StaticText(self, -1, self.toggler) titlefont = wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.BOLD) self.medtitle.SetFont(titlefont) mainmed.Add(leftmed, 0) mainmed.Add((15, -1)) mainmed.Add(rightmed, 1, wx.EXPAND) rightall.Add(self.allergylist, 1, wx.EXPAND | wx.TOP, 3) rightmed.Add(addmed, 1, wx.EXPAND) mainall.Add(leftall, 0) mainall.Add((15, -1)) mainall.Add(rightall, 1, wx.EXPAND) mainsizer.Add(mainall, 2, wx.EXPAND) mainsizer.Add(self.medtitle, 0, wx.ALIGN_CENTER | wx.ALL, 5) mainsizer.Add(mainmed, 4, wx.EXPAND) mainsizer.Add((-1, 5)) self.SetSizer(mainsizer) self.Centre() self.Show(True) def OnArchMed( self, event ): #need add/edit form pulled up on selected meds, update query, requery meds #open AddEditMed form with selected/checked med filled in obj = self.list.GetSelectedObjects() for items in obj: qry = 'UPDATE meds SET archive = 1 WHERE med_number = %s;' % items[ 'med_number'] self.list.RemoveObject(items) EMR_utilities.updateData(qry) def OnpRintMed(self, event): obj = self.list.GetSelectedObjects() string = '' for items in obj: string = '%s %s\n take %s %s %s #%s refills: %s\n\n' % \ (items["med_name"], items["dose"], items["number_tablets"], items["route"], items["frequency"], items["number_pills"], items["refills"]) + string form_lt = "%s/EMR_outputs/Script.html" % settings.LINUXPATH form_at = "%s/EMR_outputs/Script.html" % settings.APPLEPATH form_wt = "%s\EMR_outputs\Script.html" % settings.WINPATH form = open(EMR_utilities.platformText(form_lt, form_at, form_wt), 'r') s = form.read() form.close() dem_data = EMR_utilities.getDictData( 'SELECT * FROM demographics WHERE patient_ID = %s;' % self.ptID) dem_data['string'] = string dem_data['date'] = EMR_utilities.dateToday() dem_data['name_address'] = EMR_formats.format_address(dem_data) script_text = s % (dem_data) printer = EMR_utilities.Printer() printer.PreviewText(script_text) path_lt = "%s/EMR_outputs/%s/Orders" % (settings.LINUXPATH, self.ptID) path_at = "%s/EMR_outputs/%s/Orders" % (settings.APPLEPATH, self.ptID) path_wt = "%s\EMR_outputs\%s\Orders" % (settings.WINPATH, self.ptID) path = EMR_utilities.platformText(path_lt, path_at, path_wt) filename = "%s/script%s.html" % ( path, EMR_utilities.dateToday(t='file format')) f = open(filename, 'w') f.write(script_text) f.close() def OnDeleteMed(self, event): obj = self.list.GetSelectedObjects() for items in obj: qry = 'DELETE FROM meds WHERE med_number = %s;' % items[ 'med_number'] self.list.RemoveObject(items) EMR_utilities.updateData(qry) def OnToggleMed(self, event): if self.toggler == 'Current Meds': self.toggler = 'Archived Meds' self.medtitle.SetLabel(self.toggler) qry = 'SELECT * FROM meds WHERE archive = 1 AND patient_ID = %s' % ( self.ptID) data = EMR_utilities.getAllDictData(qry) self.list.SetObjects(list(data)) else: self.toggler = 'Current Meds' self.medtitle.SetLabel(self.toggler) self.UpdateList() def OnInteractions(self, event): obj = self.list.GetSelectedObjects() string = 'http://mletter.best.vwh.net/Psc/dip2.cgi?userid=guest' count = 1 for items in obj: string = string + '&drug%s=%s' % (count, items['med_name']) count = count + 1 results = EMR_utilities.HTML_Frame(self, "Medication Interactions", html_str=string) results.Show() def OnReviewed(self, event): self.reviewed = 1 def OnNewAll(self, event): allergy = wx.GetTextFromUser('What is the patient allergic to?', 'New Allergy') if allergy == "": pass else: reaction = wx.GetTextFromUser('What happened?', 'Reaction') query = 'INSERT INTO allergies SET allergy = "%s", reaction = "%s", patient_ID = %s;' % \ (allergy, reaction, self.ptID) EMR_utilities.updateData(query) self.UpdateAllergy() def OnRemAll(self, event): obj = self.allergylist.GetSelectedObjects() for items in obj: qry = 'DELETE FROM allergies WHERE allergy_number = %s;' % items[ 'allergy_number'] self.allergylist.RemoveObject(items) EMR_utilities.updateData(qry) def UpdateList( self ): #this function just updates the list after new med added or deleted meds = med_find(self.ptID) #These lines put the data from the query self.list.SetObjects(meds) def UpdateAllergy(self): allergies = allergy_find(self.ptID) self.allergylist.SetObjects(allergies) def HandleCellEditStarting(self, event): pass def allergyHandleCellEditFinished(self, event): sqlstmt = 'UPDATE allergies SET %s = "%s" WHERE allergy_number = %s;' \ % (self.allergylist.columns[event.subItemIndex].valueGetter, self.allergylist.GetItem(event.rowIndex, event.subItemIndex).GetText(), event.rowModel["allergy_number"]) EMR_utilities.updateData(sqlstmt) def listHandleCellEditFinished(self, event): sqlstmt = 'UPDATE meds SET %s = "%s" WHERE med_number = %s;' \ % (self.list.columns[event.subItemIndex].valueGetter, self.list.GetItem(event.rowIndex, event.subItemIndex).GetText(), event.rowModel["med_number"]) EMR_utilities.updateData(sqlstmt)
class LeftPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent=parent) self.plots = [] self.pickedColors = [] self.colors = self.setupColors() self.plotsOlv = ObjectListView(self, wx.ID_ANY, style=wx.LC_REPORT | wx.SUNKEN_BORDER, useAlternateBackColors=False) self.plotsOlv.Bind(OLVEvent.EVT_ITEM_CHECKED, self.checkboxClicked) self.plotsOlv.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.onDoubleClick) #self.plotsOlv.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.onRightClick) self.getPlots() self.setColumns() self.plotsOlv.CreateCheckStateColumn() self.plotsOlv.SetObjects(self.plots) bsizer = wx.BoxSizer() #bsizer.Add(lb, 1, wx.EXPAND) bsizer.Add(self.plotsOlv, 1, wx.EXPAND) self.SetSizer(bsizer) self.checkedPlots = {} pub.subscribe(self.refreshList, 'list.updated') pub.subscribe(self.checkboxClicked, 'checkbox.clicked') pub.subscribe(self.onSavePlot, 'file.savePlot') pub.subscribe(self.onDelete, 'edit.delete') def onDoubleClick(self, event): #print event.m_itemIndex dlg = wx.ColourDialog(self) # Ensure the full colour dialog is displayed, # not the abbreviated version. dlg.GetColourData().SetChooseFull(True) if dlg.ShowModal() == wx.ID_OK: data = dlg.GetColourData() color = data.GetColour().Get() htmlColor = "#%02x%02x%02x" % color dlg.Destroy() index = event.m_itemIndex stored.plots[index]['Color'] = htmlColor self.plots[index].icon = self.plots[index].createIcon( self.plotsOlv, htmlColor) self.plotsOlv.RefreshObject(self.plots[index]) pub.sendMessage('item.checked', data=self.checkedPlots) def onDelete(self): if self.plotsOlv.GetSelectedObjects(): objectList = self.plotsOlv.GetSelectedObjects() for object in objectList: index = object.index stored.plots.pop(index) self.plots.pop(index) self.refreshList() pub.sendMessage('update.statusBar', data="Plots deleted!") else: pub.sendMessage( 'update.statusBar', data="Cannot delete plots! Please select one ore more plots!") def onSavePlot(self): if self.plotsOlv.GetSelectedObject(): index = self.plotsOlv.GetSelectedObject().index data = stored.plots[index] outputString = "%s\n" % data['Title'] outputString += "%s\n" % data['Type'] outputString += "%s,%s\n" % (data['xTitle'], data['xTitle']) for idx, row in enumerate(data['xData'].tolist()): z = 0 outputString += "%1.3f,%1.3f\n" % (data['xData'][idx], data['yData'][idx]) if stored.plots[index]['Type'] == "DifferenceMap" or stored.plots[ index]['Type'] == "DistanceMap": outputString += "z-Data:\n" numpy.set_printoptions(threshold=numpy.nan) zData = numpy.array_str(data['zData']) outputString += zData dialog = wx.FileDialog(None, message="Save plot data as ...", defaultDir=os.getcwd(), defaultFile=stored.plots[index]['Title'], wildcard="*.dat", style=wx.SAVE | wx.OVERWRITE_PROMPT) if dialog.ShowModal() == wx.ID_OK: path = dialog.GetPath() dataFile = open(path, 'w') print "\nSaving data...", dataFile.write(outputString) print "Done!\n" dataFile.close() dialog.Destroy() pub.sendMessage('update.statusBar', data="Plot data saved!") else: pub.sendMessage('update.statusBar', data="Cannot save data! Please select one plot!") def setupColors(self): cnames = { 'aliceblue': '#F0F8FF', 'antiquewhite': '#FAEBD7', 'aqua': '#00FFFF', 'aquamarine': '#7FFFD4', 'azure': '#F0FFFF', 'beige': '#F5F5DC', 'bisque': '#FFE4C4', 'black': '#000000', 'blanchedalmond': '#FFEBCD', 'blue': '#0000FF', 'blueviolet': '#8A2BE2', 'brown': '#A52A2A', 'burlywood': '#DEB887', 'cadetblue': '#5F9EA0', 'chartreuse': '#7FFF00', 'chocolate': '#D2691E', 'coral': '#FF7F50', 'cornflowerblue': '#6495ED', 'cornsilk': '#FFF8DC', 'crimson': '#DC143C', 'cyan': '#00FFFF', 'darkblue': '#00008B', 'darkcyan': '#008B8B', 'darkgoldenrod': '#B8860B', 'darkgray': '#A9A9A9', 'darkgreen': '#006400', 'darkkhaki': '#BDB76B', 'darkmagenta': '#8B008B', 'darkolivegreen': '#556B2F', 'darkorange': '#FF8C00', 'darkorchid': '#9932CC', 'darkred': '#8B0000', 'darksalmon': '#E9967A', 'darkseagreen': '#8FBC8F', 'darkslateblue': '#483D8B', 'darkslategray': '#2F4F4F', 'darkturquoise': '#00CED1', 'darkviolet': '#9400D3', 'deeppink': '#FF1493', 'deepskyblue': '#00BFFF', 'dimgray': '#696969', 'dodgerblue': '#1E90FF', 'firebrick': '#B22222', 'floralwhite': '#FFFAF0', 'forestgreen': '#228B22', 'fuchsia': '#FF00FF', 'gainsboro': '#DCDCDC', 'ghostwhite': '#F8F8FF', 'gold': '#FFD700', 'goldenrod': '#DAA520', 'gray': '#808080', 'green': '#008000', 'greenyellow': '#ADFF2F', 'honeydew': '#F0FFF0', 'hotpink': '#FF69B4', 'indianred': '#CD5C5C', 'indigo': '#4B0082', 'ivory': '#FFFFF0', 'khaki': '#F0E68C', 'lavender': '#E6E6FA', 'lavenderblush': '#FFF0F5', 'lawngreen': '#7CFC00', 'lemonchiffon': '#FFFACD', 'lightblue': '#ADD8E6', 'lightcoral': '#F08080', 'lightcyan': '#E0FFFF', 'lightgoldenrodyellow': '#FAFAD2', 'lightgreen': '#90EE90', 'lightgray': '#D3D3D3', 'lightpink': '#FFB6C1', 'lightsalmon': '#FFA07A', 'lightseagreen': '#20B2AA', 'lightskyblue': '#87CEFA', 'lightslategray': '#778899', 'lightsteelblue': '#B0C4DE', 'lightyellow': '#FFFFE0', 'lime': '#00FF00', 'limegreen': '#32CD32', 'linen': '#FAF0E6', 'magenta': '#FF00FF', 'maroon': '#800000', 'mediumaquamarine': '#66CDAA', 'mediumblue': '#0000CD', 'mediumorchid': '#BA55D3', 'mediumpurple': '#9370DB', 'mediumseagreen': '#3CB371', 'mediumslateblue': '#7B68EE', 'mediumspringgreen': '#00FA9A', 'mediumturquoise': '#48D1CC', 'mediumvioletred': '#C71585', 'midnightblue': '#191970', 'mintcream': '#F5FFFA', 'mistyrose': '#FFE4E1', 'moccasin': '#FFE4B5', 'navajowhite': '#FFDEAD', 'navy': '#000080', 'oldlace': '#FDF5E6', 'olive': '#808000', 'olivedrab': '#6B8E23', 'orange': '#FFA500', 'orangered': '#FF4500', 'orchid': '#DA70D6', 'palegoldenrod': '#EEE8AA', 'palegreen': '#98FB98', 'paleturquoise': '#AFEEEE', 'palevioletred': '#DB7093', 'papayawhip': '#FFEFD5', 'peachpuff': '#FFDAB9', 'peru': '#CD853F', 'pink': '#FFC0CB', 'plum': '#DDA0DD', 'powderblue': '#B0E0E6', 'purple': '#800080', 'red': '#FF0000', 'rosybrown': '#BC8F8F', 'royalblue': '#4169E1', 'saddlebrown': '#8B4513', 'salmon': '#FA8072', 'sandybrown': '#FAA460', 'seagreen': '#2E8B57', 'seashell': '#FFF5EE', 'sienna': '#A0522D', 'silver': '#C0C0C0', 'skyblue': '#87CEEB', 'slateblue': '#6A5ACD', 'slategray': '#708090', 'snow': '#FFFAFA', 'springgreen': '#00FF7F', 'steelblue': '#4682B4', 'tan': '#D2B48C', 'teal': '#008080', 'thistle': '#D8BFD8', 'tomato': '#FF6347', 'turquoise': '#40E0D0', 'violet': '#EE82EE', 'wheat': '#F5DEB3', 'white': '#FFFFFF', 'whitesmoke': '#F5F5F5', 'yellow': '#FFFF00', 'yellowgreen': '#9ACD32' } return cnames def setColumns(self, data=None): self.plotsOlv.SetColumns([ #imageGetter: "icon" is a property of plotListEntry objects ColumnDefn("Title", "left", 500, "title", imageGetter="icon") ]) #print "hallo" def refreshList(self): self.plotsOlv.ClearAll() self.plots = [] self.pickedColors = [] self.colors = self.setupColors() self.getPlots() self.setColumns() self.plotsOlv.CreateCheckStateColumn() self.plotsOlv.SetObjects(self.plots) self.checkedPlots = {} def getPlots(self): for idx, plot in enumerate(stored.plots): #print self.colors if not "Color" in plot: allowedColor = False preferredCnames = { 'blue': '#0000FF', 'green': '#008000', 'red': '#FF00FF', 'orange': '#FFA500', 'violet': '#EE82EE', 'magenta': '#FF0000' } while not allowedColor: if len(preferredCnames) > 0: color = preferredCnames.popitem()[1] else: color = self.colors.popitem()[1] if not color in self.pickedColors: allowedColor = True self.pickedColors.append(color) #print color plot['Color'] = color else: pass olv = self.plotsOlv self.plots.append( PlotListEntry(olv, plot['Type'], plot['Title'], plot['Color'], idx)) #print self.plots def checkboxClicked(self, data): data.rowModel.toggleState() index = data.rowModel.index isChecked = data.rowModel.isChecked currentPlot = stored.plots[index] currentId = index currentType = currentPlot["Type"] allowed = True nonSuperposeableTypes = ["DifferenceMap", "DistanceMap"] if len(self.checkedPlots) == 0 and isChecked: #this is the first checked plot, just add it self.checkedPlots[currentId] = currentPlot #print "Added first plot" elif len(self.checkedPlots) > 0 and isChecked: #check if of same type as other checked plots for key, value in self.checkedPlots.iteritems(): #value will be a graph dict from mtsslWizard if currentType != value[ "Type"] or currentType in nonSuperposeableTypes: allowed = False #print "False, cannot add plot" if allowed: self.checkedPlots[currentId] = currentPlot #print "True, plot added" else: #self.lb.Check(index, check=False) print "New:" print self.plotsOlv.GetCheckState(data.rowModel) self.plotsOlv.SetCheckState(data.rowModel, False) #data.rowModel.setCheckedState(False) pub.sendMessage( 'update.statusBar', data="Plots are not of same type or not superposeable!") print self.plotsOlv.GetCheckState(data.rowModel) self.plotsOlv.RefreshObject(data.rowModel) elif len(self.checkedPlots) > 0 and not isChecked: self.checkedPlots.pop(currentId, None) #print "removed plot from plot list" pub.sendMessage('item.checked', data=self.checkedPlots)
class PanelTwo(wx.ScrolledWindow): def __init__(self, parent): wx.ScrolledWindow.__init__(self, parent=parent) self.SetBackgroundColour('BLACK') self.SetScrollbars(20, 20, 55, 40) self.Scroll(0, 0) self.Show() hbox = wx.BoxSizer(wx.HORIZONTAL) pnl1 = wx.Panel(self, -1, style=wx.SIMPLE_BORDER) #pnl1.Bind(wx.EVT_SCROLLWIN, self.OnScroll) #first = pnl1.SetScrollbar(wx.VERTICAL, 0, 6, 50); pnl2 = wx.Panel(self, -1, style=wx.SIMPLE_BORDER) pnl3 = wx.Panel(self, -1, style=wx.SIMPLE_BORDER) pnl4 = wx.Panel(self, -1, style=wx.SIMPLE_BORDER) hbox.Add(pnl1, 1, wx.EXPAND | wx.ALL, 3) hbox.Add(pnl2, 1, wx.EXPAND | wx.ALL, 3) hbox.Add(pnl3, 1, wx.EXPAND | wx.ALL, 3) hbox.Add(pnl4, 1, wx.EXPAND | wx.ALL, 3) siz = wx.GridBagSizer(4, 4) self.base_path = os.path.dirname(os.path.abspath(__file__)) self.data = [] # ----------------------------------------------- # create the widgel.ts # add the data viewing control self.pdfOlv = ObjectListView(pnl1, style=wx.LC_REPORT | wx.SUNKEN_BORDER) ### USE TO MAKE LIST OF ITEM DOUBLE CLICK AND OPEN self.pdfOlv.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.onDoubleClick) ### FIRST THING TO DISPLAY IF NOTHING IS LOADED self.pdfOlv.SetEmptyListMsg("No PDFs Found!") self.updateDisplay() browseBtn = wx.Button(pnl1, label="Browse") browseBtn.Bind(wx.EVT_BUTTON, self.getPdfs) # ----------------------------------------------- # layout the widgets mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(self.pdfOlv, 1, wx.ALL | wx.EXPAND, 5) mainSizer.Add(browseBtn, 0, wx.ALL | wx.CENTER, 5) self.SetSizer(mainSizer) # ----------------------------------------------- # layout the widgets mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(self.pdfOlv, 1, wx.ALL | wx.EXPAND, 5) mainSizer.Add(browseBtn, 0, wx.ALL | wx.CENTER, 5) self.SetSizer(mainSizer) ########################################################################################################################################## ## # #Panel 2 Button Starts Here siz2 = wx.GridBagSizer(4, 4) movbtn21 = gbtn.GradientButton(pnl2, 1, label='Better', bitmap=wx.Bitmap( "ima/mov.jpg", wx.BITMAP_TYPE_JPEG)) siz2.Add(movbtn21, (1, 1), flag=wx.LEFT | wx.RIGHT, border=5) movbtn31 = gbtn.GradientButton(pnl2, 1, label='Drills ', bitmap=wx.Bitmap( "ima/mov17.jpg", wx.BITMAP_TYPE_JPEG)) siz2.Add(movbtn31, (2, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn41 = gbtn.GradientButton(pnl2, 1, label='Freed', bitmap=wx.Bitmap( "ima/mov23.jpg", wx.BITMAP_TYPE_JPEG)) siz2.Add(movbtn41, (3, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn51 = gbtn.GradientButton(pnl2, 1, label='Billz ', bitmap=wx.Bitmap( "ima/mov6.jpg", wx.BITMAP_TYPE_JPEG)) siz2.Add(movbtn51, (4, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn61 = gbtn.GradientButton(pnl2, 1, label='Drills', bitmap=wx.Bitmap( "ima/mov7.jpg", wx.BITMAP_TYPE_JPEG)) siz2.Add(movbtn61, (5, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn71 = gbtn.GradientButton(pnl2, 1, label='Drills', bitmap=wx.Bitmap( "ima/mov8.jpg", wx.BITMAP_TYPE_JPEG)) siz2.Add(movbtn71, (6, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn81 = gbtn.GradientButton(pnl2, 1, label='Drills', bitmap=wx.Bitmap( "ima/mov9c.jpg", wx.BITMAP_TYPE_JPEG)) siz2.Add(movbtn81, (7, 0), flag=wx.LEFT | wx.RIGHT, border=5) ########################################################################################################################################## ########################################################################################################################################## #Panel 3 Button Starts Here siz3 = wx.GridBagSizer(4, 4) movbtn211 = gbtn.GradientButton(pnl3, 1, label='Better', bitmap=wx.Bitmap( "ima/mov17.jpg", wx.BITMAP_TYPE_JPEG)) siz3.Add(movbtn211, (1, 1), flag=wx.LEFT | wx.RIGHT, border=5) movbtn311 = gbtn.GradientButton(pnl3, 1, label='Drills ', bitmap=wx.Bitmap( "ima/mov.jpg", wx.BITMAP_TYPE_JPEG)) siz3.Add(movbtn311, (2, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn411 = gbtn.GradientButton(pnl3, 1, label='Freed', bitmap=wx.Bitmap( "ima/mov6.jpg", wx.BITMAP_TYPE_JPEG)) siz3.Add(movbtn411, (3, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn511 = gbtn.GradientButton(pnl3, 1, label='Billz ', bitmap=wx.Bitmap( "ima/mov23.jpg", wx.BITMAP_TYPE_JPEG)) siz3.Add(movbtn511, (4, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn611 = gbtn.GradientButton(pnl3, 1, label='Drills', bitmap=wx.Bitmap( "ima/mov8.jpg", wx.BITMAP_TYPE_JPEG)) siz3.Add(movbtn611, (5, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn711 = gbtn.GradientButton(pnl3, 1, label='Drills', bitmap=wx.Bitmap( "ima/mov7.jpg", wx.BITMAP_TYPE_JPEG)) siz3.Add(movbtn711, (6, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn811 = gbtn.GradientButton(pnl3, 1, label='Drills', bitmap=wx.Bitmap( "ima/mov9c.jpg", wx.BITMAP_TYPE_JPEG)) siz3.Add(movbtn811, (7, 0), flag=wx.LEFT | wx.RIGHT, border=5) ######################################################################################################################################## ########################################################################################################################################## ## # #Panel 4 Button Starts Here siz4 = wx.GridBagSizer(4, 4) movbtn2111 = gbtn.GradientButton(pnl4, 1, label='Better', bitmap=wx.Bitmap( "ima/mov.jpg", wx.BITMAP_TYPE_JPEG)) siz4.Add(movbtn2111, (1, 1), flag=wx.LEFT | wx.RIGHT, border=5) movbtn3111 = gbtn.GradientButton(pnl4, 1, label='Drills ', bitmap=wx.Bitmap( "ima/mov23.jpg", wx.BITMAP_TYPE_JPEG)) siz4.Add(movbtn3111, (2, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn4111 = gbtn.GradientButton(pnl4, 1, label='Freed', bitmap=wx.Bitmap( "ima/mov17.jpg", wx.BITMAP_TYPE_JPEG)) siz4.Add(movbtn4111, (3, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn5111 = gbtn.GradientButton(pnl4, 1, label='Billz ', bitmap=wx.Bitmap( "ima/mov8.jpg", wx.BITMAP_TYPE_JPEG)) siz4.Add(movbtn5111, (4, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn6111 = gbtn.GradientButton(pnl4, 1, label='Drills', bitmap=wx.Bitmap( "ima/mov9c.jpg", wx.BITMAP_TYPE_JPEG)) siz4.Add(movbtn6111, (5, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn7111 = gbtn.GradientButton(pnl4, 1, label='Drills', bitmap=wx.Bitmap( "ima/mov6.jpg", wx.BITMAP_TYPE_JPEG)) siz4.Add(movbtn7111, (6, 0), flag=wx.LEFT | wx.RIGHT, border=5) movbtn8111 = gbtn.GradientButton(pnl4, 1, label='Drills', bitmap=wx.Bitmap( "ima/mov7.jpg", wx.BITMAP_TYPE_JPEG)) siz4.Add(movbtn8111, (7, 0), flag=wx.LEFT | wx.RIGHT, border=5) ######################################################################################################################################## self.SetSize((400, 120)) self.SetSizer(hbox) self.Centre() #siz.AddGrowableRow(1) #siz.AddGrowableCol(2) #pnl1.SetSizer(siz) pnl2.SetSizer(siz2) pnl3.SetSizer(siz3) pnl4.SetSizer(siz4) #def OnScroll(self, evt): #pnl1.Scroll(50,10) def updateDisplay(self): """ Updates the object list view control """ self.pdfOlv.SetColumns([ ColumnDefn("Files", "left", 300, "filename"), ColumnDefn("Title", "left", 120, "title"), ColumnDefn("Size (MB)", "center", 100, "GetSizeInMb"), ColumnDefn("Last Played", "left", 100, "lastPlayed"), ColumnDefn("Rating", "center", 100, "rating") ]) self.pdfOlv.SetObjects(self.data) def getPdfs(self, event): """ Attempts to load PDFs into objectlistview """ self.dataq = [] dlg = wx.DirDialog( self, "UCNET SOUND LIBRARY:", 'c:/users/kingston/documents/job/testor_player/bitmaps', style=wx.DD_DEFAULT_STYLE) res = dlg.ShowModal() if res != wx.ID_OK: return path = dlg.GetPath() dlg.Destroy() #### Only display pdf files pdfs = glob.glob(path + "/*.mp3") if pdfs: for pdf in pdfs: self.data.append(File(pdf)) self.updateDisplay() #---------------------------------------------------------------------- def onDoubleClick(self, event): """ Opens the PDF that is double-clicked """ obj = self.pdfOlv.GetSelectedObject( ) # USE THIS TO GET EVENT OF DOUBLE CLICKED FILE print "You just double-clicked on %s" % obj.path mess = onPlayer(self, -1, "Player") mess.Show(True) mc = mediactrl ##################################################################################################### # MEDIA CONTROL HERE def symbol(self, event): sym = Symbols(None, -1, "Administration Point") sym.Show(True)
class PCapMainFrame(wx.Frame): FRAME_VIEW_WIDTH = 480 FRAME_VIEW_HEIGHT = 270 def __init__(self, controller, resources_path): wx.Frame.__init__(self, None) self.control = controller self.resources_path = resources_path self.cam_pos = None self.cam_ray = None self.cam_pos_lock = RLock() self.pointer = 0 self.SetTitle("3-Demeter PlantCapture") self.status_bar = self.CreateStatusBar() self.is_mvs_on = False self.map_points = None self._update_counter = 0 # Creating menus filemenu = wx.Menu() menuAbout = filemenu.Append(wx.ID_ABOUT, "&About", " Information about this program") menuExit = filemenu.Append(wx.ID_EXIT, "E&xit", " Terminate the program") menuBar = wx.MenuBar() menuBar.Append(filemenu, "&File") setmenu = wx.Menu() device_menu_item = setmenu.Append( 0, "&Camera device", " Choose an \ available camera for capturing") scale_menu_item = setmenu.Append(1, "&Scale correction", " Look for a\ scale pattern") menuBar.Append(setmenu, "S&ettings") self.SetMenuBar(menuBar) # Tools actions = { 'cap_new': ('New capture', 'image_add.svg', 'Start new image acquisition', self.OnNewAcq), 'cap_continue': ('Continue', 'image_run.svg', 'Resume acquisition', self.OnResumeAcq), 'cap_pause': ('Pause', 'image_pause.svg', 'Pause acquisition', self.OnPauseAcq), 'cap_finish': ('Finish capture', 'image_stop.svg', 'Finish acquisition', self.OnFinishAcq), 'dir_save_to': ('Save as...', 'folder_downloads.svg', 'Save capture files to a new directory', self.OnSave2Dir), 'dir_open': ('Open...', 'folder_image.svg', 'Open a directory with previously captured frames', self.OnOpenDir), 'mvs_export': ('Export to MVS', 'download.svg', 'Export files to the MVS subsystem', self.OnExportMVS), 'mvs_run': ('Multiple View Stereo', 'tree.svg', 'Start 3-D reconstruction', self.OnMVS), 'norm': ('Normalize', 'size_height_accept.svg', 'Normalize scale and orientation', self.OnNormalize), 'exit': ('Quit', 'logout.svg', 'Exit application', self.OnExit) } # Creating the toolbar self._toolbar = self.CreateToolBar() self._tools = {} tools_list = [ 'cap_new', 'cap_continue', 'cap_pause', 'cap_finish', '|', 'dir_save_to', 'dir_open', 'mvs_export', 'mvs_run', 'norm', '|', 'exit' ] for t in tools_list: if t is '|': self._toolbar.AddSeparator() else: label, icon, help, command = actions[t] bitmap_path = self.resources_path + '/picol/' + icon bitmap = wx.Bitmap(bitmap_path) self._tools[t] = self._toolbar.AddLabelTool(wx.ID_ANY, label, bitmap, shortHelp=help) self.Bind(wx.EVT_TOOL, command, self._tools[t]) self._toolbar.Realize() # Creating the main window self.main_window = wx.SplitterWindow(self, wx.ID_ANY) self.left_pane = wx.Panel(self.main_window, wx.ID_ANY) self.right_pane = wx.Panel(self.main_window, wx.ID_ANY) self.main_window.SplitVertically(self.left_pane, self.right_pane, sashPosition=256) self.main_vsizer = wx.BoxSizer(wx.VERTICAL) self.main_vsizer.Add(self.main_window, 1, wx.EXPAND) # Adding frame list self.keyframes = [] self.frame_list = ObjectListView(self, wx.ID_ANY, style=wx.LC_REPORT) self.frame_list.SetColumns([ ColumnDefn("#", "left", 30, "num"), ColumnDefn("Frame", "left", 100, "frame"), ColumnDefn("Path", "left", 130, "path") ]) self.updateKeyFrames() lsizer = wx.BoxSizer(wx.VERTICAL) lsizer.Add(self.frame_list, 1, wx.EXPAND) self.left_pane.SetSizer(lsizer) lsizer.Fit(self.left_pane) rsizer = wx.BoxSizer(wx.VERTICAL) # Adding frame display self.frame_image = None self.bitmap = wx.EmptyBitmap(PCapMainFrame.FRAME_VIEW_WIDTH, PCapMainFrame.FRAME_VIEW_HEIGHT) pnl_f = wx.Panel(self.right_pane) sb = wx.StaticBox(pnl_f, label='Camera frame') sbs = wx.StaticBoxSizer(sb, orient=wx.HORIZONTAL) sbs.AddSpacer(11) self.frame_view = wx.StaticBitmap(pnl_f, bitmap=self.bitmap) sbs.Add(self.frame_view, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ADJUST_MINSIZE, 10) sbs.AddSpacer(11) pnl_f.SetSizer(sbs) # Adding Mayavi view pnl_m = wx.Panel(self.right_pane) sb = wx.StaticBox(pnl_m, label='3-D Viewer') sbs = wx.StaticBoxSizer(sb, orient=wx.HORIZONTAL) sbs.AddSpacer(11) self.mayavi_view = MayaviView() traits_ui = self.mayavi_view.edit_traits(parent=pnl_m, kind='subpanel') self.mayavi_control = traits_ui.control sbs.Add(self.mayavi_control, 1, wx.CENTER | wx.EXPAND) sbs.AddSpacer(11) pnl_m.SetSizer(sbs) rsizer.Add(pnl_f, 0, wx.LEFT) rsizer.Add(pnl_m, 1, wx.CENTER | wx.EXPAND) self.right_pane.SetSizer(rsizer) rsizer.Fit(self.right_pane) # Set events: self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout) self.Bind(wx.EVT_MENU, self.OnExit, menuExit) self.Bind(wx.EVT_MENU, self.OnSetDevice, device_menu_item) self.Bind(wx.EVT_MENU, self.OnSetScaleCor, scale_menu_item) self.frame_list.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnFrameSelected) self.SetSizer(self.main_vsizer) self.SetAutoLayout(1) self.main_vsizer.Fit(self) self.SetSize((900, 800)) logo_path = self.resources_path + '/splash-logo.png' logo = cv2.imread(logo_path)[:, :, (2, 1, 0)] self.updateFrame(logo, 0) self.viewer_updater = MayaviUpdater(self) def updateFrame(self, frame, frame_num): """Update the bitmap to the frame from new frame event.""" w, h = PCapMainFrame.FRAME_VIEW_WIDTH, PCapMainFrame.FRAME_VIEW_HEIGHT thumbnail = cv2.resize(frame, (w, h)) self.frame_image = wx.ImageFromData(w, h, thumbnail.tostring()) self.bitmap = wx.BitmapFromImage(self.frame_image) self.frame_view.SetBitmap(self.bitmap) if frame_num > 0: h, w, _ = frame.shape msg = 'Frame %d (%d x %d)' % (frame_num, w, h) self.status_bar.SetStatusText(msg) def updateOdometry(self, Tcw): """Add the new odometry data and refresh the 3-D viewer.""" with self.cam_pos_lock: cam_center = Tcw[0:3, 3] cam_center.shape = 1, 3 cam_p_ray = np.dot(Tcw[0:3, 0:3], np.array([0, 0, 1.])) if self.cam_pos is None: self.cam_pos = cam_center.copy() self.cam_ray = cam_p_ray.copy() else: self.cam_pos = np.vstack((self.cam_pos, cam_center)) self.cam_ray = np.vstack((self.cam_ray, cam_p_ray)) def appendKeyFrame(self, frame_num, frame_path, map_points=None): n = len(self.keyframes) + 1 self.keyframes.append({ 'num': n, 'frame': 'Frame %.5d' % frame_num, 'path': frame_path }) self.updateKeyFrames() if map_points is not None: self.map_points = map_points def updateKeyFrames(self): self.frame_list.SetObjects(self.keyframes) def update3DViewer(self): with self.cam_pos_lock: self._update_counter += 1 if self.cam_pos is not None and self.cam_pos.shape[0] > 3: self.mayavi_view.scene.disable_render = True # Update path plot ms = self.mayavi_view.cam_path_plot.mlab_source ms.reset(x=self.cam_pos[:, 0], y=self.cam_pos[:, 1], z=self.cam_pos[:, 2], scalars=np.arange(self.cam_pos.shape[0])) # Update quiver plot (current camera position) ms = self.mayavi_view.cam_pos_plot.mlab_source ms.reset(x=self.cam_pos[-1, 0], y=self.cam_pos[-1, 1], z=self.cam_pos[-1, 2], u=self.cam_ray[-1, 0], v=self.cam_ray[-1, 1], w=self.cam_ray[-1, 2]) # Update the map once each 30 updates if self._update_counter % 30 == 0 \ and self.map_points is not None: ms = self.mayavi_view.map_plot.mlab_source ms.reset(x=self.map_points[:, 0], y=self.map_points[:, 1], z=self.map_points[:, 2]) if self._update_counter == 30: self.mayavi_view.scene.reset_zoom() mlab = self.mayavi_view.scene.mlab dist = la.norm(self.cam_pos[-1] - self.cam_pos[-2]) self.mayavi_view.scene.disable_render = False def loadPLY(self, ply_path, clear_previous=False): self.mayavi_view.scene.disable_render = True with open(ply_path, 'r') as fp: line_num = 0 line = 'X' while len(line) > 0: line = fp.readline() line_num += 1 if line.startswith('end_header'): break data = np.loadtxt(ply_path, skiprows=line_num) X = data[:, 0:3] color = data[:, 6:] s = np.max(color, axis=1) mlab = self.mayavi_view.scene.mlab if clear_previous: mlab.clf() mlab.points3d(X[:, 0], X[:, 1], X[:, 2], s, colormap='gray', mode='point') self.mayavi_view.scene.reset_zoom() self.mayavi_view.scene.disable_render = False def loadOdometry(self, filename): with open(filename, 'r') as f: params = [line.split() for line in f.readlines()] kf_ts = [int(float(p[0])) for p in params] # Translation vectors t = [np.array([float(v) for v in p[1:4]]) for p in params] for ti in t: ti.shape = 3, 1 # q for quaternions q = [np.array([float(v) for v in p[4:]]) for p in params] # Get Tcw Tcw = [] pr = [] for (qx, qy, qz, qw), t_ts in zip(q, t): R = np.array([[ 1 - 2 * qy**2 - 2 * qz**2, 2 * qx * qy - 2 * qz * qw, 2 * qx * qz + 2 * qy * qw ], [ 2 * qx * qy + 2 * qz * qw, 1 - 2 * qx**2 - 2 * qz**2, 2 * qy * qz - 2 * qx * qw ], [ 2 * qx * qz - 2 * qy * qw, 2 * qy * qz + 2 * qx * qw, 1 - 2 * qx**2 - 2 * qy**2 ]]) T_ts = np.hstack((R, t_ts)) pr_ts = np.dot(R, np.array([0, 0, 1.])) Tcw.append(T_ts) pr.append(pr_ts) self.mayavi_view.scene.mlab.clf() self.mayavi_view.scene.mlab.quiver3d([T[0, 3] for T in Tcw], [T[1, 3] for T in Tcw], [T[2, 3] for T in Tcw], [p[0] for p in pr], [p[1] for p in pr], [p[2] for p in pr], opacity=0.5, color=(1, 0, 0), mode='2darrow') if self.map_points is not None: mlab = self.mayavi_view.scene.mlab mlab.points3d(self.map_points[:, 0], self.map_points[:, 1], self.map_points[:, 2], color=(0, 1, 0.2), mode='point') work_dir = os.path.dirname(filename) fpaths = glob.glob(work_dir + os.sep + '*.jpg') fpaths.sort() fnames = [os.path.basename(fpath) for fpath in fpaths] fnums = [re.match('frame\-0*(\d+)\.jpg', fn).group(1) for fn in fnames] fnames = ['Frame %s' % n for n in fnums] self.keyframes = [{ 'num': i + 1, 'frame': fn, 'path': fp } for i, (fn, fp) in enumerate(zip(fnames, fpaths))] self.frame_list.DeleteAllItems() self.updateKeyFrames() def OnAbout(self, e): dlg = wx.MessageDialog(self, "Create 3-D models for plants.", "About 3-Demeter PlantCapture", wx.OK) dlg.ShowModal() dlg.Destroy() def OnSetDevice(self, e): args = ['v4l2-ctl', '--list-devices'] l_cams = subprocess.check_output(args).split('\n') l_cams = [u.strip() for u in l_cams if len(u) > 0] cams = {l_cams[i]: l_cams[i + 1] for i in range(0, len(l_cams), 2)} dialog = wx.SingleChoiceDialog(self, "Select camera device:", "Camera", cams.keys()) if dialog.ShowModal() == wx.ID_OK: sel_device = dialog.GetStringSelection() self.control.set_cap_device(cams[sel_device]) dialog.Destroy() def OnSetScaleCor(self, e): options = { 'Look for scale correction pattern': True, 'Do not perform scale correction': False } dialog = wx.SingleChoiceDialog(self, "Scale correction:", "Options", options.keys()) if dialog.ShowModal() == wx.ID_OK: sel_opt = dialog.GetStringSelection() self.control.setScaleCor(options[sel_opt]) dialog.Destroy() def OnError(self, message): dialog = wx.MessageDialog(self, message, "Error", wx.OK) dialog.ShowModal() dialog.Destroy() def OnNewAcq(self, e): self.viewer_updater.updating = True self.viewer_updater.start() self.control.new_acquisition() def OnResumeAcq(self, e): self.viewer_updater = MayaviUpdater(self) self.viewer_updater.updating = True self.viewer_updater.start() self.control.resume_acquisition() def OnPauseAcq(self, e): self.viewer_updater.updating = False self.control.pause_acquisition() def OnFinishAcq(self, e): for t in ['cap_new', 'cap_continue', 'cap_pause', 'cap_finish']: self._tools[t].Enable(False) self._toolbar.Realize() self.control.finish_acquisition() self.viewer_updater.updating = False def OnSave2Dir(self, e): dlg = wx.DirDialog(self, message="Choose a directory") if dlg.ShowModal() == wx.ID_OK: full_path = dlg.GetPath() self.control.save_capture(full_path) dlg.Destroy() def OnOpenDir(self, e): dlg = wx.DirDialog(self, message="Choose an existing directory", style=wx.DD_DIR_MUST_EXIST) if dlg.ShowModal() == wx.ID_OK: dir_path = dlg.GetPath() self.control.open_cap_dir(dir_path) dlg.Destroy() def OnExportMVS(self, e): self.control.export_to_mvs() def OnMVS(self, e): self.is_mvs_on = True dialog = pp.PyProgress(self, -1, "3-D Reconstruction", "Running PMVS...", agwStyle=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME) dialog.SetGaugeProportion(0.2) dialog.SetGaugeSteps(50) dialog.SetGaugeBackground(wx.WHITE) dialog.SetFirstGradientColour(wx.WHITE) dialog.SetSecondGradientColour(wx.BLACK) self.control.start_mvs() while self.is_mvs_on: wx.MilliSleep(100) dialog.UpdatePulse() dialog.Destroy() def MVSFinished(self): self.is_mvs_on = False def notify(message, msg_type): if msg_type == 'error': wx.MessageBox(message, 'Error', wx.OK | wx.ICON_ERROR) elif msg_type == 'info': wx.MessageBox(message, 'Info', wx.OK | wx.ICON_INFORMATION) def OnNormalize(self, e): self.control.normalize() def OnExit(self, e): self.Close(True) # Close the frame. def OnFrameSelected(self, event): i = event.GetIndex() kf_data = self.keyframes[i] frame = cv2.imread(kf_data['path']) squares = scale.preprocess_and_find_squares(frame) mapping = scale.detect_markers(frame, squares) frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) pts = [s.reshape((-1, 1, 2)) for s, _ in mapping.values()] frame_rgb = cv2.polylines(frame_rgb, pts, True, (255, 0, 0), thickness=3, lineType=cv2.LINE_AA) for k, (pt, _) in mapping.iteritems(): x, y = pt.mean(axis=0) pos = (int(x), int(y)) cv2.putText(frame_rgb, '%d' % (k), pos, cv2.FONT_ITALIC, 2, (255, 0, 0), 2, cv2.LINE_AA) w, h = PCapMainFrame.FRAME_VIEW_WIDTH, PCapMainFrame.FRAME_VIEW_HEIGHT thumbnail = cv2.resize(frame_rgb, (w, h)) self.frame_image = wx.ImageFromData(w, h, thumbnail.tostring()) self.bitmap = wx.BitmapFromImage(self.frame_image) self.frame_view.SetBitmap(self.bitmap) self.status_bar.SetStatusText('Frame %d' % kf_data['num']) def SetStatus(self, message): self.status_bar.SetStatusText(message)
class PanelLogs(wx.Panel): lock = threading.RLock() def __init__(self, parentNotebook, frame_myr, size=None, style=wx.BORDER_DEFAULT): wx.Panel.__init__(self, parent=parentNotebook, size=size, id=wx.ID_ANY, style=style) self.parentNotebook = parentNotebook self.frame_myr = frame_myr self.logPath = self.frame_myr.notebook.getTempConfigParam("logPath") self.wvLogs = webview.WebView.New(self) self.selection = None #scrollPanel = wx.Panel(self) self.listLogs = ObjectListView(self, size=(108, -1), style=wx.LC_REPORT, sortable=False) self.listLogs.oddRowsBackColor = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW) self.listLogs.SetColumns([ ColumnDefn("Log File", "center", 94, "log") ]) self.listLogs.SetFont(wx.Font(8.5, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False)) self.loadList() self.listLogs.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onLogSelected) self.listLogs.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick) self.wvLogs.Bind(webview.EVT_WEBVIEW_TITLE_CHANGED, self.onFocusLost) sizer = wx.BoxSizer(wx.HORIZONTAL) self.wvLogs.SetPage('<html><body style="background-color: #111111;"></body></html>', "") sizer.Add(self.wvLogs, 1, wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.TOP, -3) sizer.Add(self.listLogs, 0, wx.EXPAND | wx.LEFT, 0) self.SetSizer(sizer) def onFocusLost(self, event): self.listLogs.SetFocus() event.Skip() def loadList(self): with self.lock: self.logPath = self.frame_myr.notebook.getTempConfigParam("logPath") if not self.logPath or not os.path.isdir(self.logPath): self.listLogs.DeleteAllItems() return logFiles = [ {"log": os.path.splitext(f)[0] } for f in reversed(listdir(self.logPath)) if isfile(join(self.logPath, f)) and f.endswith('.html') ] self.listLogs.DeleteAllItems() self.listLogs.SetObjects(logFiles) if self.selection is not None: try: self.listLogs.SelectObjects([self.selection]) except IndexError: self.selection = None self.listLogs.SetFocus() def onLogSelected(self, event): self.selection = self.listLogs.GetObjects()[event.GetEventObject().GetFirstSelected()] self.onLogSelectedIndex(self.selection) self.listLogs.SetFocus() event.Skip() def onLogSelectedIndex(self, selectedObj): #logFile = event.GetEventObject().GetValue(self.selection, 0) #logFile = self.listLogs.GetValue(index, 0) logFile = selectedObj['log'] self.loadLogFile(logFile) def loadLogFile(self, logFile): f = open(self.logPath + "/" + logFile + ".html") html = f.read() f.close() self.onLog(html) def onLog(self, html): self.wvLogs.SetPage(html, "") self.wvLogs.Reload() def reloadLog(self): #self.wvLogs.Reload() if self.selection: self.loadLogFile(self.selection['log']) def OnRightClick(self, event): #self.log.WriteText("OnRightClick %s\n" % self.list.GetItemText(self.currentItem)) # only do this part the first time so the events are only bound once if not hasattr(self, "popupID1"): self.popupOpenLocation = wx.NewId() self.popupDelete = wx.NewId() self.Bind(wx.EVT_MENU, self.onPopUpOpenLocation, id=self.popupOpenLocation) self.Bind(wx.EVT_MENU, self.onPopUpDelete, id=self.popupDelete) # make a menu menu = wx.Menu() # add some items menu.Append(self.popupOpenLocation, "Open file location") menu.Append(self.popupDelete, "Delete files...") # Popup the menu. If an item is selected then its handler # will be called before PopupMenu returns. self.PopupMenu(menu) menu.Destroy() def onPopUpOpenLocation(self, event): if os.name == "nt": #os.spawnl(os.P_NOWAIT, os.getenv('windir') + '\\explorer.exe', '.', '/n,/e,/select,"%s"'%self.logPath+"\\") psutil.Popen('explorer ' + '"' + self.logPath + '"') if os.name == "posix": pass def onPopUpDelete(self, event): question = "Are you sure you want to delete those files?" dlg = GMD.GenericMessageDialog(self, question, "Confirm deletion", wx.YES_NO | wx.NO_DEFAULT | wx.ICON_WARNING) result = dlg.ShowModal() == wx.ID_YES dlg.Destroy() if result: selected = self.listLogs.GetSelectedObjects() for file in selected: os.remove(self.logPath + '/' + file['log'] + '.html') self.loadList()
class RssPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent, style=wx.NO_FULL_REPAINT_ON_RESIZE) self.data = [] lbl = wx.StaticText(self, label="Feed URL:") lbl2 = wx.StaticText(self, label="Search by key words in title:") lbl3 = wx.StaticText(self, label="Search by key words in text:") self.rssSearch = wx.TextCtrl(self, value="") self.rssSearch2 = wx.TextCtrl(self, value="") self.rssUrlTxt = wx.TextCtrl( self, value="https://www.newsinlevels.com/feed/") searchBtn = wx.Button(self, label="Get Search") searchBtn.Bind(wx.EVT_BUTTON, self.searchTitle) searchBtn2 = wx.Button(self, label="Get Search") searchBtn2.Bind(wx.EVT_BUTTON, self.searchSummary) urlBtn = wx.Button(self, label="Get Feed") urlBtn.Bind(wx.EVT_BUTTON, self.get_data) self.rssOlv = ObjectListView(self, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.rssOlv.SetEmptyListMsg("No data") self.rssOlv.Bind(wx.EVT_LIST_ITEM_SELECTED, self.on_select) self.rssOlv.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_double_click) self.summaryTxt = webview.WebView.New(self) self.searchOlv = ObjectListView(self, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.searchOlv.SetEmptyListMsg("No results") self.searchOlv.Bind(wx.EVT_LIST_ITEM_SELECTED, self.on_select1) self.searchOlv.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_double_click1) self.searchOlv2 = ObjectListView(self, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.searchOlv2.SetEmptyListMsg("No results") self.searchOlv2.Bind(wx.EVT_LIST_ITEM_SELECTED, self.on_select2) self.searchOlv2.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_double_click2) self.wv = webview.WebView.New(self) self.listoffeeds = [] # add sizers toolbar2 = wx.ToolBar(self) qtool = toolbar2.AddTool(wx.ID_ANY, '', wx.Bitmap('greenplus.png')) qtool2 = toolbar2.AddTool(wx.ID_ANY, '', wx.Bitmap('redplus.png')) qtool3 = toolbar2.AddTool(wx.ID_ANY, '', wx.Bitmap('notif.png')) toolbar2.Realize() toolbar2.Bind(wx.EVT_TOOL, self.enterCategory, qtool) toolbar2.Bind(wx.EVT_TOOL, self.save_page, qtool2) toolbar2.Bind(wx.EVT_TOOL, self.new_window, qtool3) rowSizer = wx.BoxSizer(wx.HORIZONTAL) rowSizer.Add(lbl, 0, wx.ALL, 5) rowSizer.Add(self.rssUrlTxt, 1, wx.EXPAND | wx.ALL, 5) rowSizer.Add(urlBtn, 0, wx.ALL, 5) vSizer = wx.BoxSizer(wx.VERTICAL) vSizer.Add(self.rssOlv, 1, wx.EXPAND | wx.ALL, 5) vSizer.Add(self.summaryTxt, 1, wx.EXPAND | wx.ALL, 5) rowSizer1 = wx.BoxSizer(wx.HORIZONTAL) rowSizer1.Add(lbl2, 0, wx.ALL, 5) rowSizer1.Add(self.rssSearch, 1, wx.EXPAND | wx.ALL, 5) rowSizer1.Add(searchBtn, 0, wx.ALL, 5) rowSizer3 = wx.BoxSizer(wx.HORIZONTAL) rowSizer3.Add(lbl3, 0, wx.ALL, 5) rowSizer3.Add(self.rssSearch2, 1, wx.EXPAND | wx.ALL, 5) rowSizer3.Add(searchBtn2, 0, wx.ALL, 5) rowSizer4 = wx.BoxSizer(wx.HORIZONTAL) rowSizer4.Add(self.searchOlv, 1, wx.EXPAND | wx.ALL, 5) rowSizer4.Add(self.searchOlv2, 1, wx.EXPAND | wx.ALL, 5) dispSizer = wx.BoxSizer(wx.HORIZONTAL) dispSizer.Add(vSizer, 1, wx.EXPAND | wx.ALL, 5) dispSizer1 = wx.BoxSizer(wx.VERTICAL) dispSizer1.Add(self.wv, 2, wx.EXPAND | wx.ALL, 5) dispSizer1.Add(rowSizer4, 1, wx.EXPAND | wx.ALL, 5) rowSizer2 = wx.BoxSizer(wx.HORIZONTAL) rowSizer2.Add(dispSizer, 0, wx.EXPAND | wx.ALL, 5) rowSizer2.Add(dispSizer1, 1, wx.EXPAND | wx.ALL, 5) mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(toolbar2, 0, wx.RIGHT) mainSizer.Add(rowSizer, 0, wx.EXPAND) mainSizer.Add(rowSizer1, 0, wx.EXPAND) mainSizer.Add(rowSizer3, 0, wx.EXPAND) mainSizer.Add(rowSizer2, 1, wx.EXPAND | wx.ALL) self.SetSizer(mainSizer) self.update_display() def enterCategory(self, event): global category dlog = wx.TextEntryDialog(None, "Enter the category:") dlog.ShowModal() category = dlog.GetValue() #---------------------------------------------------------------------- def new_window(self, event): # Окно с сохраненными ссылкамистраницы window = wx.Frame(None, -1, "All data") list_view = wx.ListCtrl(window, -1, style=wx.LC_REPORT) list_view.InsertColumn(0, 'title', width=100) list_view.InsertColumn(1, 'link', wx.LIST_FORMAT_RIGHT, 100) list_view.InsertColumn(2, 'category', wx.LIST_FORMAT_RIGHT, 100) for i in select_sth(): index = list_view.InsertStringItem(sys.maxsize, i[0]) list_view.SetStringItem(index, 1, i[1]) list_view.SetStringItem(index, 2, i[2]) window.Show() #---------------------------------------------------------------------- def save_page(self, event): obj = self.rssOlv.GetSelectedObject() name = obj.title link = obj.link insert_sth_smw(name, link, category) #---------------------------------------------------------------------- def get_data(self, event): # Получить RSS feed и добавить на дисплей msg = "Processing feed..." busyDlg = wx.BusyInfo(msg) rss = self.rssUrlTxt.GetValue() feed = feedparser.parse(rss) website = feed["feed"]["title"] for key in feed["entries"]: title = unidecode.unidecode(key["title"]) link = unidecode.unidecode(key["link"]) summary = unidecode.unidecode(key["summary"]) self.data.append(RSS(title, link, website, summary, key)) busyDlg = None self.update_display() #---------------------------------------------------------------------- def searchTitle(self, event): # Поиск по названию статьи search_list = [] for key in self.data: title = key.title result = re.search('\s*%s' % self.rssSearch.GetValue(), title) if result != None: search_list.append(key) self.search_list = search_list self.update_display1() #---------------------------------------------------------------------- def searchSummary(self, event): # Поиск по краткому содержанию статьи search_list1 = [] for key in self.data: summary = key.summary result1 = re.search('\s*%s' % self.rssSearch2.GetValue(), summary) if result1 != None: search_list1.append(key) self.search_list1 = search_list1 self.update_display2() #---------------------------------------------------------------------- def on_double_click(self, event): # Загрузить выбранную ссылку в виджет браузера obj = self.rssOlv.GetSelectedObject() self.wv.LoadURL(obj.link) #---------------------------------------------------------------------- def on_double_click1(self, event): obj = self.searchOlv.GetSelectedObject() self.wv.LoadURL(obj.link) #---------------------------------------------------------------------- def on_double_click2(self, event): obj = self.searchOlv2.GetSelectedObject() self.wv.LoadURL(obj.link) #---------------------------------------------------------------------- def on_select(self, event): # Загрузить ссылку в меню для краткого содержания base_path = os.path.dirname(os.path.abspath(__file__)) obj = self.rssOlv.GetSelectedObject() html = "<html><body>%s</body></html>" % obj.summary fname = "summary.html" full_path = os.path.join(base_path, fname) try: with open(full_path, "w") as fh: fh.write(html) print("file:///" + full_path) self.summaryTxt.LoadURL("file:///" + full_path) except (OSError, IOError): print("Error writing html summary") #---------------------------------------------------------------------- def on_select1(self, event): base_path = os.path.dirname(os.path.abspath(__file__)) obj = self.searchOlv.GetSelectedObject() html = "<html><body>%s</body></html>" % obj.summary fname = "summary.html" full_path = os.path.join(base_path, fname) try: with open(full_path, "w") as fh: fh.write(html) print("file:///" + full_path) self.summaryTxt.LoadURL("file:///" + full_path) except (OSError, IOError): print("Error writing html summary") #---------------------------------------------------------------------- def on_select2(self, event): base_path = os.path.dirname(os.path.abspath(__file__)) obj = self.searchOlv2.GetSelectedObject() html = "<html><body>%s</body></html>" % obj.summary fname = "summary.html" full_path = os.path.join(base_path, fname) try: with open(full_path, "w") as fh: fh.write(html) print("file:///" + full_path) self.summaryTxt.LoadURL("file:///" + full_path) except (OSError, IOError): print("Error writing html summary") #---------------------------------------------------------------------- def update_display(self): # Обновить RSS feed дисплей self.rssOlv.SetColumns([ ColumnDefn("Title", "left", 200, "title"), ColumnDefn("Website", "left", 200, "website"), ]) self.rssOlv.SetObjects(self.data) #---------------------------------------------------------------------- def update_display1(self): self.searchOlv.SetColumns([ ColumnDefn("Title", "left", 200, "title"), ColumnDefn("Website", "left", 200, "website"), ]) self.searchOlv.SetObjects(self.search_list) #---------------------------------------------------------------------- def update_display2(self): self.searchOlv2.SetColumns([ ColumnDefn("Title", "left", 200, "title"), ColumnDefn("Website", "left", 200, "website"), ]) self.searchOlv2.SetObjects(self.search_list1)
class Prevention(wx.Panel): def __init__(self, parent, id, ptID): wx.Panel.__init__(self, parent, id) self.ptID = ptID prevents = prevent_find(ptID) self.preventList = ObjectListView(self, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.preventList.SetColumns([ ColumnDefn("Name", "left", 250, valueGetter="prevent_name", isEditable=True), ColumnDefn("Last Date", "center", 100, valueGetter="date", isEditable=True), ColumnDefn("Result", "center", 300, valueGetter="reason", isEditable=True), ColumnDefn("Interval", "center", 60, valueGetter="p_interval", isEditable=True), ColumnDefn("Notes", "left", 500, valueGetter="notes", isEditable=True), ]) self.preventList.SetObjects(prevents) self.preventList.cellEditMode = ObjectListView.CELLEDIT_DOUBLECLICK self.preventList.Bind(EVT_CELL_EDIT_STARTING, self.HandleCellEditStarting) self.preventList.Bind(EVT_CELL_EDIT_FINISHED, self.preventListHandleCellEditFinished) mainSizer = wx.BoxSizer(wx.VERTICAL) vaccines = vaccine_find(ptID) self.vaccineList = ObjectListView(self, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.vaccineList.SetColumns([ ColumnDefn("Vaccine", "left", 150, valueGetter="vaccine", isEditable=True), ColumnDefn("Dates Given", "left", 600, valueGetter="dates", isEditable=True), ColumnDefn("Notes", "left", 500, valueGetter="notes", isEditable=True), ]) self.vaccineList.SetObjects(vaccines) self.vaccineList.cellEditMode = ObjectListView.CELLEDIT_DOUBLECLICK self.vaccineList.Bind(EVT_CELL_EDIT_STARTING, self.HandleCellEditStarting) self.vaccineList.Bind(EVT_CELL_EDIT_FINISHED, self.vaccineListHandleCellEditFinished) #Build the add/delete buttons for each list preventSizer = wx.BoxSizer(wx.HORIZONTAL) vaccineSizer = wx.BoxSizer(wx.HORIZONTAL) prevButtons = (('Add', self.OnAddPrevent), ('Delete', self.OnDelPrevent)) for label, handler in prevButtons: EMR_utilities.buildOneButton(self, self, label, handler, preventSizer) vacButtons = (('Add', self.OnAddVaccine), ('Delete', self.OnDelVaccine), ('Print', self.OnPrintVaccines)) for label, handler in vacButtons: EMR_utilities.buildOneButton(self, self, label, handler, vaccineSizer) #Set the sizers that have not already been set self.preventTitle = wx.StaticText(self, -1, 'Health Maintenance') self.vaccineTitle = wx.StaticText(self, -1, 'Vaccines') titlefont = wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.BOLD) self.preventTitle.SetFont(titlefont) self.vaccineTitle.SetFont(titlefont) preventSizer.Add(self.preventTitle, 0, wx.ALIGN_CENTER | wx.ALL, 5) mainSizer.Add(preventSizer) mainSizer.Add(self.preventList, 1, wx.EXPAND | wx.TOP, 3) mainSizer.Add((15, -1)) vaccineSizer.Add(self.vaccineTitle, 0, wx.ALIGN_CENTER | wx.ALL, 5) mainSizer.Add(vaccineSizer) mainSizer.Add(self.vaccineList, 1, wx.EXPAND | wx.TOP, 3) mainSizer.Add((-1, 5)) self.SetSizer(mainSizer) self.Centre() self.Show(True) #def getKey(item): # return item['vaccine'] def OnPrintVaccines(self, event): obj = self.vaccineList.GetObjects() string = '' v = [] for items in obj: v.append((items['vaccine'], items['dates'], items['notes'])) for things in sorted(v): string = '%s %s %s\n' % \ (things[1], things[0], things[2]) + string form_lt = "%s/EMR_outputs/Vaccines.html" % settings.LINUXPATH form_at = "%s/EMR_outputs/Vaccines.html" % settings.APPLEPATH form_wt = "%s\EMR_outputs\Vaccines.html" % settings.WINPATH form = open(EMR_utilities.platformText(form_lt, form_at, form_wt), 'r') s = form.read() form.close() dem_data = EMR_utilities.getDictData( 'SELECT * FROM demographics WHERE patient_ID = %s;' % self.ptID) dem_data['string'] = string dem_data['date'] = EMR_utilities.dateToday() dem_data['name_address'] = EMR_formats.format_address(dem_data) script_text = s % (dem_data) printer = EMR_utilities.Printer() printer.PreviewText(script_text) '''path_lt = "%s/EMR_outputs/%s/Orders" % (settings.LINUXPATH, self.ptID) path_at = "%s/EMR_outputs/%s/Orders" % (settings.APPLEPATH, self.ptID) path_wt = "%s\EMR_outputs\%s\Orders" % (settings.WINPATH, self.ptID) path = EMR_utilities.platformText(path_lt, path_at, path_wt) filename = "%s\script%s.html" % (path, EMR_utilities.dateToday(t='yes')) f = open(filename, 'w') f.write(script_text) f.close()''' def HandleCellEditStarting(self, event): pass def vaccineListHandleCellEditFinished(self, event): sqlstmt = 'UPDATE vaccines SET %s = "%s" WHERE vaccine_number = %s;' \ % (self.vaccineList.columns[event.subItemIndex].valueGetter, self.vaccineList.GetItem(event.rowIndex, event.subItemIndex).GetText(), event.rowModel["vaccine_number"]) EMR_utilities.updateData(sqlstmt) def preventListHandleCellEditFinished(self, event): sqlstmt = 'UPDATE prevents2 SET %s = "%s" WHERE prevent_number = %s;' \ % (self.preventList.columns[event.subItemIndex].valueGetter, self.preventList.GetItem(event.rowIndex, event.subItemIndex).GetText(), event.rowModel["prevent_number"]) EMR_utilities.updateData(sqlstmt) def OnAddPrevent(self, event): prev = wx.GetTextFromUser('What is the new health maintance item?', 'Health Maintenance') if prev == "": pass else: note = wx.GetTextFromUser('Any notes?', 'Notes') query = 'INSERT INTO prevents2 SET prevent_name = "%s", date = "%s", reason = "normal", p_interval = 1, notes = "%s", patient_ID = %s;' % \ (prev, EMR_utilities.dateToday(), note, self.ptID) EMR_utilities.updateData(query) self.UpdatePrevents() def OnAddVaccine(self, event): vac = wx.GetTextFromUser('What is the new vaccine?', 'Vaccines') dates = wx.GetTextFromUser('What date(s) was vaccine given?', 'Vaccines') if vac == "": pass else: note = wx.GetTextFromUser('Any notes?', 'Notes') query = 'INSERT INTO vaccines SET vaccine = "%s", dates = "%s", notes = "%s", patient_ID = %s;' % \ (vac, dates, note, self.ptID) EMR_utilities.updateData(query) self.UpdateVaccines() def OnDelPrevent(self, event): obj = self.preventList.GetSelectedObjects() for items in obj: qry = 'DELETE FROM prevents2 WHERE prevent_number = %s;' % items[ 'prevent_number'] self.preventList.RemoveObject(items) EMR_utilities.updateData(qry) def OnDelVaccine(self, event): obj = self.vaccineList.GetSelectedObjects() for items in obj: qry = 'DELETE FROM vaccines WHERE vaccine_number = %s;' % items[ 'vaccine_number'] self.vaccineList.RemoveObject(items) EMR_utilities.updateData(qry) def UpdatePrevents(self): prevents = prevent_find(self.ptID) self.preventList.SetObjects(prevents) def UpdateVaccines(self): vac = vaccine_find(self.ptID) self.vaccineList.SetObjects(vac)
class MainPanel(wx.Panel): def __init__(self, parent): super().__init__(parent) self.search_results = [] self.max_size = 300 self.paths = wx.StandardPaths.Get() font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL) main_sizer = wx.BoxSizer(wx.VERTICAL) txt = 'Search for images on NASA' label = wx.StaticText(self, label=txt) main_sizer.Add(label, 0, wx.ALL, 5) self.search = wx.SearchCtrl( self, style=wx.TE_PROCESS_ENTER, size=(-1, 25)) self.search.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN, self.on_search) self.search.Bind(wx.EVT_TEXT_ENTER, self.on_search) main_sizer.Add(self.search, 0, wx.EXPAND) self.search_results_olv = ObjectListView( self, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.search_results_olv.SetEmptyListMsg("No Results Found") self.search_results_olv.Bind(wx.EVT_LIST_ITEM_SELECTED, self.on_selection) main_sizer.Add(self.search_results_olv, 1, wx.EXPAND) self.update_search_results() main_sizer.AddSpacer(30) self.title = wx.TextCtrl(self, style=wx.TE_READONLY) self.title.SetFont(font) main_sizer.Add(self.title, 0, wx.ALL|wx.EXPAND, 5) img = wx.Image(240, 240) self.image_ctrl = wx.StaticBitmap(self, bitmap=wx.Bitmap(img)) main_sizer.Add(self.image_ctrl, 0, wx.CENTER|wx.ALL, 5 ) download_btn = wx.Button(self, label='Download Image') download_btn.Bind(wx.EVT_BUTTON, self.on_download) main_sizer.Add(download_btn, 0, wx.ALL|wx.CENTER, 5) self.SetSizer(main_sizer) def on_download(self, event): selection = self.search_results_olv.GetSelectedObject() if selection: with DownloadDialog(selection) as dlg: dlg.ShowModal() def on_search(self, event): search_term = event.GetString() if search_term: query = {'q': search_term, 'media_type': 'image'} full_url = base_url + '?' + urlencode(query, quote_via=quote_plus) r = requests.get(full_url) data = r.json() self.search_results = [] for item in data['collection']['items']: if item.get('data') and len(item.get('data')) > 0: data = item['data'][0] if data['title'].strip() == '': # Skip results with blank titles continue result = Result(item) self.search_results.append(result) self.update_search_results() def on_selection(self, event): selection = self.search_results_olv.GetSelectedObject() self.title.SetValue(f'{selection.title}') if selection.thumbnail: self.update_image(selection.thumbnail) else: img = wx.Image(240, 240) self.image_ctrl.SetBitmap(wx.Bitmap(img)) self.Refresh() self.Layout() def update_image(self, url): filename = url.split('/')[-1] tmp_location = os.path.join(self.paths.GetTempDir(), filename) r = requests.get(url) with open(tmp_location, "wb") as thumbnail: thumbnail.write(r.content) if os.path.exists(tmp_location): img = wx.Image(tmp_location, wx.BITMAP_TYPE_ANY) W = img.GetWidth() H = img.GetHeight() if W > H: NewW = self.max_size NewH = self.max_size * H / W else: NewH = self.max_size NewW = self.max_size * W / H img = img.Scale(NewW,NewH) else: img = wx.Image(240, 240) self.image_ctrl.SetBitmap(wx.Bitmap(img)) self.Refresh() self.Layout() def update_search_results(self): self.search_results_olv.SetColumns([ ColumnDefn("Title", "left", 250, "title"), ColumnDefn("Description", "left", 350, "description"), ColumnDefn("Photographer", "left", 100, "photographer"), ColumnDefn("Date Created", "left", 150, "date_created") ]) self.search_results_olv.SetObjects(self.search_results)
class ConfigPanel(wx.Panel): """""" #---------------------------------------------------------------------- def __init__(self, parent): """Conostructor""" wx.Panel.__init__(self, parent) try: self.bookResults = controller.getAllRecords() except: self.bookResults = [] mainSizer = wx.BoxSizer(wx.VERTICAL) #searchSizer = wx.BoxSizer(wx.HORIZONTAL) btnSizer = wx.BoxSizer(wx.HORIZONTAL) #font = wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD) self.bookResultsOlv = ObjectListView(self, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.bookResultsOlv.SetEmptyListMsg("No Records Found") self.bookResultsOlv.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.onEditRecord) self.setBooks() # create the button row addRecordBtn = wx.Button(self, label="Add") addRecordBtn.Bind(wx.EVT_BUTTON, self.onAddRecord) btnSizer.Add(addRecordBtn, 0, wx.ALL, 5) editRecordBtn = wx.Button(self, label="Edit") editRecordBtn.Bind(wx.EVT_BUTTON, self.onEditRecord) btnSizer.Add(editRecordBtn, 0, wx.ALL, 5) deleteRecordBtn = wx.Button(self, label="Delete") deleteRecordBtn.Bind(wx.EVT_BUTTON, self.onDelete) btnSizer.Add(deleteRecordBtn, 0, wx.ALL, 5) showAllBtn = wx.Button(self, label="Show All") showAllBtn.Bind(wx.EVT_BUTTON, self.onShowAllRecord) btnSizer.Add(showAllBtn, 0, wx.ALL, 5) #mainSizer.Add(searchSizer) mainSizer.Add(self.bookResultsOlv, 1, wx.ALL | wx.EXPAND, 5) mainSizer.Add(btnSizer, 0, wx.CENTER) self.SetSizer(mainSizer) self.Hide() #---------------------------------------------------------------------- def onShowList(self, event): self.Hide() def onAddRecord(self, event): """ Add a record to the database """ dlg = addModRecord.AddModRecDialog() dlg.ShowModal() dlg.Destroy() self.showAllRecords() #---------------------------------------------------------------------- def onEditRecord(self, event): """ Edit a record """ selectedRow = self.bookResultsOlv.GetSelectedObject() if selectedRow == None: commonDlgs.showMessageDlg("No row selected!", "Error") return dlg = addModRecord.AddModRecDialog(selectedRow, title="Modify", addRecord=False) dlg.ShowModal() dlg.Destroy() self.showAllRecords() #---------------------------------------------------------------------- def onDelete(self, event): """ Delete a record """ selectedRow = self.bookResultsOlv.GetSelectedObject() if selectedRow == None: commonDlgs.showMessageDlg("No row selected!", "Error") return controller.deleteRecord(selectedRow.id) self.showAllRecords() #---------------------------------------------------------------------- # 713528 0818 def onSearch(self, event): """ Searches database based on the user's filter choice and keyword """ filterChoice = self.categories.GetValue() keyword = self.search.GetValue() print("%s %s" % (filterChoice, keyword)) self.bookResults = controller.searchRecords(filterChoice, keyword) self.setBooks() #---------------------------------------------------------------------- def onShowAllRecord(self, event): """ Updates the record list to show all of them """ self.showAllRecords() #---------------------------------------------------------------------- def setBooks(self): self.bookResultsOlv.SetColumns([ ColumnDefn("Config Item", "left", 150, "title"), ColumnDefn("Commment", "left", 350, "comment"), ColumnDefn("Config Value", "left", 150, "config_value"), ColumnDefn("Is list?", "left", 100, checkStateGetter="is_list", checkStateSetter="is_list") ]) self.bookResultsOlv.SetObjects(self.bookResults) #---------------------------------------------------------------------- def showAllRecords(self): """ Show all records in the object list view control """ self.bookResults = controller.getAllRecords() self.setBooks()
class MainPanel(wx.Panel): """""" #---------------------------------------------------------------------- def __init__(self, parent): """Constructor""" wx.Panel.__init__(self, parent=parent) self.currentSelection = None self.gui_shown = False self.procs = [] self.sort_col = 0 self.col_w = { "name": 175, "pid": 60, "exe": 300, "user": 75, "mem": 75 } self.procmonOlv = ObjectListView(self, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.procmonOlv.Bind(wx.EVT_LIST_COL_CLICK, self.onColClick) self.procmonOlv.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onSelect) #self.procmonOlv.Select self.setProcs() endProcBtn = wx.Button(self, label="End Process") endProcBtn.Bind(wx.EVT_BUTTON, self.onKillProc) mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(self.procmonOlv, 1, wx.EXPAND | wx.ALL, 5) mainSizer.Add(endProcBtn, 0, wx.ALIGN_RIGHT | wx.ALL, 5) self.SetSizer(mainSizer) # check for updates every 5 seconds self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.update, self.timer) self.update("") self.setProcs() # create a pubsub receiver Publisher().subscribe(self.updateDisplay, "update") #---------------------------------------------------------------------- def onColClick(self, event): """ Remember which column to sort by, currently only does ascending """ self.sort_col = event.GetColumn() #---------------------------------------------------------------------- def onKillProc(self, event): """ Kill the selected process by pid """ obj = self.procmonOlv.GetSelectedObject() print pid = int(obj.pid) try: p = psutil.Process(pid) p.terminate() self.update("") except Exception, e: print "Error: " + e
class Vitals(wx.Panel): def __init__(self, parent, ID, PtID): wx.Panel.__init__(self, parent, ID) #I need some way to set the max size for the grid self.PtID = PtID self.qry = "SELECT * FROM vitals WHERE patient_ID = %s;" % (str(self.PtID)) self.vitals = list(EMR_utilities.getAllDictData(self.qry)) self.textctrl = {} self.vitalsList = ObjectListView(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER) self.vitalsList.SetColumns([ ColumnDefn("Weight", "center", 80, valueGetter="wt"), ColumnDefn("Height", "center", 80, valueGetter="ht"), ColumnDefn("HC", "center", 80, valueGetter="hc"), ColumnDefn("Systolic", "center", 80, valueGetter="sBP"), ColumnDefn("Diastolic", "center", 80, valueGetter="dBP"), ColumnDefn("Pulse", "center", 80, valueGetter="pulse"), ColumnDefn("Resp", "center", 80, valueGetter="resp"), ColumnDefn("O2 Sat", "center", 80, valueGetter="sats"), ColumnDefn("Temp", "center", 80, valueGetter="temp"), ColumnDefn("Date", "center", 120, valueGetter="vitals_date") ]) self.vitalsList.SetObjects(self.vitals) self.vitalsList.cellEditMode = ObjectListView.CELLEDIT_DOUBLECLICK self.vitalsList.Bind(EVT_CELL_EDIT_STARTING, self.HandleCellEditStarting) self.vitalsList.Bind(EVT_CELL_EDIT_FINISHED, self.listHandleCellEditFinished) self.vitalsbox = wx.BoxSizer(wx.HORIZONTAL) self.vitalsbox.Add(self.vitalsList, 1, wx.EXPAND |wx.ALL, 20) self.mainsizer = wx.BoxSizer(wx.VERTICAL) border = wx.StaticBox(self, -1, 'Add Vitals') f = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.LIGHT) border.SetFont(f) addvitals = wx.StaticBoxSizer(border, wx.HORIZONTAL) controls = [('Wt', 40), ('Ht', 30), ('HC', 30), ('Temp', 40), ('SBP', 40), ('DBP', 40), ('Pulse', 40), ('Resp', 30), \ ('O2 Sats', 30), ('Date', 80)] for label, size in controls: EMR_utilities.buildOneTextCtrl(self, label, size, addvitals) self.textctrl['Date'].SetValue(str(EMR_utilities.dateToday())) self.mainsizer.Add(self.vitalsbox) self.mainsizer.Add(addvitals, 0, wx.ALL, 20) buttonAdd = EMR_utilities.buildOneButton(self, self, 'Update Vitals', self.UpdateVitals) buttonDel = EMR_utilities.buildOneButton(self, self, 'Delete Vitals', self.DeleteVitals) self.mainsizer.Add(buttonAdd, 0, wx.ALIGN_LEFT|wx.ALIGN_TOP|wx.LEFT|wx.TOP, 20) self.mainsizer.Add(buttonDel, 0, wx.ALIGN_LEFT|wx.ALIGN_TOP|wx.LEFT|wx.TOP, 20) self.SetSizer(self.mainsizer) def HandleCellEditStarting(self, event): pass def listHandleCellEditFinished(self, event): sqlstmt = 'UPDATE vitals SET %s = "%s" WHERE vitals_number = %s;' \ % (self.vitalsList.columns[event.subItemIndex].valueGetter, self.vitalsList.GetItem(event.rowIndex, event.subItemIndex).GetText(), event.rowModel["vitals_number"]) EMR_utilities.updateData(sqlstmt) def UpdateVitals(self, event): updateqry = 'INSERT INTO vitals SET wt = "%s", ht = "%s", hc = "%s", temp = "%s", sBP = "%s", dBP = "%s", \ pulse = "%s", resp = "%s", sats = "%s", vitals_date = "%s", patient_ID = %s;' % (self.textctrl['Wt'].GetValue(), self.textctrl['Ht'].GetValue(), self.textctrl['HC'].GetValue(), self.textctrl['Temp'].GetValue(), self.textctrl['SBP'].GetValue(), self.textctrl['DBP'].GetValue(), self.textctrl['Pulse'].GetValue(), self.textctrl['Resp'].GetValue(), self.textctrl['O2 Sats'].GetValue(), self.textctrl['Date'].GetValue(), self.PtID) EMR_utilities.updateData(updateqry) self.UpdateList() data = EMR_utilities.getData("SELECT dob, sex FROM demographics WHERE patient_ID = %s;" % self.PtID) if data[1] == 'male': sex = 'boy' else: sex = 'girl' s = data[0].strftime("%B") + ',' + str(data[0].day) + ',' + str(data[0].year) + ',' + sex + ',' + \ self.textctrl['Ht'].GetValue() + ',' + self.textctrl['Wt'].GetValue() + ',' + self.textctrl['HC'].GetValue() with open('/home/mb/Dropbox/iMacros/Datasources/growth.txt', 'w') as f: f.write(s) f.close() self.Layout() #this line from C M and Robin Dunn on the mailing list; see 20 Feb 08 email for items in self.textctrl: self.textctrl[items].SetValue("") def DeleteVitals(self, event): obj = self.vitalsList.GetSelectedObjects() for items in obj: qry = 'DELETE FROM vitals WHERE vitals_number = %s;' % items['vitals_number'] EMR_utilities.updateData(qry) self.UpdateList() def UpdateList(self): self.vitals = list(EMR_utilities.getAllDictData(self.qry)) #this function just updates the list after new vitals added or deleted self.vitalsList.SetObjects(self.vitals)
class Problems(wx.Panel): def __init__(self, parent, id, ptID): wx.Panel.__init__(self, parent, id) self.ptID = ptID self.problem = '' #receives the newly selected problem back from AddProblemDialog self.probs = [] for items in prob_find(ptID): self.probs.append( Problem(items["short_des"], items["prob_date"], items["icd10"], items["problem_number"])) self.problist = ObjectListView(self, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.problist.SetColumns([ ColumnDefn("Problem", "left", 400, valueGetter="short_des"), ColumnDefn("First Treated", "left", 100, valueGetter="prob_date"), ColumnDefn("ICD-10 Code", "left", 100, valueGetter="icd10") ]) self.problist.rowFormatter = self.rowFormatter self.problist.useAlternateBackColors = False self.problist.SetObjects(self.probs) self.problist.cellEditMode = ObjectListView.CELLEDIT_DOUBLECLICK self.problist.Bind(EVT_CELL_EDIT_STARTING, self.HandleCellEditStarting) self.problist.Bind(EVT_CELL_EDIT_FINISHED, self.HandleCellEditFinished) leftprob = wx.BoxSizer(wx.VERTICAL) rightprob = wx.BoxSizer(wx.VERTICAL) mainsizer = wx.BoxSizer(wx.HORIZONTAL) buttons = (('Add', self.OnNewProb, leftprob), ('Remove', self.OnRemProb, leftprob), ('icd Toggle', self.OnToggle, leftprob)) for label, handler, sizer in buttons: EMR_utilities.buildOneButton(self, self, label, handler, sizer) clock = EMR_utilities.makeClock(self, leftprob) rightprob.Add(self.problist, 1, wx.EXPAND | wx.TOP, 5) mainsizer.Add(leftprob, 0) mainsizer.Add(rightprob, 1, wx.EXPAND) self.SetSizer(mainsizer) listBilledICD(ptID) self.myFont = wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD) def OnNewProb(self, event): #opens dialog window with fields for new problem, does lookup based on description only, updates MySQL, #then clears the list and resets the lists with new query for problems dlg = AddProblemDialog(self, self, -1, 'New Problem') dlg.ProbInstance = self dlg.CenterOnScreen() if dlg.ShowModal() == wx.ID_OK: today = datetime.date.today() newICD = EMR_utilities.getData( 'SELECT icd10 FROM ICD10billable WHERE short_des = "%s";' % self.problem) query = 'INSERT INTO problems10 SET short_des = "%s", prob_date = "%s", patient_ID = "%s", icd10 = "%s";' % \ (self.problem, today, self.ptID, newICD[0]) EMR_utilities.updateData(query) self.UpdateList() dlg.Destroy() def OnRemProb(self, event): obj = self.problist.GetSelectedObjects() for items in obj: qry = 'DELETE FROM problems10 WHERE problem_number = %s;' % items.problem_number self.problist.RemoveObject(items) EMR_utilities.updateData(qry) def UpdateList(self): #problems = prob_find(self.ptID) self.probs = [] for items in prob_find(self.ptID): self.probs.append( Problem(items["short_des"], items["prob_date"], items["icd10"], items["problem_number"])) self.problist.SetObjects(self.probs) def HandleCellEditStarting(self, event): pass def HandleCellEditFinished(self, event): sqlstmt = 'UPDATE problems10 SET short_des = "%s" WHERE problem_number = %s;' \ % (self.problist.GetItem(event.rowIndex, event.subItemIndex).GetText(), event.rowModel["problem_number"]) EMR_utilities.updateData(sqlstmt) def OnToggle(self, event): pass def rowFormatter(self, listItem, model): qryBill = 'SELECT billable FROM ICD10billable WHERE icd10 = "%s";' % model.icd10 qryHCC = 'SELECT hcc FROM hcc WHERE icd10 = "%s";' % model.icd10 resultsBill = EMR_utilities.getData(qryBill) resultsHCC = EMR_utilities.getData(qryHCC) if resultsBill[0] == '0': listItem.SetTextColour(wx.RED) else: pass try: if resultsHCC[0] == 'Yes': listItem.SetBackgroundColour('Light Grey') except: pass
class DataCoefPanel(wx.Frame): def __init__(self, parent): pos = wx.DefaultPosition size = (377, 282) if _platform == 'darwin': style = wx.DEFAULT_FRAME_STYLE else: style = (wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN | wx.FRAME_FLOAT_ON_PARENT) wx.Frame.__init__(self, wx.GetApp().TopWindow, wx.ID_ANY, p4R.Application_name + " - Strain and DW Values", pos, size, style) self.Bind(wx.EVT_CLOSE, self.on_close) self.SetIcon(prog_icon.GetIcon()) pnl = wx.Panel(self) def handleCellEditStarting(evt): currentCol = self.GetOLVColClicked(evt) if currentCol == 0: evt.Veto() def handleCellEditFinishing(evt): currentline = evt.rowIndex currentCol = self.GetOLVColClicked(evt) val = evt.cellValue self.update_param_dict(currentline, currentCol, val) self.list = ObjectListView(pnl, sortable=False, style=wx.LC_REPORT | wx.SUNKEN_BORDER, size=(450, 500)) self.list.cellEditMode = ObjectListView.CELLEDIT_SINGLECLICK self.list.handleStandardKeys = False self.list.SetEmptyListMsg("This database has no rows") self.list.SetEmptyListMsgFont( wx.FFont(24, wx.DEFAULT, faceName="Tekton")) if _platform == "linux" or _platform == "linux2": self.width_name = 120 else: self.width_name = 80 self.width = 70 self.widthCheck = 25 self.col2checkstatus = {1: 0, 2: 0} self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list) self.Bind(wx.EVT_LIST_COL_CLICK, self.OnItemSelected, self.list) self.list.Bind(EVT_CELL_EDIT_STARTING, handleCellEditStarting) self.list.Bind(EVT_CELL_EDIT_FINISHING, handleCellEditFinishing) mastersizer = wx.BoxSizer(wx.HORIZONTAL) mastersizer.Add(self.list, 0, wx.ALL | wx.EXPAND, 5) pub.subscribe(self.on_fill_list, pubsub_Fill_List_coef) pub.subscribe(self.on_open_window, pubsub_Open_data_coef_Window) # self.Bind(wx.EVT_SIZE, self.OnSize) pnl.SetSizer(mastersizer) pnl.Layout() pnl.Fit() self.InitializeList() def on_open_window(self): self.CenterOnParent() def on_close(self, event): pub.sendMessage(pubsub_Hide_Show_data_coef, test=1) def InitializeList(self): temp = [] ic_ = prog_icon_curve.GetBitmap() ImageIndex = self.list.AddImages(ic_) self.list.AddNamedImages("name", ic_) temp.append( ColumnDefn(headercolumnname[0], "center", self.width_name, valueGetter=headercolumnname[0], imageGetter=ImageIndex, maximumWidth=self.width_name)) temp.append( ColumnDefn(headercolumnname[1], "center", self.width, valueGetter="sp", maximumWidth=self.width, checkStateGetter="state1")) temp.append( ColumnDefn(headercolumnname[3], "center", self.width, valueGetter="dwp", maximumWidth=self.width, checkStateGetter="state2")) self.list.SetColumns(temp) def on_fill_list(self): a = P4Rm() self.Freeze() list_temp = [] roundval = 3 if a.AllDataDict['model'] == 2: for i in range(7): name = asym_pv[i] val_sp = str(round(a.ParamDict['sp'][i], roundval)) val_dwp = str(round(a.ParamDict['dwp'][i], roundval)) check_sp = a.ParamDict['state_sp'][i] check_dwp = a.ParamDict['state_dwp'][i] list_temp.append( CoefListData(name, val_sp, check_sp, val_dwp, check_dwp)) else: len_sp = len(a.ParamDict['sp']) len_dwp = len(a.ParamDict['dwp']) if len_sp > len_dwp: num = len_sp else: num = len_dwp for i in range(num): if i < len_sp: val_sp = str(round(a.ParamDict['sp'][i], roundval)) check_sp = a.ParamDict['state_sp'][i] else: val_sp = "" check_sp = True if i < len_dwp: val_dwp = str(round(a.ParamDict['dwp'][i], roundval)) check_dwp = a.ParamDict['state_dwp'][i] else: val_dwp = "" check_dwp = True list_temp.append( CoefListData(i + 1, val_sp, check_sp, val_dwp, check_dwp)) self.list.SetObjects(list_temp) self.Thaw() def update_param_dict(self, currentline, currentCol, val): if currentCol == 1: P4Rm.ParamDict['sp'][currentline] = float(val) if currentCol == 2: P4Rm.ParamDict['dwp'][currentline] = float(val) self.read_and_update() def read_and_update(self): pub.sendMessage(pubsub_update_sp_dwp_eta) b = Calcul4Radmax() b.on_update() def OnItemSelected(self, event): if 'phoenix' in wx.PlatformInfo: currentline = event.Index else: currentline = event.m_itemIndex currentCol = self.GetOLVColClicked(event) if currentline == -1: self.Freeze() if currentCol == 1 or currentCol == 2: if self.col2checkstatus[currentCol] == 0: val = False self.col2checkstatus[currentCol] = 1 else: val = True self.col2checkstatus[currentCol] = 0 objects = self.list.GetObjects() if currentCol == 1: for obj in objects: obj.state1 = val elif currentCol == 2: for obj in objects: obj.state2 = val self.list.SetObjects(objects) self.list.RefreshObject(objects) self.Thaw() if currentCol == 1 or currentCol == 2: a = P4Rm() objects = self.list.GetObjects() len_sp = len(a.ParamDict['sp']) len_dwp = len(a.ParamDict['dwp']) check_sp = [] check_dwp = [] i = 0 for obj in objects: if i < len_sp: check_sp.append(obj.state1) if i < len_dwp: check_dwp.append(obj.state2) i += 1 P4Rm.ParamDict['state_sp'] = check_sp P4Rm.ParamDict['state_dwp'] = check_dwp def GetOLVColClicked(self, event): """ [email protected] 2011-01 Jan-13 For use with a 3rd party module named ObjectListView used with wxPython. """ spt = wx.GetMousePosition() fpt = self.list.ScreenToClient(spt) x, y = fpt last_col = 0 for col in range(self.list.GetColumnCount()): col_width = self.list.GetColumnWidth(col) left_pxl_col = last_col right_pxl_col = last_col + col_width - 1 if left_pxl_col <= x <= right_pxl_col: col_selected = col break col_selected = None last_col = last_col + col_width return col_selected def OnSize(self, event): sizet = event.GetSize() print("%s, %s" % (sizet.width, sizet.height)) event.Skip()
class SkeletonPanel(wx.Panel): """ Skeleton panel widget """ def __init__(self, parent): super().__init__(parent) self.db_name = "" self.skeleton_results = [] self.session = None self.parent = parent # self.session = controller.connect_to_database() main_sizer = wx.BoxSizer(wx.VERTICAL) search_sizer = wx.BoxSizer(wx.HORIZONTAL) btn_sizer = wx.BoxSizer(wx.HORIZONTAL) font = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL) # create the search related widgets categories = ["Site", "Location", "Observer", "Skeleton"] search_label = wx.StaticText(self, label=" Filter By:") search_label.SetFont(font) search_sizer.Add(search_label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 5) search_sizer.AddSpacer(5) if platform.system().lower() == 'linux': self.categories = wx.ComboBox(self, value="Skeleton", choices=categories, style=wx.CB_READONLY, size=(150, -1)) else: self.categories = wx.ComboBox(self, value="Skeleton", choices=categories, style=wx.CB_READONLY) search_sizer.Add(self.categories, 0, wx.ALL, 5) search_sizer.AddSpacer(5) if platform.system().lower() == 'linux': self.search_ctrl = wx.SearchCtrl(self, style=wx.TE_PROCESS_ENTER, size=(200, 27)) else: self.search_ctrl = wx.SearchCtrl(self, style=wx.TE_PROCESS_ENTER, size=(200, -1)) # self.search_ctrl.ShowCancelButton(True) self.search_ctrl.SetDescriptiveText('Filter') self.search_ctrl.Bind(wx.EVT_TEXT_ENTER, self.search) search_sizer.Add(self.search_ctrl, 0, wx.ALIGN_CENTER_VERTICAL, 5) search_sizer.AddSpacer(5) self.show_all_btn = wx.Button(self, label="Show All") self.show_all_btn.Bind(wx.EVT_BUTTON, self.on_show_all) search_sizer.Add(self.show_all_btn, 0, wx.ALL, 5) lfont = self.GetFont() lfont.SetPointSize(10) self.skeleton_results_olv = ObjectListView( self, style=wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_SINGLE_SEL) self.skeleton_results_olv.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.onDoubleClick) self.skeleton_results_olv.EnableBellOnNoMatch(on=False) self.skeleton_results_olv.SetFont(lfont) self.skeleton_results_olv.SetEmptyListMsg("No Records Found") self.update_skeleton_results() # create the button row self.add_record_btn = wx.Button(self, label="&Add") self.add_record_btn.Bind(wx.EVT_BUTTON, self.add_record) btn_sizer.Add(self.add_record_btn, 0, wx.ALL, 5) self.edit_record_btn = wx.Button(self, label="&Edit") self.edit_record_btn.Bind(wx.EVT_BUTTON, self.edit_record) btn_sizer.Add(self.edit_record_btn, 0, wx.ALL, 5) self.pre_record_btn = wx.Button(self, label="&Preservation") self.pre_record_btn.Bind(wx.EVT_BUTTON, self.edit_preservation) btn_sizer.Add(self.pre_record_btn, 0, wx.ALL, 5) self.delete_record_btn = wx.Button(self, label="&Delete") self.delete_record_btn.Bind(wx.EVT_BUTTON, self.delete_record) btn_sizer.Add(self.delete_record_btn, 0, wx.ALL, 5) self.report_btn = wx.Button(self, label="&Create a report") self.report_btn.Bind(wx.EVT_BUTTON, self.create_report) btn_sizer.Add(self.report_btn, 0, wx.ALL, 5) self.controls_state(False) main_sizer.Add(search_sizer) main_sizer.Add(self.skeleton_results_olv, 1, wx.ALL | wx.EXPAND, 5) main_sizer.Add(btn_sizer, 0, wx.CENTER) self.SetSizer(main_sizer) def controls_state(self, state): self.add_record_btn.Enable(state) self.edit_record_btn.Enable(state) self.pre_record_btn.Enable(state) self.delete_record_btn.Enable(state) self.report_btn.Enable(state) self.show_all_btn.Enable(state) self.search_ctrl.Enable(state) def on_open_file(self, event): wildcard = "DATABASE files (*.db)|*.db" with wx.FileDialog(self, "Choose a file", wildcard=wildcard, style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as dialog: if dialog.ShowModal() == wx.ID_OK: self.db_name = dialog.GetPath() # zapis w ostatnio używanych plikach self.parent.filehistory.AddFileToHistory(dialog.GetPath()) self.parent.filehistory.Save(self.parent.config) self.parent.config.Flush() if self.session != None: self.skeleton_results_olv.DeleteAllItems() self.parent.SetTitle("{}: ".format(APP_NAME)) self.session.close() self.session = controller.connect_to_database(self.db_name) self.parent.SetTitle("{}: ".format(APP_NAME) + self.db_name) self.controls_state(True) self.show_all_records() def on_create_file(self, event): wildcard = "DATABASE files (*.db)|*.db" with wx.FileDialog(self, "Create a file", wildcard=wildcard, style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as dialog: if dialog.ShowModal() == wx.ID_OK: self.db_name = dialog.GetPath() # zapis w ostatnio używanych plikach self.parent.filehistory.AddFileToHistory(dialog.GetPath()) self.parent.filehistory.Save(self.parent.config) self.parent.config.Flush() if self.session != None: self.skeleton_results_olv.DeleteAllItems() self.parent.SetTitle("{}: ".format(APP_NAME)) self.session.close() self.session = controller.connect_to_database(self.db_name) self.parent.SetTitle("{}: ".format(APP_NAME) + self.db_name) self.controls_state(True) self.show_all_records() def on_export_file(self, event): """ export db to xlsx """ if self.session == None: dialogs.show_message('No data available for export.', 'Error') return wildcard = "XLSX files (*.xlsx)|*.xlsx" with wx.FileDialog(self, "Export to XLSX", wildcard=wildcard, style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as dialog: if dialog.ShowModal() == wx.ID_OK: self.xlsx_name = dialog.GetPath() result = controller.export_xlsx(self.session, self.xlsx_name) if result != '': dialogs.show_message(result, 'Error') self.skeleton_results_olv.SetFocus() def add_record(self, event): """ Add a record to the database """ with dialogs.RecordDialog(self.session) as dlg: dlg.CenterOnScreen() dlg.ShowModal() if dlg.result == 1: data = {} data['skeleton_id'] = dlg.skeleton_id data['site'] = dlg.skeleton_dict['site'] data['location'] = dlg.skeleton_dict['location'] data['skeleton'] = dlg.skeleton_dict['skeleton'] data['observer'] = dlg.skeleton_dict['observer'] data['obs_date'] = dlg.skeleton_dict['obs_date'] new_skeleton = olvSkeleton(data) self.skeleton_results_olv.AddObject(new_skeleton) idx = self.skeleton_results_olv.GetIndexOf(new_skeleton) self.skeleton_results_olv.Select(idx) self.skeleton_results_olv.SelectObject(new_skeleton) self.skeleton_results_olv.SetFocus() def edit_skeleton(self): selected_row = self.skeleton_results_olv.GetSelectedObject() active_row = self.skeleton_results_olv.GetIndexOf(selected_row) if selected_row is None: dialogs.show_message('No record selected!', 'Error') return with dialogs.RecordDialog(self.session, selected_row, title='Modify', addRecord=False) as dlg: dlg.CenterOnScreen() dlg.ShowModal() if dlg.result == 1: self.skeleton_results_olv.RefreshObject(selected_row) self.skeleton_results_olv.SetFocus() def edit_record(self, event): """ Edit a record """ self.edit_skeleton() def onDoubleClick(self, event): self.edit_skeleton() def delete_record(self, event): """ Delete a record """ selected_row = self.skeleton_results_olv.GetSelectedObject() row_index = self.skeleton_results_olv.GetIndexOf(selected_row) if selected_row is None: dialogs.show_message('No record selected!', 'Error') return info = 'Delete current record?\n\nSite: {}\nLocation: {}\nSkeleton: {}'.format( selected_row.site, selected_row.location, selected_row.skeleton) if dialogs.ask_message(info, 'Delete record'): controller.delete_record(self.session, selected_row.skeleton_id) self.skeleton_results_olv.RemoveObject(selected_row) if row_index > 0: row_index -= 1 self.skeleton_results_olv.Select(row_index) self.skeleton_results_olv.SetFocus() def edit_preservation(self, event): selected_row = self.skeleton_results_olv.GetSelectedObject() active_row = self.skeleton_results_olv.GetIndexOf(selected_row) if selected_row is None: dialogs.show_message('No record selected!', 'Error') return with dialogs.PreservationDialog(self.session, selected_row) as dlg: dlg.CenterOnScreen() dlg.ShowModal() self.skeleton_results_olv.SetFocus() def show_all_records(self, active_row=0): """ Updates the record list to show all of them """ self.skeleton_results = controller.get_all_records(self.session) self.update_skeleton_results(active_row) def create_report(self, event): """ select report """ dlg = wx.SingleChoiceDialog(self, 'Select report:', 'Create report', [ 'Skull report', 'Skull report - SVG', 'Inventory sheet', 'Full report' ], wx.CHOICEDLG_STYLE) if dlg.ShowModal() == wx.ID_OK: selected = dlg.GetStringSelection() else: selected = '' dlg.Destroy() if selected == '': return if selected == 'Skull report': self.create_report_skull() elif selected == 'Skull report - SVG': self.create_report_skull_svg() else: dialogs.show_message( 'Sorry, report "{}" not ready yet.'.format(selected), 'Error') def create_report_skull(self): """ generating a skeleton report """ filename = "" wildcard = "PDF files (*.pdf)|*.pdf" with wx.FileDialog(self, "Create a report", wildcard=wildcard, style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as dialog: if dialog.ShowModal() == wx.ID_OK: filename = dialog.GetPath() if filename == "": return my_id = self.skeleton_results_olv.GetSelectedObject().skeleton_id rekord = controller.find_skeleton(self.session, my_id) if rekord == None: dialogs.show_message('No record was found', 'Error') return data = {} data['site'] = rekord.site data['location'] = rekord.location data['skeleton'] = rekord.skeleton data['observer'] = rekord.observer data['obs_date'] = rekord.obs_date # rekord.frontal if rekord.frontal != None else 0 data['frontal'] = rekord.frontal data['sphenoid'] = rekord.sphenoid data['mandible'] = rekord.mandible data['ethmoid'] = rekord.ethmoid data['parietal_l'] = rekord.parietal_l data['parietal_r'] = rekord.parietal_r data['nasal_l'] = rekord.nasal_l data['nasal_r'] = rekord.nasal_r data['palatine_l'] = rekord.palatine_l data['palatine_r'] = rekord.palatine_r data['thyroid'] = rekord.thyroid data['occipital'] = rekord.occipital data['maxilla_l'] = rekord.maxilla_l data['maxilla_r'] = rekord.maxilla_r data['lacrimal_l'] = rekord.lacrimal_l data['lacrimal_r'] = rekord.lacrimal_r data['hyoid'] = rekord.hyoid data['temporal_l'] = rekord.temporal_l data['temporal_r'] = rekord.temporal_r data['zygomatic_l'] = rekord.zygomatic_l data['zygomatic_r'] = rekord.zygomatic_r data['orbit_l'] = rekord.orbit_l data['orbit_r'] = rekord.orbit_r data['calotte'] = rekord.calotte report = SheetExport() result = report.export_sheet(filename, data) if result != '': dialogs.show_message( 'Problems occurred during the creation of the report:\n{}'. format(result), 'Error') self.skeleton_results_olv.SetFocus() def create_report_skull_svg(self): """ generating a skull picture """ filename = "" wildcard = "SVG files (*.svg)|*.svg" with wx.FileDialog(self, "Create a picture", wildcard=wildcard, style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as dialog: if dialog.ShowModal() == wx.ID_OK: filename = dialog.GetPath() if filename == "": return my_id = self.skeleton_results_olv.GetSelectedObject().skeleton_id rekord = controller.find_skeleton(self.session, my_id) if rekord == None: dialogs.show_message('No record was found', 'Error') return data = {} data['site'] = rekord.site data['location'] = rekord.location data['skeleton'] = rekord.skeleton data['observer'] = rekord.observer data['obs_date'] = rekord.obs_date data['frontal'] = rekord.frontal data['sphenoid'] = rekord.sphenoid data['mandible'] = rekord.mandible data['ethmoid'] = rekord.ethmoid data['parietal_l'] = rekord.parietal_l data['parietal_r'] = rekord.parietal_r data['nasal_l'] = rekord.nasal_l data['nasal_r'] = rekord.nasal_r data['palatine_l'] = rekord.palatine_l data['palatine_r'] = rekord.palatine_r data['thyroid'] = rekord.thyroid data['occipital'] = rekord.occipital data['maxilla_l'] = rekord.maxilla_l data['maxilla_r'] = rekord.maxilla_r data['lacrimal_l'] = rekord.lacrimal_l data['lacrimal_r'] = rekord.lacrimal_r data['hyoid'] = rekord.hyoid data['temporal_l'] = rekord.temporal_l data['temporal_r'] = rekord.temporal_r data['zygomatic_l'] = rekord.zygomatic_l data['zygomatic_r'] = rekord.zygomatic_r data['orbit_l'] = rekord.orbit_l data['orbit_r'] = rekord.orbit_r data['calotte'] = rekord.calotte report = SheetExport() result = report.export_skull_svg(filename, data) if result != '': dialogs.show_message( 'Problems occurred during the creation of the picture:\n{}'. format(result), 'Error') self.skeleton_results_olv.SetFocus() def search(self, event): """ Searches database based on the user's filter choice and keyword """ filter_choice = self.categories.GetValue() keyword = self.search_ctrl.GetValue() self.skeleton_results = controller.search_records( self.session, filter_choice, keyword) self.update_skeleton_results() def on_show_all(self, event): """ Updates the record list to show all the records """ self.show_all_records() def update_skeleton_results(self, active_row=0): """ Updates the ObjectListView's contents """ self.skeleton_results_olv.SetColumns([ ColumnDefn("Site", "left", 350, "site", isSpaceFilling=True, minimumWidth=50), ColumnDefn("Location", "left", 150, "location", isSpaceFilling=True, minimumWidth=50), ColumnDefn("Skeleton", "left", 150, "skeleton", isSpaceFilling=True, minimumWidth=50), ColumnDefn("Observer", "left", 150, "observer", isSpaceFilling=True, minimumWidth=50), ColumnDefn("Observation date", "center", 80, "obs_date", isSpaceFilling=True, minimumWidth=50) ]) self.skeleton_results_olv.SetObjects(self.skeleton_results) if self.skeleton_results_olv.GetItemCount() > 0: self.skeleton_results_olv.Select(active_row) self.skeleton_results_olv.SetFocus()
class ProvPanel(wx.Panel): def __init__(self, parent, id, style): LoadLog.LogMsg(gen.logger.info, u"加载下边框架面板") wx.Panel.__init__(self, id=id, parent=parent, style=style) vSizer = wx.BoxSizer(wx.VERTICAL) self.SetBackgroundColour("while") self.ProgrameList = ObjectListView(self, id=wx.ID_VIEW_LIST, size=(-1, 50), style=wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_VRULES | wx.LC_HRULES) #self.ProgrameList.cellEditMode = ObjectListView.CELLEDIT_SINGLECLICK self.setResults(gen._filedata) self.ListButtonUI() ##列表控件布局 vSizer.Add(self.ProgrameList, 1, wx.EXPAND | wx.ALL, 5) ##按钮的布局 vSizer.Add(self.sSizer, 0, wx.ALL, 2) self.SetSizerAndFit(vSizer) ##双击列表事件绑定 self.evt = EventHandle(gen._filedata, self.ProgrameList) ##实例调用EventHandle 类的一个对话框事件方法 self.OnAdd_Edit_Dialog = self.evt.OnAdd_Edit_Dialog self.ProgrameList.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnAdd_Edit_Dialog, id=wx.ID_VIEW_LIST) def setResults(self, filename): self.ProgrameList.SetColumns([ ColumnDefn(u"序号", "left", 40, "id"), ColumnDefn(u"名称", "left", 100, "name"), ColumnDefn(u"程序", "left", 150, "programe"), ColumnDefn(u"参数", "left", 150, "logfile"), ColumnDefn(u"状态", "center", 60, "status"), ColumnDefn(u"监控", "left", 40, "monitor"), ColumnDefn(u"条件", "center", 50, "operator"), ColumnDefn(u"进程数", "left", 50, "processNum"), ColumnDefn(u"启动方式", "center", 60, "runAs"), ColumnDefn(u"备注", "left", 150, "note"), ]) ##使用checkBox 复选框 self.ProgrameList.CreateCheckStateColumn() self.SetDataInListctrl(filename) def SetDataInListctrl(self, filename): LoadLog.LogMsg(gen.logger.info, u"加载控件列表,初始化数据") ##获取数据列表 self.list_data = DataHandle(filename).handleList() ##设置数据列表到列表控件 self.ProgrameList.SetObjects(self.list_data) ##列表控件下面的按钮 def ListButtonUI(self): self.sSizer = sSizer = wx.BoxSizer(wx.HORIZONTAL) SelectAllButton = wx.Button(self, id=wx.ID_SELECTALL, size=(50, 22), label=u"全选") RSelectAllButton = wx.Button(self, id=gen.ID_UNSELECTALL, size=(50, 22), label=u"取消") #ClearButton = wx.Button(self,id=gen.ID_SELECTCLEAR,size=(50,22),label = u"测试") #ImportButton = wx.Button(self,id=gen.ID_IMPORT,size=(50,22),label = u"导入") #ExportButton = wx.Button(self,id=gen.ID_EXPORT,size=(50,22),label = u"导出") sSizer.Add(SelectAllButton, 0, wx.LEFT, 2) sSizer.Add(RSelectAllButton, 0, wx.LEFT, 10) #sSizer.Add(ClearButton,0,wx.LEFT,10) #sSizer.Add(ImportButton,0,wx.LEFT,10) #sSizer.Add(ExportButton,0,wx.LEFT,10) self.evt = EventHandle(gen._filedata, self.ProgrameList) self.Bind(wx.EVT_BUTTON, self.evt.OnSelectAll, id=wx.ID_SELECTALL) self.Bind(wx.EVT_BUTTON, self.evt.OnSelectAll, id=gen.ID_UNSELECTALL)