1
# -*- coding: utf-8; indent-tabs-mode: t; tab-width: 4 -*-
3
import copy, os, sys, webbrowser, gettext
4
from gi.repository import Gtk, Gdk, GdkPixbuf
5
from glogic import config, const
6
from gettext import gettext as _
7
from glogic.DrawArea import DrawArea
8
from glogic.ComponentWindow import ComponentWindow
9
from glogic.CircuitManager import CircuitManager
10
from glogic.PropertyWindow import PropertyWindow
11
from glogic.Components import *
12
from glogic.TimingChartWindow import TimingChartWindow
14
gettext.textdomain("glogic")
16
themed_icons = Gtk.IconTheme.get_default()
17
themed_icons.append_search_path(config.DATADIR+"/images")
19
class MainFrame(Gtk.Window):
21
Gtk.Window.__init__(self, title="%s - %s" % (const.text_notitle, const.app_name))
23
self.running_mode = False
25
self.circuit = CircuitManager(self)
29
if len(sys.argv) >= 2:
30
self.circuit.open_file(sys.argv[1])
31
self.drawarea.redraw = True
32
self.drawarea.queue_draw()
34
def create_window(self):
35
self.set_default_size(640, 400)
36
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
40
<menubar name="MenuBar">
42
<menuitem action="new"/>
43
<menuitem action="open"/>
45
<menuitem action="save"/>
46
<menuitem action="saveas"/>
48
<menuitem action="quit"/>
51
<menuitem action="undo"/>
52
<menuitem action="redo"/>
55
<menuitem action="cut"/>
56
<menuitem action="copy"/>
57
<menuitem action="paste"/>
60
<menuitem action="delete"/>
62
<menuitem action="property"/>
65
<menuitem action="components"/>
66
<menuitem action="net"/>
68
<menu action="simulate">
69
<menuitem action="run"/>
70
<menuitem action="chart"/>
73
<menuitem action="trans"/>
74
<menuitem action="report"/>
76
<menuitem action="about"/>
79
<toolbar name='ToolBar'>
80
<toolitem action='new' />
81
<toolitem action='open' />
82
<toolitem action='save' />
84
<toolitem action='undo' />
85
<toolitem action='redo' />
87
<toolitem action='components' />
88
<toolitem action='net' />
90
<toolitem action='run' />
95
actiongroup = Gtk.ActionGroup("menu")
97
("new", Gtk.STOCK_NEW, _("_New"), "<Control>N", _("Close this circuit and create a new one."), self.on_action_new_pressed),
98
("open", Gtk.STOCK_OPEN, _("_Open..."), "<Control>O", _("Close this circuit and open the other one."), self.on_action_open_pressed),
99
("save", Gtk.STOCK_SAVE, _("_Save"), "<Control>S", _("Save this circuit."), self.on_action_save_pressed),
100
("saveas", Gtk.STOCK_SAVE_AS, _("Save _As..."), "<Shift><Control>S", _("Save this circuit with a new name."), self.on_action_saveas_pressed),
101
("quit", Gtk.STOCK_QUIT, _("_Quit"), "<Control>Q", _("Close this application."), self.on_action_quit_pressed),
102
("undo", Gtk.STOCK_UNDO, _("_Undo"), "<Control>Z", _("Undo the previous action."), self.on_action_undo_pressed),
103
("redo", Gtk.STOCK_REDO, _("_Redo"), "<Shift><Control>Z", _("Redo the action that you have canceled."), self.on_action_redo_pressed),
104
("cut", Gtk.STOCK_CUT, _("Cu_t"), "<Control>X", _("Cut selected components."), None),
105
("copy", Gtk.STOCK_COPY, _("_Copy"), "<Control>C", _("Copy selected components."), self.on_action_copy_pressed),
106
("paste", Gtk.STOCK_PASTE, _("_Paste"), "<Control>V", _("Paste copied components."), self.on_action_paste_pressed),
107
("delete", Gtk.STOCK_DELETE, _("_Delete"), "Delete", _("Delete selected components."), self.on_action_delete_pressed),
108
("trans", None, _("Translate This Application..."), None, _("Connect to the Launchpad website to help translate this application."), self.on_action_translate_pressed),
109
("report", None, _("Report a Problem..."), None, _("Connect to the Launchpad website to report a problem of this application."), self.on_action_bug_pressed),
110
("about", Gtk.STOCK_ABOUT, _("_About"), None, _("Show about dialog."), self.on_action_about_pressed),
111
("file", None, _("_File")),
112
("edit", None, _("_Edit")),
113
("add", None, _("_Add")),
114
("simulate", None, _("_Simulate")),
115
("help", None, _("_Help"))
118
("property", Gtk.STOCK_PREFERENCES, _("_Properties"), "<Control>N", _("Show property dialog."), self.on_action_property_toggled),
119
("components", None, _("_Components..."), "<Control>A", _("Show components window."), self.on_btn_add_components_toggled),
120
("net", None, _("_Net"), "<Control>E", _("Add nets to this circuit."), self.on_action_net_toggled),
121
("run", Gtk.STOCK_MEDIA_PLAY, _("_Run"), "F5", _("Run and simulate this circuit."), self.on_action_play_toggled),
122
("chart", None, _("_Timing Chart"), "<Control>T", _("Show timing chart window."), self.on_action_timingchart_pressed),
124
self.menubar = Gtk.Menu()
126
actiongroup.add_actions(actions)
127
actiongroup.add_toggle_actions(toggle_actions)
129
self.action_undo = actiongroup.get_action("undo")
130
self.action_redo = actiongroup.get_action("redo")
131
self.action_cut = actiongroup.get_action("cut")
132
self.action_copy = actiongroup.get_action("copy")
133
self.action_paste = actiongroup.get_action("paste")
134
self.action_delete = actiongroup.get_action("delete")
135
self.action_property = actiongroup.get_action("property")
136
self.action_components = actiongroup.get_action("components")
137
self.action_net = actiongroup.get_action("net")
138
self.action_run = actiongroup.get_action("run")
139
self.action_chart = actiongroup.get_action("chart")
141
self.action_undo.set_sensitive(False)
142
self.action_redo.set_sensitive(False)
143
self.action_cut.set_sensitive(False)
144
self.action_copy.set_sensitive(False)
145
self.action_delete.set_sensitive(False)
146
self.action_chart.set_sensitive(False)
148
uimanager = Gtk.UIManager()
149
uimanager.add_ui_from_string(menu_xml)
150
self.add_accel_group(uimanager.get_accel_group())
151
uimanager.insert_action_group(actiongroup)
153
menubar = uimanager.get_widget("/MenuBar")
154
box.pack_start(menubar, False, False, 0)
156
toolbar = uimanager.get_widget("/ToolBar")
157
toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)
158
box.pack_start(toolbar, False, False, 0)
160
action = actiongroup.get_action('components')
161
action.set_icon_name("add-component")
162
action = actiongroup.get_action('net')
163
action.set_icon_name("add-net")
166
self.drawarea = DrawArea(self)
167
self.drawarea.circuit = self.circuit
168
self.drawarea.pushed_component = comp_dict[const.component_none]
169
box.pack_start(self.drawarea, False, True, 0)
172
self.statusbar = Gtk.Statusbar()
173
box.pack_start(self.statusbar, False, False, 0)
178
self.comp_window = ComponentWindow(self)
181
self.prop_window = PropertyWindow(self)
183
# Timing chart window
184
self.chart_window = TimingChartWindow(self)
187
self.about_dialog = Gtk.AboutDialog()
188
self.about_dialog.set_logo(GdkPixbuf.Pixbuf.new_from_file(config.DATADIR+"/images/glogic.png"))
189
self.about_dialog.set_program_name(const.app_name)
190
self.about_dialog.set_version(config.VERSION)
191
self.about_dialog.set_comments(const.description)
192
self.about_dialog.set_copyright(const.copyright)
193
self.about_dialog.set_website(const.website)
194
self.about_dialog.set_license(const.license)
195
self.about_dialog.set_authors(const.developer)
196
tr_credits = _("translator-credits")
197
if tr_credits != "translator-credits":
198
self.about_dialog.set_translator_credits(tr_credits)
201
self.connect("delete-event", self.on_window_delete)
203
def on_action_about_pressed(self, widget):
204
self.about_dialog.run()
205
self.about_dialog.hide()
207
def on_action_new_pressed(self, widget):
208
if self.check_modified():
211
self.set_title("%s - wxLogic" % const.text_notitle)
213
self.circuit.reset_circuit()
214
self.drawarea.redraw = True
215
self.drawarea.queue_draw()
217
def add_filters(self, dialog):
218
filter_wxl = Gtk.FileFilter()
219
filter_wxl.set_name(_("gLogic files (*.glc)"))
220
filter_wxl.add_pattern("*.glc")
221
dialog.add_filter(filter_wxl)
222
filter_any = Gtk.FileFilter()
223
filter_any.set_name(_("All files"))
224
filter_any.add_pattern("*")
225
dialog.add_filter(filter_any)
227
def reset_frame(self):
228
self.comp_window.uncheck_all_buttons()
230
self.statusbar.push(0, "")
231
self.running_mode = False
232
self.comp_window.checked_button = const.component_none
233
self.drawarea.pushed_component = comp_dict[const.component_none]
234
self.action_undo.set_sensitive(False)
235
self.action_redo.set_sensitive(False)
236
self.action_cut.set_sensitive(False)
237
self.action_copy.set_sensitive(False)
238
self.action_delete.set_sensitive(False)
239
self.action_net.set_active(False)
240
self.action_run.set_active(False)
242
def on_action_open_pressed(self, widget):
243
if self.check_modified():
246
dialog = Gtk.FileChooserDialog(_("Open file"), self, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.ACCEPT))
247
dialog.set_transient_for(self)
248
self.add_filters(dialog)
249
if dialog.run() == Gtk.ResponseType.ACCEPT:
250
filepath = dialog.get_filename()
254
if not self.circuit.open_file(filepath):
256
self.drawarea.redraw = True
257
self.drawarea.queue_draw()
262
def overwrite_save(self):
263
if self.circuit.filepath == "":
264
return self.rename_save()
266
if self.circuit.save_file(self.circuit.filepath):
267
return self.rename_save()
270
def rename_save(self):
271
chooser = Gtk.FileChooserDialog(_("Save file"), self, Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.ACCEPT), flags=Gtk.DialogFlags.MODAL)
272
chooser.set_transient_for(self)
273
chooser.set_modal(True)
275
self.add_filters(chooser)
276
if chooser.run() == Gtk.ResponseType.ACCEPT:
277
filepath = chooser.get_filename()
278
filter_name = chooser.get_filter().get_name()
279
if filter_name == _("gLogic files (*.glc)"):
280
if not "." in os.path.basename(filepath):
283
if os.path.exists(filepath):
284
dialog = Gtk.MessageDialog(chooser, Gtk.DialogFlags.MODAL, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, _("Overwrite to the existing file?"))
285
dialog.format_secondary_text(_("The file already exist. Overwrite it?"))
286
retval = dialog.run()
288
if retval == Gtk.ResponseType.NO:
295
if not self.circuit.save_file(filepath):
299
def on_action_save_pressed(self, widget):
300
self.overwrite_save()
302
def on_action_saveas_pressed(self, widget):
305
def on_action_quit_pressed(self, widget):
306
event = Gdk.Event(Gdk.EventType.DELETE)
307
self.emit("delete-event", event)
309
def check_modified(self):
310
if self.circuit.need_save:
311
dialog = Gtk.MessageDialog(self, Gtk.DialogFlags.MODAL, Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, _("Save the modified schematics?"))
312
dialog.format_secondary_text(_("The schematics was modifed. Save the changes before closing?"))
313
retval = dialog.run()
315
if retval == Gtk.ResponseType.YES:
316
return self.overwrite_save()
317
elif retval == Gtk.ResponseType.NO:
323
def on_btn_add_components_toggled(self, widget):
324
if widget.get_active():
325
self.comp_window.show_all()
327
self.comp_window.hide()
329
def on_window_delete(self, widget, event):
330
if self.check_modified():
335
def on_action_net_toggled(self, widget):
336
if widget.get_active():
337
self.comp_window.uncheck_all_buttons()
338
widget.set_active(True)
339
self.comp_window.checked_button = const.component_net
340
self.drawarea.pushed_component = comp_dict[const.component_net]
341
elif self.comp_window.checked_button == const.component_net:
342
self.comp_window.checked_button = const.component_none
343
self.drawarea.pushed_component = comp_dict[const.component_none]
344
self.drawarea.queue_draw()
346
def on_action_play_toggled(self, widget):
347
if self.running_mode:
348
self.running_mode = False
349
if self.circuit.action_count > 0:
350
self.action_undo.set_sensitive(True)
351
if self.circuit.action_count < len(self.circuit.components_history) - 1:
352
self.action_redo.set_sensitive(True)
353
self.action_property.set_sensitive(True)
354
self.action_components.set_sensitive(True)
355
self.action_net.set_sensitive(True)
356
self.action_chart.set_sensitive(False)
357
self.action_chart.set_active(False)
358
self.chart_window.hide()
359
self.statusbar.push(0, "")
361
self.running_mode = True
362
self.circuit.selected_components = []
363
self.action_undo.set_sensitive(False)
364
self.action_redo.set_sensitive(False)
365
self.action_cut.set_sensitive(False)
366
self.action_copy.set_sensitive(False)
367
self.action_delete.set_sensitive(False)
368
self.action_property.set_sensitive(False)
369
self.action_property.set_active(False)
370
self.action_components.set_sensitive(False)
371
self.action_components.set_active(False)
372
self.action_net.set_sensitive(False)
373
self.action_chart.set_sensitive(True)
374
self.comp_window.hide()
375
self.prop_window.hide()
376
self.comp_window.checked_button = const.component_none
377
self.drawarea.pushed_component = comp_dict[const.component_none]
378
self.circuit.analyze_connections()
379
self.circuit.initialize_logic()
380
if not self.circuit.analyze_logic():
381
self.chart_window.chartarea.createChart()
382
self.drawarea.redraw = True
383
self.drawarea.queue_draw()
385
def on_action_copy_pressed(self, widget):
388
def on_action_paste_pressed(self, widget):
391
def on_action_undo_pressed(self, widget):
393
if self.circuit.action_count == 0:
394
self.action_undo.set_sensitive(False)
395
self.action_redo.set_sensitive(True)
396
self.action_cut.set_sensitive(False)
397
self.action_copy.set_sensitive(False)
398
self.action_delete.set_sensitive(False)
399
self.drawarea.redraw = True
400
self.drawarea.queue_draw()
402
def on_action_redo_pressed(self, widget):
404
self.action_undo.set_sensitive(True)
405
if self.circuit.action_count == len(self.circuit.components_history) - 1:
406
self.action_redo.set_sensitive(False)
407
self.action_cut.set_sensitive(False)
408
self.action_copy.set_sensitive(False)
409
self.action_delete.set_sensitive(False)
410
self.drawarea.redraw = True
411
self.drawarea.queue_draw()
413
def on_action_delete_pressed(self, widget):
414
self.circuit.remove_selected_component()
415
self.drawarea.nearest_component = None
416
self.drawarea.preselected_component = None
417
self.circuit.push_history()
418
self.action_undo.set_sensitive(True)
419
self.action_redo.set_sensitive(False)
420
self.action_cut.set_sensitive(False)
421
self.action_copy.set_sensitive(False)
422
self.action_delete.set_sensitive(False)
423
self.drawarea.redraw = True
424
self.drawarea.queue_draw()
426
def on_action_property_toggled(self, widget):
427
if widget.get_active():
428
self.drawarea.set_selected_component_to_prop_window()
429
self.prop_window.show_all()
431
self.prop_window.hide()
433
def on_action_translate_pressed(self, widget):
434
webbrowser.open(const.devel_translate)
436
def on_action_bug_pressed(self, widget):
437
webbrowser.open(const.devel_bug)
439
def on_action_timingchart_pressed(self, widget):
440
if widget.get_active():
441
self.chart_window.show_all()
443
self.chart_window.hide()