|
4 | 4 |
|
5 | 5 | import shlex
|
6 | 6 | from tkinter import Tk
|
7 |
| -import clipboard |
8 | 7 | import wx
|
9 | 8 | import PySimpleGUI as sg
|
10 | 9 |
|
|
13 | 12 | tk = Tk()
|
14 | 13 | tk.withdraw()
|
15 | 14 |
|
| 15 | +wx_app = [] # pylint: disable=unused-variable |
| 16 | +wx_app = wx.App(None) |
| 17 | + |
| 18 | + |
16 | 19 | # change the default theme.
|
17 |
| -sg.theme('dark grey 9') |
| 20 | +# sg.theme('dark grey 9') |
18 | 21 |
|
19 | 22 | WINDOW_WIDTH: int = 90
|
20 | 23 | WINDOW_HEIGHT: int = 25
|
21 | 24 | FILE_NAME: str = None
|
22 | 25 | DEFAULT_FONT_NAME: str = 'Times New Roman'
|
| 26 | +APP_NAME: str = 'NotepadPy+' |
| 27 | +SELECTED_THEME: str = '' |
23 | 28 |
|
24 | 29 | def ShowFontDialog():
|
25 | 30 | '''Get a font dialog to display and return all the
|
@@ -30,9 +35,6 @@ def ShowFontDialog():
|
30 | 35 | # bold, italic, underline, and overstrike. These styles can be specified as a
|
31 | 36 | # string like - 'overstrike underline italic'
|
32 | 37 |
|
33 |
| -wx_app = [] # pylint: disable=unused-variable |
34 |
| -wx_app = wx.App(None) |
35 |
| - |
36 | 38 | font_style_modifier: str = ''
|
37 | 39 |
|
38 | 40 | dialog = wx.FontDialog(None, wx.FontData())
|
@@ -73,40 +75,97 @@ def ShowFontDialog():
|
73 | 75 | WINDOW['-BODY-'].update(font=(font_facename, font_size, font_style_modifier.rstrip()),
|
74 | 76 | text_color=font_color)
|
75 | 77 |
|
| 78 | +def ShowPrintDialog(): |
| 79 | +'''Displays the System print dialog.''' |
| 80 | +data = wx.PrintDialogData() |
| 81 | +data.EnableSelection(True) |
| 82 | +data.EnablePrintToFile(True) |
| 83 | +data.EnablePageNumbers(True) |
| 84 | +data.SetMinPage(1) |
| 85 | +data.SetMaxPage(10) |
| 86 | + |
| 87 | +dialog = wx.PrintDialog(None, data) |
| 88 | + |
| 89 | +text_to_print = VALUES['-BODY-'] |
| 90 | +if dialog.ShowModal() == wx.ID_OK: |
| 91 | +data = dialog.GetPrintDialogData() |
| 92 | +dc = dialog.GetPrintDC() |
| 93 | + |
| 94 | +dc.StartDoc("MyDoc") |
| 95 | +dc.StartPage() |
| 96 | +dc.SetMapMode(wx.MM_POINTS) |
| 97 | + |
| 98 | +dc.SetTextForeground("black") |
| 99 | +dc.DrawText(text_to_print, 50, 100) |
| 100 | + |
| 101 | +dc.EndPage() |
| 102 | +dc.EndDoc() |
| 103 | +del dc |
| 104 | + |
| 105 | +printer = wx.Printer(data) |
| 106 | +printer_config = wx.PrintData(printer.GetPrintDialogData().GetPrintData()) |
| 107 | + |
| 108 | +# print('GetAllPages: %d\n' % data.GetAllPages()) |
| 109 | + |
| 110 | + |
| 111 | +dialog.Destroy() |
76 | 112 |
|
77 | 113 | def rgb2hex(r, g, b):
|
78 | 114 | '''Convert RGB to hex values.'''
|
79 | 115 | return "#{:02x}{:02x}{:02x}".format(r, g, b)
|
80 | 116 |
|
81 | 117 | # file menu constants.
|
82 |
| -file_new: str = 'New (CTRL+N)' |
83 |
| -file_open: str = 'Open (CTRL+O)' |
84 |
| -file_save: str = 'Save (CTRL+S)' |
| 118 | +file_new: str = 'New CTRL+N' |
| 119 | +file_open: str = 'Open CTRL+O' |
| 120 | +file_save: str = 'Save CTRL+S' |
| 121 | +file_print: str = 'Print CTRL+P' |
85 | 122 |
|
86 | 123 | # edit menu constants.
|
87 |
| -edit_cut: str = 'Cut (CTRL+X)' |
88 |
| -edit_copy: str = 'Copy (CTRL+C)' |
89 |
| -edit_paste: str = 'Paste (CTRL+V)' |
90 |
| -edit_delete: str = 'Delete (Del)' |
| 124 | +edit_cut: str = 'Cut CTRL+X' |
| 125 | +edit_copy: str = 'Copy CTRL+C' |
| 126 | +edit_paste: str = 'Paste CTRL+V' |
| 127 | +edit_delete: str = 'Delete Del' |
91 | 128 |
|
92 |
| -menu_layout: list = [['&File', [file_new, file_open, file_save, 'Save As', '______________________', 'Exit']], |
93 |
| -['&Edit', [edit_cut, edit_copy, edit_paste, edit_delete]], |
94 |
| -['&Statistics', ['Word Count', 'Line Count', 'Character With Spaces', 'Character Without Spaces', ]], |
95 |
| -['F&ormat', ['Font', ]], |
96 |
| -['&Help', ['About']]] |
| 129 | + |
| 130 | +menu_layout: list = [['&File', [file_new, file_open, file_save, 'Save As', '______________________', file_print, '______________________', 'Exit']], |
| 131 | +['&Edit', [edit_cut, edit_copy, edit_paste, edit_delete]], |
| 132 | +['&Statistics', ['Word Count', 'Line Count', 'Character With Spaces', 'Character Without Spaces', ]], |
| 133 | +['F&ormat', ['Font', ]], |
| 134 | +['&Help', ['About']]] |
97 | 135 |
|
98 | 136 | layout: list = [[sg.Menu(menu_layout)],
|
99 | 137 | [sg.Text('New File:', font=('Times New Roman', 10),
|
100 |
| -size=(WINDOW_WIDTH, 1), key='-FILE_INFO-')], |
| 138 | +size=(WINDOW_WIDTH, 1), key='-FILE_INFO-', visible=False)], |
101 | 139 | [sg.Multiline(font=(DEFAULT_FONT_NAME, 12),
|
102 |
| -size=(WINDOW_WIDTH, WINDOW_HEIGHT), key='-BODY-')]] |
| 140 | +size=(WINDOW_WIDTH, WINDOW_HEIGHT), key='-BODY-', reroute_cprint=True)]] |
103 | 141 |
|
104 |
| -WINDOW = sg.Window('Notepad', layout=layout, margins=(0, 0), |
105 |
| -resizable=True, return_keyboard_events=True) |
106 |
| -WINDOW.read(timeout=1) |
| 142 | +WINDOW = sg.Window('untitled - ' + APP_NAME, layout=layout, margins=(0, 0), |
| 143 | +resizable=True, return_keyboard_events=True, finalize=True) |
| 144 | +# WINDOW.read(timeout=1) |
107 | 145 | WINDOW.maximize()
|
108 | 146 | WINDOW['-BODY-'].expand(expand_x=True, expand_y=True)
|
109 | 147 |
|
| 148 | +# APPLICATION THEME CHANGING DIALOG - A good place to refer are the following resources - |
| 149 | +# https://.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Design_Pattern_Multiple_Windows2.py |
| 150 | +# https://.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Design_Pattern_Multiple_Windows.py |
| 151 | +# https://.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Design_Pattern_Multiple_Windows1.py |
| 152 | + |
| 153 | +def create_theme_browser(): |
| 154 | +'''Creates a GUI Theme browser dialog to select |
| 155 | +and apply the application theme.''' |
| 156 | + |
| 157 | +theme_window_layout = [[sg.Text('Select a theme from the list below and\nclick on Apply for changes to take effect.')], |
| 158 | +[sg.Listbox(values=sg.theme_list(), size=(20, 12), key='-THEMELIST-', enable_events=True)], |
| 159 | +[sg.Button('Apply', tooltip="Applies the selected theme.", key='-APPLYTHEME-'), |
| 160 | +sg.Button('Exit', key='-EXITTHEME-')]] |
| 161 | + |
| 162 | +# Define the second window |
| 163 | +# Link it to the first window (master=window) |
| 164 | +# Assign a key to the window so that it can be easily referenced |
| 165 | +theme_window = sg.Window(title='Theme Browser', layout=theme_window_layout, finalize=True, modal=True) |
| 166 | + |
| 167 | +return theme_window |
| 168 | + |
110 | 169 | def new_file() -> str:
|
111 | 170 | ''' Reset body and info bar, and clear FILE_NAME variable '''
|
112 | 171 | WINDOW['-BODY-'].update(value='')
|
@@ -134,7 +193,8 @@ def save_file(file_name: str):
|
134 | 193 | f.write(VALUES.get('-BODY-'))
|
135 | 194 | WINDOW['-FILE_INFO-'].update(value=file_name)
|
136 | 195 | else:
|
137 |
| -save_as() |
| 196 | +file_name = save_as() |
| 197 | +WINDOW.set_title(file_name + ' - ' + APP_NAME) |
138 | 198 |
|
139 | 199 | def save_as() -> str:
|
140 | 200 | ''' Save new file or save existing file with another name '''
|
@@ -228,14 +288,20 @@ def about():
|
228 | 288 | sg.PopupQuick('A simple Notepad like application created using\
|
229 | 289 | PySimpleGUI framework.', auto_close=False)
|
230 | 290 |
|
| 291 | +window1, window2 = WINDOW(), None |
231 | 292 | # read the events and take appropriate actions.
|
232 | 293 | while True:
|
233 |
| -EVENT, VALUES = WINDOW.read() |
234 | 294 |
|
235 |
| -if EVENT in (sg.WINDOW_CLOSED, 'Exit'): |
| 295 | +WIN, EVENT, VALUES = sg.read_all_windows() #WINDOW.read() |
| 296 | + |
| 297 | +if EVENT in (sg.WINDOW_CLOSED, 'Exit', '-EXITTHEME-'): |
236 | 298 | # exit out of the application is close or exit clicked.
|
237 |
| -break |
238 |
| - |
| 299 | +WIN.close() |
| 300 | +if WIN == window2: # if closing win 2, mark as closed |
| 301 | +window2 = None |
| 302 | +else: # if closing win 1, exit program |
| 303 | +break |
| 304 | + |
239 | 305 | # file menu events.
|
240 | 306 | if EVENT in (file_new, 'n:78'):
|
241 | 307 | new_file()
|
@@ -245,13 +311,16 @@ def about():
|
245 | 311 | save_file(FILE_NAME)
|
246 | 312 | if EVENT in ('Save As',):
|
247 | 313 | FILE_NAME = save_as()
|
| 314 | +if EVENT in (file_print, 'p:80'): |
| 315 | +ShowPrintDialog() |
248 | 316 |
|
249 | 317 | # edit menu events.
|
250 | 318 | if EVENT == edit_cut:
|
251 | 319 | selected_text = WINDOW['-BODY-'].Widget.selection_get()
|
252 | 320 | tk.clipboard_clear()
|
253 | 321 | tk.clipboard_append(selected_text)
|
254 | 322 | tk.update()
|
| 323 | +WINDOW['-BODY-'].Widget.delete("sel.first", "sel.last") |
255 | 324 |
|
256 | 325 | if EVENT == edit_copy:
|
257 | 326 | selected_text = WINDOW['-BODY-'].Widget.selection_get()
|
@@ -285,5 +354,7 @@ def about():
|
285 | 354 | auto_close=False)
|
286 | 355 | if EVENT in ('About',):
|
287 | 356 | about()
|
| 357 | + |
| 358 | +# Format Menu |
288 | 359 | if EVENT in ('Font',):
|
289 | 360 | ShowFontDialog()
|
0 commit comments