def signal_clicked_cb(self, gl, item): pp = Popup(self._parent) pp.part_text_set('title,text', 'Signal content') en = Entry(self, text=prettify_if_needed(item.data['args'])) en.size_hint_weight = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND en.size_hint_align = EVAS_HINT_FILL, EVAS_HINT_FILL en.size_hint_min = 800, 800 # TODO: this should be respected :/ en.editable = False en.scrollable = True pp.content = en bt = Button(pp, text="Close") bt.callback_clicked_add(lambda b: pp.delete()) pp.part_content_set('button2', bt) def prettify_clicked_cb(chk): options.pretty_output = chk.state en.text = prettify_if_needed(item.data['args']) ck = Check(pp, text="Prettify") ck.state = options.pretty_output ck.callback_changed_add(prettify_clicked_cb) pp.part_content_set('button1', ck) pp.show()
def errorPopup(window, errorMsg): errorPopup = Popup(window, size_hint_weight=EXPAND_BOTH) errorPopup.callback_block_clicked_add(lambda obj: errorPopup.delete()) # Add a table to hold dialog image and text to Popup tb = Table(errorPopup, size_hint_weight=EXPAND_BOTH) errorPopup.part_content_set("default", tb) tb.show() # Add dialog-error Image to table need_ethumb() icon = Icon(errorPopup, thumb='True') icon.standard_set('dialog-warning') # Using gksudo or sudo fails to load Image here # unless options specify using preserving their existing environment. # may also fail to load other icons but does not raise an exception # in that situation. # Works fine using eSudo as a gksudo alternative, # other alternatives not tested try: dialogImage = Image(errorPopup, size_hint_weight=EXPAND_HORIZ, size_hint_align=FILL_BOTH, file=icon.file_get()) tb.pack(dialogImage, 0, 0, 1, 1) dialogImage.show() except RuntimeError: # An error message is displayed for this same error # when aboutWin is initialized so no need to redisplay. pass # Add dialog text to table dialogLabel = Label(errorPopup, line_wrap=ELM_WRAP_WORD, size_hint_weight=EXPAND_HORIZ, size_hint_align=FILL_BOTH) dialogLabel.text = errorMsg tb.pack(dialogLabel, 1, 0, 1, 1) dialogLabel.show() # Ok Button ok_btt = Button(errorPopup) ok_btt.text = "Ok" ok_btt.callback_clicked_add(lambda obj: errorPopup.delete()) ok_btt.show() # add button to popup errorPopup.part_content_set("button3", ok_btt) errorPopup.show()
def __init__(self, canvas, title, text): n = Popup(canvas) n.part_text_set("title,text", title) n.text = text b = Button(canvas) b.text = "OK" b.callback_clicked_add(lambda x: n.delete()) n.part_content_set("button1", b) n.show()
def showDialog(self, title, msg): dia = Popup(self) dia.part_text_set("title,text", title) dia.part_text_set("default", msg) bt = Button(dia, text="Ok") bt.callback_clicked_add(lambda b: dia.delete()) dia.part_content_set("button1", bt) dia.show()
def showDialog(self, title, msg): dia = Popup(self) dia.part_text_set("title,text", title) dia.part_text_set("default", msg) bt = Button(dia, text="Ok") bt.callback_clicked_add(lambda b: dia.delete()) dia.part_content_set("button1", bt) dia.show()
def show_error_msg(self, msg): pop = Popup(self, text=msg) pop.part_text_set('title,text', _('Error')) btn = Button(self, text=_('Continue')) btn.callback_clicked_add(lambda b: pop.delete()) pop.part_content_set('button1', btn) btn = Button(self, text=_('Exit')) btn.callback_clicked_add(lambda b: self.app.exit()) pop.part_content_set('button2', btn) pop.show()
def _confirm_delete(self, m, item): pp = Popup(self.top_widget, text=self._task.text) pp.part_text_set('title,text', 'Confirm task deletion?') btn = Button(pp, text='Cancel') btn.callback_clicked_add(lambda b: pp.delete()) pp.part_content_set('button1', btn) btn = Button(pp, text='Delete Task') btn.callback_clicked_add(self._delete_confirmed, pp) pp.part_content_set('button2', btn) pp.show()
class FolderSelector(Fileselector): def __init__(self, parent): Fileselector.__init__(self, parent, is_save=False, folder_only=True, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.path = os.getcwd() # table+rect to respect min size :/ tb = Table(self, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) r = Rectangle(self.evas, color=(0,0,0,0), size_hint_min=(300,300), size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) tb.pack(r, 0, 0, 1, 1) tb.pack(self, 0, 0, 1, 1) self.popup = Popup(parent) self.popup.part_text_set('title,text', 'Choose repository') self.popup.content = tb self.popup.show() self.show() def delete(self): self.popup.delete()
def show_error_msg(self, msg): pop = Popup(self, text=msg) pop.part_text_set('title,text', _('Error')) btn = Button(self, text=_('Continue')) btn.callback_clicked_add(lambda b: pop.delete()) pop.part_content_set('button1', btn) btn = Button(self, text=_('Exit')) btn.callback_clicked_add(lambda b: self.app.exit()) pop.part_content_set('button2', btn) pop.show()
def __init__(self, canvas, exit_func): n = Popup(canvas) n.part_text_set("title,text", "Confirm exit") n.text = "Are you sure you wish to exit Epour?" b = Button(canvas) b.text = "Yes" b.callback_clicked_add(lambda x: exit_func()) n.part_content_set("button1", b) b = Button(canvas) b.text = "No" b.callback_clicked_add(lambda x: n.delete()) n.part_content_set("button2", b) n.show()
def _popup_build(self): popup = Popup(self.top_widget) popup.part_text_set('title,text', 'Choose the color for %s' % self._tag_name) popup.callback_block_clicked_add(lambda p: popup.delete()) cs = Colorselector(popup, color=self._rect.color) cs.callback_changed_add(lambda s: setattr(rect, 'color', cs.color)) popup.content = cs rect = Rectangle(popup.evas, color=self._rect.color) frame = Frame(popup, style='pad_small', content=rect) popup.part_content_set('button1', frame) bt = Button(popup, text='Accept') bt.callback_clicked_add(self._popup_accept_cb, popup, cs) popup.part_content_set('button2', bt) bt = Button(popup, text='Cancel') bt.callback_clicked_add(lambda b: popup.delete()) popup.part_content_set('button3', bt) popup.show()
def _task_edit_start(self, task): pp = Popup(self.top_widget) pp.part_text_set('title,text', 'Edit task') en = Entry(pp, editable=True, single_line=True, scrollable=True, text=task.raw_txt) en.callback_activated_add(lambda e: self._task_edit_end(task, en, pp)) en.callback_aborted_add(lambda e: pp.delete()) pp.part_content_set('default', en) b = Button(pp, text='Cancel') b.callback_clicked_add(lambda b: pp.delete()) pp.part_content_set('button1', b) b = Button(pp, text='Accept') b.callback_clicked_add(lambda b: self._task_edit_end(task, en, pp)) pp.part_content_set('button2', b) pp.show() en.cursor_begin_set() en.cursor_selection_begin() en.cursor_end_set() en.cursor_selection_end()
def safe_quit(self): if need_save() is False: elm.exit() else: pp = Popup(self, text="You have unsave changes, if you don't save now all your recent modification will be lost.") pp.part_text_set('title,text', 'Save changes to your txt file?') btn = Button(pp, text='Close without saving') btn.callback_clicked_add(lambda b: elm.exit()) pp.part_content_set('button1', btn) btn = Button(pp, text='Cancel') btn.callback_clicked_add(lambda b: pp.delete()) pp.part_content_set('button2', btn) btn = Button(pp, text='Save') btn.callback_clicked_add(lambda b: self.save(True)) pp.part_content_set('button3', btn) pp.show()
def ask_what_to_do_next(self): pop = Popup(self) pop.part_text_set('title,text', _('Extract completed')) box = Box(pop) pop.content = box box.show() lb = Label(pop, text=_('What to do next?'), size_hint_align=FILL_HORIZ) box.pack_end(lb) lb.show() btn = Button(pop, text=_('Open Filemanager'), size_hint_align=FILL_HORIZ) btn.callback_clicked_add(self._open_fm_and_exit_cb) box.pack_end(btn) btn.show() btn = Button(pop, text=_('Open Terminal'), size_hint_align=FILL_HORIZ) btn.callback_clicked_add(self._open_term_and_exit_cb) box.pack_end(btn) btn.show() btn = Button(pop, text=_('Close this popup'), size_hint_align=FILL_HORIZ) btn.callback_clicked_add(lambda b: pop.delete()) box.pack_end(btn) btn.show() btn = Button(pop, text=_('Exit'), size_hint_align=FILL_HORIZ) btn.callback_clicked_add(lambda b: self.app.exit()) box.pack_end(btn) btn.show() pop.show()
def ask_what_to_do_next(self): pop = Popup(self) pop.part_text_set('title,text', _('Extract completed')) box = Box(pop) pop.content = box box.show() lb = Label(pop, text=_('What to do next?'), size_hint_align=FILL_HORIZ) box.pack_end(lb) lb.show() btn = Button(pop, text=_('Open Filemanager'), size_hint_align=FILL_HORIZ) btn.callback_clicked_add(self._open_fm_and_exit_cb) box.pack_end(btn) btn.show() btn = Button(pop, text=_('Open Terminal'), size_hint_align=FILL_HORIZ) btn.callback_clicked_add(self._open_term_and_exit_cb) box.pack_end(btn) btn.show() btn = Button(pop, text=_('Close this popup'), size_hint_align=FILL_HORIZ) btn.callback_clicked_add(lambda b: pop.delete()) box.pack_end(btn) btn.show() btn = Button(pop, text=_('Exit'), size_hint_align=FILL_HORIZ) btn.callback_clicked_add(lambda b: self.app.exit()) box.pack_end(btn) btn.show() pop.show()
class Interface(object): def __init__(self): self.mainWindow = StandardWindow("epad", "Untitled - ePad", size=(600, 400)) self.mainWindow.callback_delete_request_add(self.closeChecks) self.mainWindow.elm_event_callback_add(self.eventsCb) icon = Icon(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) icon.standard_set('accessories-text-editor') icon.show() self.mainWindow.icon_object_set(icon.object_get()) self.mainBox = Box(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.mainBox.show() self.mainTb = ePadToolbar(self, self.mainWindow) self.mainTb.show() self.mainBox.pack_end(self.mainTb) # Initialize Text entry box print("Word wrap Initialized: {0}".format(self.wordwrap)) self.entryInit() # Add label to show current cursor position if SHOW_POS: self.line_label = Label(self.mainWindow, size_hint_weight=EXPAND_HORIZ, size_hint_align=ALIGN_RIGHT) self.curChanged(self.mainEn, self.line_label) self.line_label.show() self.mainBox.pack_end(self.line_label) self.mainEn.callback_cursor_changed_add(self.curChanged, self.line_label) # Build our file selector for saving/loading files self.fileBox = Box(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.fileBox.show() self.fileLabel = Label(self.mainWindow, size_hint_weight=EXPAND_HORIZ, size_hint_align=FILL_BOTH, text="") self.fileLabel.show() self.fileSelector = Fileselector(self.mainWindow, is_save=False, expandable=False, folder_only=False, path=os.getenv("HOME"), size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.fileSelector.callback_done_add(self.fileSelected) self.fileSelector.show() self.fileBox.pack_end(self.fileLabel) self.fileBox.pack_end(self.fileSelector) # Flip object has the file selector on one side # and the GUI on the other self.flip = Flip(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.flip.part_content_set("front", self.mainBox) self.flip.part_content_set("back", self.fileBox) self.mainWindow.resize_object_add(self.flip) self.flip.show() self.isSaved = True self.isNewFile = False self.confirmPopup = None def entryInit(self): self.mainEn = Entry(self.mainWindow, scrollable=True, line_wrap=self.wordwrap, autosave=False, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.mainEn.callback_changed_user_add(self.textEdited) self.mainEn.elm_event_callback_add(self.eventsCb) # self.mainEn.markup_filter_append(self.textFilter) self.mainEn.show() self.mainBox.pack_end(self.mainEn) def curChanged(self, entry, label): # get linear index into current text index = entry.cursor_pos_get() # Replace <br /> tag with single char # to simplify (line, col) calculation tmp_text = entry.entry_get().replace("<br/>", "\n") line = tmp_text[:index].count("\n") + 1 col = len(tmp_text[:index].split("\n")[-1]) + 1 # Update label text with line, col label.text = "Ln {0} Col {1} ".format(line, col) def textEdited(self, obj): current_file = self.mainEn.file[0] current_file = \ os.path.basename(current_file) if \ current_file and not self.isNewFile else \ "Untitled" self.mainWindow.title = "*%s - ePad" % (current_file) self.isSaved = False def fileSelected(self, fs, file_selected, onStartup=False): if not onStartup: self.flip.go(ELM_FLIP_INTERACTION_ROTATE) print(file_selected) IsSave = fs.is_save_get() if file_selected: if IsSave: newfile = open(file_selected, 'w') tmp_text = self.mainEn.entry_get() newfile.write(tmp_text) newfile.close() self.mainEn.file_set(file_selected, ELM_TEXT_FORMAT_PLAIN_UTF8) self.mainEn.entry_set(tmp_text) self.mainEn.file_save() self.mainWindow.title_set("%s - ePad" % os.path.basename(file_selected)) self.isSaved = True self.isNewFile = False else: try: self.mainEn.file_set(file_selected, ELM_TEXT_FORMAT_PLAIN_UTF8) except RuntimeError: print("Empty file: {0}".format(file_selected)) self.mainWindow.title_set("%s - ePad" % os.path.basename(file_selected)) def newFile(self, obj=None, ignoreSave=False): if self.isSaved is True or ignoreSave is True: trans = Transit() trans.object_add(self.mainEn) trans.auto_reverse = True trans.effect_wipe_add(ELM_TRANSIT_EFFECT_WIPE_TYPE_HIDE, ELM_TRANSIT_EFFECT_WIPE_DIR_RIGHT) trans.duration = 0.5 trans.go() time.sleep(0.5) self.mainWindow.title_set("Untitled - ePad") self.mainEn.delete() self.entryInit() self.isNewFile = True elif self.confirmPopup is None: self.confirmSave(self.newFile) def openFile(self, obj=None, ignoreSave=False): if self.isSaved is True or ignoreSave is True: self.fileSelector.is_save_set(False) self.fileLabel.text = "<b>Select a text file to open:</b>" self.flip.go(ELM_FLIP_ROTATE_YZ_CENTER_AXIS) elif self.confirmPopup is None: self.confirmSave(self.openFile) def confirmSave(self, ourCallback=None): self.confirmPopup = Popup(self.mainWindow, size_hint_weight=EXPAND_BOTH) self.confirmPopup.part_text_set("title,text", "File Unsaved") current_file = self.mainEn.file[0] current_file = \ os.path.basename(current_file) if current_file else "Untitled" self.confirmPopup.text = "Save changes to '%s'?" % (current_file) # Close without saving button no_btt = Button(self.mainWindow) no_btt.text = "No" no_btt.callback_clicked_add(self.closePopup, self.confirmPopup) if ourCallback is not None: no_btt.callback_clicked_add(ourCallback, True) no_btt.show() # cancel close request cancel_btt = Button(self.mainWindow) cancel_btt.text = "Cancel" cancel_btt.callback_clicked_add(self.closePopup, self.confirmPopup) cancel_btt.show() # Save the file and then close button sav_btt = Button(self.mainWindow) sav_btt.text = "Yes" sav_btt.callback_clicked_add(self.saveFile) sav_btt.callback_clicked_add(self.closePopup, self.confirmPopup) sav_btt.show() # add buttons to popup self.confirmPopup.part_content_set("button1", no_btt) self.confirmPopup.part_content_set("button2", cancel_btt) self.confirmPopup.part_content_set("button3", sav_btt) self.confirmPopup.show() def saveAs(self): self.fileSelector.is_save_set(True) self.fileLabel.text = "<b>Save new file to where:</b>" self.flip.go(ELM_FLIP_ROTATE_XZ_CENTER_AXIS) def saveFile(self, obj=False): if self.mainEn.file_get()[0] is None or self.isNewFile: self.saveAs() else: self.mainEn.file_save() self.mainWindow.title_set("%s - ePad" % os.path.basename(self.mainEn.file[0])) self.isSaved = True def closeChecks(self, obj): print(self.isSaved) if self.isSaved is False and self.confirmPopup is None: self.confirmSave(self.closeApp) else: self.closeApp() def closePopup(self, bt, confirmPopup): self.confirmPopup.delete() self.confirmPopup = None def closeApp(self, obj=False, trash=False): elementary.exit() def eventsCb(self, obj, src, event_type, event): if event.modifier_is_set("Control"): if event.key.lower() == "n": self.newFile() elif event.key.lower() == "s" and event.modifier_is_set("Shift"): self.saveAs() elif event.key.lower() == "s": self.saveFile() elif event.key.lower() == "o": self.openFile() # Legacy hack no longer needed # there was an issue in elementary entry where it would # accept those character controls # def textFilter( self, obj, theText, data ): # # Block ctrl+hot keys used in eventsCb # # # # Ctrl O Ctrl N Ctrl S # ctrl_block = [chr(14), chr(15), chr(19)] # if theText in ctrl_block: # return None # else: # return theText def launch(self, startingFile=False): if startingFile: self.fileSelected(self.fileSelector, startingFile, True) self.mainWindow.show()
class ePadToolbar(Toolbar): def __init__(self, parent, canvas): Toolbar.__init__(self, canvas) self._parent = parent self._canvas = canvas self.homogeneous = False self.size_hint_weight = (0.0, 0.0) self.size_hint_align = (EVAS_HINT_FILL, 0.0) self.select_mode = ELM_OBJECT_SELECT_MODE_NONE self.menu_parent = canvas self.item_append("document-new", "New", self.newPress) self.item_append("document-open", "Open", self.openPress) self.item_append("document-save", "Save", self.savePress) self.item_append("document-save-as", "Save As", self.saveAsPress) # -- Edit Dropdown Menu -- tb_it = self.item_append("edit", "Edit") tb_it.menu = True menu = tb_it.menu menu.item_add(None, "Copy", "edit-copy", self.copyPress) menu.item_add(None, "Paste", "edit-paste", self.pastePress) menu.item_add(None, "Cut", "edit-cut", self.cutPress) menu.item_separator_add() menu.item_add(None, "Select All", "edit-select-all", self.selectAllPress) # ----------------------- # # -- Options Dropdown Menu -- # # self.item_append("settings", "Options", self.optionsPress) tb_it = self.item_append("preferences-desktop", "Options") tb_it.menu = True menu = tb_it.menu self._parent.wordwrap = WORD_WRAP it = menu.item_add(None, "Wordwrap", None, self.optionsWWPress) chk = Check(canvas, disabled=True) it.content = chk # --------------------------- self.item_append("dialog-information", "About", self.aboutPress) def newPress(self, obj, it): self._parent.newFile() def openPress(self, obj, it): self._parent.openFile() def savePress(self, obj, it): self._parent.saveFile() def saveAsPress(self, obj, it): self._parent.saveAs() def optionsWWPress(self, obj, it): wordwrap = self._parent.mainEn.line_wrap wordwrap = not wordwrap self._parent.mainEn.line_wrap = wordwrap it.content.state = wordwrap # FIXME: is this variable needed for anything? self._parent.wordwrap = wordwrap def copyPress(self, obj, it): self._parent.mainEn.selection_copy() def pastePress(self, obj, it): self._parent.mainEn.selection_paste() def cutPress(self, obj, it): self._parent.mainEn.selection_cut() def selectAllPress(self, obj, it): self._parent.mainEn.select_all() def aboutPress(self, obj, it): # About popup self.popupAbout = Popup(self._canvas, size_hint_weight=EXPAND_BOTH) self.popupAbout.part_text_set("title,text", "ePad version {0}".format(__version__)) self.popupAbout.text = ("A simple text editor written in " "python and elementary<br><br> " "By: Jeff Hoogland") bt = Button(self._canvas, text="Done") bt.callback_clicked_add(self.aboutClose) self.popupAbout.part_content_set("button1", bt) self.popupAbout.show() def aboutClose(self, bt): self.popupAbout.delete()
class Interface(object): def __init__(self): self.mainWindow = StandardWindow("epad", "Untitled - ePad", size=(600, 400)) self.mainWindow.callback_delete_request_add(self.closeChecks) self.mainWindow.elm_event_callback_add(self.eventsCb) icon = Icon(self.mainWindow) icon.size_hint_weight_set(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND) icon.size_hint_align_set(EVAS_HINT_FILL, EVAS_HINT_FILL) icon.standard_set( 'accessories-text-editor' ) # assumes image icon is in local dir, may need to change later icon.show() self.mainWindow.icon_object_set(icon.object_get()) self.mainBox = Box(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.mainBox.show() self.mainTb = Toolbar(self.mainWindow, homogeneous=False, size_hint_weight=(0.0, 0.0), size_hint_align=(EVAS_HINT_FILL, 0.0)) self.mainTb.menu_parent = self.mainWindow self.mainTb.item_append("document-new", "New", self.newPress) self.mainTb.item_append("document-open", "Open", self.openPress) self.mainTb.item_append("document-save", "Save", self.savePress) self.mainTb.item_append("document-save-as", "Save As", self.saveAsPress) # -- Edit Dropdown Menu -- tb_it = self.mainTb.item_append("edit", "Edit") tb_it.menu = True menu = tb_it.menu menu.item_add(None, "Copy", "edit-copy", self.copyPress) menu.item_add(None, "Paste", "edit-paste", self.pastePress) menu.item_add(None, "Cut", "edit-cut", self.cutPress) menu.item_separator_add() menu.item_add(None, "Select All", "edit-select-all", self.selectAllPress) # ----------------------- # self.mainTb.item_append("settings", "Options", self.optionsPress) self.mainTb.item_append("dialog-information", "About", self.aboutPress) self.mainEn = Entry(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.mainEn.callback_changed_user_add(self.textEdited) self.mainEn.scrollable_set( True) # creates scrollbars rather than enlarge window self.mainEn.line_wrap_set( False) # does not allow line wrap (can be changed by user) self.mainEn.autosave_set(False) # set to false to reduce disk I/O self.mainEn.elm_event_callback_add(self.eventsCb) self.mainEn.markup_filter_append(self.textFilter) self.mainEn.show() self.mainTb.show() self.mainBox.pack_end(self.mainTb) self.mainBox.pack_end(self.mainEn) #Build our file selector for saving/loading files self.fileBox = Box(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.fileBox.show() self.fileLabel = Label(self.mainWindow, size_hint_weight=EXPAND_HORIZ, size_hint_align=FILL_BOTH) self.fileLabel.text = "" self.fileLabel.show() self.fileSelector = Fileselector(self.mainWindow, is_save=False, expandable=False, folder_only=False, path=os.getenv("HOME"), size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.fileSelector.callback_done_add(self.fileSelected) #self.fileSelector.callback_selected_add(fs_cb_selected, win) #self.fileSelector.callback_directory_open_add(fs_cb_directory_open, win) self.fileSelector.show() self.fileBox.pack_end(self.fileLabel) self.fileBox.pack_end(self.fileSelector) # the flip object has the file selector on one side and the GUI on the other self.flip = Flip(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.flip.part_content_set("front", self.mainBox) self.flip.part_content_set("back", self.fileBox) self.mainWindow.resize_object_add(self.flip) self.flip.show() self.isSaved = True self.isNewFile = False self.confirmPopup = None def newPress(self, obj, it): self.newFile() it.selected_set(False) def openPress(self, obj, it): self.openFile() it.selected_set(False) def savePress(self, obj, it): self.saveFile() it.selected_set(False) def saveAsPress(self, obj, it): self.saveAs() it.selected_set(False) def optionsPress(self, obj, it): it.selected_set(False) def copyPress(self, obj, it): self.mainEn.selection_copy() it.selected_set(False) def pastePress(self, obj, it): self.mainEn.selection_paste() it.selected_set(False) def cutPress(self, obj, it): self.mainEn.selection_cut() it.selected_set(False) def selectAllPress(self, obj, it): self.mainEn.select_all() it.selected_set(False) def textEdited(self, obj): ourFile = self.mainEn.file_get()[0] if ourFile and not self.isNewFile: self.mainWindow.title_set( "*%s - ePad" % self.mainEn.file_get()[0].split("/")[ len(self.mainEn.file_get()[0].split("/")) - 1]) else: self.mainWindow.title_set("*Untitlted - ePad") self.isSaved = False def fileSelected(self, fs, file_selected, onStartup=False): if not onStartup: self.flip.go(ELM_FLIP_INTERACTION_ROTATE) print(file_selected) IsSave = fs.is_save_get() if file_selected: if IsSave: newfile = open(file_selected, 'w') # creates new file tmp_text = self.mainEn.entry_get() newfile.write(tmp_text) newfile.close() self.mainEn.file_set(file_selected, ELM_TEXT_FORMAT_PLAIN_UTF8) self.mainEn.entry_set(tmp_text) self.mainEn.file_save() self.mainWindow.title_set( "%s - ePad" % file_selected.split("/")[len(file_selected.split("/")) - 1]) self.isSaved = True self.isNewFile = False else: try: self.mainEn.file_set(file_selected, ELM_TEXT_FORMAT_PLAIN_UTF8) except RuntimeError: print("Empty file: {0}".format(file_selected)) self.mainWindow.title_set( "%s - ePad" % file_selected.split("/")[len(file_selected.split("/")) - 1]) def aboutPress(self, obj, it): #About popup self.popupAbout = Popup(self.mainWindow, size_hint_weight=EXPAND_BOTH) self.popupAbout.text = "ePad - A simple text editor written in python and elementary<br><br> " \ "By: Jeff Hoogland" bt = Button(self.mainWindow, text="Done") bt.callback_clicked_add(self.aboutClose) self.popupAbout.part_content_set("button1", bt) self.popupAbout.show() it.selected_set(False) def aboutClose(self, bt): self.popupAbout.delete() def newFile(self, obj=None, ignoreSave=False): if self.isSaved == True or ignoreSave == True: trans = Transit() trans.object_add(self.mainEn) trans.auto_reverse = True trans.effect_wipe_add(ELM_TRANSIT_EFFECT_WIPE_TYPE_HIDE, ELM_TRANSIT_EFFECT_WIPE_DIR_RIGHT) trans.duration = 0.5 trans.go() time.sleep(0.5) self.mainWindow.title_set("Untitlted - ePad") self.mainEn.delete() self.mainEn = Entry(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.mainEn.callback_changed_user_add(self.textEdited) self.mainEn.scrollable_set( True) # creates scrollbars rather than enlarge window self.mainEn.line_wrap_set( False) # does not allow line wrap (can be changed by user) self.mainEn.autosave_set(False) # set to false to reduce disk I/O self.mainEn.elm_event_callback_add(self.eventsCb) self.mainEn.markup_filter_append(self.textFilter) self.mainEn.show() self.mainBox.pack_end(self.mainEn) self.isNewFile = True elif self.confirmPopup == None: self.confirmSave(self.newFile) def openFile(self, obj=None, ignoreSave=False): if self.isSaved == True or ignoreSave == True: self.fileSelector.is_save_set(False) self.fileLabel.text = "<b>Select a text file to open:</b>" self.flip.go(ELM_FLIP_ROTATE_YZ_CENTER_AXIS) elif self.confirmPopup == None: self.confirmSave(self.openFile) def confirmSave(self, ourCallback=None): self.confirmPopup = Popup(self.mainWindow, size_hint_weight=EXPAND_BOTH) self.confirmPopup.part_text_set("title,text", "File Unsaved") if self.mainEn.file_get()[0]: self.confirmPopup.text = "Save changes to '%s'?" % self.mainEn.file_get( )[0].split("/")[len(self.mainEn.file_get()[0].split("/")) - 1] else: self.confirmPopup.text = "Save changes to 'Untitlted'?" # Close without saving button no_btt = Button(self.mainWindow) no_btt.text = "No" no_btt.callback_clicked_add(self.closePopup, self.confirmPopup) if ourCallback is not None: no_btt.callback_clicked_add(ourCallback, True) no_btt.show() # cancel close request cancel_btt = Button(self.mainWindow) cancel_btt.text = "Cancel" cancel_btt.callback_clicked_add(self.closePopup, self.confirmPopup) cancel_btt.show() # Save the file and then close button sav_btt = Button(self.mainWindow) sav_btt.text = "Yes" sav_btt.callback_clicked_add(self.saveFile) sav_btt.callback_clicked_add(self.closePopup, self.confirmPopup) sav_btt.show() # add buttons to popup self.confirmPopup.part_content_set("button1", no_btt) self.confirmPopup.part_content_set("button2", cancel_btt) self.confirmPopup.part_content_set("button3", sav_btt) self.confirmPopup.show() def saveAs(self): self.fileSelector.is_save_set(True) self.fileLabel.text = "<b>Save new file to where:</b>" self.flip.go(ELM_FLIP_ROTATE_XZ_CENTER_AXIS) def saveFile(self, obj=False): if self.mainEn.file_get()[0] == None or self.isNewFile: self.saveAs() else: self.mainEn.file_save() self.mainWindow.title_set( "%s - ePad" % self.mainEn.file_get()[0].split("/")[ len(self.mainEn.file_get()[0].split("/")) - 1]) self.isSaved = True def closeChecks(self, obj): print(self.isSaved) if self.isSaved == False and self.confirmPopup == None: self.confirmSave(self.closeApp) else: self.closeApp() def closePopup(self, bt, confirmPopup): self.confirmPopup.delete() self.confirmPopup = None def closeApp(self, obj=False, trash=False): elementary.exit() def eventsCb(self, obj, src, event_type, event): #print event_type #print event.key #print "Control Key Status: %s" %event.modifier_is_set("Control") #print "Shift Key Status: %s" %event.modifier_is_set("Shift") #print event.modifier_is_set("Alt") if event.modifier_is_set("Control"): if event.key.lower() == "n": self.newFile() elif event.key.lower() == "s" and event.modifier_is_set("Shift"): self.saveAs() elif event.key.lower() == "s": self.saveFile() elif event.key.lower() == "o": self.openFile() def textFilter(self, obj, theText, data): #print theText #Block ctrl+hot keys if theText == "" or theText == "" or theText == "": return None else: return theText def launch(self, startingFile=False): if startingFile: self.fileSelected(self.fileSelector, startingFile, True) self.mainWindow.show()
class Interface(object): def __init__(self): self.mainWindow = StandardWindow("epad", "Untitled - ePad", size=(600, 400)) self.mainWindow.callback_delete_request_add(self.closeChecks) self.mainWindow.elm_event_callback_add(self.eventsCb) icon = Icon(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) icon.standard_set('accessories-text-editor') icon.show() self.mainWindow.icon_object_set(icon.object_get()) self.mainBox = Box(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.mainBox.show() self.mainTb = ePadToolbar(self, self.mainWindow) self.mainTb.show() self.mainBox.pack_end(self.mainTb) # Initialize Text entry box print("Word wrap Initialized: {0}".format(self.wordwrap)) self.entryInit() # Add label to show current cursor position if SHOW_POS: self.line_label = Label(self.mainWindow, size_hint_weight=EXPAND_HORIZ, size_hint_align=ALIGN_RIGHT) self.curChanged(self.mainEn, self.line_label) self.line_label.show() self.mainBox.pack_end(self.line_label) self.mainEn.callback_cursor_changed_add(self.curChanged, self.line_label) # Build our file selector for saving/loading files self.fileBox = Box(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.fileBox.show() self.fileLabel = Label(self.mainWindow, size_hint_weight=EXPAND_HORIZ, size_hint_align=FILL_BOTH, text="") self.fileLabel.show() self.fileSelector = Fileselector(self.mainWindow, is_save=False, expandable=False, folder_only=False, path=os.getenv("HOME"), size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.fileSelector.callback_done_add(self.fileSelected) self.fileSelector.show() self.fileBox.pack_end(self.fileLabel) self.fileBox.pack_end(self.fileSelector) # Flip object has the file selector on one side # and the GUI on the other self.flip = Flip(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.flip.part_content_set("front", self.mainBox) self.flip.part_content_set("back", self.fileBox) self.mainWindow.resize_object_add(self.flip) self.flip.show() self.isSaved = True self.isNewFile = False self.confirmPopup = None def entryInit(self): self.mainEn = Entry(self.mainWindow, scrollable=True, line_wrap=self.wordwrap, autosave=False, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.mainEn.callback_changed_user_add(self.textEdited) self.mainEn.elm_event_callback_add(self.eventsCb) # self.mainEn.markup_filter_append(self.textFilter) self.mainEn.show() self.mainBox.pack_end(self.mainEn) def curChanged(self, entry, label): # get linear index into current text index = entry.cursor_pos_get() # Replace <br /> tag with single char # to simplify (line, col) calculation tmp_text = entry.entry_get().replace("<br/>", "\n") line = tmp_text[:index].count("\n") + 1 col = len(tmp_text[:index].split("\n")[-1]) + 1 # Update label text with line, col label.text = "Ln {0} Col {1} ".format(line, col) def textEdited(self, obj): current_file = self.mainEn.file[0] current_file = \ os.path.basename(current_file) if \ current_file and not self.isNewFile else \ "Untitled" self.mainWindow.title = "*%s - ePad" % (current_file) self.isSaved = False def fileSelected(self, fs, file_selected, onStartup=False): if not onStartup: self.flip.go(ELM_FLIP_INTERACTION_ROTATE) print(file_selected) IsSave = fs.is_save_get() if file_selected: if IsSave: newfile = open(file_selected, 'w') tmp_text = self.mainEn.entry_get() newfile.write(tmp_text) newfile.close() self.mainEn.file_set(file_selected, ELM_TEXT_FORMAT_PLAIN_UTF8) self.mainEn.entry_set(tmp_text) self.mainEn.file_save() self.mainWindow.title_set("%s - ePad" % os.path.basename(file_selected)) self.isSaved = True self.isNewFile = False else: try: self.mainEn.file_set(file_selected, ELM_TEXT_FORMAT_PLAIN_UTF8) except RuntimeError: print("Empty file: {0}".format(file_selected)) self.mainWindow.title_set("%s - ePad" % os.path.basename(file_selected)) def newFile(self, obj=None, ignoreSave=False): if self.isSaved is True or ignoreSave is True: trans = Transit() trans.object_add(self.mainEn) trans.auto_reverse = True trans.effect_wipe_add( ELM_TRANSIT_EFFECT_WIPE_TYPE_HIDE, ELM_TRANSIT_EFFECT_WIPE_DIR_RIGHT) trans.duration = 0.5 trans.go() time.sleep(0.5) self.mainWindow.title_set("Untitled - ePad") self.mainEn.delete() self.entryInit() self.isNewFile = True elif self.confirmPopup is None: self.confirmSave(self.newFile) def openFile(self, obj=None, ignoreSave=False): if self.isSaved is True or ignoreSave is True: self.fileSelector.is_save_set(False) self.fileLabel.text = "<b>Select a text file to open:</b>" self.flip.go(ELM_FLIP_ROTATE_YZ_CENTER_AXIS) elif self.confirmPopup is None: self.confirmSave(self.openFile) def confirmSave(self, ourCallback=None): self.confirmPopup = Popup(self.mainWindow, size_hint_weight=EXPAND_BOTH) self.confirmPopup.part_text_set("title,text", "File Unsaved") current_file = self.mainEn.file[0] current_file = \ os.path.basename(current_file) if current_file else "Untitled" self.confirmPopup.text = "Save changes to '%s'?" % (current_file) # Close without saving button no_btt = Button(self.mainWindow) no_btt.text = "No" no_btt.callback_clicked_add(self.closePopup, self.confirmPopup) if ourCallback is not None: no_btt.callback_clicked_add(ourCallback, True) no_btt.show() # cancel close request cancel_btt = Button(self.mainWindow) cancel_btt.text = "Cancel" cancel_btt.callback_clicked_add(self.closePopup, self.confirmPopup) cancel_btt.show() # Save the file and then close button sav_btt = Button(self.mainWindow) sav_btt.text = "Yes" sav_btt.callback_clicked_add(self.saveFile) sav_btt.callback_clicked_add(self.closePopup, self.confirmPopup) sav_btt.show() # add buttons to popup self.confirmPopup.part_content_set("button1", no_btt) self.confirmPopup.part_content_set("button2", cancel_btt) self.confirmPopup.part_content_set("button3", sav_btt) self.confirmPopup.show() def saveAs(self): self.fileSelector.is_save_set(True) self.fileLabel.text = "<b>Save new file to where:</b>" self.flip.go(ELM_FLIP_ROTATE_XZ_CENTER_AXIS) def saveFile(self, obj=False): if self.mainEn.file_get()[0] is None or self.isNewFile: self.saveAs() else: self.mainEn.file_save() self.mainWindow.title_set("%s - ePad" % os.path.basename(self.mainEn.file[0])) self.isSaved = True def closeChecks(self, obj): print(self.isSaved) if self.isSaved is False and self.confirmPopup is None: self.confirmSave(self.closeApp) else: self.closeApp() def closePopup(self, bt, confirmPopup): self.confirmPopup.delete() self.confirmPopup = None def closeApp(self, obj=False, trash=False): elementary.exit() def eventsCb(self, obj, src, event_type, event): if event.modifier_is_set("Control"): if event.key.lower() == "n": self.newFile() elif event.key.lower() == "s" and event.modifier_is_set("Shift"): self.saveAs() elif event.key.lower() == "s": self.saveFile() elif event.key.lower() == "o": self.openFile() # Legacy hack no longer needed # there was an issue in elementary entry where it would # accept those character controls # def textFilter( self, obj, theText, data ): # # Block ctrl+hot keys used in eventsCb # # # # Ctrl O Ctrl N Ctrl S # ctrl_block = [chr(14), chr(15), chr(19)] # if theText in ctrl_block: # return None # else: # return theText def launch(self, startingFile=False): if startingFile: self.fileSelected(self.fileSelector, startingFile, True) self.mainWindow.show()
class ePadToolbar(Toolbar): def __init__(self, parent, canvas): Toolbar.__init__(self, canvas) self._parent = parent self._canvas = canvas self.homogeneous = False self.size_hint_weight = (0.0, 0.0) self.size_hint_align = (EVAS_HINT_FILL, 0.0) self.select_mode = ELM_OBJECT_SELECT_MODE_NONE self.menu_parent = canvas self.item_append("document-new", "New", self.newPress) self.item_append("document-open", "Open", self.openPress) self.item_append("document-save", "Save", self.savePress) self.item_append("document-save-as", "Save As", self.saveAsPress) # -- Edit Dropdown Menu -- tb_it = self.item_append("edit", "Edit") tb_it.menu = True menu = tb_it.menu menu.item_add(None, "Copy", "edit-copy", self.copyPress) menu.item_add(None, "Paste", "edit-paste", self.pastePress) menu.item_add(None, "Cut", "edit-cut", self.cutPress) menu.item_separator_add() menu.item_add(None, "Select All", "edit-select-all", self.selectAllPress) # ----------------------- # # -- Options Dropdown Menu -- # # self.item_append("settings", "Options", self.optionsPress) tb_it = self.item_append("preferences-desktop", "Options") tb_it.menu = True menu = tb_it.menu self._parent.wordwrap = WORD_WRAP it = menu.item_add(None, "Wordwrap", None, self.optionsWWPress) chk = Check(canvas, disabled=True) it.content = chk # --------------------------- self.item_append("dialog-information", "About", self.aboutPress) def newPress(self, obj, it): self._parent.newFile() def openPress(self, obj, it): self._parent.openFile() def savePress(self, obj, it): self._parent.saveFile() def saveAsPress(self, obj, it): self._parent.saveAs() def optionsWWPress(self, obj, it): wordwrap = self._parent.mainEn.line_wrap wordwrap = not wordwrap self._parent.mainEn.line_wrap = wordwrap it.content.state = wordwrap # FIXME: is this variable needed for anything? self._parent.wordwrap = wordwrap def copyPress(self, obj, it): self._parent.mainEn.selection_copy() def pastePress(self, obj, it): self._parent.mainEn.selection_paste() def cutPress(self, obj, it): self._parent.mainEn.selection_cut() def selectAllPress(self, obj, it): self._parent.mainEn.select_all() def aboutPress(self, obj, it): # About popup self.popupAbout = Popup(self._canvas, size_hint_weight=EXPAND_BOTH) self.popupAbout.part_text_set("title,text", "ePad version {0}".format(__version__)) self.popupAbout.text = ( "A simple text editor written in " "python and elementary<br><br> " "By: Jeff Hoogland" ) bt = Button(self._canvas, text="Done") bt.callback_clicked_add(self.aboutClose) self.popupAbout.part_content_set("button1", bt) self.popupAbout.show() def aboutClose(self, bt): self.popupAbout.delete()
class aboutWin(Window): def __init__(self, parent, canvas): self._parent = parent self._canvas = canvas # Dialog Window Basics self.aboutDialog = Window("epad", ELM_WIN_DIALOG_BASIC) # self.aboutDialog.callback_delete_request_add(self.closeabout) # Set Dialog background background = Background(self.aboutDialog, size_hint_weight=EXPAND_BOTH) self.aboutDialog.resize_object_add(background) background.show() # mainBox = Box(self.aboutDialog, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.aboutDialog.resize_object_add(mainBox) mainBox.show() # need_ethumb() icon = Icon(self.aboutDialog, thumb='True') icon.standard_set('accessories-text-editor') # Using gksudo or sudo fails to load Image here # unless options specify using preserving their existing environment. # may also fail to load other icons but does not raise an exception # in that situation. # Works fine using eSudo as a gksudo alternative, # other alternatives not tested try: aboutImage = Image(self.aboutDialog, no_scale=True, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH, file=icon.file_get()) aboutImage.aspect_fixed_set(False) mainBox.pack_end(aboutImage) aboutImage.show() except RuntimeError as msg: print("Warning: to run as root please use:\n" "\t gksudo -k or sudo -E \n" "Continuing with minor errors ...") labelBox = Box(self.aboutDialog, size_hint_weight=EXPAND_NONE) mainBox.pack_end(labelBox) labelBox.show() # Entry to hold text titleStr = '<br>ePad version <em>{0}</em><br>'.format(__version__) aboutStr = ('<br>A simple text editor written in <br>' 'python and elementary<br>') aboutLbTitle = Label(self.aboutDialog, style='marker') aboutLbTitle.text = titleStr aboutLbTitle.show() labelBox.pack_end(aboutLbTitle) sep = Separator(self.aboutDialog, horizontal=True) labelBox.pack_end(sep) sep.show() aboutText = Label(self.aboutDialog) aboutText.text = aboutStr aboutText.show() labelBox.pack_end(aboutText) aboutCopyright = Label(self.aboutDialog) aboutCopyright.text = '<b>Copyright</b> © <i>2014 Bodhi Linux</i><br>' aboutCopyright.show() labelBox.pack_end(aboutCopyright) # Dialog Buttons # Horizontal Box for Dialog Buttons buttonBox = Box(self.aboutDialog, horizontal=True, size_hint_weight=EXPAND_HORIZ, size_hint_align=FILL_BOTH, padding=PADDING) buttonBox.size_hint_weight_set(EVAS_HINT_EXPAND, 0.0) buttonBox.show() labelBox.pack_end(buttonBox) # Credits Button creditsBtn = Button(self.aboutDialog, text="Credits ", size_hint_weight=EXPAND_NONE) creditsBtn.callback_clicked_add(self.creditsPress) creditsBtn.show() buttonBox.pack_end(creditsBtn) # Close Button okBtn = Button(self.aboutDialog, text=" Close ", size_hint_weight=EXPAND_NONE) okBtn.callback_clicked_add(self.closeabout) okBtn.show() buttonBox.pack_end(okBtn) # Ensure the min height self.aboutDialog.resize(300, 100) def creditsPress(self, obj): # About popup self.popupAbout = Popup(self.aboutDialog, size_hint_weight=EXPAND_BOTH) self.popupAbout.text = ( "Jeff Hoogland <<i>Jef91</i>><br><br>" "Robert Wiley <<i>ylee</i>><br><br>" "Kai Huuhko <<i>kuuko</i>><br>" ) self.popupAbout.callback_block_clicked_add(self.cb_bnt_close) self.popupAbout.show() def cb_bnt_close(self, btn): self.popupAbout.delete() def closeabout(self, obj=False, trash=False): self.aboutDialog.hide() def launch(self, startingFile=False): center = self._parent.mainWindow.center_get() self.aboutDialog.center_set(center[0], center[1]) self.aboutDialog.show()
class Interface(object): def __init__( self ): self.mainWindow = StandardWindow("epad", "Untitled - ePad", size=(600, 400)) self.mainWindow.callback_delete_request_add(self.closeChecks) self.mainWindow.elm_event_callback_add(self.eventsCb) icon = Icon(self.mainWindow) icon.size_hint_weight_set(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND) icon.size_hint_align_set(EVAS_HINT_FILL, EVAS_HINT_FILL) icon.standard_set('accessories-text-editor') # assumes image icon is in local dir, may need to change later icon.show() self.mainWindow.icon_object_set(icon.object_get()) self.mainBox = Box(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.mainBox.show() self.mainTb = Toolbar(self.mainWindow, homogeneous=False, size_hint_weight=(0.0, 0.0), size_hint_align=(EVAS_HINT_FILL, 0.0)) self.mainTb.menu_parent = self.mainWindow self.mainTb.item_append("document-new", "New", self.newPress) self.mainTb.item_append("document-open", "Open", self.openPress) self.mainTb.item_append("document-save", "Save", self.savePress) self.mainTb.item_append("document-save-as", "Save As", self.saveAsPress) # -- Edit Dropdown Menu -- tb_it = self.mainTb.item_append("edit", "Edit") tb_it.menu = True menu = tb_it.menu menu.item_add(None, "Copy", "edit-copy", self.copyPress) menu.item_add(None, "Paste", "edit-paste", self.pastePress) menu.item_add(None, "Cut", "edit-cut", self.cutPress) menu.item_separator_add() menu.item_add(None, "Select All", "edit-select-all", self.selectAllPress) # ----------------------- # self.mainTb.item_append("settings", "Options", self.optionsPress) self.mainTb.item_append("dialog-information", "About", self.aboutPress) self.mainEn = Entry(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.mainEn.callback_changed_user_add(self.textEdited) self.mainEn.scrollable_set(True) # creates scrollbars rather than enlarge window self.mainEn.line_wrap_set(False) # does not allow line wrap (can be changed by user) self.mainEn.autosave_set(False) # set to false to reduce disk I/O self.mainEn.elm_event_callback_add(self.eventsCb) self.mainEn.markup_filter_append(self.textFilter) self.mainEn.show() self.mainTb.show() self.mainBox.pack_end(self.mainTb) self.mainBox.pack_end(self.mainEn) #Build our file selector for saving/loading files self.fileBox = Box(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.fileBox.show() self.fileLabel = Label(self.mainWindow, size_hint_weight=EXPAND_HORIZ, size_hint_align=FILL_BOTH) self.fileLabel.text = "" self.fileLabel.show() self.fileSelector = Fileselector(self.mainWindow, is_save=False, expandable=False, folder_only=False, path=os.getenv("HOME"), size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.fileSelector.callback_done_add(self.fileSelected) #self.fileSelector.callback_selected_add(fs_cb_selected, win) #self.fileSelector.callback_directory_open_add(fs_cb_directory_open, win) self.fileSelector.show() self.fileBox.pack_end(self.fileLabel) self.fileBox.pack_end(self.fileSelector) # the flip object has the file selector on one side and the GUI on the other self.flip = Flip(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.flip.part_content_set("front", self.mainBox) self.flip.part_content_set("back", self.fileBox) self.mainWindow.resize_object_add(self.flip) self.flip.show() self.isSaved = True self.isNewFile = False self.confirmPopup = None def newPress( self, obj, it ): self.newFile() it.selected_set(False) def openPress( self, obj, it ): self.openFile() it.selected_set(False) def savePress( self, obj, it ): self.saveFile() it.selected_set(False) def saveAsPress( self, obj, it ): self.saveAs() it.selected_set(False) def optionsPress( self, obj, it ): it.selected_set(False) def copyPress( self, obj, it ): self.mainEn.selection_copy() it.selected_set(False) def pastePress( self, obj, it ): self.mainEn.selection_paste() it.selected_set(False) def cutPress( self, obj, it ): self.mainEn.selection_cut() it.selected_set(False) def selectAllPress( self, obj, it ): self.mainEn.select_all() it.selected_set(False) def textEdited( self, obj ): ourFile = self.mainEn.file_get()[0] if ourFile and not self.isNewFile: self.mainWindow.title_set("*%s - ePad"%self.mainEn.file_get()[0].split("/")[len(self.mainEn.file_get()[0].split("/"))-1]) else: self.mainWindow.title_set("*Untitlted - ePad") self.isSaved = False def fileSelected( self, fs, file_selected, onStartup=False ): if not onStartup: self.flip.go(ELM_FLIP_INTERACTION_ROTATE) print(file_selected) IsSave = fs.is_save_get() if file_selected: if IsSave: newfile = open(file_selected,'w') # creates new file tmp_text = self.mainEn.entry_get() newfile.write(tmp_text) newfile.close() self.mainEn.file_set(file_selected, ELM_TEXT_FORMAT_PLAIN_UTF8) self.mainEn.entry_set(tmp_text) self.mainEn.file_save() self.mainWindow.title_set("%s - ePad" % file_selected.split("/")[len(file_selected.split("/"))-1]) self.isSaved = True self.isNewFile = False else: try: self.mainEn.file_set(file_selected, ELM_TEXT_FORMAT_PLAIN_UTF8) except RuntimeError: print("Empty file: {0}".format(file_selected)) self.mainWindow.title_set("%s - ePad" % file_selected.split("/")[len(file_selected.split("/"))-1]) def aboutPress( self, obj, it ): #About popup self.popupAbout = Popup(self.mainWindow, size_hint_weight=EXPAND_BOTH) self.popupAbout.text = "ePad - A simple text editor written in python and elementary<br><br> " \ "By: Jeff Hoogland" bt = Button(self.mainWindow, text="Done") bt.callback_clicked_add(self.aboutClose) self.popupAbout.part_content_set("button1", bt) self.popupAbout.show() it.selected_set(False) def aboutClose( self, bt ): self.popupAbout.delete() def newFile( self , obj=None, ignoreSave=False ): if self.isSaved == True or ignoreSave == True: trans = Transit() trans.object_add(self.mainEn) trans.auto_reverse = True trans.effect_wipe_add( ELM_TRANSIT_EFFECT_WIPE_TYPE_HIDE, ELM_TRANSIT_EFFECT_WIPE_DIR_RIGHT) trans.duration = 0.5 trans.go() time.sleep(0.5) self.mainWindow.title_set("Untitlted - ePad") self.mainEn.delete() self.mainEn = Entry(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.mainEn.callback_changed_user_add(self.textEdited) self.mainEn.scrollable_set(True) # creates scrollbars rather than enlarge window self.mainEn.line_wrap_set(False) # does not allow line wrap (can be changed by user) self.mainEn.autosave_set(False) # set to false to reduce disk I/O self.mainEn.elm_event_callback_add(self.eventsCb) self.mainEn.markup_filter_append(self.textFilter) self.mainEn.show() self.mainBox.pack_end(self.mainEn) self.isNewFile = True elif self.confirmPopup == None: self.confirmSave(self.newFile) def openFile( self, obj=None, ignoreSave=False ): if self.isSaved == True or ignoreSave == True: self.fileSelector.is_save_set(False) self.fileLabel.text = "<b>Select a text file to open:</b>" self.flip.go(ELM_FLIP_ROTATE_YZ_CENTER_AXIS) elif self.confirmPopup == None: self.confirmSave(self.openFile) def confirmSave( self, ourCallback=None ): self.confirmPopup = Popup(self.mainWindow, size_hint_weight=EXPAND_BOTH) self.confirmPopup.part_text_set("title,text","File Unsaved") if self.mainEn.file_get()[0]: self.confirmPopup.text = "Save changes to '%s'?" % self.mainEn.file_get()[0].split("/")[len(self.mainEn.file_get()[0].split("/"))-1] else: self.confirmPopup.text = "Save changes to 'Untitlted'?" # Close without saving button no_btt = Button(self.mainWindow) no_btt.text = "No" no_btt.callback_clicked_add(self.closePopup, self.confirmPopup) if ourCallback is not None: no_btt.callback_clicked_add(ourCallback, True) no_btt.show() # cancel close request cancel_btt = Button(self.mainWindow) cancel_btt.text = "Cancel" cancel_btt.callback_clicked_add(self.closePopup, self.confirmPopup) cancel_btt.show() # Save the file and then close button sav_btt = Button(self.mainWindow) sav_btt.text = "Yes" sav_btt.callback_clicked_add(self.saveFile) sav_btt.callback_clicked_add(self.closePopup, self.confirmPopup) sav_btt.show() # add buttons to popup self.confirmPopup.part_content_set("button1", no_btt) self.confirmPopup.part_content_set("button2", cancel_btt) self.confirmPopup.part_content_set("button3", sav_btt) self.confirmPopup.show() def saveAs( self ): self.fileSelector.is_save_set(True) self.fileLabel.text = "<b>Save new file to where:</b>" self.flip.go(ELM_FLIP_ROTATE_XZ_CENTER_AXIS) def saveFile( self, obj=False ): if self.mainEn.file_get()[0] == None or self.isNewFile: self.saveAs() else: self.mainEn.file_save() self.mainWindow.title_set("%s - ePad"%self.mainEn.file_get()[0].split("/")[len(self.mainEn.file_get()[0].split("/"))-1]) self.isSaved = True def closeChecks( self, obj ): print(self.isSaved) if self.isSaved == False and self.confirmPopup == None: self.confirmSave(self.closeApp) else: self.closeApp() def closePopup( self, bt, confirmPopup ): self.confirmPopup.delete() self.confirmPopup = None def closeApp( self, obj=False, trash=False ): elementary.exit() def eventsCb( self, obj, src, event_type, event ): #print event_type #print event.key #print "Control Key Status: %s" %event.modifier_is_set("Control") #print "Shift Key Status: %s" %event.modifier_is_set("Shift") #print event.modifier_is_set("Alt") if event.modifier_is_set("Control"): if event.key.lower() == "n": self.newFile() elif event.key.lower() == "s" and event.modifier_is_set("Shift"): self.saveAs() elif event.key.lower() == "s": self.saveFile() elif event.key.lower() == "o": self.openFile() def textFilter( self, obj, theText, data ): #print theText #Block ctrl+hot keys if theText == "" or theText == "" or theText == "": return None else: return theText def launch( self, startingFile=False ): if startingFile: self.fileSelected(self.fileSelector, startingFile, True) self.mainWindow.show()
class Interface(object): def __init__(self): self.mainWindow = StandardWindow("epad", "Untitled - ePad", size=(600, 400)) self.mainWindow.callback_delete_request_add(self.closeChecks) self.mainWindow.elm_event_callback_add(self.eventsCb) icon = Icon(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) icon.standard_set('accessories-text-editor') icon.show() self.mainWindow.icon_object_set(icon.object_get()) self.mainBox = Box(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.mainBox.show() self.newInstance = NEW_INSTANCE self.mainTb = ePadToolbar(self, self.mainWindow) self.mainTb.focus_allow = False self.mainTb.show() self.mainBox.pack_end(self.mainTb) # Root User Notification if os.geteuid() == 0: printErr("Caution: Root User") if NOTIFY_ROOT: notifyBox = Box(self.mainWindow, horizontal=True) notifyBox.show() notify = Notify(self.mainWindow, size_hint_weight=EXPAND_BOTH, align=(ELM_NOTIFY_ALIGN_FILL, 0.0), content=notifyBox) notifyLabel = Label(self.mainWindow) notifyLabel.text = "<b><i>Root User</i></b>" notifyBox.pack_end(notifyLabel) notifyLabel.show() self.mainBox.pack_end(notifyBox) self.about = aboutWin(self, self.mainWindow) self.about.hide() # Initialize Text entry box and line label # FIXME: self.wordwrap initialized by ePadToolbar print("Word wrap Initialized: {0}".format(self.wordwrap)) self.entryInit() # Build our file selector for saving/loading files self.fileBox = Box(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.fileBox.show() self.fileLabel = Label(self.mainWindow, size_hint_weight=EXPAND_HORIZ, size_hint_align=FILL_BOTH, text="") self.fileLabel.show() self.lastDir = os.getenv("HOME") self.fileSelector = Fileselector(self.mainWindow, is_save=False, expandable=False, folder_only=False, hidden_visible=SHOW_HIDDEN, path=self.lastDir, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.fileSelector.callback_done_add(self.fileSelected) self.fileSelector.callback_activated_add(self.fileSelected) self.fileSelector.callback_directory_open_add(self.updateLastDir) self.fileSelector.path_set(os.getcwd()) self.fileSelector.show() self.fileBox.pack_end(self.fileLabel) self.fileBox.pack_end(self.fileSelector) # Flip object has the file selector on one side # and the GUI on the other self.flip = Flip(self.mainWindow, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.flip.part_content_set("front", self.mainBox) self.flip.part_content_set("back", self.fileBox) self.mainWindow.resize_object_add(self.flip) self.flip.show() self.isSaved = True self.isNewFile = False self.confirmPopup = None self.fileExistsFlag = False def entryInit(self): self.mainEn = Entry(self.mainWindow, scrollable=True, line_wrap=self.wordwrap, autosave=False, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) self.mainEn.callback_changed_user_add(self.textEdited) self.mainEn.elm_event_callback_add(self.eventsCb) self.mainEn.callback_clicked_add(resetCloseMenuCount) # delete line lable if it exist so we can create and add new one # Later need to rethink logic here try: self.line_label.delete() except AttributeError: pass # Add label to show current cursor position if SHOW_POS: self.line_label = Label(self.mainWindow, size_hint_weight=EXPAND_HORIZ, size_hint_align=ALIGN_RIGHT) self.mainEn.callback_cursor_changed_add(self.curChanged, self.line_label) self.curChanged(self.mainEn, self.line_label) self.line_label.show() self.mainBox.pack_end(self.line_label) # self.mainEn.markup_filter_append(self.textFilter) self.mainEn.show() self.mainEn.focus_set(True) try: self.mainBox.pack_before(self.mainEn, self.line_label) except AttributeError: # line_label has not been initialized on first run # Should have better logic on all this self.mainBox.pack_end(self.mainEn) def curChanged(self, entry, label): # get linear index into current text index = entry.cursor_pos_get() # Replace <br /> tag with single char # to simplify (line, col) calculation tmp_text = markup_to_utf8(entry.entry_get()) line = tmp_text[:index].count("\n") + 1 col = len(tmp_text[:index].split("\n")[-1]) + 1 # Update label text with line, col label.text = "Ln {0} Col {1} ".format(line, col) def textEdited(self, obj): current_file = self.mainEn.file[0] current_file = \ os.path.basename(current_file) if \ current_file and not self.isNewFile else \ "Untitled" self.mainWindow.title = "*%s - ePad" % (current_file) self.isSaved = False def newFile(self, obj=None, ignoreSave=False): if self.newInstance: # sh does not properly handle space between -d and path command = "epad -d'{0}'".format(self.lastDir) print("Launching new instance: {0}".format(command)) ecore.Exe(command, ecore.ECORE_EXE_PIPE_READ | ecore.ECORE_EXE_PIPE_ERROR | ecore.ECORE_EXE_PIPE_WRITE) return if self.isSaved is True or ignoreSave is True: trans = Transit() trans.object_add(self.mainEn) trans.auto_reverse = True trans.effect_wipe_add( ELM_TRANSIT_EFFECT_WIPE_TYPE_HIDE, ELM_TRANSIT_EFFECT_WIPE_DIR_RIGHT) trans.duration = 0.5 trans.go() time.sleep(0.5) self.mainWindow.title_set("Untitled - ePad") self.mainEn.delete() self.entryInit() self.isNewFile = True elif self.confirmPopup is None: self.confirmSave(self.newFile) self.mainEn.focus_set(True) def openFile(self, obj=None, ignoreSave=False): if self.isSaved is True or ignoreSave is True: self.fileSelector.is_save_set(False) self.fileLabel.text = "<b>Select a text file to open:</b>" self.flip.go(ELM_FLIP_ROTATE_YZ_CENTER_AXIS) elif self.confirmPopup is None: self.confirmSave(self.openFile) def confirmSave(self, ourCallback=None): self.confirmPopup = Popup(self.mainWindow, size_hint_weight=EXPAND_BOTH) self.confirmPopup.part_text_set("title,text", "File Unsaved") current_file = self.mainEn.file[0] current_file = \ os.path.basename(current_file) if current_file else "Untitled" self.confirmPopup.text = "Save changes to '%s'?" % (current_file) # Close without saving button no_btt = Button(self.mainWindow) no_btt.text = "No" no_btt.callback_clicked_add(self.closePopup, self.confirmPopup) if ourCallback is not None: no_btt.callback_clicked_add(ourCallback, True) no_btt.show() # cancel close request cancel_btt = Button(self.mainWindow) cancel_btt.text = "Cancel" cancel_btt.callback_clicked_add(self.closePopup, self.confirmPopup) cancel_btt.show() # Save the file and then close button sav_btt = Button(self.mainWindow) sav_btt.text = "Yes" sav_btt.callback_clicked_add(self.saveFile) sav_btt.callback_clicked_add(self.closePopup, self.confirmPopup) sav_btt.show() # add buttons to popup self.confirmPopup.part_content_set("button1", no_btt) self.confirmPopup.part_content_set("button2", cancel_btt) self.confirmPopup.part_content_set("button3", sav_btt) self.confirmPopup.show() def saveAs(self): self.fileSelector.is_save_set(True) self.fileLabel.text = "<b>Save new file to where:</b>" self.flip.go(ELM_FLIP_ROTATE_XZ_CENTER_AXIS) def saveFile(self, obj=False): if self.mainEn.file_get()[0] is None or self.isNewFile: self.saveAs() else: file_selected = self.mainEn.file_get()[0] # Detect save errors as entry.file_save currently returns no errors # even in the case where the file fails to save :( try: newfile = open(file_selected, 'w') except IOError as err: if err.errno == errno.EACCES: errorMsg = ("Permision denied: <b>'%s'</b>." "<br><br>Operation failed !!!" % (file_selected)) errorPopup(self.mainWindow, errorMsg) else: errorMsg = ("ERROR: %s: '%s'" "<br><br>Operation failed !!!" % (err.strerror, file_selected)) errorPopup(self.mainWindow, errorMsg) return newfile.close() # if entry is empty and the file does not exists then # entry.file_save will destroy the file created about by the # open statement above for some odd reason ... if not self.mainEn.is_empty: self.mainEn.file_save() self.mainWindow.title_set("%s - ePad" % os.path.basename(self.mainEn.file[0])) self.isSaved = True def doSelected(self, obj): # Something I should avoid but here I prefer a polymorphic function if isinstance(obj, Button): file_selected = self.fileSelector.selected_get() else: file_selected = obj IsSave = self.fileSelector.is_save_get() if file_selected: if IsSave: try: newfile = open(file_selected, 'w') except IOError as err: print("ERROR: {0}: '{1}'".format(err.strerror, file_selected)) if err.errno == errno.EACCES: errorMsg = ("Permision denied: <b>'%s'</b>." "<br><br>Operation failed !!!</br>" % (file_selected)) errorPopup(self.mainWindow, errorMsg) else: errorMsg = ("ERROR: %s: '%s'" "<br><br>Operation failed !!!</br>" % (err.strerror, file_selected)) errorPopup(self.mainWindow, errorMsg) return tmp_text = self.mainEn.entry_get() # FIXME: Why save twice? newfile.write(tmp_text) newfile.close() # Suppress error message when empty file is saved try: self.mainEn.file_set(file_selected, ELM_TEXT_FORMAT_PLAIN_UTF8) except RuntimeError: print("Empty file saved:{0}".format(file_selected)) self.mainEn.entry_set(tmp_text) # if empty file entry.file_save destroys file :( if len(tmp_text): self.mainEn.file_save() self.mainWindow.title_set("%s - ePad" % os.path.basename(file_selected)) self.isSaved = True self.isNewFile = False else: if os.path.isdir(file_selected): print("ERROR: {0}: is a directory. " "Could not set file.".format(file_selected)) current_file = os.path.basename(file_selected) errorMsg = ("<b>'%s'</b> is a folder." "<br><br>Operation failed !!!</br>" % (current_file)) errorPopup(self.mainWindow, errorMsg) return # Test to see if file can be opened to catch permission errors # as entry.file_set function does not differentiate # different possible errors. try: with open(file_selected) as f: tmp_text = f.readline() except IOError as err: if err.errno == errno.ENOENT: print("Creating New file '{0}'".format(file_selected)) # self.fileSelector.current_name_set(file_selected) self.isSaved = False elif err.errno == errno.EACCES: print("ERROR: {0}: '{1}'".format(err.strerror, file_selected)) errorMsg = ("Permision denied: <b>'%s'</b>." "<br><br>Operation failed !!!</br>" % (file_selected)) errorPopup(self.mainWindow, errorMsg) return else: print("ERROR: {0}: '{1}'".format(err.strerror, file_selected)) errorMsg = ("ERROR: %s: '%s'" "<br><br>Operation failed !!!</br>" % (err.strerror, file_selected)) errorPopup(self.mainWindow, errorMsg) return try: self.mainEn.file_set(file_selected, ELM_TEXT_FORMAT_PLAIN_UTF8) except RuntimeError as msg: # Entry.file_set fails on empty files print("Empty file: {0}".format(file_selected)) self.mainWindow.title_set("%s - ePad" % os.path.basename(file_selected)) self.mainEn.focus_set(True) def fileExists(self, filePath): self.confirmPopup = Popup(self.mainWindow, size_hint_weight=EXPAND_BOTH) # Add a table to hold dialog image and text to Popup tb = Table(self.confirmPopup, size_hint_weight=EXPAND_BOTH) self.confirmPopup.part_content_set("default", tb) tb.show() # Add dialog-error Image to table need_ethumb() icon = Icon(self.confirmPopup, thumb='True') icon.standard_set('dialog-question') # Using gksudo or sudo fails to load Image here # unless options specify using preserving their existing environment. # may also fail to load other icons but does not raise an exception # in that situation. # Works fine using eSudo as a gksudo alternative, # other alternatives not tested try: dialogImage = Image(self.confirmPopup, size_hint_weight=EXPAND_HORIZ, size_hint_align=FILL_BOTH, file=icon.file_get()) tb.pack(dialogImage, 0, 0, 1, 1) dialogImage.show() except RuntimeError: # An error message is displayed for this same error # when aboutWin is initialized so no need to redisplay. pass # Add dialog text to table dialogLabel = Label(self.confirmPopup, line_wrap=ELM_WRAP_WORD, size_hint_weight=EXPAND_HORIZ, size_hint_align=FILL_BOTH) current_file = os.path.basename(filePath) dialogLabel.text = "'%s' already exists. Overwrite?<br><br>" \ % (current_file) tb.pack(dialogLabel, 1, 0, 1, 1) dialogLabel.show() # Close without saving button no_btt = Button(self.mainWindow) no_btt.text = "No" no_btt.callback_clicked_add(self.closePopup, self.confirmPopup) no_btt.show() # Save the file and then close button sav_btt = Button(self.mainWindow) sav_btt.text = "Yes" sav_btt.callback_clicked_add(self.doSelected) sav_btt.callback_clicked_add(self.closePopup, self.confirmPopup) sav_btt.show() # add buttons to popup self.confirmPopup.part_content_set("button1", no_btt) self.confirmPopup.part_content_set("button3", sav_btt) self.confirmPopup.show() def fileSelected(self, fs, file_selected, onStartup=False): if not onStartup: self.flip.go(ELM_FLIP_INTERACTION_ROTATE) # Markup can end up in file names because file_selector name_entry # is an elementary entry. So lets sanitize file_selected. file_selected = markup_to_utf8(file_selected) if file_selected: print("File Selected: {0}".format(file_selected)) self.lastDir = os.path.dirname(file_selected) fs.path_set(self.lastDir) # This fails if file_selected does not exist yet try: fs.selected = file_selected except RuntimeError: # FIXME: would be nice if I could set fileSelector name entry pass IsSave = fs.is_save_get() if file_selected: if IsSave: if os.path.isdir(file_selected): current_file = os.path.basename(file_selected) errorMsg = ("<b>'%s'</b> is a folder." "<br><br>Operation failed !!!" % (current_file)) errorPopup(self.mainWindow, errorMsg) return elif os.path.exists(file_selected): self.fileExistsFlag = True self.fileExists(file_selected) return self.doSelected(file_selected) def updateLastDir(self, fs, path): self.lastDir = path def closeChecks(self, obj): print("File is Saved: ", self.isSaved) if not self.flip.front_visible_get(): self.flip.go(ELM_FLIP_ROTATE_XZ_CENTER_AXIS) elif self.isSaved is False and self.confirmPopup is None: self.confirmSave(self.closeApp) else: self.closeApp() def closePopup(self, bt, confirmPopup): self.confirmPopup.delete() self.confirmPopup = None def showAbout(self): self.about.launch() def closeApp(self, obj=False, trash=False): elementary.exit() def eventsCb(self, obj, src, event_type, event): if event.modifier_is_set("Control"): if event.key.lower() == "n": self.newFile() elif event.key.lower() == "s" and event.modifier_is_set("Shift"): self.saveAs() elif event.key.lower() == "s": self.saveFile() elif event.key.lower() == "o": self.openFile() elif event.key.lower() == "h": if not self.flip.front_visible_get(): toggleHidden(self.fileSelector) elif event.key.lower() == "q": closeCtrlChecks(self) # Legacy hack no longer needed # there was an issue in elementary entry where it would # accept those character controls # def textFilter( self, obj, theText, data ): # # Block ctrl+hot keys used in eventsCb # # # # Ctrl O Ctrl N Ctrl S # ctrl_block = [chr(14), chr(15), chr(19)] # if theText in ctrl_block: # return None # else: # return theText def launch(self, start=[]): if start and start[0] and os.path.dirname(start[0]) == '': start[0] = os.getcwd() + '/' + start[0] if start and start[0]: if os.path.isdir(os.path.dirname(start[0])): self.fileSelected(self.fileSelector, start[0], True) else: print("Error: {0} is an Invalid Path".format(start)) errorMsg = ("<b>'%s'</b> is an Invalid path." "<br><br>Open failed !!!" % (start)) errorPopup(self.mainWindow, errorMsg) if start and start[1]: if os.path.isdir(start[1]): print("Initializing file selection path: {0}".format(start[1])) self.fileSelector.path_set(start[1]) self.lastDir = start[1] else: print("Error: {0} is an Invalid Path".format(start[1])) self.mainWindow.show()